Date: | 2011-06-19 10:57:18 (11 years 11 months ago) |
---|---|
Author: | Maarten ter Huurne |
Commit: | c9d94cdcee21e8aeed85632648c473235f14f3fe |
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 (5 diffs) |
Change Details
drivers/mmc/host/jz4740_mmc.c | ||
---|---|---|
24 | 24 | #include <linux/delay.h> |
25 | 25 | #include <linux/scatterlist.h> |
26 | 26 | #include <linux/clk.h> |
27 | #include <linux/cpufreq.h> | |
27 | 28 | |
28 | 29 | #include <linux/bitops.h> |
29 | 30 | #include <linux/gpio.h> |
... | ... | |
667 | 668 | jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_SDIO, enable); |
668 | 669 | } |
669 | 670 | |
671 | #ifdef CONFIG_CPU_FREQ | |
672 | ||
673 | static struct jz4740_mmc_host *cpufreq_host; | |
674 | ||
675 | static int jz4740_mmc_cpufreq_transition(struct notifier_block *nb, | |
676 | unsigned long val, void *data) | |
677 | { | |
678 | /* TODO: We only have to take action when the PLL freq changes: | |
679 | the main dividers have no influence on the MSC device clock. */ | |
680 | ||
681 | if (val == CPUFREQ_PRECHANGE) { | |
682 | mmc_claim_host(cpufreq_host->mmc); | |
683 | clk_disable(cpufreq_host->clk); | |
684 | } else if (val == CPUFREQ_POSTCHANGE) { | |
685 | struct mmc_ios *ios = &cpufreq_host->mmc->ios; | |
686 | if (ios->clock) | |
687 | jz4740_mmc_set_clock_rate(cpufreq_host, ios->clock); | |
688 | if (ios->power_mode != MMC_POWER_OFF) | |
689 | clk_enable(cpufreq_host->clk); | |
690 | mmc_release_host(cpufreq_host->mmc); | |
691 | } | |
692 | return 0; | |
693 | } | |
694 | ||
695 | static struct notifier_block jz4740_mmc_cpufreq_nb = { | |
696 | .notifier_call = jz4740_mmc_cpufreq_transition, | |
697 | }; | |
698 | ||
699 | static inline int jz4740_mmc_cpufreq_register(struct jz4740_mmc_host *host) | |
700 | { | |
701 | cpufreq_host = host; | |
702 | return cpufreq_register_notifier(&jz4740_mmc_cpufreq_nb, | |
703 | CPUFREQ_TRANSITION_NOTIFIER); | |
704 | } | |
705 | ||
706 | static inline void jz4740_mmc_cpufreq_unregister(void) | |
707 | { | |
708 | cpufreq_unregister_notifier(&jz4740_mmc_cpufreq_nb, | |
709 | CPUFREQ_TRANSITION_NOTIFIER); | |
710 | } | |
711 | ||
712 | #else | |
713 | ||
714 | static inline int jz4740_mmc_cpufreq_register(struct jz4740_mmc_host *host) | |
715 | { | |
716 | return 0; | |
717 | } | |
718 | ||
719 | static inline void jz4740_mmc_cpufreq_unregister(void) | |
720 | { | |
721 | } | |
722 | ||
723 | #endif | |
724 | ||
670 | 725 | static const struct mmc_host_ops jz4740_mmc_ops = { |
671 | 726 | .request = jz4740_mmc_request, |
672 | 727 | .set_ios = jz4740_mmc_set_ios, |
... | ... | |
789 | 844 | goto err_free_host; |
790 | 845 | } |
791 | 846 | |
847 | ret = jz4740_mmc_cpufreq_register(host); | |
848 | if (ret) { | |
849 | dev_err(&pdev->dev, | |
850 | "Failed to register cpufreq transition notifier\n"); | |
851 | goto err_free_host; | |
852 | } | |
853 | ||
792 | 854 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
793 | 855 | host->base = devm_ioremap_resource(&pdev->dev, res); |
794 | 856 | if (IS_ERR(host->base)) { |
795 | 857 | ret = PTR_ERR(host->base); |
796 | goto err_free_host; | |
858 | dev_err(&pdev->dev, "Failed to ioremap base memory\n"); | |
859 | goto err_cpufreq_unreg; | |
797 | 860 | } |
798 | 861 | |
799 | 862 | ret = jz_gpio_bulk_request(jz4740_mmc_pins, jz4740_mmc_num_pins(host)); |
800 | 863 | if (ret) { |
801 | 864 | dev_err(&pdev->dev, "Failed to request mmc pins: %d\n", ret); |
802 | goto err_free_host; | |
865 | goto err_cpufreq_unreg; | |
803 | 866 | } |
804 | 867 | |
805 | 868 | ret = jz4740_mmc_request_gpios(mmc, pdev); |
... | ... | |
856 | 919 | jz4740_mmc_free_gpios(pdev); |
857 | 920 | err_gpio_bulk_free: |
858 | 921 | jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host)); |
922 | err_cpufreq_unreg: | |
923 | jz4740_mmc_cpufreq_unregister(); | |
859 | 924 | err_free_host: |
860 | 925 | mmc_free_host(mmc); |
861 | 926 | |
... | ... | |
877 | 942 | jz4740_mmc_free_gpios(pdev); |
878 | 943 | jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host)); |
879 | 944 | |
945 | jz4740_mmc_cpufreq_unregister(); | |
880 | 946 | mmc_free_host(host->mmc); |
881 | 947 | |
882 | 948 | return 0; |
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