diff options
author | Tony Lin <tony.lin@freescale.com> | 2011-11-11 11:00:39 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-01-09 21:07:39 +0800 |
commit | b7194e8008bc1a5a81a3bbb447cba76a2480b763 (patch) | |
tree | 4818270df2d656c7a0dffa8282cdb0371142eb4e /drivers/misc | |
parent | 8a5a641b80d7e589585881a1aa78ead1511ab896 (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/Kconfig | 2 | ||||
-rw-r--r-- | drivers/misc/mxs-perfmon.c | 27 |
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; |