summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorTony Lin <tony.lin@freescale.com>2011-11-11 11:00:39 +0800
committerJason Liu <r64343@freescale.com>2012-01-09 21:07:39 +0800
commitb7194e8008bc1a5a81a3bbb447cba76a2480b763 (patch)
tree4818270df2d656c7a0dffa8282cdb0371142eb4e /drivers/misc
parent8a5a641b80d7e589585881a1aa78ead1511ab896 (diff)
ENGR00161951-1 [mx6q]performance monitor driver
add plt_init & plt_exit functions to structure, so that the driver would have chance to do platform specific init and exit Signed-off-by: Tony Lin <tony.lin@freescale.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig2
-rw-r--r--drivers/misc/mxs-perfmon.c27
2 files changed, 28 insertions, 1 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 32c3ffef1f62..b8bc353fa6aa 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -492,7 +492,7 @@ config PCH_PHUB
config MXS_PERFMON
tristate "i.MX Performance Monitor"
- depends on ARCH_MX50
+ depends on ARCH_MX50 || ARCH_MX6
default y
source "drivers/misc/c2port/Kconfig"
diff --git a/drivers/misc/mxs-perfmon.c b/drivers/misc/mxs-perfmon.c
index 94916e000e84..5986e1ca9508 100644
--- a/drivers/misc/mxs-perfmon.c
+++ b/drivers/misc/mxs-perfmon.c
@@ -27,6 +27,7 @@
#include <linux/platform_device.h>
#include <linux/sysfs.h>
#include <linux/io.h>
+#include <linux/clk.h>
#include <linux/fsl_devices.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -104,6 +105,7 @@ struct mxs_perfmon_data {
struct attribute_group attr_group;
unsigned int base;
unsigned int initial;
+ struct clk *clk;
/* attribute ** follow */
/* device_attribute follow */
};
@@ -150,6 +152,7 @@ perfmon_show(struct device *dev, struct device_attribute *attr, char *buf)
int idx;
u32 val;
ssize_t result = 0;
+ struct mxs_platform_perfmon_data *pdata = pdev->dev.platform_data;
idx = attr - devattr;
if ((unsigned int)idx >= pd->count)
@@ -163,6 +166,11 @@ perfmon_show(struct device *dev, struct device_attribute *attr, char *buf)
[idx - pd->pdata->bit_config_cnt];
if (!pd->initial) {
+ if (pd->clk)
+ clk_enable(pd->clk);
+ if (pdata->plt_init)
+ pdata->plt_init();
+
mxs_reset_block((void *)pd->base, true);
pd->initial = true;
}
@@ -204,6 +212,7 @@ perfmon_store(struct device *dev, struct device_attribute *attr,
struct mxs_perfmon_bit_config *pb;
int idx, r;
unsigned long val, newval;
+ struct mxs_platform_perfmon_data *pdata = pdev->dev.platform_data;
idx = attr - devattr;
if ((unsigned int)idx >= pd->count)
@@ -220,6 +229,11 @@ perfmon_store(struct device *dev, struct device_attribute *attr,
[idx - pd->pdata->bit_config_cnt];
if (!pd->initial) {
+ if (pd->clk)
+ clk_enable(pd->clk);
+ if (pdata->plt_init)
+ pdata->plt_init();
+
mxs_reset_block((void *)pd->base, true);
pd->initial = true;
}
@@ -278,6 +292,7 @@ static int __devinit mxs_perfmon_probe(struct platform_device *pdev)
struct device_attribute *devattr;
int i, cnt, size;
int err;
+ struct device *dev = &pdev->dev;
pdata = pdev->dev.platform_data;
if (pdata == NULL)
@@ -301,6 +316,7 @@ static int __devinit mxs_perfmon_probe(struct platform_device *pdev)
pd->pdata_common = pdata_common;
pd->base = (unsigned int)ioremap(res->start, res->end - res->start);
pd->initial = false;
+ pd->clk = clk_get(dev, "perfmon");
platform_set_drvdata(pdev, pd);
pd->count = cnt;
@@ -341,10 +357,21 @@ static int __devinit mxs_perfmon_probe(struct platform_device *pdev)
static int __devexit mxs_perfmon_remove(struct platform_device *pdev)
{
struct mxs_perfmon_data *pd;
+ struct mxs_platform_perfmon_data *pdata = pdev->dev.platform_data;;
pd = platform_get_drvdata(pdev);
sysfs_remove_group(&pdev->dev.kobj, &pd->attr_group);
platform_set_drvdata(pdev, NULL);
+
+ if (pdata->plt_exit)
+ pdata->plt_exit();
+
+ if (pd->clk) {
+ if (pd->initial)
+ clk_disable(pd->clk);
+ clk_put(pd->clk);
+ }
+
kfree(pd);
return 0;