Date: | 2011-06-19 10:57:18 (12 years 9 months ago) |
---|---|
Author: | Maarten ter Huurne |
Commit: | cdde9cf73945d547acd3e96f9508c79e84ad0bf1 |
Message: | 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. |
Files: |
drivers/mmc/host/jz4740_mmc.c (6 diffs) |
Change Details
drivers/mmc/host/jz4740_mmc.c | ||
---|---|---|
23 | 23 | #include <linux/delay.h> |
24 | 24 | #include <linux/scatterlist.h> |
25 | 25 | #include <linux/clk.h> |
26 | #include <linux/cpufreq.h> | |
26 | 27 | |
27 | 28 | #include <linux/bitops.h> |
28 | 29 | #include <linux/gpio.h> |
... | ... | |
688 | 689 | jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_SDIO, enable); |
689 | 690 | } |
690 | 691 | |
692 | #ifdef CONFIG_CPU_FREQ | |
693 | ||
694 | static struct jz4740_mmc_host *cpufreq_host; | |
695 | ||
696 | static int jz4740_mmc_cpufreq_transition(struct notifier_block *nb, | |
697 | unsigned long val, void *data) | |
698 | { | |
699 | /* TODO: We only have to take action when the PLL freq changes: | |
700 | the main dividers have no influence on the MSC device clock. */ | |
701 | ||
702 | if (val == CPUFREQ_PRECHANGE) { | |
703 | mmc_claim_host(cpufreq_host->mmc); | |
704 | clk_disable(cpufreq_host->clk); | |
705 | } else if (val == CPUFREQ_POSTCHANGE) { | |
706 | struct mmc_ios *ios = &cpufreq_host->mmc->ios; | |
707 | if (ios->clock) | |
708 | jz4740_mmc_set_clock_rate(cpufreq_host, ios->clock); | |
709 | if (ios->power_mode != MMC_POWER_OFF) | |
710 | clk_enable(cpufreq_host->clk); | |
711 | mmc_release_host(cpufreq_host->mmc); | |
712 | } | |
713 | return 0; | |
714 | } | |
715 | ||
716 | static struct notifier_block jz4740_mmc_cpufreq_nb = { | |
717 | .notifier_call = jz4740_mmc_cpufreq_transition, | |
718 | }; | |
719 | ||
720 | static inline int jz4740_mmc_cpufreq_register(struct jz4740_mmc_host *host) | |
721 | { | |
722 | cpufreq_host = host; | |
723 | return cpufreq_register_notifier(&jz4740_mmc_cpufreq_nb, | |
724 | CPUFREQ_TRANSITION_NOTIFIER); | |
725 | } | |
726 | ||
727 | static inline void jz4740_mmc_cpufreq_unregister(void) | |
728 | { | |
729 | cpufreq_unregister_notifier(&jz4740_mmc_cpufreq_nb, | |
730 | CPUFREQ_TRANSITION_NOTIFIER); | |
731 | } | |
732 | ||
733 | #else | |
734 | ||
735 | static inline int jz4740_mmc_cpufreq_register(struct jz4740_mmc_host *host) | |
736 | { | |
737 | return 0; | |
738 | } | |
739 | ||
740 | static inline void jz4740_mmc_cpufreq_unregister(void) | |
741 | { | |
742 | } | |
743 | ||
744 | #endif | |
745 | ||
691 | 746 | static const struct mmc_host_ops jz4740_mmc_ops = { |
692 | 747 | .request = jz4740_mmc_request, |
693 | 748 | .set_ios = jz4740_mmc_set_ios, |
... | ... | |
837 | 892 | goto err_free_host; |
838 | 893 | } |
839 | 894 | |
895 | ret = jz4740_mmc_cpufreq_register(host); | |
896 | if (ret) { | |
897 | dev_err(&pdev->dev, | |
898 | "Failed to register cpufreq transition notifier\n"); | |
899 | goto err_clk_put; | |
900 | } | |
901 | ||
840 | 902 | host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
841 | 903 | if (!host->mem) { |
842 | 904 | ret = -ENOENT; |
843 | 905 | dev_err(&pdev->dev, "Failed to get base platform memory\n"); |
844 | goto err_clk_put; | |
906 | goto err_cpufreq_unreg; | |
845 | 907 | } |
846 | 908 | |
847 | 909 | host->mem = request_mem_region(host->mem->start, |
... | ... | |
849 | 911 | if (!host->mem) { |
850 | 912 | ret = -EBUSY; |
851 | 913 | dev_err(&pdev->dev, "Failed to request base memory region\n"); |
852 | goto err_clk_put; | |
914 | goto err_cpufreq_unreg; | |
853 | 915 | } |
854 | 916 | |
855 | 917 | host->base = ioremap_nocache(host->mem->start, resource_size(host->mem)); |
... | ... | |
932 | 994 | iounmap(host->base); |
933 | 995 | err_release_mem_region: |
934 | 996 | release_mem_region(host->mem->start, resource_size(host->mem)); |
997 | err_cpufreq_unreg: | |
998 | jz4740_mmc_cpufreq_unregister(); | |
935 | 999 | err_clk_put: |
936 | 1000 | clk_put(host->clk); |
937 | 1001 | err_free_host: |
... | ... | |
961 | 1025 | iounmap(host->base); |
962 | 1026 | release_mem_region(host->mem->start, resource_size(host->mem)); |
963 | 1027 | |
1028 | jz4740_mmc_cpufreq_unregister(); | |
964 | 1029 | clk_put(host->clk); |
965 | 1030 | |
966 | 1031 | platform_set_drvdata(pdev, NULL); |
Branches:
ben-wpan
ben-wpan-stefan
5396a9238205f20f811ea57898980d3ca82df0b6
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9