diff options
author | Olof Johansson <olof@lixom.net> | 2013-02-12 17:59:50 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-02-12 18:00:14 -0500 |
commit | b22d18c3b412f1a8877c59f043a0a8334d19d50c (patch) | |
tree | a8c041c84eaa78b5fd804b06ec0123d961174609 /drivers/mfd/db8500-prcmu.c | |
parent | a900e5d9971860f2c400ed84d529c891fcd9a3b2 (diff) | |
parent | 05ec260edecaf3dc214cff49d43b1ad9b2cbb710 (diff) |
Merge tag 'for-arm-soc-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson into next/cleanup
From Linus Walleij:
Two fixes for broken <mach/id.h> cleanup.
* tag 'for-arm-soc-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson:
mfd: db8500-prcmu: update resource passing
drivers/db8500-cpufreq: delete dangling include
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/mfd/db8500-prcmu.c')
-rw-r--r-- | drivers/mfd/db8500-prcmu.c | 122 |
1 files changed, 79 insertions, 43 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 6658f3cb0832..1192518e1aca 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -38,9 +38,6 @@ | |||
38 | #include <mach/db8500-regs.h> | 38 | #include <mach/db8500-regs.h> |
39 | #include "dbx500-prcmu-regs.h" | 39 | #include "dbx500-prcmu-regs.h" |
40 | 40 | ||
41 | /* Offset for the firmware version within the TCPM */ | ||
42 | #define PRCMU_FW_VERSION_OFFSET 0xA4 | ||
43 | |||
44 | /* Index of different voltages to be used when accessing AVSData */ | 41 | /* Index of different voltages to be used when accessing AVSData */ |
45 | #define PRCM_AVS_BASE 0x2FC | 42 | #define PRCM_AVS_BASE 0x2FC |
46 | #define PRCM_AVS_VBB_RET (PRCM_AVS_BASE + 0x0) | 43 | #define PRCM_AVS_VBB_RET (PRCM_AVS_BASE + 0x0) |
@@ -2704,21 +2701,43 @@ static struct irq_chip prcmu_irq_chip = { | |||
2704 | .irq_unmask = prcmu_irq_unmask, | 2701 | .irq_unmask = prcmu_irq_unmask, |
2705 | }; | 2702 | }; |
2706 | 2703 | ||
2707 | static char *fw_project_name(u8 project) | 2704 | static __init char *fw_project_name(u32 project) |
2708 | { | 2705 | { |
2709 | switch (project) { | 2706 | switch (project) { |
2710 | case PRCMU_FW_PROJECT_U8500: | 2707 | case PRCMU_FW_PROJECT_U8500: |
2711 | return "U8500"; | 2708 | return "U8500"; |
2712 | case PRCMU_FW_PROJECT_U8500_C2: | 2709 | case PRCMU_FW_PROJECT_U8400: |
2713 | return "U8500 C2"; | 2710 | return "U8400"; |
2714 | case PRCMU_FW_PROJECT_U9500: | 2711 | case PRCMU_FW_PROJECT_U9500: |
2715 | return "U9500"; | 2712 | return "U9500"; |
2716 | case PRCMU_FW_PROJECT_U9500_C2: | 2713 | case PRCMU_FW_PROJECT_U8500_MBB: |
2717 | return "U9500 C2"; | 2714 | return "U8500 MBB"; |
2715 | case PRCMU_FW_PROJECT_U8500_C1: | ||
2716 | return "U8500 C1"; | ||
2717 | case PRCMU_FW_PROJECT_U8500_C2: | ||
2718 | return "U8500 C2"; | ||
2719 | case PRCMU_FW_PROJECT_U8500_C3: | ||
2720 | return "U8500 C3"; | ||
2721 | case PRCMU_FW_PROJECT_U8500_C4: | ||
2722 | return "U8500 C4"; | ||
2723 | case PRCMU_FW_PROJECT_U9500_MBL: | ||
2724 | return "U9500 MBL"; | ||
2725 | case PRCMU_FW_PROJECT_U8500_MBL: | ||
2726 | return "U8500 MBL"; | ||
2727 | case PRCMU_FW_PROJECT_U8500_MBL2: | ||
2728 | return "U8500 MBL2"; | ||
2718 | case PRCMU_FW_PROJECT_U8520: | 2729 | case PRCMU_FW_PROJECT_U8520: |
2719 | return "U8520"; | 2730 | return "U8520 MBL"; |
2720 | case PRCMU_FW_PROJECT_U8420: | 2731 | case PRCMU_FW_PROJECT_U8420: |
2721 | return "U8420"; | 2732 | return "U8420"; |
2733 | case PRCMU_FW_PROJECT_U9540: | ||
2734 | return "U9540"; | ||
2735 | case PRCMU_FW_PROJECT_A9420: | ||
2736 | return "A9420"; | ||
2737 | case PRCMU_FW_PROJECT_L8540: | ||
2738 | return "L8540"; | ||
2739 | case PRCMU_FW_PROJECT_L8580: | ||
2740 | return "L8580"; | ||
2722 | default: | 2741 | default: |
2723 | return "Unknown"; | 2742 | return "Unknown"; |
2724 | } | 2743 | } |
@@ -2764,37 +2783,44 @@ static int db8500_irq_init(struct device_node *np) | |||
2764 | return 0; | 2783 | return 0; |
2765 | } | 2784 | } |
2766 | 2785 | ||
2767 | void __init db8500_prcmu_early_init(void) | 2786 | static void dbx500_fw_version_init(struct platform_device *pdev, |
2787 | u32 version_offset) | ||
2768 | { | 2788 | { |
2769 | if (cpu_is_u8500v2() || cpu_is_u9540()) { | 2789 | struct resource *res; |
2770 | void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K); | 2790 | void __iomem *tcpm_base; |
2771 | |||
2772 | if (tcpm_base != NULL) { | ||
2773 | u32 version; | ||
2774 | version = readl(tcpm_base + PRCMU_FW_VERSION_OFFSET); | ||
2775 | fw_info.version.project = version & 0xFF; | ||
2776 | fw_info.version.api_version = (version >> 8) & 0xFF; | ||
2777 | fw_info.version.func_version = (version >> 16) & 0xFF; | ||
2778 | fw_info.version.errata = (version >> 24) & 0xFF; | ||
2779 | fw_info.valid = true; | ||
2780 | pr_info("PRCMU firmware: %s, version %d.%d.%d\n", | ||
2781 | fw_project_name(fw_info.version.project), | ||
2782 | (version >> 8) & 0xFF, (version >> 16) & 0xFF, | ||
2783 | (version >> 24) & 0xFF); | ||
2784 | iounmap(tcpm_base); | ||
2785 | } | ||
2786 | 2791 | ||
2787 | if (cpu_is_u9540()) | 2792 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
2788 | tcdm_base = ioremap_nocache(U8500_PRCMU_TCDM_BASE, | 2793 | "prcmu-tcpm"); |
2789 | SZ_4K + SZ_8K) + SZ_8K; | 2794 | if (!res) { |
2790 | else | 2795 | dev_err(&pdev->dev, |
2791 | tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); | 2796 | "Error: no prcmu tcpm memory region provided\n"); |
2792 | } else { | 2797 | return; |
2793 | pr_err("prcmu: Unsupported chip version\n"); | 2798 | } |
2794 | BUG(); | 2799 | tcpm_base = ioremap(res->start, resource_size(res)); |
2800 | if (tcpm_base != NULL) { | ||
2801 | u32 version; | ||
2802 | |||
2803 | version = readl(tcpm_base + version_offset); | ||
2804 | fw_info.version.project = (version & 0xFF); | ||
2805 | fw_info.version.api_version = (version >> 8) & 0xFF; | ||
2806 | fw_info.version.func_version = (version >> 16) & 0xFF; | ||
2807 | fw_info.version.errata = (version >> 24) & 0xFF; | ||
2808 | strncpy(fw_info.version.project_name, | ||
2809 | fw_project_name(fw_info.version.project), | ||
2810 | PRCMU_FW_PROJECT_NAME_LEN); | ||
2811 | fw_info.valid = true; | ||
2812 | pr_info("PRCMU firmware: %s(%d), version %d.%d.%d\n", | ||
2813 | fw_info.version.project_name, | ||
2814 | fw_info.version.project, | ||
2815 | fw_info.version.api_version, | ||
2816 | fw_info.version.func_version, | ||
2817 | fw_info.version.errata); | ||
2818 | iounmap(tcpm_base); | ||
2795 | } | 2819 | } |
2796 | tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); | 2820 | } |
2797 | 2821 | ||
2822 | void __init db8500_prcmu_early_init(void) | ||
2823 | { | ||
2798 | spin_lock_init(&mb0_transfer.lock); | 2824 | spin_lock_init(&mb0_transfer.lock); |
2799 | spin_lock_init(&mb0_transfer.dbb_irqs_lock); | 2825 | spin_lock_init(&mb0_transfer.dbb_irqs_lock); |
2800 | mutex_init(&mb0_transfer.ac_wake_lock); | 2826 | mutex_init(&mb0_transfer.ac_wake_lock); |
@@ -3104,20 +3130,30 @@ static void db8500_prcmu_update_cpufreq(void) | |||
3104 | */ | 3130 | */ |
3105 | static int db8500_prcmu_probe(struct platform_device *pdev) | 3131 | static int db8500_prcmu_probe(struct platform_device *pdev) |
3106 | { | 3132 | { |
3107 | struct ab8500_platform_data *ab8500_platdata = pdev->dev.platform_data; | ||
3108 | struct device_node *np = pdev->dev.of_node; | 3133 | struct device_node *np = pdev->dev.of_node; |
3134 | struct prcmu_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
3109 | int irq = 0, err = 0, i; | 3135 | int irq = 0, err = 0, i; |
3136 | struct resource *res; | ||
3110 | 3137 | ||
3111 | init_prcm_registers(); | 3138 | init_prcm_registers(); |
3112 | 3139 | ||
3140 | dbx500_fw_version_init(pdev, pdata->version_offset); | ||
3141 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm"); | ||
3142 | if (!res) { | ||
3143 | dev_err(&pdev->dev, "no prcmu tcdm region provided\n"); | ||
3144 | return -ENOENT; | ||
3145 | } | ||
3146 | tcdm_base = devm_ioremap(&pdev->dev, res->start, | ||
3147 | resource_size(res)); | ||
3148 | |||
3113 | /* Clean up the mailbox interrupts after pre-kernel code. */ | 3149 | /* Clean up the mailbox interrupts after pre-kernel code. */ |
3114 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); | 3150 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); |
3115 | 3151 | ||
3116 | if (np) | 3152 | irq = platform_get_irq(pdev, 0); |
3117 | irq = platform_get_irq(pdev, 0); | 3153 | if (irq <= 0) { |
3118 | 3154 | dev_err(&pdev->dev, "no prcmu irq provided\n"); | |
3119 | if (!np || irq <= 0) | 3155 | return -ENOENT; |
3120 | irq = IRQ_DB8500_PRCMU1; | 3156 | } |
3121 | 3157 | ||
3122 | err = request_threaded_irq(irq, prcmu_irq_handler, | 3158 | err = request_threaded_irq(irq, prcmu_irq_handler, |
3123 | prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); | 3159 | prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); |
@@ -3131,7 +3167,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev) | |||
3131 | 3167 | ||
3132 | for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) { | 3168 | for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) { |
3133 | if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) { | 3169 | if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) { |
3134 | db8500_prcmu_devs[i].platform_data = ab8500_platdata; | 3170 | db8500_prcmu_devs[i].platform_data = pdata->ab_platdata; |
3135 | db8500_prcmu_devs[i].pdata_size = sizeof(struct ab8500_platform_data); | 3171 | db8500_prcmu_devs[i].pdata_size = sizeof(struct ab8500_platform_data); |
3136 | } | 3172 | } |
3137 | } | 3173 | } |