diff options
author | Arnd Bergmann <arnd@arndb.de> | 2013-03-21 17:51:07 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-04-08 07:58:15 -0400 |
commit | 55b175d7e6327939df82592ef279c534da323354 (patch) | |
tree | 94b298b8727e7371915d6160a165d6d0ae3cbebb /drivers/mfd/db8500-prcmu.c | |
parent | 90c29f980217745828096dee5504e15b5c865301 (diff) |
ARM: ux500: split out prcmu initialization
This untangles the final bits of the prcmu code from the platform
code:
* The IRQ_PRCMU_* definitions move from irqs-db8500.h into prcmu.c
because they are only of local significance.
* u8500_thsens_device goes into the prcmu, because it uses a PRCMU
IRQ that the platform does not see.
* IRQ_DB8500_AB8500 and IRQ_PRCMU_BASE go into the platform data
because the PRCMU does not see it.
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
[Fixed a oneliner bug]
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/mfd/db8500-prcmu.c')
-rw-r--r-- | drivers/mfd/db8500-prcmu.c | 140 |
1 files changed, 111 insertions, 29 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 0f99b01afa88..21434beb420a 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/regulator/machine.h> | 33 | #include <linux/regulator/machine.h> |
34 | #include <linux/cpufreq.h> | 34 | #include <linux/cpufreq.h> |
35 | #include <linux/platform_data/ux500_wdt.h> | 35 | #include <linux/platform_data/ux500_wdt.h> |
36 | #include <mach/irqs.h> | 36 | #include <linux/platform_data/db8500_thermal.h> |
37 | #include "dbx500-prcmu-regs.h" | 37 | #include "dbx500-prcmu-regs.h" |
38 | 38 | ||
39 | /* Index of different voltages to be used when accessing AVSData */ | 39 | /* Index of different voltages to be used when accessing AVSData */ |
@@ -273,8 +273,34 @@ static struct irq_domain *db8500_irq_domain; | |||
273 | * the bits in the bit field are not. (The bits also have a tendency to move | 273 | * the bits in the bit field are not. (The bits also have a tendency to move |
274 | * around, to further complicate matters.) | 274 | * around, to further complicate matters.) |
275 | */ | 275 | */ |
276 | #define IRQ_INDEX(_name) ((IRQ_PRCMU_##_name) - IRQ_PRCMU_BASE) | 276 | #define IRQ_INDEX(_name) ((IRQ_PRCMU_##_name)) |
277 | #define IRQ_ENTRY(_name)[IRQ_INDEX(_name)] = (WAKEUP_BIT_##_name) | 277 | #define IRQ_ENTRY(_name)[IRQ_INDEX(_name)] = (WAKEUP_BIT_##_name) |
278 | |||
279 | #define IRQ_PRCMU_RTC 0 | ||
280 | #define IRQ_PRCMU_RTT0 1 | ||
281 | #define IRQ_PRCMU_RTT1 2 | ||
282 | #define IRQ_PRCMU_HSI0 3 | ||
283 | #define IRQ_PRCMU_HSI1 4 | ||
284 | #define IRQ_PRCMU_CA_WAKE 5 | ||
285 | #define IRQ_PRCMU_USB 6 | ||
286 | #define IRQ_PRCMU_ABB 7 | ||
287 | #define IRQ_PRCMU_ABB_FIFO 8 | ||
288 | #define IRQ_PRCMU_ARM 9 | ||
289 | #define IRQ_PRCMU_MODEM_SW_RESET_REQ 10 | ||
290 | #define IRQ_PRCMU_GPIO0 11 | ||
291 | #define IRQ_PRCMU_GPIO1 12 | ||
292 | #define IRQ_PRCMU_GPIO2 13 | ||
293 | #define IRQ_PRCMU_GPIO3 14 | ||
294 | #define IRQ_PRCMU_GPIO4 15 | ||
295 | #define IRQ_PRCMU_GPIO5 16 | ||
296 | #define IRQ_PRCMU_GPIO6 17 | ||
297 | #define IRQ_PRCMU_GPIO7 18 | ||
298 | #define IRQ_PRCMU_GPIO8 19 | ||
299 | #define IRQ_PRCMU_CA_SLEEP 20 | ||
300 | #define IRQ_PRCMU_HOTMON_LOW 21 | ||
301 | #define IRQ_PRCMU_HOTMON_HIGH 22 | ||
302 | #define NUM_PRCMU_WAKEUPS 23 | ||
303 | |||
278 | static u32 prcmu_irq_bit[NUM_PRCMU_WAKEUPS] = { | 304 | static u32 prcmu_irq_bit[NUM_PRCMU_WAKEUPS] = { |
279 | IRQ_ENTRY(RTC), | 305 | IRQ_ENTRY(RTC), |
280 | IRQ_ENTRY(RTT0), | 306 | IRQ_ENTRY(RTT0), |
@@ -2649,14 +2675,13 @@ static struct irq_domain_ops db8500_irq_ops = { | |||
2649 | .xlate = irq_domain_xlate_twocell, | 2675 | .xlate = irq_domain_xlate_twocell, |
2650 | }; | 2676 | }; |
2651 | 2677 | ||
2652 | static int db8500_irq_init(struct device_node *np) | 2678 | static int db8500_irq_init(struct device_node *np, int irq_base) |
2653 | { | 2679 | { |
2654 | int irq_base = 0; | ||
2655 | int i; | 2680 | int i; |
2656 | 2681 | ||
2657 | /* In the device tree case, just take some IRQs */ | 2682 | /* In the device tree case, just take some IRQs */ |
2658 | if (!np) | 2683 | if (np) |
2659 | irq_base = IRQ_PRCMU_BASE; | 2684 | irq_base = 0; |
2660 | 2685 | ||
2661 | db8500_irq_domain = irq_domain_add_simple( | 2686 | db8500_irq_domain = irq_domain_add_simple( |
2662 | np, NUM_PRCMU_WAKEUPS, irq_base, | 2687 | np, NUM_PRCMU_WAKEUPS, irq_base, |
@@ -2988,18 +3013,57 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
2988 | }, | 3013 | }, |
2989 | }; | 3014 | }; |
2990 | 3015 | ||
2991 | static struct resource ab8500_resources[] = { | ||
2992 | [0] = { | ||
2993 | .start = IRQ_DB8500_AB8500, | ||
2994 | .end = IRQ_DB8500_AB8500, | ||
2995 | .flags = IORESOURCE_IRQ | ||
2996 | } | ||
2997 | }; | ||
2998 | |||
2999 | static struct ux500_wdt_data db8500_wdt_pdata = { | 3016 | static struct ux500_wdt_data db8500_wdt_pdata = { |
3000 | .timeout = 600, /* 10 minutes */ | 3017 | .timeout = 600, /* 10 minutes */ |
3001 | .has_28_bits_resolution = true, | 3018 | .has_28_bits_resolution = true, |
3002 | }; | 3019 | }; |
3020 | /* | ||
3021 | * Thermal Sensor | ||
3022 | */ | ||
3023 | |||
3024 | static struct resource db8500_thsens_resources[] = { | ||
3025 | { | ||
3026 | .name = "IRQ_HOTMON_LOW", | ||
3027 | .start = IRQ_PRCMU_HOTMON_LOW, | ||
3028 | .end = IRQ_PRCMU_HOTMON_LOW, | ||
3029 | .flags = IORESOURCE_IRQ, | ||
3030 | }, | ||
3031 | { | ||
3032 | .name = "IRQ_HOTMON_HIGH", | ||
3033 | .start = IRQ_PRCMU_HOTMON_HIGH, | ||
3034 | .end = IRQ_PRCMU_HOTMON_HIGH, | ||
3035 | .flags = IORESOURCE_IRQ, | ||
3036 | }, | ||
3037 | }; | ||
3038 | |||
3039 | static struct db8500_thsens_platform_data db8500_thsens_data = { | ||
3040 | .trip_points[0] = { | ||
3041 | .temp = 70000, | ||
3042 | .type = THERMAL_TRIP_ACTIVE, | ||
3043 | .cdev_name = { | ||
3044 | [0] = "thermal-cpufreq-0", | ||
3045 | }, | ||
3046 | }, | ||
3047 | .trip_points[1] = { | ||
3048 | .temp = 75000, | ||
3049 | .type = THERMAL_TRIP_ACTIVE, | ||
3050 | .cdev_name = { | ||
3051 | [0] = "thermal-cpufreq-0", | ||
3052 | }, | ||
3053 | }, | ||
3054 | .trip_points[2] = { | ||
3055 | .temp = 80000, | ||
3056 | .type = THERMAL_TRIP_ACTIVE, | ||
3057 | .cdev_name = { | ||
3058 | [0] = "thermal-cpufreq-0", | ||
3059 | }, | ||
3060 | }, | ||
3061 | .trip_points[3] = { | ||
3062 | .temp = 85000, | ||
3063 | .type = THERMAL_TRIP_CRITICAL, | ||
3064 | }, | ||
3065 | .num_trips = 4, | ||
3066 | }; | ||
3003 | 3067 | ||
3004 | static struct mfd_cell db8500_prcmu_devs[] = { | 3068 | static struct mfd_cell db8500_prcmu_devs[] = { |
3005 | { | 3069 | { |
@@ -3021,11 +3085,10 @@ static struct mfd_cell db8500_prcmu_devs[] = { | |||
3021 | .id = -1, | 3085 | .id = -1, |
3022 | }, | 3086 | }, |
3023 | { | 3087 | { |
3024 | .name = "ab8500-core", | 3088 | .name = "db8500-thermal", |
3025 | .of_compatible = "stericsson,ab8500", | 3089 | .num_resources = ARRAY_SIZE(db8500_thsens_resources), |
3026 | .num_resources = ARRAY_SIZE(ab8500_resources), | 3090 | .resources = db8500_thsens_resources, |
3027 | .resources = ab8500_resources, | 3091 | .platform_data = &db8500_thsens_data, |
3028 | .id = AB8500_VERSION_AB8500, | ||
3029 | }, | 3092 | }, |
3030 | }; | 3093 | }; |
3031 | 3094 | ||
@@ -3037,6 +3100,24 @@ static void db8500_prcmu_update_cpufreq(void) | |||
3037 | } | 3100 | } |
3038 | } | 3101 | } |
3039 | 3102 | ||
3103 | static int db8500_prcmu_register_ab8500(struct device *parent, | ||
3104 | struct ab8500_platform_data *pdata, | ||
3105 | int irq) | ||
3106 | { | ||
3107 | struct resource ab8500_resource = DEFINE_RES_IRQ(irq); | ||
3108 | struct mfd_cell ab8500_cell = { | ||
3109 | .name = "ab8500-core", | ||
3110 | .of_compatible = "stericsson,ab8500", | ||
3111 | .id = AB8500_VERSION_AB8500, | ||
3112 | .platform_data = pdata, | ||
3113 | .pdata_size = sizeof(struct ab8500_platform_data), | ||
3114 | .resources = &ab8500_resource, | ||
3115 | .num_resources = 1, | ||
3116 | }; | ||
3117 | |||
3118 | return mfd_add_devices(parent, 0, &ab8500_cell, 1, NULL, 0, NULL); | ||
3119 | } | ||
3120 | |||
3040 | /** | 3121 | /** |
3041 | * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic | 3122 | * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic |
3042 | * | 3123 | * |
@@ -3045,7 +3126,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev) | |||
3045 | { | 3126 | { |
3046 | struct device_node *np = pdev->dev.of_node; | 3127 | struct device_node *np = pdev->dev.of_node; |
3047 | struct prcmu_pdata *pdata = dev_get_platdata(&pdev->dev); | 3128 | struct prcmu_pdata *pdata = dev_get_platdata(&pdev->dev); |
3048 | int irq = 0, err = 0, i; | 3129 | int irq = 0, err = 0; |
3049 | struct resource *res; | 3130 | struct resource *res; |
3050 | 3131 | ||
3051 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu"); | 3132 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu"); |
@@ -3086,26 +3167,27 @@ static int db8500_prcmu_probe(struct platform_device *pdev) | |||
3086 | goto no_irq_return; | 3167 | goto no_irq_return; |
3087 | } | 3168 | } |
3088 | 3169 | ||
3089 | db8500_irq_init(np); | 3170 | db8500_irq_init(np, pdata->irq_base); |
3090 | |||
3091 | for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) { | ||
3092 | if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) { | ||
3093 | db8500_prcmu_devs[i].platform_data = pdata->ab_platdata; | ||
3094 | db8500_prcmu_devs[i].pdata_size = sizeof(struct ab8500_platform_data); | ||
3095 | } | ||
3096 | } | ||
3097 | 3171 | ||
3098 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); | 3172 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); |
3099 | 3173 | ||
3100 | db8500_prcmu_update_cpufreq(); | 3174 | db8500_prcmu_update_cpufreq(); |
3101 | 3175 | ||
3102 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, | 3176 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, |
3103 | ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL); | 3177 | ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, db8500_irq_domain); |
3104 | if (err) { | 3178 | if (err) { |
3105 | pr_err("prcmu: Failed to add subdevices\n"); | 3179 | pr_err("prcmu: Failed to add subdevices\n"); |
3106 | return err; | 3180 | return err; |
3107 | } | 3181 | } |
3108 | 3182 | ||
3183 | err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata, | ||
3184 | pdata->ab_irq); | ||
3185 | if (err) { | ||
3186 | mfd_remove_devices(&pdev->dev); | ||
3187 | pr_err("prcmu: Failed to add ab8500 subdevice\n"); | ||
3188 | goto no_irq_return; | ||
3189 | } | ||
3190 | |||
3109 | pr_info("DB8500 PRCMU initialized\n"); | 3191 | pr_info("DB8500 PRCMU initialized\n"); |
3110 | 3192 | ||
3111 | no_irq_return: | 3193 | no_irq_return: |