From 901d1719b048c8a6d70a1d17b9930b38549dfd70 Mon Sep 17 00:00:00 2001 From: Pratik Patel Date: Fri, 25 May 2012 22:23:52 -0700 Subject: [PATCH] cs: let each driver manage the clk for its device Each device driver manages its own clk by using the clk apis that now support CoreSight clock. Remove qdss clock wrapper functions and their usage. Change-Id: If73198f273f69e5525a6444e7a7c277c20c96111 Signed-off-by: Pratik Patel --- arch/arm/mach-msm/clock-8960.c | 24 +++++++++---- drivers/cs/cs-etb.c | 27 ++++++++++++++- drivers/cs/cs-etm.c | 36 +++++++++++++++---- drivers/cs/cs-funnel.c | 30 +++++++++++++++- drivers/cs/cs-priv.h | 4 +-- drivers/cs/cs-stm.c | 29 ++++++++++++++-- drivers/cs/cs-tpiu.c | 17 +++++++++ drivers/cs/cs.c | 63 ---------------------------------- include/linux/cs.h | 10 +++--- 9 files changed, 155 insertions(+), 85 deletions(-) diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c index 481cd3d0b1a..fa912491f31 100644 --- a/arch/arm/mach-msm/clock-8960.c +++ b/arch/arm/mach-msm/clock-8960.c @@ -5069,8 +5069,12 @@ static struct clk_lookup msm_clocks_8064[] = { CLK_LOOKUP("mem_a_clk", ebi1_msmbus_a_clk.c, "msm_bus"), CLK_LOOKUP("dfab_clk", dfab_msmbus_clk.c, "msm_bus"), CLK_LOOKUP("dfab_a_clk", dfab_msmbus_a_clk.c, "msm_bus"), - CLK_LOOKUP("core_clk", qdss_clk.c, "msm_qdss"), - CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "msm_qdss"), + CLK_LOOKUP("core_a_clk", qdss_a_clk.c, ""), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etb.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_tpiu.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_funnel.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_stm.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etm.0"), CLK_LOOKUP("ebi1_clk", ebi1_clk.c, ""), CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, ""), @@ -5395,8 +5399,12 @@ static struct clk_lookup msm_clocks_8960[] = { CLK_LOOKUP("mem_a_clk", ebi1_msmbus_a_clk.c, "msm_bus"), CLK_LOOKUP("dfab_clk", dfab_msmbus_clk.c, "msm_bus"), CLK_LOOKUP("dfab_a_clk", dfab_msmbus_a_clk.c, "msm_bus"), - CLK_LOOKUP("core_clk", qdss_clk.c, "msm_qdss"), - CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "msm_qdss"), + CLK_LOOKUP("core_a_clk", qdss_a_clk.c, ""), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etb.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_tpiu.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_funnel.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_stm.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etm.0"), CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL), CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, NULL), @@ -5713,8 +5721,12 @@ static struct clk_lookup msm_clocks_8930[] = { CLK_LOOKUP("mem_a_clk", ebi1_msmbus_a_clk.c, "msm_bus"), CLK_LOOKUP("dfab_clk", dfab_msmbus_clk.c, "msm_bus"), CLK_LOOKUP("dfab_a_clk", dfab_msmbus_a_clk.c, "msm_bus"), - CLK_LOOKUP("core_clk", qdss_clk.c, "msm_qdss"), - CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "msm_qdss"), + CLK_LOOKUP("core_a_clk", qdss_a_clk.c, ""), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etb.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_tpiu.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_funnel.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_stm.0"), + CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etm.0"), CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL), CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, NULL), diff --git a/drivers/cs/cs-etb.c b/drivers/cs/cs-etb.c index 84d8e727a0d..0739057d733 100644 --- a/drivers/cs/cs-etb.c +++ b/drivers/cs/cs-etb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "cs-priv.h" @@ -74,6 +75,7 @@ struct etb_ctx { atomic_t in_use; struct device *dev; struct kobject *kobj; + struct clk *clk; uint32_t trigger_cntr; }; @@ -99,15 +101,22 @@ static void __etb_enable(void) ETB_LOCK(); } -void etb_enable(void) +int etb_enable(void) { + int ret; unsigned long flags; + ret = clk_prepare_enable(etb.clk); + if (ret) + return ret; + spin_lock_irqsave(&etb.spinlock, flags); __etb_enable(); etb.enabled = true; dev_info(etb.dev, "ETB enabled\n"); spin_unlock_irqrestore(&etb.spinlock, flags); + + return 0; } static void __etb_disable(void) @@ -147,6 +156,8 @@ void etb_disable(void) etb.enabled = false; dev_info(etb.dev, "ETB disabled\n"); spin_unlock_irqrestore(&etb.spinlock, flags); + + clk_disable_unprepare(etb.clk); } static void __etb_dump(void) @@ -352,6 +363,16 @@ static int __devinit etb_probe(struct platform_device *pdev) spin_lock_init(&etb.spinlock); + etb.clk = clk_get(etb.dev, "core_clk"); + if (IS_ERR(etb.clk)) { + ret = PTR_ERR(etb.clk); + goto err_clk_get; + } + + ret = clk_set_rate(etb.clk, CS_CLK_RATE_TRACE); + if (ret) + goto err_clk_rate; + ret = misc_register(&etb_misc); if (ret) goto err_misc; @@ -370,6 +391,9 @@ static int __devinit etb_probe(struct platform_device *pdev) err_alloc: misc_deregister(&etb_misc); err_misc: +err_clk_rate: + clk_put(etb.clk); +err_clk_get: iounmap(etb.base); err_ioremap: err_res: @@ -384,6 +408,7 @@ static int __devexit etb_remove(struct platform_device *pdev) etb_sysfs_exit(); kfree(etb.buf); misc_deregister(&etb_misc); + clk_put(etb.clk); iounmap(etb.base); return 0; diff --git a/drivers/cs/cs-etm.c b/drivers/cs/cs-etm.c index 724cc71838d..da7fe0c430c 100644 --- a/drivers/cs/cs-etm.c +++ b/drivers/cs/cs-etm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -161,6 +162,7 @@ struct etm_ctx { struct mutex mutex; struct device *dev; struct kobject *kobj; + struct clk *clk; uint8_t arch; uint8_t nr_addr_cmp; uint8_t nr_cntr; @@ -351,6 +353,10 @@ static int etm_enable(void) */ pm_qos_update_request(&etm.qos_req, 0); + ret = clk_prepare_enable(etm.clk); + if (ret) + goto err_clk; + ret = qdss_enable(etm.src); if (ret) goto err_qdss; @@ -367,6 +373,8 @@ static int etm_enable(void) return 0; err_qdss: + clk_disable_unprepare(etm.clk); +err_clk: pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE); wake_unlock(&etm.wake_lock); err: @@ -409,9 +417,11 @@ static int etm_disable(void) for_each_online_cpu(cpu) __etm_disable(cpu); + etm.enabled = false; + qdss_disable(etm.src); - etm.enabled = false; + clk_disable_unprepare(etm.clk); pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE); wake_unlock(&etm.wake_lock); @@ -1253,9 +1263,19 @@ static int __devinit etm_probe(struct platform_device *pdev) goto err_qdssget; } - ret = qdss_clk_enable(); + etm.clk = clk_get(etm.dev, "core_clk"); + if (IS_ERR(etm.clk)) { + ret = PTR_ERR(etm.clk); + goto err_clk_get; + } + + ret = clk_set_rate(etm.clk, CS_CLK_RATE_TRACE); if (ret) - goto err_clk; + goto err_clk_rate; + + ret = clk_prepare_enable(etm.clk); + if (ret) + goto err_clk_enable; ret = etm_arch_init(); if (ret) @@ -1267,7 +1287,7 @@ static int __devinit etm_probe(struct platform_device *pdev) etm.enabled = false; - qdss_clk_disable(); + clk_disable_unprepare(etm.clk); dev_info(etm.dev, "ETM initialized\n"); @@ -1278,8 +1298,11 @@ static int __devinit etm_probe(struct platform_device *pdev) err_sysfs: err_arch: - qdss_clk_disable(); -err_clk: + clk_disable_unprepare(etm.clk); +err_clk_enable: +err_clk_rate: + clk_put(etm.clk); +err_clk_get: qdss_put(etm.src); err_qdssget: pm_qos_remove_request(&etm.qos_req); @@ -1297,6 +1320,7 @@ static int __devexit etm_remove(struct platform_device *pdev) if (etm.enabled) etm_disable(); etm_sysfs_exit(); + clk_put(etm.clk); qdss_put(etm.src); pm_qos_remove_request(&etm.qos_req); wake_lock_destroy(&etm.wake_lock); diff --git a/drivers/cs/cs-funnel.c b/drivers/cs/cs-funnel.c index 2ae8ac95509..94d18f3312c 100644 --- a/drivers/cs/cs-funnel.c +++ b/drivers/cs/cs-funnel.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "cs-priv.h" @@ -56,6 +57,7 @@ struct funnel_ctx { struct mutex mutex; struct device *dev; struct kobject *kobj; + struct clk *clk; uint32_t priority; }; @@ -77,14 +79,22 @@ static void __funnel_enable(uint8_t id, uint32_t port_mask) FUNNEL_LOCK(id); } -void funnel_enable(uint8_t id, uint32_t port_mask) +int funnel_enable(uint8_t id, uint32_t port_mask) { + int ret; + + ret = clk_prepare_enable(funnel.clk); + if (ret) + return ret; + mutex_lock(&funnel.mutex); __funnel_enable(id, port_mask); funnel.enabled = true; dev_info(funnel.dev, "FUNNEL port mask 0x%lx enabled\n", (unsigned long) port_mask); mutex_unlock(&funnel.mutex); + + return 0; } static void __funnel_disable(uint8_t id, uint32_t port_mask) @@ -108,6 +118,8 @@ void funnel_disable(uint8_t id, uint32_t port_mask) dev_info(funnel.dev, "FUNNEL port mask 0x%lx disabled\n", (unsigned long) port_mask); mutex_unlock(&funnel.mutex); + + clk_disable_unprepare(funnel.clk); } #define FUNNEL_ATTR(__name) \ @@ -187,11 +199,26 @@ static int __devinit funnel_probe(struct platform_device *pdev) mutex_init(&funnel.mutex); + funnel.clk = clk_get(funnel.dev, "core_clk"); + if (IS_ERR(funnel.clk)) { + ret = PTR_ERR(funnel.clk); + goto err_clk_get; + } + + ret = clk_set_rate(funnel.clk, CS_CLK_RATE_TRACE); + if (ret) + goto err_clk_rate; + funnel_sysfs_init(); dev_info(funnel.dev, "FUNNEL initialized\n"); return 0; +err_clk_rate: + clk_put(funnel.clk); +err_clk_get: + mutex_destroy(&funnel.mutex); + iounmap(funnel.base); err_ioremap: err_res: dev_err(funnel.dev, "FUNNEL init failed\n"); @@ -203,6 +230,7 @@ static int __devexit funnel_remove(struct platform_device *pdev) if (funnel.enabled) funnel_disable(0x0, 0xFF); funnel_sysfs_exit(); + clk_put(funnel.clk); mutex_destroy(&funnel.mutex); iounmap(funnel.base); diff --git a/drivers/cs/cs-priv.h b/drivers/cs/cs-priv.h index d89f461890d..a4028f5d1de 100644 --- a/drivers/cs/cs-priv.h +++ b/drivers/cs/cs-priv.h @@ -36,11 +36,11 @@ #define BMVAL(val, lsb, msb) ((val & BM(lsb, msb)) >> lsb) #define BVAL(val, n) ((val & BIT(n)) >> n) -void etb_enable(void); +int etb_enable(void); void etb_disable(void); void etb_dump(void); void tpiu_disable(void); -void funnel_enable(uint8_t id, uint32_t port_mask); +int funnel_enable(uint8_t id, uint32_t port_mask); void funnel_disable(uint8_t id, uint32_t port_mask); struct kobject *qdss_get_modulekobj(void); diff --git a/drivers/cs/cs-stm.c b/drivers/cs/cs-stm.c index ddc22a3d5d6..9c296be8c03 100644 --- a/drivers/cs/cs-stm.c +++ b/drivers/cs/cs-stm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +99,7 @@ struct stm_ctx { struct qdss_source *src; struct device *dev; struct kobject *kobj; + struct clk *clk; uint32_t entity; struct channel_space chs; }; @@ -129,9 +131,13 @@ static int stm_enable(void) goto err; } + ret = clk_prepare_enable(stm.clk); + if (ret) + goto err_clk; + ret = qdss_enable(stm.src); if (ret) - goto err; + goto err_qdss; __stm_enable(); @@ -140,6 +146,9 @@ static int stm_enable(void) dev_info(stm.dev, "STM tracing enabled\n"); return 0; +err_qdss: + clk_disable_unprepare(stm.clk); +err_clk: err: return ret; } @@ -167,9 +176,11 @@ static int stm_disable(void) __stm_disable(); + stm.enabled = false; + qdss_disable(stm.src); - stm.enabled = false; + clk_disable_unprepare(stm.clk); dev_info(stm.dev, "STM tracing disabled\n"); return 0; @@ -531,6 +542,16 @@ static int __devinit stm_probe(struct platform_device *pdev) goto err_qdssget; } + stm.clk = clk_get(stm.dev, "core_clk"); + if (IS_ERR(stm.clk)) { + ret = PTR_ERR(stm.clk); + goto err_clk_get; + } + + ret = clk_set_rate(stm.clk, CS_CLK_RATE_TRACE); + if (ret) + goto err_clk_rate; + ret = stm_sysfs_init(); if (ret) goto err_sysfs; @@ -542,6 +563,9 @@ static int __devinit stm_probe(struct platform_device *pdev) return 0; err_sysfs: +err_clk_rate: + clk_put(stm.clk); +err_clk_get: qdss_put(stm.src); err_qdssget: misc_deregister(&stm_misc); @@ -563,6 +587,7 @@ static int __devexit stm_remove(struct platform_device *pdev) if (stm.enabled) stm_disable(); stm_sysfs_exit(); + clk_put(stm.clk); qdss_put(stm.src); misc_deregister(&stm_misc); iounmap(stm.chs.base); diff --git a/drivers/cs/cs-tpiu.c b/drivers/cs/cs-tpiu.c index c5e28ebb0fe..8191d2c959b 100644 --- a/drivers/cs/cs-tpiu.c +++ b/drivers/cs/cs-tpiu.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "cs-priv.h" @@ -60,6 +61,7 @@ struct tpiu_ctx { void __iomem *base; bool enabled; struct device *dev; + struct clk *clk; }; static struct tpiu_ctx tpiu; @@ -100,9 +102,23 @@ static int __devinit tpiu_probe(struct platform_device *pdev) tpiu.dev = &pdev->dev; + tpiu.clk = clk_get(tpiu.dev, "core_clk"); + if (IS_ERR(tpiu.clk)) { + ret = PTR_ERR(tpiu.clk); + goto err_clk_get; + } + + ret = clk_set_rate(tpiu.clk, CS_CLK_RATE_TRACE); + if (ret) + goto err_clk_rate; + dev_info(tpiu.dev, "TPIU initialized\n"); return 0; +err_clk_rate: + clk_put(tpiu.clk); +err_clk_get: + iounmap(tpiu.base); err_ioremap: err_res: dev_err(tpiu.dev, "TPIU init failed\n"); @@ -113,6 +129,7 @@ static int __devexit tpiu_remove(struct platform_device *pdev) { if (tpiu.enabled) tpiu_disable(); + clk_put(tpiu.clk); iounmap(tpiu.base); return 0; diff --git a/drivers/cs/cs.c b/drivers/cs/cs.c index acc22a4f74b..ee02f90045a 100644 --- a/drivers/cs/cs.c +++ b/drivers/cs/cs.c @@ -28,11 +28,6 @@ #define MAX_STR_LEN (65535) -enum { - QDSS_CLK_OFF, - QDSS_CLK_ON_DBG, - QDSS_CLK_ON_HSDBG, -}; static LIST_HEAD(cs_orph_conns); static DEFINE_MUTEX(cs_orph_conns_mutex); @@ -387,19 +382,12 @@ EXPORT_SYMBOL(qdss_put); */ int qdss_enable(struct qdss_source *src) { - int ret; - if (!src) return -EINVAL; - ret = qdss_clk_enable(); - if (ret) - goto err; - if (qdss.afamily) { mutex_lock(&qdss.sink_mutex); if (qdss.sink_count == 0) { - etb_disable(); tpiu_disable(); /* enable ETB first to avoid losing any trace data */ etb_enable(); @@ -410,8 +398,6 @@ int qdss_enable(struct qdss_source *src) funnel_enable(0x0, src->fport_mask); return 0; -err: - return ret; } EXPORT_SYMBOL(qdss_enable); @@ -443,7 +429,6 @@ void qdss_disable(struct qdss_source *src) } funnel_disable(0x0, src->fport_mask); - qdss_clk_disable(); return; out: mutex_unlock(&qdss.sink_mutex); @@ -470,37 +455,6 @@ void qdss_disable_sink(void) } EXPORT_SYMBOL(qdss_disable_sink); -/** - * qdss_clk_enable - enable qdss clocks - * - * Enables qdss clocks - * - * CONTEXT: - * Might sleep. Should be called from a non-atomic context. - * - * RETURNS: - * 0 on success, non-zero on failure - */ -int qdss_clk_enable(void) -{ - return clk_prepare_enable(qdss.clk); -} -EXPORT_SYMBOL(qdss_clk_enable); - -/** - * qdss_clk_disable - disable qdss clocks - * - * Disables qdss clocks - * - * CONTEXT: - * Might sleep. Should be called from a non-atomic context. - */ -void qdss_clk_disable(void) -{ - clk_disable_unprepare(qdss.clk); -} -EXPORT_SYMBOL(qdss_clk_disable); - struct kobject *qdss_get_modulekobj(void) { return qdss.modulekobj; @@ -582,27 +536,11 @@ static int __devinit qdss_probe(struct platform_device *pdev) if (!pdata) goto err_pdata; - qdss.clk = clk_get(&pdev->dev, "core_clk"); - if (IS_ERR(qdss.clk)) { - ret = PTR_ERR(qdss.clk); - pr_info("clk get failed\n"); - goto err_clk_get; - } - - ret = clk_set_rate(qdss.clk, QDSS_CLK_ON_DBG); - if (ret) { - pr_info("clk rate failed\n"); - goto err_clk_rate; - } - qdss.afamily = pdata->afamily; qdss_add_sources(pdata->src_table, pdata->size); pr_info("QDSS arch initialized\n"); return 0; -err_clk_rate: - clk_put(qdss.clk); -err_clk_get: err_pdata: mutex_destroy(&qdss.sink_mutex); mutex_destroy(&qdss.sources_mutex); @@ -613,7 +551,6 @@ err_pdata: static int __devexit qdss_remove(struct platform_device *pdev) { qdss_sysfs_exit(); - clk_put(qdss.clk); mutex_destroy(&qdss.sink_mutex); mutex_destroy(&qdss.sources_mutex); diff --git a/include/linux/cs.h b/include/linux/cs.h index 1a0094c6b27..0e494b02b9c 100644 --- a/include/linux/cs.h +++ b/include/linux/cs.h @@ -38,6 +38,12 @@ #define ETM_ARCH_V3_3 (0x23) #define PFT_ARCH_V1_1 (0x31) +enum cs_clk_rate { + CS_CLK_RATE_OFF, + CS_CLK_RATE_TRACE, + CS_CLK_RATE_HSTRACE, +}; + enum cs_device_type { CS_DEVICE_TYPE_SOURCE, CS_DEVICE_TYPE_LINK, @@ -114,16 +120,12 @@ extern void qdss_put(struct qdss_source *src); extern int qdss_enable(struct qdss_source *src); extern void qdss_disable(struct qdss_source *src); extern void qdss_disable_sink(void); -extern int qdss_clk_enable(void); -extern void qdss_clk_disable(void); #else static inline struct qdss_source *qdss_get(const char *name) { return NULL; } static inline void qdss_put(struct qdss_source *src) {} static inline int qdss_enable(struct qdss_source *src) { return -ENOSYS; } static inline void qdss_disable(struct qdss_source *src) {} static inline void qdss_disable_sink(void) {} -static inline int qdss_clk_enable(void) { return -ENOSYS; } -static inline void qdss_clk_disable(void) {} #endif #endif