From 8f313bd0fd01042d55168559c2712a60896b2235 Mon Sep 17 00:00:00 2001 From: juhosg Date: Sun, 27 May 2012 15:01:32 +0000 Subject: xburst: add support for 3.3 git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31902 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- ...-Added-support-for-CPU-frequency-changing.patch | 129 +++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 target/linux/xburst/patches-3.3/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch (limited to 'target/linux/xburst/patches-3.3/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch') diff --git a/target/linux/xburst/patches-3.3/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch b/target/linux/xburst/patches-3.3/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch new file mode 100644 index 000000000..f42d67a6f --- /dev/null +++ b/target/linux/xburst/patches-3.3/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch @@ -0,0 +1,129 @@ +From b95144c1b702f98c7902c75beb83f323701eb7c5 Mon Sep 17 00:00:00 2001 +From: Maarten ter Huurne +Date: Sun, 19 Jun 2011 10:57:18 +0200 +Subject: [PATCH 13/21] MMC: JZ4740: Added support for CPU frequency changing. + +The MSC device clock is stopped before the frequency change. +After the change a new divider is computed and the clock is restarted. +Also the frequency change is postponed if an I/O operation is in progress. +--- + drivers/mmc/host/jz4740_mmc.c | 69 +++++++++++++++++++++++++++++++++++++++- + 1 files changed, 67 insertions(+), 2 deletions(-) + +--- a/drivers/mmc/host/jz4740_mmc.c ++++ b/drivers/mmc/host/jz4740_mmc.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -685,6 +686,60 @@ static void jz4740_mmc_enable_sdio_irq(s + jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_SDIO, enable); + } + ++#ifdef CONFIG_CPU_FREQ ++ ++static struct jz4740_mmc_host *cpufreq_host; ++ ++static int jz4740_mmc_cpufreq_transition(struct notifier_block *nb, ++ unsigned long val, void *data) ++{ ++ /* TODO: We only have to take action when the PLL freq changes: ++ the main dividers have no influence on the MSC device clock. */ ++ ++ if (val == CPUFREQ_PRECHANGE) { ++ mmc_claim_host(cpufreq_host->mmc); ++ clk_disable(cpufreq_host->clk); ++ } else if (val == CPUFREQ_POSTCHANGE) { ++ struct mmc_ios *ios = &cpufreq_host->mmc->ios; ++ if (ios->clock) ++ jz4740_mmc_set_clock_rate(cpufreq_host, ios->clock); ++ if (ios->power_mode != MMC_POWER_OFF) ++ clk_enable(cpufreq_host->clk); ++ mmc_release_host(cpufreq_host->mmc); ++ } ++ return 0; ++} ++ ++static struct notifier_block jz4740_mmc_cpufreq_nb = { ++ .notifier_call = jz4740_mmc_cpufreq_transition, ++}; ++ ++static inline int jz4740_mmc_cpufreq_register(struct jz4740_mmc_host *host) ++{ ++ cpufreq_host = host; ++ return cpufreq_register_notifier(&jz4740_mmc_cpufreq_nb, ++ CPUFREQ_TRANSITION_NOTIFIER); ++} ++ ++static inline void jz4740_mmc_cpufreq_unregister(void) ++{ ++ cpufreq_unregister_notifier(&jz4740_mmc_cpufreq_nb, ++ CPUFREQ_TRANSITION_NOTIFIER); ++} ++ ++#else ++ ++static inline int jz4740_mmc_cpufreq_register(struct jz4740_mmc_host *host) ++{ ++ return 0; ++} ++ ++static inline void jz4740_mmc_cpufreq_unregister(void) ++{ ++} ++ ++#endif ++ + static const struct mmc_host_ops jz4740_mmc_ops = { + .request = jz4740_mmc_request, + .set_ios = jz4740_mmc_set_ios, +@@ -834,11 +889,18 @@ static int __devinit jz4740_mmc_probe(st + goto err_free_host; + } + ++ ret = jz4740_mmc_cpufreq_register(host); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "Failed to register cpufreq transition notifier\n"); ++ goto err_clk_put; ++ } ++ + host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!host->mem) { + ret = -ENOENT; + dev_err(&pdev->dev, "Failed to get base platform memory\n"); +- goto err_clk_put; ++ goto err_cpufreq_unreg; + } + + host->mem = request_mem_region(host->mem->start, +@@ -846,7 +908,7 @@ static int __devinit jz4740_mmc_probe(st + if (!host->mem) { + ret = -EBUSY; + dev_err(&pdev->dev, "Failed to request base memory region\n"); +- goto err_clk_put; ++ goto err_cpufreq_unreg; + } + + host->base = ioremap_nocache(host->mem->start, resource_size(host->mem)); +@@ -929,6 +991,8 @@ err_iounmap: + iounmap(host->base); + err_release_mem_region: + release_mem_region(host->mem->start, resource_size(host->mem)); ++err_cpufreq_unreg: ++ jz4740_mmc_cpufreq_unregister(); + err_clk_put: + clk_put(host->clk); + err_free_host: +@@ -958,6 +1022,7 @@ static int __devexit jz4740_mmc_remove(s + iounmap(host->base); + release_mem_region(host->mem->start, resource_size(host->mem)); + ++ jz4740_mmc_cpufreq_unregister(); + clk_put(host->clk); + + platform_set_drvdata(pdev, NULL); -- cgit v1.2.3