aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/db8500-prcmu.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-02-12 17:59:50 -0500
committerOlof Johansson <olof@lixom.net>2013-02-12 18:00:14 -0500
commitb22d18c3b412f1a8877c59f043a0a8334d19d50c (patch)
treea8c041c84eaa78b5fd804b06ec0123d961174609 /drivers/mfd/db8500-prcmu.c
parenta900e5d9971860f2c400ed84d529c891fcd9a3b2 (diff)
parent05ec260edecaf3dc214cff49d43b1ad9b2cbb710 (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.c122
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
2707static char *fw_project_name(u8 project) 2704static __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
2767void __init db8500_prcmu_early_init(void) 2786static 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
2822void __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 */
3105static int db8500_prcmu_probe(struct platform_device *pdev) 3131static 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 }