diff options
Diffstat (limited to 'target/linux/xburst/patches-3.8/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch')
-rw-r--r-- | target/linux/xburst/patches-3.8/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/target/linux/xburst/patches-3.8/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch b/target/linux/xburst/patches-3.8/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch new file mode 100644 index 0000000000..1fb41fa4f7 --- /dev/null +++ b/target/linux/xburst/patches-3.8/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 <maarten@treewalker.org> +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 <linux/delay.h> + #include <linux/scatterlist.h> + #include <linux/clk.h> ++#include <linux/cpufreq.h> + + #include <linux/bitops.h> + #include <linux/gpio.h> +@@ -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 jz4740_mmc_probe(struct platf + 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 jz4740_mmc_probe(struct platf + 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 jz4740_mmc_remove(struct plat + 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); |