diff options
74 files changed, 6038 insertions, 2730 deletions
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index cfa84178eb26..ba232d79fa81 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c | |||
@@ -293,8 +293,7 @@ static struct mc13xxx_platform_data mc13783_pdata = { | |||
293 | .num_regulators = ARRAY_SIZE(mx27_3ds_regulators), | 293 | .num_regulators = ARRAY_SIZE(mx27_3ds_regulators), |
294 | 294 | ||
295 | }, | 295 | }, |
296 | .flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN | | 296 | .flags = MC13XXX_USE_TOUCHSCREEN | MC13XXX_USE_RTC, |
297 | MC13783_USE_RTC, | ||
298 | }; | 297 | }; |
299 | 298 | ||
300 | /* SPI */ | 299 | /* SPI */ |
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index 60f1fda6ce97..b8c54b840185 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c | |||
@@ -492,7 +492,7 @@ static struct mc13xxx_platform_data mc13783_pdata = { | |||
492 | .regulators = mx31_3ds_regulators, | 492 | .regulators = mx31_3ds_regulators, |
493 | .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), | 493 | .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), |
494 | }, | 494 | }, |
495 | .flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN, | 495 | .flags = MC13XXX_USE_TOUCHSCREEN, |
496 | }; | 496 | }; |
497 | 497 | ||
498 | /* SPI */ | 498 | /* SPI */ |
diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c index c97c26d814ed..05f1c71ba409 100644 --- a/arch/arm/mach-imx/mach-mx31lite.c +++ b/arch/arm/mach-imx/mach-mx31lite.c | |||
@@ -112,8 +112,7 @@ static const struct spi_imx_master spi1_pdata __initconst = { | |||
112 | }; | 112 | }; |
113 | 113 | ||
114 | static struct mc13xxx_platform_data mc13783_pdata __initdata = { | 114 | static struct mc13xxx_platform_data mc13783_pdata __initdata = { |
115 | .flags = MC13XXX_USE_RTC | | 115 | .flags = MC13XXX_USE_RTC, |
116 | MC13XXX_USE_REGULATOR, | ||
117 | }; | 116 | }; |
118 | 117 | ||
119 | static struct spi_board_info mc13783_spi_dev __initdata = { | 118 | static struct spi_board_info mc13783_spi_dev __initdata = { |
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index fff7791b7e7c..07034f44466a 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/err.h> | 33 | #include <linux/err.h> |
34 | #include <linux/input.h> | ||
34 | 35 | ||
35 | #include <linux/usb/otg.h> | 36 | #include <linux/usb/otg.h> |
36 | #include <linux/usb/ulpi.h> | 37 | #include <linux/usb/ulpi.h> |
@@ -225,7 +226,7 @@ static struct mc13xxx_regulator_init_data moboard_regulators[] = { | |||
225 | }, | 226 | }, |
226 | }; | 227 | }; |
227 | 228 | ||
228 | static struct mc13783_led_platform_data moboard_led[] = { | 229 | static struct mc13xxx_led_platform_data moboard_led[] = { |
229 | { | 230 | { |
230 | .id = MC13783_LED_R1, | 231 | .id = MC13783_LED_R1, |
231 | .name = "coreboard-led-4:red", | 232 | .name = "coreboard-led-4:red", |
@@ -258,7 +259,7 @@ static struct mc13783_led_platform_data moboard_led[] = { | |||
258 | }, | 259 | }, |
259 | }; | 260 | }; |
260 | 261 | ||
261 | static struct mc13783_leds_platform_data moboard_leds = { | 262 | static struct mc13xxx_leds_platform_data moboard_leds = { |
262 | .num_leds = ARRAY_SIZE(moboard_led), | 263 | .num_leds = ARRAY_SIZE(moboard_led), |
263 | .led = moboard_led, | 264 | .led = moboard_led, |
264 | .flags = MC13783_LED_SLEWLIMTC, | 265 | .flags = MC13783_LED_SLEWLIMTC, |
@@ -267,14 +268,20 @@ static struct mc13783_leds_platform_data moboard_leds = { | |||
267 | .tc2_period = MC13783_LED_PERIOD_10MS, | 268 | .tc2_period = MC13783_LED_PERIOD_10MS, |
268 | }; | 269 | }; |
269 | 270 | ||
271 | static struct mc13xxx_buttons_platform_data moboard_buttons = { | ||
272 | .b1on_flags = MC13783_BUTTON_DBNC_750MS | MC13783_BUTTON_ENABLE | | ||
273 | MC13783_BUTTON_POL_INVERT, | ||
274 | .b1on_key = KEY_POWER, | ||
275 | }; | ||
276 | |||
270 | static struct mc13xxx_platform_data moboard_pmic = { | 277 | static struct mc13xxx_platform_data moboard_pmic = { |
271 | .regulators = { | 278 | .regulators = { |
272 | .regulators = moboard_regulators, | 279 | .regulators = moboard_regulators, |
273 | .num_regulators = ARRAY_SIZE(moboard_regulators), | 280 | .num_regulators = ARRAY_SIZE(moboard_regulators), |
274 | }, | 281 | }, |
275 | .leds = &moboard_leds, | 282 | .leds = &moboard_leds, |
276 | .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC | | 283 | .buttons = &moboard_buttons, |
277 | MC13XXX_USE_ADC | MC13XXX_USE_LED, | 284 | .flags = MC13XXX_USE_RTC | MC13XXX_USE_ADC, |
278 | }; | 285 | }; |
279 | 286 | ||
280 | static struct spi_board_info moboard_spi_board_info[] __initdata = { | 287 | static struct spi_board_info moboard_spi_board_info[] __initdata = { |
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c index 100bc733ce93..a17e9c7dfca0 100644 --- a/arch/arm/mach-imx/mach-pcm038.c +++ b/arch/arm/mach-imx/mach-pcm038.c | |||
@@ -268,8 +268,7 @@ static struct mc13xxx_platform_data pcm038_pmic = { | |||
268 | .regulators = pcm038_regulators, | 268 | .regulators = pcm038_regulators, |
269 | .num_regulators = ARRAY_SIZE(pcm038_regulators), | 269 | .num_regulators = ARRAY_SIZE(pcm038_regulators), |
270 | }, | 270 | }, |
271 | .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR | | 271 | .flags = MC13XXX_USE_ADC | MC13XXX_USE_TOUCHSCREEN, |
272 | MC13783_USE_TOUCHSCREEN, | ||
273 | }; | 272 | }; |
274 | 273 | ||
275 | static struct spi_board_info pcm038_spi_board_info[] __initdata = { | 274 | static struct spi_board_info pcm038_spi_board_info[] __initdata = { |
diff --git a/arch/arm/mach-mx5/mx51_efika.c b/arch/arm/mach-mx5/mx51_efika.c index b004e178417d..ec6ca91b299b 100644 --- a/arch/arm/mach-mx5/mx51_efika.c +++ b/arch/arm/mach-mx5/mx51_efika.c | |||
@@ -565,7 +565,7 @@ static struct mc13xxx_regulator_init_data mx51_efika_regulators[] = { | |||
565 | }; | 565 | }; |
566 | 566 | ||
567 | static struct mc13xxx_platform_data mx51_efika_mc13892_data = { | 567 | static struct mc13xxx_platform_data mx51_efika_mc13892_data = { |
568 | .flags = MC13XXX_USE_RTC | MC13XXX_USE_REGULATOR, | 568 | .flags = MC13XXX_USE_RTC, |
569 | .regulators = { | 569 | .regulators = { |
570 | .num_regulators = ARRAY_SIZE(mx51_efika_regulators), | 570 | .num_regulators = ARRAY_SIZE(mx51_efika_regulators), |
571 | .regulators = mx51_efika_regulators, | 571 | .regulators = mx51_efika_regulators, |
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 497e9dc27958..503414718905 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -14,7 +14,6 @@ config ARCH_OMAP2PLUS_TYPICAL | |||
14 | select SERIAL_OMAP_CONSOLE | 14 | select SERIAL_OMAP_CONSOLE |
15 | select I2C | 15 | select I2C |
16 | select I2C_OMAP | 16 | select I2C_OMAP |
17 | select MFD_SUPPORT | ||
18 | select MENELAUS if ARCH_OMAP2 | 17 | select MENELAUS if ARCH_OMAP2 |
19 | select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4 | 18 | select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4 |
20 | select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4 | 19 | select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4 |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 70261bcda3f9..4a71cb7e42d4 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -378,7 +378,8 @@ static struct i2c_board_info __initdata beagle_i2c_eeprom[] = { | |||
378 | static int __init omap3_beagle_i2c_init(void) | 378 | static int __init omap3_beagle_i2c_init(void) |
379 | { | 379 | { |
380 | omap3_pmic_get_config(&beagle_twldata, | 380 | omap3_pmic_get_config(&beagle_twldata, |
381 | TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO, | 381 | TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC | |
382 | TWL_COMMON_PDATA_AUDIO, | ||
382 | TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); | 383 | TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); |
383 | 384 | ||
384 | beagle_twldata.vpll2->constraints.name = "VDVI"; | 385 | beagle_twldata.vpll2->constraints.name = "VDVI"; |
@@ -444,9 +445,15 @@ static struct platform_device keys_gpio = { | |||
444 | }, | 445 | }, |
445 | }; | 446 | }; |
446 | 447 | ||
448 | static struct platform_device madc_hwmon = { | ||
449 | .name = "twl4030_madc_hwmon", | ||
450 | .id = -1, | ||
451 | }; | ||
452 | |||
447 | static struct platform_device *omap3_beagle_devices[] __initdata = { | 453 | static struct platform_device *omap3_beagle_devices[] __initdata = { |
448 | &leds_gpio, | 454 | &leds_gpio, |
449 | &keys_gpio, | 455 | &keys_gpio, |
456 | &madc_hwmon, | ||
450 | }; | 457 | }; |
451 | 458 | ||
452 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 459 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { |
diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c index f0394baa11fa..5140deeddf7b 100644 --- a/arch/arm/mach-u300/i2c.c +++ b/arch/arm/mach-u300/i2c.c | |||
@@ -256,57 +256,8 @@ static struct ab3100_platform_data ab3100_plf_data = { | |||
256 | }; | 256 | }; |
257 | #endif | 257 | #endif |
258 | 258 | ||
259 | #ifdef CONFIG_AB3550_CORE | ||
260 | static struct abx500_init_settings ab3550_init_settings[] = { | ||
261 | { | ||
262 | .bank = 0, | ||
263 | .reg = AB3550_IMR1, | ||
264 | .setting = 0xff | ||
265 | }, | ||
266 | { | ||
267 | .bank = 0, | ||
268 | .reg = AB3550_IMR2, | ||
269 | .setting = 0xff | ||
270 | }, | ||
271 | { | ||
272 | .bank = 0, | ||
273 | .reg = AB3550_IMR3, | ||
274 | .setting = 0xff | ||
275 | }, | ||
276 | { | ||
277 | .bank = 0, | ||
278 | .reg = AB3550_IMR4, | ||
279 | .setting = 0xff | ||
280 | }, | ||
281 | { | ||
282 | .bank = 0, | ||
283 | .reg = AB3550_IMR5, | ||
284 | /* The two most significant bits are not used */ | ||
285 | .setting = 0x3f | ||
286 | }, | ||
287 | }; | ||
288 | |||
289 | static struct ab3550_platform_data ab3550_plf_data = { | ||
290 | .irq = { | ||
291 | .base = IRQ_AB3550_BASE, | ||
292 | .count = (IRQ_AB3550_END - IRQ_AB3550_BASE + 1), | ||
293 | }, | ||
294 | .dev_data = { | ||
295 | }, | ||
296 | .init_settings = ab3550_init_settings, | ||
297 | .init_settings_sz = ARRAY_SIZE(ab3550_init_settings), | ||
298 | }; | ||
299 | #endif | ||
300 | |||
301 | static struct i2c_board_info __initdata bus0_i2c_board_info[] = { | 259 | static struct i2c_board_info __initdata bus0_i2c_board_info[] = { |
302 | #if defined(CONFIG_AB3550_CORE) | 260 | #ifdef CONFIG_AB3100_CORE |
303 | { | ||
304 | .type = "ab3550", | ||
305 | .addr = 0x4A, | ||
306 | .irq = IRQ_U300_IRQ0_EXT, | ||
307 | .platform_data = &ab3550_plf_data, | ||
308 | }, | ||
309 | #elif defined(CONFIG_AB3100_CORE) | ||
310 | { | 261 | { |
311 | .type = "ab3100", | 262 | .type = "ab3100", |
312 | .addr = 0x48, | 263 | .addr = 0x48, |
diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h index d270fea32926..db3fbfa1d6e9 100644 --- a/arch/arm/mach-u300/include/mach/irqs.h +++ b/arch/arm/mach-u300/include/mach/irqs.h | |||
@@ -117,14 +117,6 @@ | |||
117 | #define IRQ_U300_GPIO_END (U300_VIC_IRQS_END) | 117 | #define IRQ_U300_GPIO_END (U300_VIC_IRQS_END) |
118 | #endif | 118 | #endif |
119 | 119 | ||
120 | /* Optional AB3550 mixsig chip */ | 120 | #define NR_IRQS (IRQ_U300_GPIO_END) |
121 | #ifdef CONFIG_AB3550_CORE | ||
122 | #define IRQ_AB3550_BASE (IRQ_U300_GPIO_END) | ||
123 | #define IRQ_AB3550_END (IRQ_AB3550_BASE + 38) | ||
124 | #else | ||
125 | #define IRQ_AB3550_END (IRQ_U300_GPIO_END) | ||
126 | #endif | ||
127 | |||
128 | #define NR_IRQS (IRQ_AB3550_END) | ||
129 | 121 | ||
130 | #endif | 122 | #endif |
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index e014aa749b03..82025ba70c03 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/amba/bus.h> | 10 | #include <linux/amba/bus.h> |
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | #include <linux/i2c.h> | 12 | #include <linux/i2c.h> |
13 | #include <linux/mfd/ab5500/ab5500.h> | ||
13 | 14 | ||
14 | #include <asm/mach/arch.h> | 15 | #include <asm/mach/arch.h> |
15 | #include <asm/mach-types.h> | 16 | #include <asm/mach-types.h> |
@@ -87,7 +88,6 @@ static struct lm3530_platform_data u5500_als_platform_data = { | |||
87 | .brt_val = 0x7F, /* Max brightness */ | 88 | .brt_val = 0x7F, /* Max brightness */ |
88 | }; | 89 | }; |
89 | 90 | ||
90 | |||
91 | static struct i2c_board_info __initdata u5500_i2c2_devices[] = { | 91 | static struct i2c_board_info __initdata u5500_i2c2_devices[] = { |
92 | { | 92 | { |
93 | /* Backlight */ | 93 | /* Backlight */ |
@@ -101,6 +101,30 @@ static void __init u5500_i2c_init(void) | |||
101 | db5500_add_i2c2(&u5500_i2c2_data); | 101 | db5500_add_i2c2(&u5500_i2c2_data); |
102 | i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices)); | 102 | i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices)); |
103 | } | 103 | } |
104 | |||
105 | static struct ab5500_platform_data ab5500_plf_data = { | ||
106 | .irq = { | ||
107 | .base = 0, | ||
108 | .count = 0, | ||
109 | }, | ||
110 | .init_settings = NULL, | ||
111 | .init_settings_sz = 0, | ||
112 | .pm_power_off = false, | ||
113 | }; | ||
114 | |||
115 | static struct platform_device ab5500_device = { | ||
116 | .name = "ab5500-core", | ||
117 | .id = 0, | ||
118 | .dev = { | ||
119 | .platform_data = &ab5500_plf_data, | ||
120 | }, | ||
121 | .num_resources = 0, | ||
122 | }; | ||
123 | |||
124 | static struct platform_device *u5500_platform_devices[] __initdata = { | ||
125 | &ab5500_device, | ||
126 | }; | ||
127 | |||
104 | static void __init u5500_uart_init(void) | 128 | static void __init u5500_uart_init(void) |
105 | { | 129 | { |
106 | db5500_add_uart0(NULL); | 130 | db5500_add_uart0(NULL); |
@@ -115,6 +139,9 @@ static void __init u5500_init_machine(void) | |||
115 | u5500_i2c_init(); | 139 | u5500_i2c_init(); |
116 | u5500_sdi_init(); | 140 | u5500_sdi_init(); |
117 | u5500_uart_init(); | 141 | u5500_uart_init(); |
142 | |||
143 | platform_add_devices(u5500_platform_devices, | ||
144 | ARRAY_SIZE(u5500_platform_devices)); | ||
118 | } | 145 | } |
119 | 146 | ||
120 | MACHINE_START(U5500, "ST-Ericsson U5500 Platform") | 147 | MACHINE_START(U5500, "ST-Ericsson U5500 Platform") |
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 1405d0eb7edb..f41857494375 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c | |||
@@ -47,6 +47,6 @@ void __init ux500_init_irq(void) | |||
47 | if (cpu_is_u5500()) | 47 | if (cpu_is_u5500()) |
48 | db5500_prcmu_early_init(); | 48 | db5500_prcmu_early_init(); |
49 | if (cpu_is_u8500()) | 49 | if (cpu_is_u8500()) |
50 | prcmu_early_init(); | 50 | db8500_prcmu_early_init(); |
51 | clk_init(); | 51 | clk_init(); |
52 | } | 52 | } |
diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h index 29f66793cc55..4420993acc47 100644 --- a/arch/x86/include/asm/intel_scu_ipc.h +++ b/arch/x86/include/asm/intel_scu_ipc.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _ASM_X86_INTEL_SCU_IPC_H_ | 1 | #ifndef _ASM_X86_INTEL_SCU_IPC_H_ |
2 | #define _ASM_X86_INTEL_SCU_IPC_H_ | 2 | #define _ASM_X86_INTEL_SCU_IPC_H_ |
3 | 3 | ||
4 | #include <linux/notifier.h> | ||
5 | |||
4 | #define IPCMSG_VRTC 0xFA /* Set vRTC device */ | 6 | #define IPCMSG_VRTC 0xFA /* Set vRTC device */ |
5 | 7 | ||
6 | /* Command id associated with message IPCMSG_VRTC */ | 8 | /* Command id associated with message IPCMSG_VRTC */ |
@@ -44,4 +46,24 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data); | |||
44 | /* Update FW version */ | 46 | /* Update FW version */ |
45 | int intel_scu_ipc_fw_update(u8 *buffer, u32 length); | 47 | int intel_scu_ipc_fw_update(u8 *buffer, u32 length); |
46 | 48 | ||
49 | extern struct blocking_notifier_head intel_scu_notifier; | ||
50 | |||
51 | static inline void intel_scu_notifier_add(struct notifier_block *nb) | ||
52 | { | ||
53 | blocking_notifier_chain_register(&intel_scu_notifier, nb); | ||
54 | } | ||
55 | |||
56 | static inline void intel_scu_notifier_remove(struct notifier_block *nb) | ||
57 | { | ||
58 | blocking_notifier_chain_unregister(&intel_scu_notifier, nb); | ||
59 | } | ||
60 | |||
61 | static inline int intel_scu_notifier_post(unsigned long v, void *p) | ||
62 | { | ||
63 | return blocking_notifier_call_chain(&intel_scu_notifier, v, p); | ||
64 | } | ||
65 | |||
66 | #define SCU_AVAILABLE 1 | ||
67 | #define SCU_DOWN 2 | ||
68 | |||
47 | #endif | 69 | #endif |
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index e6379526675b..6ed7afdaf4af 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/notifier.h> | ||
30 | #include <linux/mfd/intel_msic.h> | ||
29 | 31 | ||
30 | #include <asm/setup.h> | 32 | #include <asm/setup.h> |
31 | #include <asm/mpspec_def.h> | 33 | #include <asm/mpspec_def.h> |
@@ -483,6 +485,128 @@ static void __init *no_platform_data(void *info) | |||
483 | return NULL; | 485 | return NULL; |
484 | } | 486 | } |
485 | 487 | ||
488 | static struct resource msic_resources[] = { | ||
489 | { | ||
490 | .start = INTEL_MSIC_IRQ_PHYS_BASE, | ||
491 | .end = INTEL_MSIC_IRQ_PHYS_BASE + 64 - 1, | ||
492 | .flags = IORESOURCE_MEM, | ||
493 | }, | ||
494 | }; | ||
495 | |||
496 | static struct intel_msic_platform_data msic_pdata; | ||
497 | |||
498 | static struct platform_device msic_device = { | ||
499 | .name = "intel_msic", | ||
500 | .id = -1, | ||
501 | .dev = { | ||
502 | .platform_data = &msic_pdata, | ||
503 | }, | ||
504 | .num_resources = ARRAY_SIZE(msic_resources), | ||
505 | .resource = msic_resources, | ||
506 | }; | ||
507 | |||
508 | static inline bool mrst_has_msic(void) | ||
509 | { | ||
510 | return mrst_identify_cpu() == MRST_CPU_CHIP_PENWELL; | ||
511 | } | ||
512 | |||
513 | static int msic_scu_status_change(struct notifier_block *nb, | ||
514 | unsigned long code, void *data) | ||
515 | { | ||
516 | if (code == SCU_DOWN) { | ||
517 | platform_device_unregister(&msic_device); | ||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | return platform_device_register(&msic_device); | ||
522 | } | ||
523 | |||
524 | static int __init msic_init(void) | ||
525 | { | ||
526 | static struct notifier_block msic_scu_notifier = { | ||
527 | .notifier_call = msic_scu_status_change, | ||
528 | }; | ||
529 | |||
530 | /* | ||
531 | * We need to be sure that the SCU IPC is ready before MSIC device | ||
532 | * can be registered. | ||
533 | */ | ||
534 | if (mrst_has_msic()) | ||
535 | intel_scu_notifier_add(&msic_scu_notifier); | ||
536 | |||
537 | return 0; | ||
538 | } | ||
539 | arch_initcall(msic_init); | ||
540 | |||
541 | /* | ||
542 | * msic_generic_platform_data - sets generic platform data for the block | ||
543 | * @info: pointer to the SFI device table entry for this block | ||
544 | * @block: MSIC block | ||
545 | * | ||
546 | * Function sets IRQ number from the SFI table entry for given device to | ||
547 | * the MSIC platform data. | ||
548 | */ | ||
549 | static void *msic_generic_platform_data(void *info, enum intel_msic_block block) | ||
550 | { | ||
551 | struct sfi_device_table_entry *entry = info; | ||
552 | |||
553 | BUG_ON(block < 0 || block >= INTEL_MSIC_BLOCK_LAST); | ||
554 | msic_pdata.irq[block] = entry->irq; | ||
555 | |||
556 | return no_platform_data(info); | ||
557 | } | ||
558 | |||
559 | static void *msic_battery_platform_data(void *info) | ||
560 | { | ||
561 | return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_BATTERY); | ||
562 | } | ||
563 | |||
564 | static void *msic_gpio_platform_data(void *info) | ||
565 | { | ||
566 | static struct intel_msic_gpio_pdata pdata; | ||
567 | int gpio = get_gpio_by_name("msic_gpio_base"); | ||
568 | |||
569 | if (gpio < 0) | ||
570 | return NULL; | ||
571 | |||
572 | pdata.gpio_base = gpio; | ||
573 | msic_pdata.gpio = &pdata; | ||
574 | |||
575 | return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_GPIO); | ||
576 | } | ||
577 | |||
578 | static void *msic_audio_platform_data(void *info) | ||
579 | { | ||
580 | struct platform_device *pdev; | ||
581 | |||
582 | pdev = platform_device_register_simple("sst-platform", -1, NULL, 0); | ||
583 | if (IS_ERR(pdev)) { | ||
584 | pr_err("failed to create audio platform device\n"); | ||
585 | return NULL; | ||
586 | } | ||
587 | |||
588 | return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_AUDIO); | ||
589 | } | ||
590 | |||
591 | static void *msic_power_btn_platform_data(void *info) | ||
592 | { | ||
593 | return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_POWER_BTN); | ||
594 | } | ||
595 | |||
596 | static void *msic_ocd_platform_data(void *info) | ||
597 | { | ||
598 | static struct intel_msic_ocd_pdata pdata; | ||
599 | int gpio = get_gpio_by_name("ocd_gpio"); | ||
600 | |||
601 | if (gpio < 0) | ||
602 | return NULL; | ||
603 | |||
604 | pdata.gpio = gpio; | ||
605 | msic_pdata.ocd = &pdata; | ||
606 | |||
607 | return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_OCD); | ||
608 | } | ||
609 | |||
486 | static const struct devs_id __initconst device_ids[] = { | 610 | static const struct devs_id __initconst device_ids[] = { |
487 | {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data}, | 611 | {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data}, |
488 | {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data}, | 612 | {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data}, |
@@ -491,7 +615,14 @@ static const struct devs_id __initconst device_ids[] = { | |||
491 | {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data}, | 615 | {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data}, |
492 | {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data}, | 616 | {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data}, |
493 | {"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data}, | 617 | {"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data}, |
494 | {"msic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data}, | 618 | |
619 | /* MSIC subdevices */ | ||
620 | {"msic_battery", SFI_DEV_TYPE_IPC, 1, &msic_battery_platform_data}, | ||
621 | {"msic_gpio", SFI_DEV_TYPE_IPC, 1, &msic_gpio_platform_data}, | ||
622 | {"msic_audio", SFI_DEV_TYPE_IPC, 1, &msic_audio_platform_data}, | ||
623 | {"msic_power_btn", SFI_DEV_TYPE_IPC, 1, &msic_power_btn_platform_data}, | ||
624 | {"msic_ocd", SFI_DEV_TYPE_IPC, 1, &msic_ocd_platform_data}, | ||
625 | |||
495 | {}, | 626 | {}, |
496 | }; | 627 | }; |
497 | 628 | ||
@@ -558,6 +689,9 @@ static void __init intel_scu_i2c_device_register(int bus, | |||
558 | i2c_devs[i2c_next_dev++] = new_dev; | 689 | i2c_devs[i2c_next_dev++] = new_dev; |
559 | } | 690 | } |
560 | 691 | ||
692 | BLOCKING_NOTIFIER_HEAD(intel_scu_notifier); | ||
693 | EXPORT_SYMBOL_GPL(intel_scu_notifier); | ||
694 | |||
561 | /* Called by IPC driver */ | 695 | /* Called by IPC driver */ |
562 | void intel_scu_devices_create(void) | 696 | void intel_scu_devices_create(void) |
563 | { | 697 | { |
@@ -582,6 +716,7 @@ void intel_scu_devices_create(void) | |||
582 | } else | 716 | } else |
583 | i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1); | 717 | i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1); |
584 | } | 718 | } |
719 | intel_scu_notifier_post(SCU_AVAILABLE, 0L); | ||
585 | } | 720 | } |
586 | EXPORT_SYMBOL_GPL(intel_scu_devices_create); | 721 | EXPORT_SYMBOL_GPL(intel_scu_devices_create); |
587 | 722 | ||
@@ -590,6 +725,8 @@ void intel_scu_devices_destroy(void) | |||
590 | { | 725 | { |
591 | int i; | 726 | int i; |
592 | 727 | ||
728 | intel_scu_notifier_post(SCU_DOWN, 0L); | ||
729 | |||
593 | for (i = 0; i < ipc_next_dev; i++) | 730 | for (i = 0; i < ipc_next_dev; i++) |
594 | platform_device_del(ipc_devs[i]); | 731 | platform_device_del(ipc_devs[i]); |
595 | } | 732 | } |
@@ -606,19 +743,37 @@ static void __init install_irq_resource(struct platform_device *pdev, int irq) | |||
606 | platform_device_add_resources(pdev, &res, 1); | 743 | platform_device_add_resources(pdev, &res, 1); |
607 | } | 744 | } |
608 | 745 | ||
609 | static void __init sfi_handle_ipc_dev(struct platform_device *pdev) | 746 | static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *entry) |
610 | { | 747 | { |
611 | const struct devs_id *dev = device_ids; | 748 | const struct devs_id *dev = device_ids; |
749 | struct platform_device *pdev; | ||
612 | void *pdata = NULL; | 750 | void *pdata = NULL; |
613 | 751 | ||
614 | while (dev->name[0]) { | 752 | while (dev->name[0]) { |
615 | if (dev->type == SFI_DEV_TYPE_IPC && | 753 | if (dev->type == SFI_DEV_TYPE_IPC && |
616 | !strncmp(dev->name, pdev->name, SFI_NAME_LEN)) { | 754 | !strncmp(dev->name, entry->name, SFI_NAME_LEN)) { |
617 | pdata = dev->get_platform_data(pdev); | 755 | pdata = dev->get_platform_data(entry); |
618 | break; | 756 | break; |
619 | } | 757 | } |
620 | dev++; | 758 | dev++; |
621 | } | 759 | } |
760 | |||
761 | /* | ||
762 | * On Medfield the platform device creation is handled by the MSIC | ||
763 | * MFD driver so we don't need to do it here. | ||
764 | */ | ||
765 | if (mrst_has_msic()) | ||
766 | return; | ||
767 | |||
768 | /* ID as IRQ is a hack that will go away */ | ||
769 | pdev = platform_device_alloc(entry->name, entry->irq); | ||
770 | if (pdev == NULL) { | ||
771 | pr_err("out of memory for SFI platform device '%s'.\n", | ||
772 | entry->name); | ||
773 | return; | ||
774 | } | ||
775 | install_irq_resource(pdev, entry->irq); | ||
776 | |||
622 | pdev->dev.platform_data = pdata; | 777 | pdev->dev.platform_data = pdata; |
623 | intel_scu_device_register(pdev); | 778 | intel_scu_device_register(pdev); |
624 | } | 779 | } |
@@ -671,7 +826,6 @@ static int __init sfi_parse_devs(struct sfi_table_header *table) | |||
671 | struct sfi_device_table_entry *pentry; | 826 | struct sfi_device_table_entry *pentry; |
672 | struct spi_board_info spi_info; | 827 | struct spi_board_info spi_info; |
673 | struct i2c_board_info i2c_info; | 828 | struct i2c_board_info i2c_info; |
674 | struct platform_device *pdev; | ||
675 | int num, i, bus; | 829 | int num, i, bus; |
676 | int ioapic; | 830 | int ioapic; |
677 | struct io_apic_irq_attr irq_attr; | 831 | struct io_apic_irq_attr irq_attr; |
@@ -699,17 +853,9 @@ static int __init sfi_parse_devs(struct sfi_table_header *table) | |||
699 | 853 | ||
700 | switch (pentry->type) { | 854 | switch (pentry->type) { |
701 | case SFI_DEV_TYPE_IPC: | 855 | case SFI_DEV_TYPE_IPC: |
702 | /* ID as IRQ is a hack that will go away */ | ||
703 | pdev = platform_device_alloc(pentry->name, irq); | ||
704 | if (pdev == NULL) { | ||
705 | pr_err("out of memory for SFI platform device '%s'.\n", | ||
706 | pentry->name); | ||
707 | continue; | ||
708 | } | ||
709 | install_irq_resource(pdev, irq); | ||
710 | pr_debug("info[%2d]: IPC bus, name = %16.16s, " | 856 | pr_debug("info[%2d]: IPC bus, name = %16.16s, " |
711 | "irq = 0x%2x\n", i, pentry->name, irq); | 857 | "irq = 0x%2x\n", i, pentry->name, pentry->irq); |
712 | sfi_handle_ipc_dev(pdev); | 858 | sfi_handle_ipc_dev(pentry); |
713 | break; | 859 | break; |
714 | case SFI_DEV_TYPE_SPI: | 860 | case SFI_DEV_TYPE_SPI: |
715 | memset(&spi_info, 0, sizeof(spi_info)); | 861 | memset(&spi_info, 0, sizeof(spi_info)); |
diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c index d90456a809f9..8e89dcf9d94d 100644 --- a/drivers/cpufreq/db8500-cpufreq.c +++ b/drivers/cpufreq/db8500-cpufreq.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/cpufreq.h> | 12 | #include <linux/cpufreq.h> |
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/mfd/db8500-prcmu.h> | 15 | #include <linux/mfd/dbx500-prcmu.h> |
16 | #include <mach/id.h> | 16 | #include <mach/id.h> |
17 | 17 | ||
18 | static struct cpufreq_frequency_table freq_table[] = { | 18 | static struct cpufreq_frequency_table freq_table[] = { |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index cb0bd078efc0..8b3c745b1b05 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -189,7 +189,7 @@ config GPIO_U300 | |||
189 | 189 | ||
190 | config GPIO_VX855 | 190 | config GPIO_VX855 |
191 | tristate "VIA VX855/VX875 GPIO" | 191 | tristate "VIA VX855/VX875 GPIO" |
192 | depends on MFD_SUPPORT && PCI | 192 | depends on PCI |
193 | select MFD_CORE | 193 | select MFD_CORE |
194 | select MFD_VX855 | 194 | select MFD_VX855 |
195 | help | 195 | help |
@@ -428,7 +428,6 @@ config GPIO_TIMBERDALE | |||
428 | config GPIO_RDC321X | 428 | config GPIO_RDC321X |
429 | tristate "RDC R-321x GPIO support" | 429 | tristate "RDC R-321x GPIO support" |
430 | depends on PCI | 430 | depends on PCI |
431 | select MFD_SUPPORT | ||
432 | select MFD_CORE | 431 | select MFD_CORE |
433 | select MFD_RDC321X | 432 | select MFD_RDC321X |
434 | help | 433 | help |
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c index d5226c9e1201..ef65ab56b094 100644 --- a/drivers/hwmon/mc13783-adc.c +++ b/drivers/hwmon/mc13783-adc.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #define MC13783_ADC_NAME "mc13783-adc" | 31 | #define MC13783_ADC_NAME "mc13783-adc" |
32 | 32 | ||
33 | struct mc13783_adc_priv { | 33 | struct mc13783_adc_priv { |
34 | struct mc13783 *mc13783; | 34 | struct mc13xxx *mc13xxx; |
35 | struct device *hwmon_dev; | 35 | struct device *hwmon_dev; |
36 | }; | 36 | }; |
37 | 37 | ||
@@ -51,8 +51,8 @@ static int mc13783_adc_read(struct device *dev, | |||
51 | unsigned int sample[4]; | 51 | unsigned int sample[4]; |
52 | int ret; | 52 | int ret; |
53 | 53 | ||
54 | ret = mc13783_adc_do_conversion(priv->mc13783, | 54 | ret = mc13xxx_adc_do_conversion(priv->mc13xxx, |
55 | MC13783_ADC_MODE_MULT_CHAN, | 55 | MC13XXX_ADC_MODE_MULT_CHAN, |
56 | channel, sample); | 56 | channel, sample); |
57 | if (ret) | 57 | if (ret) |
58 | return ret; | 58 | return ret; |
@@ -147,9 +147,9 @@ static const struct attribute_group mc13783_group_ts = { | |||
147 | static int mc13783_adc_use_touchscreen(struct platform_device *pdev) | 147 | static int mc13783_adc_use_touchscreen(struct platform_device *pdev) |
148 | { | 148 | { |
149 | struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); | 149 | struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); |
150 | unsigned flags = mc13783_get_flags(priv->mc13783); | 150 | unsigned flags = mc13xxx_get_flags(priv->mc13xxx); |
151 | 151 | ||
152 | return flags & MC13783_USE_TOUCHSCREEN; | 152 | return flags & MC13XXX_USE_TOUCHSCREEN; |
153 | } | 153 | } |
154 | 154 | ||
155 | static int __init mc13783_adc_probe(struct platform_device *pdev) | 155 | static int __init mc13783_adc_probe(struct platform_device *pdev) |
@@ -161,7 +161,7 @@ static int __init mc13783_adc_probe(struct platform_device *pdev) | |||
161 | if (!priv) | 161 | if (!priv) |
162 | return -ENOMEM; | 162 | return -ENOMEM; |
163 | 163 | ||
164 | priv->mc13783 = dev_get_drvdata(pdev->dev.parent); | 164 | priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); |
165 | 165 | ||
166 | platform_set_drvdata(pdev, priv); | 166 | platform_set_drvdata(pdev, priv); |
167 | 167 | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b2b85629d074..76f65314a385 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -110,7 +110,6 @@ config I2C_I801 | |||
110 | config I2C_ISCH | 110 | config I2C_ISCH |
111 | tristate "Intel SCH SMBus 1.0" | 111 | tristate "Intel SCH SMBus 1.0" |
112 | depends on PCI | 112 | depends on PCI |
113 | select MFD_CORE | ||
114 | select LPC_SCH | 113 | select LPC_SCH |
115 | help | 114 | help |
116 | Say Y here if you want to use SMBus controller on the Intel SCH | 115 | Say Y here if you want to use SMBus controller on the Intel SCH |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 56aa465d1b99..22d875fde53a 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -134,6 +134,16 @@ config INPUT_MAX8925_ONKEY | |||
134 | To compile this driver as a module, choose M here: the module | 134 | To compile this driver as a module, choose M here: the module |
135 | will be called max8925_onkey. | 135 | will be called max8925_onkey. |
136 | 136 | ||
137 | config INPUT_MC13783_PWRBUTTON | ||
138 | tristate "MC13783 ON buttons" | ||
139 | depends on MFD_MC13783 | ||
140 | help | ||
141 | Support the ON buttons of MC13783 PMIC as an input device | ||
142 | reporting power button status. | ||
143 | |||
144 | To compile this driver as a module, choose M here: the module | ||
145 | will be called mc13783-pwrbutton. | ||
146 | |||
137 | config INPUT_MMA8450 | 147 | config INPUT_MMA8450 |
138 | tristate "MMA8450 - Freescale's 3-Axis, 8/12-bit Digital Accelerometer" | 148 | tristate "MMA8450 - Freescale's 3-Axis, 8/12-bit Digital Accelerometer" |
139 | depends on I2C | 149 | depends on I2C |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 62dcd79d548f..a244fc6a781c 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -28,6 +28,7 @@ obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o | |||
28 | obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o | 28 | obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o |
29 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o | 29 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o |
30 | obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o | 30 | obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o |
31 | obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o | ||
31 | obj-$(CONFIG_INPUT_MMA8450) += mma8450.o | 32 | obj-$(CONFIG_INPUT_MMA8450) += mma8450.o |
32 | obj-$(CONFIG_INPUT_MPU3050) += mpu3050.o | 33 | obj-$(CONFIG_INPUT_MPU3050) += mpu3050.o |
33 | obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o | 34 | obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o |
diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c new file mode 100644 index 000000000000..09b052288657 --- /dev/null +++ b/drivers/input/misc/mc13783-pwrbutton.c | |||
@@ -0,0 +1,282 @@ | |||
1 | /** | ||
2 | * Copyright (C) 2011 Philippe Rétornaz | ||
3 | * | ||
4 | * Based on twl4030-pwrbutton driver by: | ||
5 | * Peter De Schrijver <peter.de-schrijver@nokia.com> | ||
6 | * Felipe Balbi <felipe.balbi@nokia.com> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file "COPYING" in the main directory of this | ||
10 | * archive for more details. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/input.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/mfd/mc13783.h> | ||
30 | #include <linux/sched.h> | ||
31 | #include <linux/slab.h> | ||
32 | |||
33 | struct mc13783_pwrb { | ||
34 | struct input_dev *pwr; | ||
35 | struct mc13xxx *mc13783; | ||
36 | #define MC13783_PWRB_B1_POL_INVERT (1 << 0) | ||
37 | #define MC13783_PWRB_B2_POL_INVERT (1 << 1) | ||
38 | #define MC13783_PWRB_B3_POL_INVERT (1 << 2) | ||
39 | int flags; | ||
40 | unsigned short keymap[3]; | ||
41 | }; | ||
42 | |||
43 | #define MC13783_REG_INTERRUPT_SENSE_1 5 | ||
44 | #define MC13783_IRQSENSE1_ONOFD1S (1 << 3) | ||
45 | #define MC13783_IRQSENSE1_ONOFD2S (1 << 4) | ||
46 | #define MC13783_IRQSENSE1_ONOFD3S (1 << 5) | ||
47 | |||
48 | #define MC13783_REG_POWER_CONTROL_2 15 | ||
49 | #define MC13783_POWER_CONTROL_2_ON1BDBNC 4 | ||
50 | #define MC13783_POWER_CONTROL_2_ON2BDBNC 6 | ||
51 | #define MC13783_POWER_CONTROL_2_ON3BDBNC 8 | ||
52 | #define MC13783_POWER_CONTROL_2_ON1BRSTEN (1 << 1) | ||
53 | #define MC13783_POWER_CONTROL_2_ON2BRSTEN (1 << 2) | ||
54 | #define MC13783_POWER_CONTROL_2_ON3BRSTEN (1 << 3) | ||
55 | |||
56 | static irqreturn_t button_irq(int irq, void *_priv) | ||
57 | { | ||
58 | struct mc13783_pwrb *priv = _priv; | ||
59 | int val; | ||
60 | |||
61 | mc13xxx_irq_ack(priv->mc13783, irq); | ||
62 | mc13xxx_reg_read(priv->mc13783, MC13783_REG_INTERRUPT_SENSE_1, &val); | ||
63 | |||
64 | switch (irq) { | ||
65 | case MC13783_IRQ_ONOFD1: | ||
66 | val = val & MC13783_IRQSENSE1_ONOFD1S ? 1 : 0; | ||
67 | if (priv->flags & MC13783_PWRB_B1_POL_INVERT) | ||
68 | val ^= 1; | ||
69 | input_report_key(priv->pwr, priv->keymap[0], val); | ||
70 | break; | ||
71 | |||
72 | case MC13783_IRQ_ONOFD2: | ||
73 | val = val & MC13783_IRQSENSE1_ONOFD2S ? 1 : 0; | ||
74 | if (priv->flags & MC13783_PWRB_B2_POL_INVERT) | ||
75 | val ^= 1; | ||
76 | input_report_key(priv->pwr, priv->keymap[1], val); | ||
77 | break; | ||
78 | |||
79 | case MC13783_IRQ_ONOFD3: | ||
80 | val = val & MC13783_IRQSENSE1_ONOFD3S ? 1 : 0; | ||
81 | if (priv->flags & MC13783_PWRB_B3_POL_INVERT) | ||
82 | val ^= 1; | ||
83 | input_report_key(priv->pwr, priv->keymap[2], val); | ||
84 | break; | ||
85 | } | ||
86 | |||
87 | input_sync(priv->pwr); | ||
88 | |||
89 | return IRQ_HANDLED; | ||
90 | } | ||
91 | |||
92 | static int __devinit mc13783_pwrbutton_probe(struct platform_device *pdev) | ||
93 | { | ||
94 | const struct mc13xxx_buttons_platform_data *pdata; | ||
95 | struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); | ||
96 | struct input_dev *pwr; | ||
97 | struct mc13783_pwrb *priv; | ||
98 | int err = 0; | ||
99 | int reg = 0; | ||
100 | |||
101 | pdata = dev_get_platdata(&pdev->dev); | ||
102 | if (!pdata) { | ||
103 | dev_err(&pdev->dev, "missing platform data\n"); | ||
104 | return -ENODEV; | ||
105 | } | ||
106 | |||
107 | pwr = input_allocate_device(); | ||
108 | if (!pwr) { | ||
109 | dev_dbg(&pdev->dev, "Can't allocate power button\n"); | ||
110 | return -ENOMEM; | ||
111 | } | ||
112 | |||
113 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
114 | if (!priv) { | ||
115 | err = -ENOMEM; | ||
116 | dev_dbg(&pdev->dev, "Can't allocate power button\n"); | ||
117 | goto free_input_dev; | ||
118 | } | ||
119 | |||
120 | reg |= (pdata->b1on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC; | ||
121 | reg |= (pdata->b2on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC; | ||
122 | reg |= (pdata->b3on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON3BDBNC; | ||
123 | |||
124 | priv->pwr = pwr; | ||
125 | priv->mc13783 = mc13783; | ||
126 | |||
127 | mc13xxx_lock(mc13783); | ||
128 | |||
129 | if (pdata->b1on_flags & MC13783_BUTTON_ENABLE) { | ||
130 | priv->keymap[0] = pdata->b1on_key; | ||
131 | if (pdata->b1on_key != KEY_RESERVED) | ||
132 | __set_bit(pdata->b1on_key, pwr->keybit); | ||
133 | |||
134 | if (pdata->b1on_flags & MC13783_BUTTON_POL_INVERT) | ||
135 | priv->flags |= MC13783_PWRB_B1_POL_INVERT; | ||
136 | |||
137 | if (pdata->b1on_flags & MC13783_BUTTON_RESET_EN) | ||
138 | reg |= MC13783_POWER_CONTROL_2_ON1BRSTEN; | ||
139 | |||
140 | err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD1, | ||
141 | button_irq, "b1on", priv); | ||
142 | if (err) { | ||
143 | dev_dbg(&pdev->dev, "Can't request irq\n"); | ||
144 | goto free_priv; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | if (pdata->b2on_flags & MC13783_BUTTON_ENABLE) { | ||
149 | priv->keymap[1] = pdata->b2on_key; | ||
150 | if (pdata->b2on_key != KEY_RESERVED) | ||
151 | __set_bit(pdata->b2on_key, pwr->keybit); | ||
152 | |||
153 | if (pdata->b2on_flags & MC13783_BUTTON_POL_INVERT) | ||
154 | priv->flags |= MC13783_PWRB_B2_POL_INVERT; | ||
155 | |||
156 | if (pdata->b2on_flags & MC13783_BUTTON_RESET_EN) | ||
157 | reg |= MC13783_POWER_CONTROL_2_ON2BRSTEN; | ||
158 | |||
159 | err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD2, | ||
160 | button_irq, "b2on", priv); | ||
161 | if (err) { | ||
162 | dev_dbg(&pdev->dev, "Can't request irq\n"); | ||
163 | goto free_irq_b1; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | if (pdata->b3on_flags & MC13783_BUTTON_ENABLE) { | ||
168 | priv->keymap[2] = pdata->b3on_key; | ||
169 | if (pdata->b3on_key != KEY_RESERVED) | ||
170 | __set_bit(pdata->b3on_key, pwr->keybit); | ||
171 | |||
172 | if (pdata->b3on_flags & MC13783_BUTTON_POL_INVERT) | ||
173 | priv->flags |= MC13783_PWRB_B3_POL_INVERT; | ||
174 | |||
175 | if (pdata->b3on_flags & MC13783_BUTTON_RESET_EN) | ||
176 | reg |= MC13783_POWER_CONTROL_2_ON3BRSTEN; | ||
177 | |||
178 | err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD3, | ||
179 | button_irq, "b3on", priv); | ||
180 | if (err) { | ||
181 | dev_dbg(&pdev->dev, "Can't request irq: %d\n", err); | ||
182 | goto free_irq_b2; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | mc13xxx_reg_rmw(mc13783, MC13783_REG_POWER_CONTROL_2, 0x3FE, reg); | ||
187 | |||
188 | mc13xxx_unlock(mc13783); | ||
189 | |||
190 | pwr->name = "mc13783_pwrbutton"; | ||
191 | pwr->phys = "mc13783_pwrbutton/input0"; | ||
192 | pwr->dev.parent = &pdev->dev; | ||
193 | |||
194 | pwr->keycode = priv->keymap; | ||
195 | pwr->keycodemax = ARRAY_SIZE(priv->keymap); | ||
196 | pwr->keycodesize = sizeof(priv->keymap[0]); | ||
197 | __set_bit(EV_KEY, pwr->evbit); | ||
198 | |||
199 | err = input_register_device(pwr); | ||
200 | if (err) { | ||
201 | dev_dbg(&pdev->dev, "Can't register power button: %d\n", err); | ||
202 | goto free_irq; | ||
203 | } | ||
204 | |||
205 | platform_set_drvdata(pdev, priv); | ||
206 | |||
207 | return 0; | ||
208 | |||
209 | free_irq: | ||
210 | mc13xxx_lock(mc13783); | ||
211 | |||
212 | if (pdata->b3on_flags & MC13783_BUTTON_ENABLE) | ||
213 | mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD3, priv); | ||
214 | |||
215 | free_irq_b2: | ||
216 | if (pdata->b2on_flags & MC13783_BUTTON_ENABLE) | ||
217 | mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD2, priv); | ||
218 | |||
219 | free_irq_b1: | ||
220 | if (pdata->b1on_flags & MC13783_BUTTON_ENABLE) | ||
221 | mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD1, priv); | ||
222 | |||
223 | free_priv: | ||
224 | mc13xxx_unlock(mc13783); | ||
225 | kfree(priv); | ||
226 | |||
227 | free_input_dev: | ||
228 | input_free_device(pwr); | ||
229 | |||
230 | return err; | ||
231 | } | ||
232 | |||
233 | static int __devexit mc13783_pwrbutton_remove(struct platform_device *pdev) | ||
234 | { | ||
235 | struct mc13783_pwrb *priv = platform_get_drvdata(pdev); | ||
236 | const struct mc13xxx_buttons_platform_data *pdata; | ||
237 | |||
238 | pdata = dev_get_platdata(&pdev->dev); | ||
239 | |||
240 | mc13xxx_lock(priv->mc13783); | ||
241 | |||
242 | if (pdata->b3on_flags & MC13783_BUTTON_ENABLE) | ||
243 | mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD3, priv); | ||
244 | if (pdata->b2on_flags & MC13783_BUTTON_ENABLE) | ||
245 | mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD2, priv); | ||
246 | if (pdata->b1on_flags & MC13783_BUTTON_ENABLE) | ||
247 | mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD1, priv); | ||
248 | |||
249 | mc13xxx_unlock(priv->mc13783); | ||
250 | |||
251 | input_unregister_device(priv->pwr); | ||
252 | kfree(priv); | ||
253 | platform_set_drvdata(pdev, NULL); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | struct platform_driver mc13783_pwrbutton_driver = { | ||
259 | .probe = mc13783_pwrbutton_probe, | ||
260 | .remove = __devexit_p(mc13783_pwrbutton_remove), | ||
261 | .driver = { | ||
262 | .name = "mc13783-pwrbutton", | ||
263 | .owner = THIS_MODULE, | ||
264 | }, | ||
265 | }; | ||
266 | |||
267 | static int __init mc13783_pwrbutton_init(void) | ||
268 | { | ||
269 | return platform_driver_register(&mc13783_pwrbutton_driver); | ||
270 | } | ||
271 | module_init(mc13783_pwrbutton_init); | ||
272 | |||
273 | static void __exit mc13783_pwrbutton_exit(void) | ||
274 | { | ||
275 | platform_driver_unregister(&mc13783_pwrbutton_driver); | ||
276 | } | ||
277 | module_exit(mc13783_pwrbutton_exit); | ||
278 | |||
279 | MODULE_ALIAS("platform:mc13783-pwrbutton"); | ||
280 | MODULE_DESCRIPTION("MC13783 Power Button"); | ||
281 | MODULE_LICENSE("GPL v2"); | ||
282 | MODULE_AUTHOR("Philippe Retornaz"); | ||
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c index c5bc62d85bb6..ede02743eac1 100644 --- a/drivers/input/touchscreen/mc13783_ts.c +++ b/drivers/input/touchscreen/mc13783_ts.c | |||
@@ -35,7 +35,7 @@ MODULE_PARM_DESC(sample_tolerance, | |||
35 | 35 | ||
36 | struct mc13783_ts_priv { | 36 | struct mc13783_ts_priv { |
37 | struct input_dev *idev; | 37 | struct input_dev *idev; |
38 | struct mc13783 *mc13783; | 38 | struct mc13xxx *mc13xxx; |
39 | struct delayed_work work; | 39 | struct delayed_work work; |
40 | struct workqueue_struct *workq; | 40 | struct workqueue_struct *workq; |
41 | unsigned int sample[4]; | 41 | unsigned int sample[4]; |
@@ -45,7 +45,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data) | |||
45 | { | 45 | { |
46 | struct mc13783_ts_priv *priv = data; | 46 | struct mc13783_ts_priv *priv = data; |
47 | 47 | ||
48 | mc13783_irq_ack(priv->mc13783, irq); | 48 | mc13xxx_irq_ack(priv->mc13xxx, irq); |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Kick off reading coordinates. Note that if work happens already | 51 | * Kick off reading coordinates. Note that if work happens already |
@@ -121,10 +121,10 @@ static void mc13783_ts_work(struct work_struct *work) | |||
121 | { | 121 | { |
122 | struct mc13783_ts_priv *priv = | 122 | struct mc13783_ts_priv *priv = |
123 | container_of(work, struct mc13783_ts_priv, work.work); | 123 | container_of(work, struct mc13783_ts_priv, work.work); |
124 | unsigned int mode = MC13783_ADC_MODE_TS; | 124 | unsigned int mode = MC13XXX_ADC_MODE_TS; |
125 | unsigned int channel = 12; | 125 | unsigned int channel = 12; |
126 | 126 | ||
127 | if (mc13783_adc_do_conversion(priv->mc13783, | 127 | if (mc13xxx_adc_do_conversion(priv->mc13xxx, |
128 | mode, channel, priv->sample) == 0) | 128 | mode, channel, priv->sample) == 0) |
129 | mc13783_ts_report_sample(priv); | 129 | mc13783_ts_report_sample(priv); |
130 | } | 130 | } |
@@ -134,21 +134,21 @@ static int mc13783_ts_open(struct input_dev *dev) | |||
134 | struct mc13783_ts_priv *priv = input_get_drvdata(dev); | 134 | struct mc13783_ts_priv *priv = input_get_drvdata(dev); |
135 | int ret; | 135 | int ret; |
136 | 136 | ||
137 | mc13783_lock(priv->mc13783); | 137 | mc13xxx_lock(priv->mc13xxx); |
138 | 138 | ||
139 | mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TS); | 139 | mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TS); |
140 | 140 | ||
141 | ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS, | 141 | ret = mc13xxx_irq_request(priv->mc13xxx, MC13XXX_IRQ_TS, |
142 | mc13783_ts_handler, MC13783_TS_NAME, priv); | 142 | mc13783_ts_handler, MC13783_TS_NAME, priv); |
143 | if (ret) | 143 | if (ret) |
144 | goto out; | 144 | goto out; |
145 | 145 | ||
146 | ret = mc13783_reg_rmw(priv->mc13783, MC13783_ADC0, | 146 | ret = mc13xxx_reg_rmw(priv->mc13xxx, MC13XXX_ADC0, |
147 | MC13783_ADC0_TSMOD_MASK, MC13783_ADC0_TSMOD0); | 147 | MC13XXX_ADC0_TSMOD_MASK, MC13XXX_ADC0_TSMOD0); |
148 | if (ret) | 148 | if (ret) |
149 | mc13783_irq_free(priv->mc13783, MC13783_IRQ_TS, priv); | 149 | mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TS, priv); |
150 | out: | 150 | out: |
151 | mc13783_unlock(priv->mc13783); | 151 | mc13xxx_unlock(priv->mc13xxx); |
152 | return ret; | 152 | return ret; |
153 | } | 153 | } |
154 | 154 | ||
@@ -156,11 +156,11 @@ static void mc13783_ts_close(struct input_dev *dev) | |||
156 | { | 156 | { |
157 | struct mc13783_ts_priv *priv = input_get_drvdata(dev); | 157 | struct mc13783_ts_priv *priv = input_get_drvdata(dev); |
158 | 158 | ||
159 | mc13783_lock(priv->mc13783); | 159 | mc13xxx_lock(priv->mc13xxx); |
160 | mc13783_reg_rmw(priv->mc13783, MC13783_ADC0, | 160 | mc13xxx_reg_rmw(priv->mc13xxx, MC13XXX_ADC0, |
161 | MC13783_ADC0_TSMOD_MASK, 0); | 161 | MC13XXX_ADC0_TSMOD_MASK, 0); |
162 | mc13783_irq_free(priv->mc13783, MC13783_IRQ_TS, priv); | 162 | mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TS, priv); |
163 | mc13783_unlock(priv->mc13783); | 163 | mc13xxx_unlock(priv->mc13xxx); |
164 | 164 | ||
165 | cancel_delayed_work_sync(&priv->work); | 165 | cancel_delayed_work_sync(&priv->work); |
166 | } | 166 | } |
@@ -177,7 +177,7 @@ static int __init mc13783_ts_probe(struct platform_device *pdev) | |||
177 | goto err_free_mem; | 177 | goto err_free_mem; |
178 | 178 | ||
179 | INIT_DELAYED_WORK(&priv->work, mc13783_ts_work); | 179 | INIT_DELAYED_WORK(&priv->work, mc13783_ts_work); |
180 | priv->mc13783 = dev_get_drvdata(pdev->dev.parent); | 180 | priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); |
181 | priv->idev = idev; | 181 | priv->idev = idev; |
182 | 182 | ||
183 | /* | 183 | /* |
diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c index 22f847c890c9..fbd5d88ccd8f 100644 --- a/drivers/leds/leds-asic3.c +++ b/drivers/leds/leds-asic3.c | |||
@@ -107,9 +107,10 @@ static int __devinit asic3_led_probe(struct platform_device *pdev) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | led->cdev->name = led->name; | 109 | led->cdev->name = led->name; |
110 | led->cdev->default_trigger = led->default_trigger; | 110 | led->cdev->flags = LED_CORE_SUSPENDRESUME; |
111 | led->cdev->brightness_set = brightness_set; | 111 | led->cdev->brightness_set = brightness_set; |
112 | led->cdev->blink_set = blink_set; | 112 | led->cdev->blink_set = blink_set; |
113 | led->cdev->default_trigger = led->default_trigger; | ||
113 | 114 | ||
114 | ret = led_classdev_register(&pdev->dev, led->cdev); | 115 | ret = led_classdev_register(&pdev->dev, led->cdev); |
115 | if (ret < 0) | 116 | if (ret < 0) |
@@ -136,12 +137,44 @@ static int __devexit asic3_led_remove(struct platform_device *pdev) | |||
136 | return mfd_cell_disable(pdev); | 137 | return mfd_cell_disable(pdev); |
137 | } | 138 | } |
138 | 139 | ||
140 | static int asic3_led_suspend(struct device *dev) | ||
141 | { | ||
142 | struct platform_device *pdev = to_platform_device(dev); | ||
143 | const struct mfd_cell *cell = mfd_get_cell(pdev); | ||
144 | int ret; | ||
145 | |||
146 | ret = 0; | ||
147 | if (cell->suspend) | ||
148 | ret = (*cell->suspend)(pdev); | ||
149 | |||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | static int asic3_led_resume(struct device *dev) | ||
154 | { | ||
155 | struct platform_device *pdev = to_platform_device(dev); | ||
156 | const struct mfd_cell *cell = mfd_get_cell(pdev); | ||
157 | int ret; | ||
158 | |||
159 | ret = 0; | ||
160 | if (cell->resume) | ||
161 | ret = (*cell->resume)(pdev); | ||
162 | |||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static const struct dev_pm_ops asic3_led_pm_ops = { | ||
167 | .suspend = asic3_led_suspend, | ||
168 | .resume = asic3_led_resume, | ||
169 | }; | ||
170 | |||
139 | static struct platform_driver asic3_led_driver = { | 171 | static struct platform_driver asic3_led_driver = { |
140 | .probe = asic3_led_probe, | 172 | .probe = asic3_led_probe, |
141 | .remove = __devexit_p(asic3_led_remove), | 173 | .remove = __devexit_p(asic3_led_remove), |
142 | .driver = { | 174 | .driver = { |
143 | .name = "leds-asic3", | 175 | .name = "leds-asic3", |
144 | .owner = THIS_MODULE, | 176 | .owner = THIS_MODULE, |
177 | .pm = &asic3_led_pm_ops, | ||
145 | }, | 178 | }, |
146 | }; | 179 | }; |
147 | 180 | ||
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c index f369e56d6547..b3393a9f2139 100644 --- a/drivers/leds/leds-mc13783.c +++ b/drivers/leds/leds-mc13783.c | |||
@@ -21,13 +21,13 @@ | |||
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/leds.h> | 22 | #include <linux/leds.h> |
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <linux/mfd/mc13783.h> | 24 | #include <linux/mfd/mc13xxx.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | 26 | ||
27 | struct mc13783_led { | 27 | struct mc13783_led { |
28 | struct led_classdev cdev; | 28 | struct led_classdev cdev; |
29 | struct work_struct work; | 29 | struct work_struct work; |
30 | struct mc13783 *master; | 30 | struct mc13xxx *master; |
31 | enum led_brightness new_brightness; | 31 | enum led_brightness new_brightness; |
32 | int id; | 32 | int id; |
33 | }; | 33 | }; |
@@ -111,11 +111,11 @@ static void mc13783_led_work(struct work_struct *work) | |||
111 | break; | 111 | break; |
112 | } | 112 | } |
113 | 113 | ||
114 | mc13783_lock(led->master); | 114 | mc13xxx_lock(led->master); |
115 | 115 | ||
116 | mc13783_reg_rmw(led->master, reg, mask, value); | 116 | mc13xxx_reg_rmw(led->master, reg, mask, value); |
117 | 117 | ||
118 | mc13783_unlock(led->master); | 118 | mc13xxx_unlock(led->master); |
119 | } | 119 | } |
120 | 120 | ||
121 | static void mc13783_led_set(struct led_classdev *led_cdev, | 121 | static void mc13783_led_set(struct led_classdev *led_cdev, |
@@ -172,23 +172,23 @@ static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current) | |||
172 | break; | 172 | break; |
173 | } | 173 | } |
174 | 174 | ||
175 | mc13783_lock(led->master); | 175 | mc13xxx_lock(led->master); |
176 | 176 | ||
177 | ret = mc13783_reg_rmw(led->master, reg, mask << shift, | 177 | ret = mc13xxx_reg_rmw(led->master, reg, mask << shift, |
178 | value << shift); | 178 | value << shift); |
179 | 179 | ||
180 | mc13783_unlock(led->master); | 180 | mc13xxx_unlock(led->master); |
181 | return ret; | 181 | return ret; |
182 | } | 182 | } |
183 | 183 | ||
184 | static int __devinit mc13783_leds_prepare(struct platform_device *pdev) | 184 | static int __devinit mc13783_leds_prepare(struct platform_device *pdev) |
185 | { | 185 | { |
186 | struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); | 186 | struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); |
187 | struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); | 187 | struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent); |
188 | int ret = 0; | 188 | int ret = 0; |
189 | int reg = 0; | 189 | int reg = 0; |
190 | 190 | ||
191 | mc13783_lock(dev); | 191 | mc13xxx_lock(dev); |
192 | 192 | ||
193 | if (pdata->flags & MC13783_LED_TC1HALF) | 193 | if (pdata->flags & MC13783_LED_TC1HALF) |
194 | reg |= MC13783_LED_C1_TC1HALF_BIT; | 194 | reg |= MC13783_LED_C1_TC1HALF_BIT; |
@@ -196,7 +196,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev) | |||
196 | if (pdata->flags & MC13783_LED_SLEWLIMTC) | 196 | if (pdata->flags & MC13783_LED_SLEWLIMTC) |
197 | reg |= MC13783_LED_Cx_SLEWLIM_BIT; | 197 | reg |= MC13783_LED_Cx_SLEWLIM_BIT; |
198 | 198 | ||
199 | ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg); | 199 | ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg); |
200 | if (ret) | 200 | if (ret) |
201 | goto out; | 201 | goto out; |
202 | 202 | ||
@@ -206,7 +206,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev) | |||
206 | if (pdata->flags & MC13783_LED_SLEWLIMBL) | 206 | if (pdata->flags & MC13783_LED_SLEWLIMBL) |
207 | reg |= MC13783_LED_Cx_SLEWLIM_BIT; | 207 | reg |= MC13783_LED_Cx_SLEWLIM_BIT; |
208 | 208 | ||
209 | ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg); | 209 | ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg); |
210 | if (ret) | 210 | if (ret) |
211 | goto out; | 211 | goto out; |
212 | 212 | ||
@@ -216,7 +216,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev) | |||
216 | if (pdata->flags & MC13783_LED_TRIODE_TC1) | 216 | if (pdata->flags & MC13783_LED_TRIODE_TC1) |
217 | reg |= MC13783_LED_Cx_TRIODE_TC_BIT; | 217 | reg |= MC13783_LED_Cx_TRIODE_TC_BIT; |
218 | 218 | ||
219 | ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg); | 219 | ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg); |
220 | if (ret) | 220 | if (ret) |
221 | goto out; | 221 | goto out; |
222 | 222 | ||
@@ -226,7 +226,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev) | |||
226 | if (pdata->flags & MC13783_LED_TRIODE_TC2) | 226 | if (pdata->flags & MC13783_LED_TRIODE_TC2) |
227 | reg |= MC13783_LED_Cx_TRIODE_TC_BIT; | 227 | reg |= MC13783_LED_Cx_TRIODE_TC_BIT; |
228 | 228 | ||
229 | ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg); | 229 | ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg); |
230 | if (ret) | 230 | if (ret) |
231 | goto out; | 231 | goto out; |
232 | 232 | ||
@@ -236,7 +236,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev) | |||
236 | if (pdata->flags & MC13783_LED_TRIODE_TC3) | 236 | if (pdata->flags & MC13783_LED_TRIODE_TC3) |
237 | reg |= MC13783_LED_Cx_TRIODE_TC_BIT; | 237 | reg |= MC13783_LED_Cx_TRIODE_TC_BIT; |
238 | 238 | ||
239 | ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg); | 239 | ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg); |
240 | if (ret) | 240 | if (ret) |
241 | goto out; | 241 | goto out; |
242 | 242 | ||
@@ -255,17 +255,17 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev) | |||
255 | reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) << | 255 | reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) << |
256 | MC13783_LED_C0_ABREF; | 256 | MC13783_LED_C0_ABREF; |
257 | 257 | ||
258 | ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg); | 258 | ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg); |
259 | 259 | ||
260 | out: | 260 | out: |
261 | mc13783_unlock(dev); | 261 | mc13xxx_unlock(dev); |
262 | return ret; | 262 | return ret; |
263 | } | 263 | } |
264 | 264 | ||
265 | static int __devinit mc13783_led_probe(struct platform_device *pdev) | 265 | static int __devinit mc13783_led_probe(struct platform_device *pdev) |
266 | { | 266 | { |
267 | struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); | 267 | struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); |
268 | struct mc13783_led_platform_data *led_cur; | 268 | struct mc13xxx_led_platform_data *led_cur; |
269 | struct mc13783_led *led, *led_dat; | 269 | struct mc13783_led *led, *led_dat; |
270 | int ret, i; | 270 | int ret, i; |
271 | int init_led = 0; | 271 | int init_led = 0; |
@@ -351,9 +351,9 @@ err_free: | |||
351 | 351 | ||
352 | static int __devexit mc13783_led_remove(struct platform_device *pdev) | 352 | static int __devexit mc13783_led_remove(struct platform_device *pdev) |
353 | { | 353 | { |
354 | struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); | 354 | struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); |
355 | struct mc13783_led *led = platform_get_drvdata(pdev); | 355 | struct mc13783_led *led = platform_get_drvdata(pdev); |
356 | struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); | 356 | struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent); |
357 | int i; | 357 | int i; |
358 | 358 | ||
359 | for (i = 0; i < pdata->num_leds; i++) { | 359 | for (i = 0; i < pdata->num_leds; i++) { |
@@ -361,16 +361,16 @@ static int __devexit mc13783_led_remove(struct platform_device *pdev) | |||
361 | cancel_work_sync(&led[i].work); | 361 | cancel_work_sync(&led[i].work); |
362 | } | 362 | } |
363 | 363 | ||
364 | mc13783_lock(dev); | 364 | mc13xxx_lock(dev); |
365 | 365 | ||
366 | mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0); | 366 | mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0); |
367 | mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0); | 367 | mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0); |
368 | mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0); | 368 | mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0); |
369 | mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0); | 369 | mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0); |
370 | mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0); | 370 | mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0); |
371 | mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0); | 371 | mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0); |
372 | 372 | ||
373 | mc13783_unlock(dev); | 373 | mc13xxx_unlock(dev); |
374 | 374 | ||
375 | kfree(led); | 375 | kfree(led); |
376 | return 0; | 376 | return 0; |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 52798a111e16..ccd5f0d8a012 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -426,7 +426,6 @@ config RADIO_TIMBERDALE | |||
426 | config RADIO_WL1273 | 426 | config RADIO_WL1273 |
427 | tristate "Texas Instruments WL1273 I2C FM Radio" | 427 | tristate "Texas Instruments WL1273 I2C FM Radio" |
428 | depends on I2C && VIDEO_V4L2 | 428 | depends on I2C && VIDEO_V4L2 |
429 | select MFD_CORE | ||
430 | select MFD_WL1273_CORE | 429 | select MFD_WL1273_CORE |
431 | select FW_LOADER | 430 | select FW_LOADER |
432 | ---help--- | 431 | ---help--- |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index a67adcbd0fa1..f1391c21ef26 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -2,23 +2,8 @@ | |||
2 | # Multifunction miscellaneous devices | 2 | # Multifunction miscellaneous devices |
3 | # | 3 | # |
4 | 4 | ||
5 | menuconfig MFD_SUPPORT | 5 | if HAS_IOMEM |
6 | bool "Multifunction device drivers" | 6 | menu "Multifunction device drivers" |
7 | depends on HAS_IOMEM | ||
8 | default y | ||
9 | help | ||
10 | Multifunction devices embed several functions (e.g. GPIOs, | ||
11 | touchscreens, keyboards, current regulators, power management chips, | ||
12 | etc...) in one single integrated circuit. They usually talk to the | ||
13 | main CPU through one or more IRQ lines and low speed data busses (SPI, | ||
14 | I2C, etc..). They appear as one single device to the main system | ||
15 | through the data bus and the MFD framework allows for sub devices | ||
16 | (a.k.a. functions) to appear as discrete platform devices. | ||
17 | MFDs are typically found on embedded platforms. | ||
18 | |||
19 | This option alone does not add any kernel code. | ||
20 | |||
21 | if MFD_SUPPORT | ||
22 | 7 | ||
23 | config MFD_CORE | 8 | config MFD_CORE |
24 | tristate | 9 | tristate |
@@ -390,6 +375,7 @@ config MFD_WM8400 | |||
390 | tristate "Support Wolfson Microelectronics WM8400" | 375 | tristate "Support Wolfson Microelectronics WM8400" |
391 | select MFD_CORE | 376 | select MFD_CORE |
392 | depends on I2C | 377 | depends on I2C |
378 | select REGMAP_I2C | ||
393 | help | 379 | help |
394 | Support for the Wolfson Microelecronics WM8400 PMIC and audio | 380 | Support for the Wolfson Microelecronics WM8400 PMIC and audio |
395 | CODEC. This driver provides common support for accessing | 381 | CODEC. This driver provides common support for accessing |
@@ -503,6 +489,7 @@ config MFD_WM8994 | |||
503 | config MFD_PCF50633 | 489 | config MFD_PCF50633 |
504 | tristate "Support for NXP PCF50633" | 490 | tristate "Support for NXP PCF50633" |
505 | depends on I2C | 491 | depends on I2C |
492 | select REGMAP_I2C | ||
506 | help | 493 | help |
507 | Say yes here if you have NXP PCF50633 chip on your board. | 494 | Say yes here if you have NXP PCF50633 chip on your board. |
508 | This core driver provides register access and IRQ handling | 495 | This core driver provides register access and IRQ handling |
@@ -579,6 +566,23 @@ config EZX_PCAP | |||
579 | This enables the PCAP ASIC present on EZX Phones. This is | 566 | This enables the PCAP ASIC present on EZX Phones. This is |
580 | needed for MMC, TouchScreen, Sound, USB, etc.. | 567 | needed for MMC, TouchScreen, Sound, USB, etc.. |
581 | 568 | ||
569 | config AB5500_CORE | ||
570 | bool "ST-Ericsson AB5500 Mixed Signal Power Management chip" | ||
571 | depends on ABX500_CORE && MFD_DB5500_PRCMU | ||
572 | select MFD_CORE | ||
573 | help | ||
574 | Select this option to enable access to AB5500 power management | ||
575 | chip. This connects to the db5500 chip via the I2C bus via PRCMU. | ||
576 | This chip embeds various other multimedia funtionalities as well. | ||
577 | |||
578 | config AB5500_DEBUG | ||
579 | bool "Enable debug info via debugfs" | ||
580 | depends on AB5500_CORE && DEBUG_FS | ||
581 | default y if DEBUG_FS | ||
582 | help | ||
583 | Select this option if you want debug information from the AB5500 | ||
584 | using the debug filesystem, debugfs. | ||
585 | |||
582 | config AB8500_CORE | 586 | config AB8500_CORE |
583 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" | 587 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" |
584 | depends on GENERIC_HARDIRQS && ABX500_CORE | 588 | depends on GENERIC_HARDIRQS && ABX500_CORE |
@@ -615,20 +619,6 @@ config AB8500_GPADC | |||
615 | help | 619 | help |
616 | AB8500 GPADC driver used to convert Acc and battery/ac/usb voltage | 620 | AB8500 GPADC driver used to convert Acc and battery/ac/usb voltage |
617 | 621 | ||
618 | config AB3550_CORE | ||
619 | bool "ST-Ericsson AB3550 Mixed Signal Circuit core functions" | ||
620 | select MFD_CORE | ||
621 | depends on I2C=y && GENERIC_HARDIRQS && ABX500_CORE | ||
622 | help | ||
623 | Select this to enable the AB3550 Mixed Signal IC core | ||
624 | functionality. This connects to a AB3550 on the I2C bus | ||
625 | and expose a number of symbols needed for dependent devices | ||
626 | to read and write registers and subscribe to events from | ||
627 | this multi-functional IC. This is needed to use other features | ||
628 | of the AB3550 such as battery-backed RTC, charging control, | ||
629 | LEDs, vibrator, system power and temperature, power management | ||
630 | and ALSA sound. | ||
631 | |||
632 | config MFD_DB8500_PRCMU | 622 | config MFD_DB8500_PRCMU |
633 | bool "ST-Ericsson DB8500 Power Reset Control Management Unit" | 623 | bool "ST-Ericsson DB8500 Power Reset Control Management Unit" |
634 | depends on UX500_SOC_DB8500 | 624 | depends on UX500_SOC_DB8500 |
@@ -773,7 +763,17 @@ config MFD_AAT2870_CORE | |||
773 | additional drivers must be enabled in order to use the | 763 | additional drivers must be enabled in order to use the |
774 | functionality of the device. | 764 | functionality of the device. |
775 | 765 | ||
776 | endif # MFD_SUPPORT | 766 | config MFD_INTEL_MSIC |
767 | bool "Support for Intel MSIC" | ||
768 | depends on INTEL_SCU_IPC | ||
769 | select MFD_CORE | ||
770 | help | ||
771 | Select this option to enable access to Intel MSIC (Avatele | ||
772 | Passage) chip. This chip embeds audio, battery, GPIO, etc. | ||
773 | devices used in Intel Medfield platforms. | ||
774 | |||
775 | endmenu | ||
776 | endif | ||
777 | 777 | ||
778 | menu "Multimedia Capabilities Port drivers" | 778 | menu "Multimedia Capabilities Port drivers" |
779 | depends on ARCH_SA1100 | 779 | depends on ARCH_SA1100 |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index c58020303d18..b2292eb75242 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -79,7 +79,8 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o | |||
79 | obj-$(CONFIG_ABX500_CORE) += abx500-core.o | 79 | obj-$(CONFIG_ABX500_CORE) += abx500-core.o |
80 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o | 80 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o |
81 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o | 81 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o |
82 | obj-$(CONFIG_AB3550_CORE) += ab3550-core.o | 82 | obj-$(CONFIG_AB5500_CORE) += ab5500-core.o |
83 | obj-$(CONFIG_AB5500_DEBUG) += ab5500-debugfs.o | ||
83 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o | 84 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o |
84 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o | 85 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o |
85 | obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o | 86 | obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o |
@@ -102,3 +103,4 @@ obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o | |||
102 | obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o | 103 | obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o |
103 | obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o | 104 | obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o |
104 | obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o | 105 | obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o |
106 | obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o | ||
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 345dc658ef06..02c42015ba51 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c | |||
@@ -295,7 +295,7 @@ static ssize_t aat2870_reg_write_file(struct file *file, | |||
295 | { | 295 | { |
296 | struct aat2870_data *aat2870 = file->private_data; | 296 | struct aat2870_data *aat2870 = file->private_data; |
297 | char buf[32]; | 297 | char buf[32]; |
298 | int buf_size; | 298 | ssize_t buf_size; |
299 | char *start = buf; | 299 | char *start = buf; |
300 | unsigned long addr, val; | 300 | unsigned long addr, val; |
301 | int ret; | 301 | int ret; |
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index a20e1c41bed2..4f5725508ac0 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c | |||
@@ -809,7 +809,7 @@ struct ab_family_id { | |||
809 | char *name; | 809 | char *name; |
810 | }; | 810 | }; |
811 | 811 | ||
812 | static const struct ab_family_id ids[] __devinitdata = { | 812 | static const struct ab_family_id ids[] __devinitconst = { |
813 | /* AB3100 */ | 813 | /* AB3100 */ |
814 | { | 814 | { |
815 | .id = 0xc0, | 815 | .id = 0xc0, |
diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c deleted file mode 100644 index 56ba1943c91d..000000000000 --- a/drivers/mfd/ab3550-core.c +++ /dev/null | |||
@@ -1,1380 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2010 ST-Ericsson | ||
3 | * License terms: GNU General Public License (GPL) version 2 | ||
4 | * Low-level core for exclusive access to the AB3550 IC on the I2C bus | ||
5 | * and some basic chip-configuration. | ||
6 | * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> | ||
7 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | ||
8 | * Author: Mattias Wallin <mattias.wallin@stericsson.com> | ||
9 | * Author: Rickard Andersson <rickard.andersson@stericsson.com> | ||
10 | */ | ||
11 | |||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/mutex.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/random.h> | ||
21 | #include <linux/workqueue.h> | ||
22 | #include <linux/debugfs.h> | ||
23 | #include <linux/seq_file.h> | ||
24 | #include <linux/uaccess.h> | ||
25 | #include <linux/mfd/abx500.h> | ||
26 | #include <linux/list.h> | ||
27 | #include <linux/bitops.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/mfd/core.h> | ||
30 | |||
31 | #define AB3550_NAME_STRING "ab3550" | ||
32 | #define AB3550_ID_FORMAT_STRING "AB3550 %s" | ||
33 | #define AB3550_NUM_BANKS 2 | ||
34 | #define AB3550_NUM_EVENT_REG 5 | ||
35 | |||
36 | /* These are the only registers inside AB3550 used in this main file */ | ||
37 | |||
38 | /* Chip ID register */ | ||
39 | #define AB3550_CID_REG 0x20 | ||
40 | |||
41 | /* Interrupt event registers */ | ||
42 | #define AB3550_EVENT_BANK 0 | ||
43 | #define AB3550_EVENT_REG 0x22 | ||
44 | |||
45 | /* Read/write operation values. */ | ||
46 | #define AB3550_PERM_RD (0x01) | ||
47 | #define AB3550_PERM_WR (0x02) | ||
48 | |||
49 | /* Read/write permissions. */ | ||
50 | #define AB3550_PERM_RO (AB3550_PERM_RD) | ||
51 | #define AB3550_PERM_RW (AB3550_PERM_RD | AB3550_PERM_WR) | ||
52 | |||
53 | /** | ||
54 | * struct ab3550 | ||
55 | * @access_mutex: lock out concurrent accesses to the AB registers | ||
56 | * @i2c_client: I2C client for this chip | ||
57 | * @chip_name: name of this chip variant | ||
58 | * @chip_id: 8 bit chip ID for this chip variant | ||
59 | * @mask_work: a worker for writing to mask registers | ||
60 | * @event_lock: a lock to protect the event_mask | ||
61 | * @event_mask: a local copy of the mask event registers | ||
62 | * @startup_events: a copy of the first reading of the event registers | ||
63 | * @startup_events_read: whether the first events have been read | ||
64 | */ | ||
65 | struct ab3550 { | ||
66 | struct mutex access_mutex; | ||
67 | struct i2c_client *i2c_client[AB3550_NUM_BANKS]; | ||
68 | char chip_name[32]; | ||
69 | u8 chip_id; | ||
70 | struct work_struct mask_work; | ||
71 | spinlock_t event_lock; | ||
72 | u8 event_mask[AB3550_NUM_EVENT_REG]; | ||
73 | u8 startup_events[AB3550_NUM_EVENT_REG]; | ||
74 | bool startup_events_read; | ||
75 | #ifdef CONFIG_DEBUG_FS | ||
76 | unsigned int debug_bank; | ||
77 | unsigned int debug_address; | ||
78 | #endif | ||
79 | }; | ||
80 | |||
81 | /** | ||
82 | * struct ab3550_reg_range | ||
83 | * @first: the first address of the range | ||
84 | * @last: the last address of the range | ||
85 | * @perm: access permissions for the range | ||
86 | */ | ||
87 | struct ab3550_reg_range { | ||
88 | u8 first; | ||
89 | u8 last; | ||
90 | u8 perm; | ||
91 | }; | ||
92 | |||
93 | /** | ||
94 | * struct ab3550_reg_ranges | ||
95 | * @count: the number of ranges in the list | ||
96 | * @range: the list of register ranges | ||
97 | */ | ||
98 | struct ab3550_reg_ranges { | ||
99 | u8 count; | ||
100 | const struct ab3550_reg_range *range; | ||
101 | }; | ||
102 | |||
103 | /* | ||
104 | * Permissible register ranges for reading and writing per device and bank. | ||
105 | * | ||
106 | * The ranges must be listed in increasing address order, and no overlaps are | ||
107 | * allowed. It is assumed that write permission implies read permission | ||
108 | * (i.e. only RO and RW permissions should be used). Ranges with write | ||
109 | * permission must not be split up. | ||
110 | */ | ||
111 | |||
112 | #define NO_RANGE {.count = 0, .range = NULL,} | ||
113 | |||
114 | static struct | ||
115 | ab3550_reg_ranges ab3550_reg_ranges[AB3550_NUM_DEVICES][AB3550_NUM_BANKS] = { | ||
116 | [AB3550_DEVID_DAC] = { | ||
117 | NO_RANGE, | ||
118 | { | ||
119 | .count = 2, | ||
120 | .range = (struct ab3550_reg_range[]) { | ||
121 | { | ||
122 | .first = 0xb0, | ||
123 | .last = 0xba, | ||
124 | .perm = AB3550_PERM_RW, | ||
125 | }, | ||
126 | { | ||
127 | .first = 0xbc, | ||
128 | .last = 0xc3, | ||
129 | .perm = AB3550_PERM_RW, | ||
130 | }, | ||
131 | }, | ||
132 | }, | ||
133 | }, | ||
134 | [AB3550_DEVID_LEDS] = { | ||
135 | NO_RANGE, | ||
136 | { | ||
137 | .count = 2, | ||
138 | .range = (struct ab3550_reg_range[]) { | ||
139 | { | ||
140 | .first = 0x5a, | ||
141 | .last = 0x88, | ||
142 | .perm = AB3550_PERM_RW, | ||
143 | }, | ||
144 | { | ||
145 | .first = 0x8a, | ||
146 | .last = 0xad, | ||
147 | .perm = AB3550_PERM_RW, | ||
148 | }, | ||
149 | } | ||
150 | }, | ||
151 | }, | ||
152 | [AB3550_DEVID_POWER] = { | ||
153 | { | ||
154 | .count = 1, | ||
155 | .range = (struct ab3550_reg_range[]) { | ||
156 | { | ||
157 | .first = 0x21, | ||
158 | .last = 0x21, | ||
159 | .perm = AB3550_PERM_RO, | ||
160 | }, | ||
161 | } | ||
162 | }, | ||
163 | NO_RANGE, | ||
164 | }, | ||
165 | [AB3550_DEVID_REGULATORS] = { | ||
166 | { | ||
167 | .count = 1, | ||
168 | .range = (struct ab3550_reg_range[]) { | ||
169 | { | ||
170 | .first = 0x69, | ||
171 | .last = 0xa3, | ||
172 | .perm = AB3550_PERM_RW, | ||
173 | }, | ||
174 | } | ||
175 | }, | ||
176 | { | ||
177 | .count = 1, | ||
178 | .range = (struct ab3550_reg_range[]) { | ||
179 | { | ||
180 | .first = 0x14, | ||
181 | .last = 0x16, | ||
182 | .perm = AB3550_PERM_RW, | ||
183 | }, | ||
184 | } | ||
185 | }, | ||
186 | }, | ||
187 | [AB3550_DEVID_SIM] = { | ||
188 | { | ||
189 | .count = 1, | ||
190 | .range = (struct ab3550_reg_range[]) { | ||
191 | { | ||
192 | .first = 0x21, | ||
193 | .last = 0x21, | ||
194 | .perm = AB3550_PERM_RO, | ||
195 | }, | ||
196 | } | ||
197 | }, | ||
198 | { | ||
199 | .count = 1, | ||
200 | .range = (struct ab3550_reg_range[]) { | ||
201 | { | ||
202 | .first = 0x14, | ||
203 | .last = 0x17, | ||
204 | .perm = AB3550_PERM_RW, | ||
205 | }, | ||
206 | } | ||
207 | |||
208 | }, | ||
209 | }, | ||
210 | [AB3550_DEVID_UART] = { | ||
211 | NO_RANGE, | ||
212 | NO_RANGE, | ||
213 | }, | ||
214 | [AB3550_DEVID_RTC] = { | ||
215 | { | ||
216 | .count = 1, | ||
217 | .range = (struct ab3550_reg_range[]) { | ||
218 | { | ||
219 | .first = 0x00, | ||
220 | .last = 0x0c, | ||
221 | .perm = AB3550_PERM_RW, | ||
222 | }, | ||
223 | } | ||
224 | }, | ||
225 | NO_RANGE, | ||
226 | }, | ||
227 | [AB3550_DEVID_CHARGER] = { | ||
228 | { | ||
229 | .count = 2, | ||
230 | .range = (struct ab3550_reg_range[]) { | ||
231 | { | ||
232 | .first = 0x10, | ||
233 | .last = 0x1a, | ||
234 | .perm = AB3550_PERM_RW, | ||
235 | }, | ||
236 | { | ||
237 | .first = 0x21, | ||
238 | .last = 0x21, | ||
239 | .perm = AB3550_PERM_RO, | ||
240 | }, | ||
241 | } | ||
242 | }, | ||
243 | NO_RANGE, | ||
244 | }, | ||
245 | [AB3550_DEVID_ADC] = { | ||
246 | NO_RANGE, | ||
247 | { | ||
248 | .count = 1, | ||
249 | .range = (struct ab3550_reg_range[]) { | ||
250 | { | ||
251 | .first = 0x20, | ||
252 | .last = 0x56, | ||
253 | .perm = AB3550_PERM_RW, | ||
254 | }, | ||
255 | |||
256 | } | ||
257 | }, | ||
258 | }, | ||
259 | [AB3550_DEVID_FUELGAUGE] = { | ||
260 | { | ||
261 | .count = 1, | ||
262 | .range = (struct ab3550_reg_range[]) { | ||
263 | { | ||
264 | .first = 0x21, | ||
265 | .last = 0x21, | ||
266 | .perm = AB3550_PERM_RO, | ||
267 | }, | ||
268 | } | ||
269 | }, | ||
270 | { | ||
271 | .count = 1, | ||
272 | .range = (struct ab3550_reg_range[]) { | ||
273 | { | ||
274 | .first = 0x00, | ||
275 | .last = 0x0e, | ||
276 | .perm = AB3550_PERM_RW, | ||
277 | }, | ||
278 | } | ||
279 | }, | ||
280 | }, | ||
281 | [AB3550_DEVID_VIBRATOR] = { | ||
282 | NO_RANGE, | ||
283 | { | ||
284 | .count = 1, | ||
285 | .range = (struct ab3550_reg_range[]) { | ||
286 | { | ||
287 | .first = 0x10, | ||
288 | .last = 0x13, | ||
289 | .perm = AB3550_PERM_RW, | ||
290 | }, | ||
291 | |||
292 | } | ||
293 | }, | ||
294 | }, | ||
295 | [AB3550_DEVID_CODEC] = { | ||
296 | { | ||
297 | .count = 2, | ||
298 | .range = (struct ab3550_reg_range[]) { | ||
299 | { | ||
300 | .first = 0x31, | ||
301 | .last = 0x63, | ||
302 | .perm = AB3550_PERM_RW, | ||
303 | }, | ||
304 | { | ||
305 | .first = 0x65, | ||
306 | .last = 0x68, | ||
307 | .perm = AB3550_PERM_RW, | ||
308 | }, | ||
309 | } | ||
310 | }, | ||
311 | NO_RANGE, | ||
312 | }, | ||
313 | }; | ||
314 | |||
315 | static struct mfd_cell ab3550_devs[AB3550_NUM_DEVICES] = { | ||
316 | [AB3550_DEVID_DAC] = { | ||
317 | .name = "ab3550-dac", | ||
318 | .id = AB3550_DEVID_DAC, | ||
319 | .num_resources = 0, | ||
320 | }, | ||
321 | [AB3550_DEVID_LEDS] = { | ||
322 | .name = "ab3550-leds", | ||
323 | .id = AB3550_DEVID_LEDS, | ||
324 | }, | ||
325 | [AB3550_DEVID_POWER] = { | ||
326 | .name = "ab3550-power", | ||
327 | .id = AB3550_DEVID_POWER, | ||
328 | }, | ||
329 | [AB3550_DEVID_REGULATORS] = { | ||
330 | .name = "ab3550-regulators", | ||
331 | .id = AB3550_DEVID_REGULATORS, | ||
332 | }, | ||
333 | [AB3550_DEVID_SIM] = { | ||
334 | .name = "ab3550-sim", | ||
335 | .id = AB3550_DEVID_SIM, | ||
336 | }, | ||
337 | [AB3550_DEVID_UART] = { | ||
338 | .name = "ab3550-uart", | ||
339 | .id = AB3550_DEVID_UART, | ||
340 | }, | ||
341 | [AB3550_DEVID_RTC] = { | ||
342 | .name = "ab3550-rtc", | ||
343 | .id = AB3550_DEVID_RTC, | ||
344 | }, | ||
345 | [AB3550_DEVID_CHARGER] = { | ||
346 | .name = "ab3550-charger", | ||
347 | .id = AB3550_DEVID_CHARGER, | ||
348 | }, | ||
349 | [AB3550_DEVID_ADC] = { | ||
350 | .name = "ab3550-adc", | ||
351 | .id = AB3550_DEVID_ADC, | ||
352 | .num_resources = 10, | ||
353 | .resources = (struct resource[]) { | ||
354 | { | ||
355 | .name = "TRIGGER-0", | ||
356 | .flags = IORESOURCE_IRQ, | ||
357 | .start = 16, | ||
358 | .end = 16, | ||
359 | }, | ||
360 | { | ||
361 | .name = "TRIGGER-1", | ||
362 | .flags = IORESOURCE_IRQ, | ||
363 | .start = 17, | ||
364 | .end = 17, | ||
365 | }, | ||
366 | { | ||
367 | .name = "TRIGGER-2", | ||
368 | .flags = IORESOURCE_IRQ, | ||
369 | .start = 18, | ||
370 | .end = 18, | ||
371 | }, | ||
372 | { | ||
373 | .name = "TRIGGER-3", | ||
374 | .flags = IORESOURCE_IRQ, | ||
375 | .start = 19, | ||
376 | .end = 19, | ||
377 | }, | ||
378 | { | ||
379 | .name = "TRIGGER-4", | ||
380 | .flags = IORESOURCE_IRQ, | ||
381 | .start = 20, | ||
382 | .end = 20, | ||
383 | }, | ||
384 | { | ||
385 | .name = "TRIGGER-5", | ||
386 | .flags = IORESOURCE_IRQ, | ||
387 | .start = 21, | ||
388 | .end = 21, | ||
389 | }, | ||
390 | { | ||
391 | .name = "TRIGGER-6", | ||
392 | .flags = IORESOURCE_IRQ, | ||
393 | .start = 22, | ||
394 | .end = 22, | ||
395 | }, | ||
396 | { | ||
397 | .name = "TRIGGER-7", | ||
398 | .flags = IORESOURCE_IRQ, | ||
399 | .start = 23, | ||
400 | .end = 23, | ||
401 | }, | ||
402 | { | ||
403 | .name = "TRIGGER-VBAT-TXON", | ||
404 | .flags = IORESOURCE_IRQ, | ||
405 | .start = 13, | ||
406 | .end = 13, | ||
407 | }, | ||
408 | { | ||
409 | .name = "TRIGGER-VBAT", | ||
410 | .flags = IORESOURCE_IRQ, | ||
411 | .start = 12, | ||
412 | .end = 12, | ||
413 | }, | ||
414 | }, | ||
415 | }, | ||
416 | [AB3550_DEVID_FUELGAUGE] = { | ||
417 | .name = "ab3550-fuelgauge", | ||
418 | .id = AB3550_DEVID_FUELGAUGE, | ||
419 | }, | ||
420 | [AB3550_DEVID_VIBRATOR] = { | ||
421 | .name = "ab3550-vibrator", | ||
422 | .id = AB3550_DEVID_VIBRATOR, | ||
423 | }, | ||
424 | [AB3550_DEVID_CODEC] = { | ||
425 | .name = "ab3550-codec", | ||
426 | .id = AB3550_DEVID_CODEC, | ||
427 | }, | ||
428 | }; | ||
429 | |||
430 | /* | ||
431 | * I2C transactions with error messages. | ||
432 | */ | ||
433 | static int ab3550_i2c_master_send(struct ab3550 *ab, u8 bank, u8 *data, | ||
434 | u8 count) | ||
435 | { | ||
436 | int err; | ||
437 | |||
438 | err = i2c_master_send(ab->i2c_client[bank], data, count); | ||
439 | if (err < 0) { | ||
440 | dev_err(&ab->i2c_client[0]->dev, "send error: %d\n", err); | ||
441 | return err; | ||
442 | } | ||
443 | return 0; | ||
444 | } | ||
445 | |||
446 | static int ab3550_i2c_master_recv(struct ab3550 *ab, u8 bank, u8 *data, | ||
447 | u8 count) | ||
448 | { | ||
449 | int err; | ||
450 | |||
451 | err = i2c_master_recv(ab->i2c_client[bank], data, count); | ||
452 | if (err < 0) { | ||
453 | dev_err(&ab->i2c_client[0]->dev, "receive error: %d\n", err); | ||
454 | return err; | ||
455 | } | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * Functionality for getting/setting register values. | ||
461 | */ | ||
462 | static int get_register_interruptible(struct ab3550 *ab, u8 bank, u8 reg, | ||
463 | u8 *value) | ||
464 | { | ||
465 | int err; | ||
466 | |||
467 | err = mutex_lock_interruptible(&ab->access_mutex); | ||
468 | if (err) | ||
469 | return err; | ||
470 | |||
471 | err = ab3550_i2c_master_send(ab, bank, ®, 1); | ||
472 | if (!err) | ||
473 | err = ab3550_i2c_master_recv(ab, bank, value, 1); | ||
474 | |||
475 | mutex_unlock(&ab->access_mutex); | ||
476 | return err; | ||
477 | } | ||
478 | |||
479 | static int get_register_page_interruptible(struct ab3550 *ab, u8 bank, | ||
480 | u8 first_reg, u8 *regvals, u8 numregs) | ||
481 | { | ||
482 | int err; | ||
483 | |||
484 | err = mutex_lock_interruptible(&ab->access_mutex); | ||
485 | if (err) | ||
486 | return err; | ||
487 | |||
488 | err = ab3550_i2c_master_send(ab, bank, &first_reg, 1); | ||
489 | if (!err) | ||
490 | err = ab3550_i2c_master_recv(ab, bank, regvals, numregs); | ||
491 | |||
492 | mutex_unlock(&ab->access_mutex); | ||
493 | return err; | ||
494 | } | ||
495 | |||
496 | static int mask_and_set_register_interruptible(struct ab3550 *ab, u8 bank, | ||
497 | u8 reg, u8 bitmask, u8 bitvalues) | ||
498 | { | ||
499 | int err = 0; | ||
500 | |||
501 | if (likely(bitmask)) { | ||
502 | u8 reg_bits[2] = {reg, 0}; | ||
503 | |||
504 | err = mutex_lock_interruptible(&ab->access_mutex); | ||
505 | if (err) | ||
506 | return err; | ||
507 | |||
508 | if (bitmask == 0xFF) /* No need to read in this case. */ | ||
509 | reg_bits[1] = bitvalues; | ||
510 | else { /* Read and modify the register value. */ | ||
511 | u8 bits; | ||
512 | |||
513 | err = ab3550_i2c_master_send(ab, bank, ®, 1); | ||
514 | if (err) | ||
515 | goto unlock_and_return; | ||
516 | err = ab3550_i2c_master_recv(ab, bank, &bits, 1); | ||
517 | if (err) | ||
518 | goto unlock_and_return; | ||
519 | reg_bits[1] = ((~bitmask & bits) | | ||
520 | (bitmask & bitvalues)); | ||
521 | } | ||
522 | /* Write the new value. */ | ||
523 | err = ab3550_i2c_master_send(ab, bank, reg_bits, 2); | ||
524 | unlock_and_return: | ||
525 | mutex_unlock(&ab->access_mutex); | ||
526 | } | ||
527 | return err; | ||
528 | } | ||
529 | |||
530 | /* | ||
531 | * Read/write permission checking functions. | ||
532 | */ | ||
533 | static bool page_write_allowed(const struct ab3550_reg_ranges *ranges, | ||
534 | u8 first_reg, u8 last_reg) | ||
535 | { | ||
536 | u8 i; | ||
537 | |||
538 | if (last_reg < first_reg) | ||
539 | return false; | ||
540 | |||
541 | for (i = 0; i < ranges->count; i++) { | ||
542 | if (first_reg < ranges->range[i].first) | ||
543 | break; | ||
544 | if ((last_reg <= ranges->range[i].last) && | ||
545 | (ranges->range[i].perm & AB3550_PERM_WR)) | ||
546 | return true; | ||
547 | } | ||
548 | return false; | ||
549 | } | ||
550 | |||
551 | static bool reg_write_allowed(const struct ab3550_reg_ranges *ranges, u8 reg) | ||
552 | { | ||
553 | return page_write_allowed(ranges, reg, reg); | ||
554 | } | ||
555 | |||
556 | static bool page_read_allowed(const struct ab3550_reg_ranges *ranges, | ||
557 | u8 first_reg, u8 last_reg) | ||
558 | { | ||
559 | u8 i; | ||
560 | |||
561 | if (last_reg < first_reg) | ||
562 | return false; | ||
563 | /* Find the range (if it exists in the list) that includes first_reg. */ | ||
564 | for (i = 0; i < ranges->count; i++) { | ||
565 | if (first_reg < ranges->range[i].first) | ||
566 | return false; | ||
567 | if (first_reg <= ranges->range[i].last) | ||
568 | break; | ||
569 | } | ||
570 | /* Make sure that the entire range up to and including last_reg is | ||
571 | * readable. This may span several of the ranges in the list. | ||
572 | */ | ||
573 | while ((i < ranges->count) && | ||
574 | (ranges->range[i].perm & AB3550_PERM_RD)) { | ||
575 | if (last_reg <= ranges->range[i].last) | ||
576 | return true; | ||
577 | if ((++i >= ranges->count) || | ||
578 | (ranges->range[i].first != | ||
579 | (ranges->range[i - 1].last + 1))) { | ||
580 | break; | ||
581 | } | ||
582 | } | ||
583 | return false; | ||
584 | } | ||
585 | |||
586 | static bool reg_read_allowed(const struct ab3550_reg_ranges *ranges, u8 reg) | ||
587 | { | ||
588 | return page_read_allowed(ranges, reg, reg); | ||
589 | } | ||
590 | |||
591 | /* | ||
592 | * The register access functionality. | ||
593 | */ | ||
594 | static int ab3550_get_chip_id(struct device *dev) | ||
595 | { | ||
596 | struct ab3550 *ab = dev_get_drvdata(dev->parent); | ||
597 | return (int)ab->chip_id; | ||
598 | } | ||
599 | |||
600 | static int ab3550_mask_and_set_register_interruptible(struct device *dev, | ||
601 | u8 bank, u8 reg, u8 bitmask, u8 bitvalues) | ||
602 | { | ||
603 | struct ab3550 *ab; | ||
604 | struct platform_device *pdev = to_platform_device(dev); | ||
605 | |||
606 | if ((AB3550_NUM_BANKS <= bank) || | ||
607 | !reg_write_allowed(&ab3550_reg_ranges[pdev->id][bank], reg)) | ||
608 | return -EINVAL; | ||
609 | |||
610 | ab = dev_get_drvdata(dev->parent); | ||
611 | return mask_and_set_register_interruptible(ab, bank, reg, | ||
612 | bitmask, bitvalues); | ||
613 | } | ||
614 | |||
615 | static int ab3550_set_register_interruptible(struct device *dev, u8 bank, | ||
616 | u8 reg, u8 value) | ||
617 | { | ||
618 | return ab3550_mask_and_set_register_interruptible(dev, bank, reg, 0xFF, | ||
619 | value); | ||
620 | } | ||
621 | |||
622 | static int ab3550_get_register_interruptible(struct device *dev, u8 bank, | ||
623 | u8 reg, u8 *value) | ||
624 | { | ||
625 | struct ab3550 *ab; | ||
626 | struct platform_device *pdev = to_platform_device(dev); | ||
627 | |||
628 | if ((AB3550_NUM_BANKS <= bank) || | ||
629 | !reg_read_allowed(&ab3550_reg_ranges[pdev->id][bank], reg)) | ||
630 | return -EINVAL; | ||
631 | |||
632 | ab = dev_get_drvdata(dev->parent); | ||
633 | return get_register_interruptible(ab, bank, reg, value); | ||
634 | } | ||
635 | |||
636 | static int ab3550_get_register_page_interruptible(struct device *dev, u8 bank, | ||
637 | u8 first_reg, u8 *regvals, u8 numregs) | ||
638 | { | ||
639 | struct ab3550 *ab; | ||
640 | struct platform_device *pdev = to_platform_device(dev); | ||
641 | |||
642 | if ((AB3550_NUM_BANKS <= bank) || | ||
643 | !page_read_allowed(&ab3550_reg_ranges[pdev->id][bank], | ||
644 | first_reg, (first_reg + numregs - 1))) | ||
645 | return -EINVAL; | ||
646 | |||
647 | ab = dev_get_drvdata(dev->parent); | ||
648 | return get_register_page_interruptible(ab, bank, first_reg, regvals, | ||
649 | numregs); | ||
650 | } | ||
651 | |||
652 | static int ab3550_event_registers_startup_state_get(struct device *dev, | ||
653 | u8 *event) | ||
654 | { | ||
655 | struct ab3550 *ab; | ||
656 | |||
657 | ab = dev_get_drvdata(dev->parent); | ||
658 | if (!ab->startup_events_read) | ||
659 | return -EAGAIN; /* Try again later */ | ||
660 | |||
661 | memcpy(event, ab->startup_events, AB3550_NUM_EVENT_REG); | ||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | static int ab3550_startup_irq_enabled(struct device *dev, unsigned int irq) | ||
666 | { | ||
667 | struct ab3550 *ab; | ||
668 | struct ab3550_platform_data *plf_data; | ||
669 | bool val; | ||
670 | |||
671 | ab = irq_get_chip_data(irq); | ||
672 | plf_data = ab->i2c_client[0]->dev.platform_data; | ||
673 | irq -= plf_data->irq.base; | ||
674 | val = ((ab->startup_events[irq / 8] & BIT(irq % 8)) != 0); | ||
675 | |||
676 | return val; | ||
677 | } | ||
678 | |||
679 | static struct abx500_ops ab3550_ops = { | ||
680 | .get_chip_id = ab3550_get_chip_id, | ||
681 | .get_register = ab3550_get_register_interruptible, | ||
682 | .set_register = ab3550_set_register_interruptible, | ||
683 | .get_register_page = ab3550_get_register_page_interruptible, | ||
684 | .set_register_page = NULL, | ||
685 | .mask_and_set_register = ab3550_mask_and_set_register_interruptible, | ||
686 | .event_registers_startup_state_get = | ||
687 | ab3550_event_registers_startup_state_get, | ||
688 | .startup_irq_enabled = ab3550_startup_irq_enabled, | ||
689 | }; | ||
690 | |||
691 | static irqreturn_t ab3550_irq_handler(int irq, void *data) | ||
692 | { | ||
693 | struct ab3550 *ab = data; | ||
694 | int err; | ||
695 | unsigned int i; | ||
696 | u8 e[AB3550_NUM_EVENT_REG]; | ||
697 | u8 *events; | ||
698 | unsigned long flags; | ||
699 | |||
700 | events = (ab->startup_events_read ? e : ab->startup_events); | ||
701 | |||
702 | err = get_register_page_interruptible(ab, AB3550_EVENT_BANK, | ||
703 | AB3550_EVENT_REG, events, AB3550_NUM_EVENT_REG); | ||
704 | if (err) | ||
705 | goto err_event_rd; | ||
706 | |||
707 | if (!ab->startup_events_read) { | ||
708 | dev_info(&ab->i2c_client[0]->dev, | ||
709 | "startup events 0x%x,0x%x,0x%x,0x%x,0x%x\n", | ||
710 | ab->startup_events[0], ab->startup_events[1], | ||
711 | ab->startup_events[2], ab->startup_events[3], | ||
712 | ab->startup_events[4]); | ||
713 | ab->startup_events_read = true; | ||
714 | goto out; | ||
715 | } | ||
716 | |||
717 | /* The two highest bits in event[4] are not used. */ | ||
718 | events[4] &= 0x3f; | ||
719 | |||
720 | spin_lock_irqsave(&ab->event_lock, flags); | ||
721 | for (i = 0; i < AB3550_NUM_EVENT_REG; i++) | ||
722 | events[i] &= ~ab->event_mask[i]; | ||
723 | spin_unlock_irqrestore(&ab->event_lock, flags); | ||
724 | |||
725 | for (i = 0; i < AB3550_NUM_EVENT_REG; i++) { | ||
726 | u8 bit; | ||
727 | u8 event_reg; | ||
728 | |||
729 | dev_dbg(&ab->i2c_client[0]->dev, "IRQ Event[%d]: 0x%2x\n", | ||
730 | i, events[i]); | ||
731 | |||
732 | event_reg = events[i]; | ||
733 | for (bit = 0; event_reg; bit++, event_reg /= 2) { | ||
734 | if (event_reg % 2) { | ||
735 | unsigned int irq; | ||
736 | struct ab3550_platform_data *plf_data; | ||
737 | |||
738 | plf_data = ab->i2c_client[0]->dev.platform_data; | ||
739 | irq = plf_data->irq.base + (i * 8) + bit; | ||
740 | handle_nested_irq(irq); | ||
741 | } | ||
742 | } | ||
743 | } | ||
744 | out: | ||
745 | return IRQ_HANDLED; | ||
746 | |||
747 | err_event_rd: | ||
748 | dev_dbg(&ab->i2c_client[0]->dev, "error reading event registers\n"); | ||
749 | return IRQ_HANDLED; | ||
750 | } | ||
751 | |||
752 | #ifdef CONFIG_DEBUG_FS | ||
753 | static struct ab3550_reg_ranges debug_ranges[AB3550_NUM_BANKS] = { | ||
754 | { | ||
755 | .count = 6, | ||
756 | .range = (struct ab3550_reg_range[]) { | ||
757 | { | ||
758 | .first = 0x00, | ||
759 | .last = 0x0e, | ||
760 | }, | ||
761 | { | ||
762 | .first = 0x10, | ||
763 | .last = 0x1a, | ||
764 | }, | ||
765 | { | ||
766 | .first = 0x1e, | ||
767 | .last = 0x4f, | ||
768 | }, | ||
769 | { | ||
770 | .first = 0x51, | ||
771 | .last = 0x63, | ||
772 | }, | ||
773 | { | ||
774 | .first = 0x65, | ||
775 | .last = 0xa3, | ||
776 | }, | ||
777 | { | ||
778 | .first = 0xa5, | ||
779 | .last = 0xa8, | ||
780 | }, | ||
781 | } | ||
782 | }, | ||
783 | { | ||
784 | .count = 8, | ||
785 | .range = (struct ab3550_reg_range[]) { | ||
786 | { | ||
787 | .first = 0x00, | ||
788 | .last = 0x0e, | ||
789 | }, | ||
790 | { | ||
791 | .first = 0x10, | ||
792 | .last = 0x17, | ||
793 | }, | ||
794 | { | ||
795 | .first = 0x1a, | ||
796 | .last = 0x1c, | ||
797 | }, | ||
798 | { | ||
799 | .first = 0x20, | ||
800 | .last = 0x56, | ||
801 | }, | ||
802 | { | ||
803 | .first = 0x5a, | ||
804 | .last = 0x88, | ||
805 | }, | ||
806 | { | ||
807 | .first = 0x8a, | ||
808 | .last = 0xad, | ||
809 | }, | ||
810 | { | ||
811 | .first = 0xb0, | ||
812 | .last = 0xba, | ||
813 | }, | ||
814 | { | ||
815 | .first = 0xbc, | ||
816 | .last = 0xc3, | ||
817 | }, | ||
818 | } | ||
819 | }, | ||
820 | }; | ||
821 | |||
822 | static int ab3550_registers_print(struct seq_file *s, void *p) | ||
823 | { | ||
824 | struct ab3550 *ab = s->private; | ||
825 | int bank; | ||
826 | |||
827 | seq_printf(s, AB3550_NAME_STRING " register values:\n"); | ||
828 | |||
829 | for (bank = 0; bank < AB3550_NUM_BANKS; bank++) { | ||
830 | unsigned int i; | ||
831 | |||
832 | seq_printf(s, " bank %d:\n", bank); | ||
833 | for (i = 0; i < debug_ranges[bank].count; i++) { | ||
834 | u8 reg; | ||
835 | |||
836 | for (reg = debug_ranges[bank].range[i].first; | ||
837 | reg <= debug_ranges[bank].range[i].last; | ||
838 | reg++) { | ||
839 | u8 value; | ||
840 | |||
841 | get_register_interruptible(ab, bank, reg, | ||
842 | &value); | ||
843 | seq_printf(s, " [%d/0x%02X]: 0x%02X\n", bank, | ||
844 | reg, value); | ||
845 | } | ||
846 | } | ||
847 | } | ||
848 | return 0; | ||
849 | } | ||
850 | |||
851 | static int ab3550_registers_open(struct inode *inode, struct file *file) | ||
852 | { | ||
853 | return single_open(file, ab3550_registers_print, inode->i_private); | ||
854 | } | ||
855 | |||
856 | static const struct file_operations ab3550_registers_fops = { | ||
857 | .open = ab3550_registers_open, | ||
858 | .read = seq_read, | ||
859 | .llseek = seq_lseek, | ||
860 | .release = single_release, | ||
861 | .owner = THIS_MODULE, | ||
862 | }; | ||
863 | |||
864 | static int ab3550_bank_print(struct seq_file *s, void *p) | ||
865 | { | ||
866 | struct ab3550 *ab = s->private; | ||
867 | |||
868 | seq_printf(s, "%d\n", ab->debug_bank); | ||
869 | return 0; | ||
870 | } | ||
871 | |||
872 | static int ab3550_bank_open(struct inode *inode, struct file *file) | ||
873 | { | ||
874 | return single_open(file, ab3550_bank_print, inode->i_private); | ||
875 | } | ||
876 | |||
877 | static ssize_t ab3550_bank_write(struct file *file, | ||
878 | const char __user *user_buf, | ||
879 | size_t count, loff_t *ppos) | ||
880 | { | ||
881 | struct ab3550 *ab = ((struct seq_file *)(file->private_data))->private; | ||
882 | unsigned long user_bank; | ||
883 | int err; | ||
884 | |||
885 | /* Get userspace string and assure termination */ | ||
886 | err = kstrtoul_from_user(user_buf, count, 0, &user_bank); | ||
887 | if (err) | ||
888 | return err; | ||
889 | |||
890 | if (user_bank >= AB3550_NUM_BANKS) { | ||
891 | dev_err(&ab->i2c_client[0]->dev, | ||
892 | "debugfs error input > number of banks\n"); | ||
893 | return -EINVAL; | ||
894 | } | ||
895 | |||
896 | ab->debug_bank = user_bank; | ||
897 | |||
898 | return count; | ||
899 | } | ||
900 | |||
901 | static int ab3550_address_print(struct seq_file *s, void *p) | ||
902 | { | ||
903 | struct ab3550 *ab = s->private; | ||
904 | |||
905 | seq_printf(s, "0x%02X\n", ab->debug_address); | ||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | static int ab3550_address_open(struct inode *inode, struct file *file) | ||
910 | { | ||
911 | return single_open(file, ab3550_address_print, inode->i_private); | ||
912 | } | ||
913 | |||
914 | static ssize_t ab3550_address_write(struct file *file, | ||
915 | const char __user *user_buf, | ||
916 | size_t count, loff_t *ppos) | ||
917 | { | ||
918 | struct ab3550 *ab = ((struct seq_file *)(file->private_data))->private; | ||
919 | unsigned long user_address; | ||
920 | int err; | ||
921 | |||
922 | /* Get userspace string and assure termination */ | ||
923 | err = kstrtoul_from_user(user_buf, count, 0, &user_address); | ||
924 | if (err) | ||
925 | return err; | ||
926 | |||
927 | if (user_address > 0xff) { | ||
928 | dev_err(&ab->i2c_client[0]->dev, | ||
929 | "debugfs error input > 0xff\n"); | ||
930 | return -EINVAL; | ||
931 | } | ||
932 | ab->debug_address = user_address; | ||
933 | return count; | ||
934 | } | ||
935 | |||
936 | static int ab3550_val_print(struct seq_file *s, void *p) | ||
937 | { | ||
938 | struct ab3550 *ab = s->private; | ||
939 | int err; | ||
940 | u8 regvalue; | ||
941 | |||
942 | err = get_register_interruptible(ab, (u8)ab->debug_bank, | ||
943 | (u8)ab->debug_address, ®value); | ||
944 | if (err) | ||
945 | return -EINVAL; | ||
946 | seq_printf(s, "0x%02X\n", regvalue); | ||
947 | |||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | static int ab3550_val_open(struct inode *inode, struct file *file) | ||
952 | { | ||
953 | return single_open(file, ab3550_val_print, inode->i_private); | ||
954 | } | ||
955 | |||
956 | static ssize_t ab3550_val_write(struct file *file, | ||
957 | const char __user *user_buf, | ||
958 | size_t count, loff_t *ppos) | ||
959 | { | ||
960 | struct ab3550 *ab = ((struct seq_file *)(file->private_data))->private; | ||
961 | unsigned long user_val; | ||
962 | int err; | ||
963 | u8 regvalue; | ||
964 | |||
965 | /* Get userspace string and assure termination */ | ||
966 | err = kstrtoul_from_user(user_buf, count, 0, &user_val); | ||
967 | if (err) | ||
968 | return err; | ||
969 | |||
970 | if (user_val > 0xff) { | ||
971 | dev_err(&ab->i2c_client[0]->dev, | ||
972 | "debugfs error input > 0xff\n"); | ||
973 | return -EINVAL; | ||
974 | } | ||
975 | err = mask_and_set_register_interruptible( | ||
976 | ab, (u8)ab->debug_bank, | ||
977 | (u8)ab->debug_address, 0xFF, (u8)user_val); | ||
978 | if (err) | ||
979 | return -EINVAL; | ||
980 | |||
981 | get_register_interruptible(ab, (u8)ab->debug_bank, | ||
982 | (u8)ab->debug_address, ®value); | ||
983 | if (err) | ||
984 | return -EINVAL; | ||
985 | |||
986 | return count; | ||
987 | } | ||
988 | |||
989 | static const struct file_operations ab3550_bank_fops = { | ||
990 | .open = ab3550_bank_open, | ||
991 | .write = ab3550_bank_write, | ||
992 | .read = seq_read, | ||
993 | .llseek = seq_lseek, | ||
994 | .release = single_release, | ||
995 | .owner = THIS_MODULE, | ||
996 | }; | ||
997 | |||
998 | static const struct file_operations ab3550_address_fops = { | ||
999 | .open = ab3550_address_open, | ||
1000 | .write = ab3550_address_write, | ||
1001 | .read = seq_read, | ||
1002 | .llseek = seq_lseek, | ||
1003 | .release = single_release, | ||
1004 | .owner = THIS_MODULE, | ||
1005 | }; | ||
1006 | |||
1007 | static const struct file_operations ab3550_val_fops = { | ||
1008 | .open = ab3550_val_open, | ||
1009 | .write = ab3550_val_write, | ||
1010 | .read = seq_read, | ||
1011 | .llseek = seq_lseek, | ||
1012 | .release = single_release, | ||
1013 | .owner = THIS_MODULE, | ||
1014 | }; | ||
1015 | |||
1016 | static struct dentry *ab3550_dir; | ||
1017 | static struct dentry *ab3550_reg_file; | ||
1018 | static struct dentry *ab3550_bank_file; | ||
1019 | static struct dentry *ab3550_address_file; | ||
1020 | static struct dentry *ab3550_val_file; | ||
1021 | |||
1022 | static inline void ab3550_setup_debugfs(struct ab3550 *ab) | ||
1023 | { | ||
1024 | ab->debug_bank = 0; | ||
1025 | ab->debug_address = 0x00; | ||
1026 | |||
1027 | ab3550_dir = debugfs_create_dir(AB3550_NAME_STRING, NULL); | ||
1028 | if (!ab3550_dir) | ||
1029 | goto exit_no_debugfs; | ||
1030 | |||
1031 | ab3550_reg_file = debugfs_create_file("all-registers", | ||
1032 | S_IRUGO, ab3550_dir, ab, &ab3550_registers_fops); | ||
1033 | if (!ab3550_reg_file) | ||
1034 | goto exit_destroy_dir; | ||
1035 | |||
1036 | ab3550_bank_file = debugfs_create_file("register-bank", | ||
1037 | (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_bank_fops); | ||
1038 | if (!ab3550_bank_file) | ||
1039 | goto exit_destroy_reg; | ||
1040 | |||
1041 | ab3550_address_file = debugfs_create_file("register-address", | ||
1042 | (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_address_fops); | ||
1043 | if (!ab3550_address_file) | ||
1044 | goto exit_destroy_bank; | ||
1045 | |||
1046 | ab3550_val_file = debugfs_create_file("register-value", | ||
1047 | (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_val_fops); | ||
1048 | if (!ab3550_val_file) | ||
1049 | goto exit_destroy_address; | ||
1050 | |||
1051 | return; | ||
1052 | |||
1053 | exit_destroy_address: | ||
1054 | debugfs_remove(ab3550_address_file); | ||
1055 | exit_destroy_bank: | ||
1056 | debugfs_remove(ab3550_bank_file); | ||
1057 | exit_destroy_reg: | ||
1058 | debugfs_remove(ab3550_reg_file); | ||
1059 | exit_destroy_dir: | ||
1060 | debugfs_remove(ab3550_dir); | ||
1061 | exit_no_debugfs: | ||
1062 | dev_err(&ab->i2c_client[0]->dev, "failed to create debugfs entries.\n"); | ||
1063 | return; | ||
1064 | } | ||
1065 | |||
1066 | static inline void ab3550_remove_debugfs(void) | ||
1067 | { | ||
1068 | debugfs_remove(ab3550_val_file); | ||
1069 | debugfs_remove(ab3550_address_file); | ||
1070 | debugfs_remove(ab3550_bank_file); | ||
1071 | debugfs_remove(ab3550_reg_file); | ||
1072 | debugfs_remove(ab3550_dir); | ||
1073 | } | ||
1074 | |||
1075 | #else /* !CONFIG_DEBUG_FS */ | ||
1076 | static inline void ab3550_setup_debugfs(struct ab3550 *ab) | ||
1077 | { | ||
1078 | } | ||
1079 | static inline void ab3550_remove_debugfs(void) | ||
1080 | { | ||
1081 | } | ||
1082 | #endif | ||
1083 | |||
1084 | /* | ||
1085 | * Basic set-up, datastructure creation/destruction and I2C interface. | ||
1086 | * This sets up a default config in the AB3550 chip so that it | ||
1087 | * will work as expected. | ||
1088 | */ | ||
1089 | static int __init ab3550_setup(struct ab3550 *ab) | ||
1090 | { | ||
1091 | int err = 0; | ||
1092 | int i; | ||
1093 | struct ab3550_platform_data *plf_data; | ||
1094 | struct abx500_init_settings *settings; | ||
1095 | |||
1096 | plf_data = ab->i2c_client[0]->dev.platform_data; | ||
1097 | settings = plf_data->init_settings; | ||
1098 | |||
1099 | for (i = 0; i < plf_data->init_settings_sz; i++) { | ||
1100 | err = mask_and_set_register_interruptible(ab, | ||
1101 | settings[i].bank, | ||
1102 | settings[i].reg, | ||
1103 | 0xFF, settings[i].setting); | ||
1104 | if (err) | ||
1105 | goto exit_no_setup; | ||
1106 | |||
1107 | /* If event mask register update the event mask in ab3550 */ | ||
1108 | if ((settings[i].bank == 0) && | ||
1109 | (AB3550_IMR1 <= settings[i].reg) && | ||
1110 | (settings[i].reg <= AB3550_IMR5)) { | ||
1111 | ab->event_mask[settings[i].reg - AB3550_IMR1] = | ||
1112 | settings[i].setting; | ||
1113 | } | ||
1114 | } | ||
1115 | exit_no_setup: | ||
1116 | return err; | ||
1117 | } | ||
1118 | |||
1119 | static void ab3550_mask_work(struct work_struct *work) | ||
1120 | { | ||
1121 | struct ab3550 *ab = container_of(work, struct ab3550, mask_work); | ||
1122 | int i; | ||
1123 | unsigned long flags; | ||
1124 | u8 mask[AB3550_NUM_EVENT_REG]; | ||
1125 | |||
1126 | spin_lock_irqsave(&ab->event_lock, flags); | ||
1127 | for (i = 0; i < AB3550_NUM_EVENT_REG; i++) | ||
1128 | mask[i] = ab->event_mask[i]; | ||
1129 | spin_unlock_irqrestore(&ab->event_lock, flags); | ||
1130 | |||
1131 | for (i = 0; i < AB3550_NUM_EVENT_REG; i++) { | ||
1132 | int err; | ||
1133 | |||
1134 | err = mask_and_set_register_interruptible(ab, 0, | ||
1135 | (AB3550_IMR1 + i), ~0, mask[i]); | ||
1136 | if (err) | ||
1137 | dev_err(&ab->i2c_client[0]->dev, | ||
1138 | "ab3550_mask_work failed 0x%x,0x%x\n", | ||
1139 | (AB3550_IMR1 + i), mask[i]); | ||
1140 | } | ||
1141 | } | ||
1142 | |||
1143 | static void ab3550_mask(struct irq_data *data) | ||
1144 | { | ||
1145 | unsigned long flags; | ||
1146 | struct ab3550 *ab; | ||
1147 | struct ab3550_platform_data *plf_data; | ||
1148 | int irq; | ||
1149 | |||
1150 | ab = irq_data_get_irq_chip_data(data); | ||
1151 | plf_data = ab->i2c_client[0]->dev.platform_data; | ||
1152 | irq = data->irq - plf_data->irq.base; | ||
1153 | |||
1154 | spin_lock_irqsave(&ab->event_lock, flags); | ||
1155 | ab->event_mask[irq / 8] |= BIT(irq % 8); | ||
1156 | spin_unlock_irqrestore(&ab->event_lock, flags); | ||
1157 | |||
1158 | schedule_work(&ab->mask_work); | ||
1159 | } | ||
1160 | |||
1161 | static void ab3550_unmask(struct irq_data *data) | ||
1162 | { | ||
1163 | unsigned long flags; | ||
1164 | struct ab3550 *ab; | ||
1165 | struct ab3550_platform_data *plf_data; | ||
1166 | int irq; | ||
1167 | |||
1168 | ab = irq_data_get_irq_chip_data(data); | ||
1169 | plf_data = ab->i2c_client[0]->dev.platform_data; | ||
1170 | irq = data->irq - plf_data->irq.base; | ||
1171 | |||
1172 | spin_lock_irqsave(&ab->event_lock, flags); | ||
1173 | ab->event_mask[irq / 8] &= ~BIT(irq % 8); | ||
1174 | spin_unlock_irqrestore(&ab->event_lock, flags); | ||
1175 | |||
1176 | schedule_work(&ab->mask_work); | ||
1177 | } | ||
1178 | |||
1179 | static void noop(struct irq_data *data) | ||
1180 | { | ||
1181 | } | ||
1182 | |||
1183 | static struct irq_chip ab3550_irq_chip = { | ||
1184 | .name = "ab3550-core", /* Keep the same name as the request */ | ||
1185 | .irq_disable = ab3550_mask, /* No default to mask in chip.c */ | ||
1186 | .irq_ack = noop, | ||
1187 | .irq_mask = ab3550_mask, | ||
1188 | .irq_unmask = ab3550_unmask, | ||
1189 | }; | ||
1190 | |||
1191 | struct ab_family_id { | ||
1192 | u8 id; | ||
1193 | char *name; | ||
1194 | }; | ||
1195 | |||
1196 | static const struct ab_family_id ids[] __initdata = { | ||
1197 | /* AB3550 */ | ||
1198 | { | ||
1199 | .id = AB3550_P1A, | ||
1200 | .name = "P1A" | ||
1201 | }, | ||
1202 | /* Terminator */ | ||
1203 | { | ||
1204 | .id = 0x00, | ||
1205 | } | ||
1206 | }; | ||
1207 | |||
1208 | static int __init ab3550_probe(struct i2c_client *client, | ||
1209 | const struct i2c_device_id *id) | ||
1210 | { | ||
1211 | struct ab3550 *ab; | ||
1212 | struct ab3550_platform_data *ab3550_plf_data = | ||
1213 | client->dev.platform_data; | ||
1214 | int err; | ||
1215 | int i; | ||
1216 | int num_i2c_clients = 0; | ||
1217 | |||
1218 | ab = kzalloc(sizeof(struct ab3550), GFP_KERNEL); | ||
1219 | if (!ab) { | ||
1220 | dev_err(&client->dev, | ||
1221 | "could not allocate " AB3550_NAME_STRING " device\n"); | ||
1222 | return -ENOMEM; | ||
1223 | } | ||
1224 | |||
1225 | /* Initialize data structure */ | ||
1226 | mutex_init(&ab->access_mutex); | ||
1227 | spin_lock_init(&ab->event_lock); | ||
1228 | ab->i2c_client[0] = client; | ||
1229 | |||
1230 | i2c_set_clientdata(client, ab); | ||
1231 | |||
1232 | /* Read chip ID register */ | ||
1233 | err = get_register_interruptible(ab, 0, AB3550_CID_REG, &ab->chip_id); | ||
1234 | if (err) { | ||
1235 | dev_err(&client->dev, "could not communicate with the analog " | ||
1236 | "baseband chip\n"); | ||
1237 | goto exit_no_detect; | ||
1238 | } | ||
1239 | |||
1240 | for (i = 0; ids[i].id != 0x0; i++) { | ||
1241 | if (ids[i].id == ab->chip_id) { | ||
1242 | snprintf(&ab->chip_name[0], sizeof(ab->chip_name) - 1, | ||
1243 | AB3550_ID_FORMAT_STRING, ids[i].name); | ||
1244 | break; | ||
1245 | } | ||
1246 | } | ||
1247 | |||
1248 | if (ids[i].id == 0x0) { | ||
1249 | dev_err(&client->dev, "unknown analog baseband chip id: 0x%x\n", | ||
1250 | ab->chip_id); | ||
1251 | dev_err(&client->dev, "driver not started!\n"); | ||
1252 | goto exit_no_detect; | ||
1253 | } | ||
1254 | |||
1255 | dev_info(&client->dev, "detected AB chip: %s\n", &ab->chip_name[0]); | ||
1256 | |||
1257 | /* Attach other dummy I2C clients. */ | ||
1258 | while (++num_i2c_clients < AB3550_NUM_BANKS) { | ||
1259 | ab->i2c_client[num_i2c_clients] = | ||
1260 | i2c_new_dummy(client->adapter, | ||
1261 | (client->addr + num_i2c_clients)); | ||
1262 | if (!ab->i2c_client[num_i2c_clients]) { | ||
1263 | err = -ENOMEM; | ||
1264 | goto exit_no_dummy_client; | ||
1265 | } | ||
1266 | strlcpy(ab->i2c_client[num_i2c_clients]->name, id->name, | ||
1267 | sizeof(ab->i2c_client[num_i2c_clients]->name)); | ||
1268 | } | ||
1269 | |||
1270 | err = ab3550_setup(ab); | ||
1271 | if (err) | ||
1272 | goto exit_no_setup; | ||
1273 | |||
1274 | INIT_WORK(&ab->mask_work, ab3550_mask_work); | ||
1275 | |||
1276 | for (i = 0; i < ab3550_plf_data->irq.count; i++) { | ||
1277 | unsigned int irq; | ||
1278 | |||
1279 | irq = ab3550_plf_data->irq.base + i; | ||
1280 | irq_set_chip_data(irq, ab); | ||
1281 | irq_set_chip_and_handler(irq, &ab3550_irq_chip, | ||
1282 | handle_simple_irq); | ||
1283 | irq_set_nested_thread(irq, 1); | ||
1284 | #ifdef CONFIG_ARM | ||
1285 | set_irq_flags(irq, IRQF_VALID); | ||
1286 | #else | ||
1287 | irq_set_noprobe(irq); | ||
1288 | #endif | ||
1289 | } | ||
1290 | |||
1291 | err = request_threaded_irq(client->irq, NULL, ab3550_irq_handler, | ||
1292 | IRQF_ONESHOT, "ab3550-core", ab); | ||
1293 | /* This real unpredictable IRQ is of course sampled for entropy */ | ||
1294 | rand_initialize_irq(client->irq); | ||
1295 | |||
1296 | if (err) | ||
1297 | goto exit_no_irq; | ||
1298 | |||
1299 | err = abx500_register_ops(&client->dev, &ab3550_ops); | ||
1300 | if (err) | ||
1301 | goto exit_no_ops; | ||
1302 | |||
1303 | /* Set up and register the platform devices. */ | ||
1304 | for (i = 0; i < AB3550_NUM_DEVICES; i++) { | ||
1305 | ab3550_devs[i].platform_data = ab3550_plf_data->dev_data[i]; | ||
1306 | ab3550_devs[i].pdata_size = ab3550_plf_data->dev_data_sz[i]; | ||
1307 | } | ||
1308 | |||
1309 | err = mfd_add_devices(&client->dev, 0, ab3550_devs, | ||
1310 | ARRAY_SIZE(ab3550_devs), NULL, | ||
1311 | ab3550_plf_data->irq.base); | ||
1312 | |||
1313 | ab3550_setup_debugfs(ab); | ||
1314 | |||
1315 | return 0; | ||
1316 | |||
1317 | exit_no_ops: | ||
1318 | exit_no_irq: | ||
1319 | exit_no_setup: | ||
1320 | exit_no_dummy_client: | ||
1321 | /* Unregister the dummy i2c clients. */ | ||
1322 | while (--num_i2c_clients) | ||
1323 | i2c_unregister_device(ab->i2c_client[num_i2c_clients]); | ||
1324 | exit_no_detect: | ||
1325 | kfree(ab); | ||
1326 | return err; | ||
1327 | } | ||
1328 | |||
1329 | static int __exit ab3550_remove(struct i2c_client *client) | ||
1330 | { | ||
1331 | struct ab3550 *ab = i2c_get_clientdata(client); | ||
1332 | int num_i2c_clients = AB3550_NUM_BANKS; | ||
1333 | |||
1334 | mfd_remove_devices(&client->dev); | ||
1335 | ab3550_remove_debugfs(); | ||
1336 | |||
1337 | while (--num_i2c_clients) | ||
1338 | i2c_unregister_device(ab->i2c_client[num_i2c_clients]); | ||
1339 | |||
1340 | /* | ||
1341 | * At this point, all subscribers should have unregistered | ||
1342 | * their notifiers so deactivate IRQ | ||
1343 | */ | ||
1344 | free_irq(client->irq, ab); | ||
1345 | kfree(ab); | ||
1346 | return 0; | ||
1347 | } | ||
1348 | |||
1349 | static const struct i2c_device_id ab3550_id[] = { | ||
1350 | {AB3550_NAME_STRING, 0}, | ||
1351 | {} | ||
1352 | }; | ||
1353 | MODULE_DEVICE_TABLE(i2c, ab3550_id); | ||
1354 | |||
1355 | static struct i2c_driver ab3550_driver = { | ||
1356 | .driver = { | ||
1357 | .name = AB3550_NAME_STRING, | ||
1358 | .owner = THIS_MODULE, | ||
1359 | }, | ||
1360 | .id_table = ab3550_id, | ||
1361 | .probe = ab3550_probe, | ||
1362 | .remove = __exit_p(ab3550_remove), | ||
1363 | }; | ||
1364 | |||
1365 | static int __init ab3550_i2c_init(void) | ||
1366 | { | ||
1367 | return i2c_add_driver(&ab3550_driver); | ||
1368 | } | ||
1369 | |||
1370 | static void __exit ab3550_i2c_exit(void) | ||
1371 | { | ||
1372 | i2c_del_driver(&ab3550_driver); | ||
1373 | } | ||
1374 | |||
1375 | subsys_initcall(ab3550_i2c_init); | ||
1376 | module_exit(ab3550_i2c_exit); | ||
1377 | |||
1378 | MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>"); | ||
1379 | MODULE_DESCRIPTION("AB3550 core driver"); | ||
1380 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c new file mode 100644 index 000000000000..4175544b491b --- /dev/null +++ b/drivers/mfd/ab5500-core.c | |||
@@ -0,0 +1,1439 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2011 ST-Ericsson | ||
3 | * License terms: GNU General Public License (GPL) version 2 | ||
4 | * Low-level core for exclusive access to the AB5500 IC on the I2C bus | ||
5 | * and some basic chip-configuration. | ||
6 | * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> | ||
7 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | ||
8 | * Author: Mattias Wallin <mattias.wallin@stericsson.com> | ||
9 | * Author: Rickard Andersson <rickard.andersson@stericsson.com> | ||
10 | * Author: Karl Komierowski <karl.komierowski@stericsson.com> | ||
11 | * Author: Bibek Basu <bibek.basu@stericsson.com> | ||
12 | * | ||
13 | * TODO: Event handling with irq_chip. Waiting for PRCMU fw support. | ||
14 | */ | ||
15 | |||
16 | #include <linux/mutex.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/irq.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/random.h> | ||
24 | #include <linux/mfd/ab5500/ab5500.h> | ||
25 | #include <linux/mfd/abx500.h> | ||
26 | #include <linux/list.h> | ||
27 | #include <linux/bitops.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/mfd/core.h> | ||
30 | #include <linux/version.h> | ||
31 | #include <linux/mfd/db5500-prcmu.h> | ||
32 | |||
33 | #include "ab5500-core.h" | ||
34 | #include "ab5500-debugfs.h" | ||
35 | |||
36 | #define AB5500_NUM_EVENT_REG 23 | ||
37 | #define AB5500_IT_LATCH0_REG 0x40 | ||
38 | #define AB5500_IT_MASK0_REG 0x60 | ||
39 | |||
40 | /* | ||
41 | * Permissible register ranges for reading and writing per device and bank. | ||
42 | * | ||
43 | * The ranges must be listed in increasing address order, and no overlaps are | ||
44 | * allowed. It is assumed that write permission implies read permission | ||
45 | * (i.e. only RO and RW permissions should be used). Ranges with write | ||
46 | * permission must not be split up. | ||
47 | */ | ||
48 | |||
49 | #define NO_RANGE {.count = 0, .range = NULL,} | ||
50 | static struct ab5500_i2c_banks ab5500_bank_ranges[AB5500_NUM_DEVICES] = { | ||
51 | [AB5500_DEVID_USB] = { | ||
52 | .nbanks = 1, | ||
53 | .bank = (struct ab5500_i2c_ranges []) { | ||
54 | { | ||
55 | .bankid = AB5500_BANK_USB, | ||
56 | .nranges = 12, | ||
57 | .range = (struct ab5500_reg_range[]) { | ||
58 | { | ||
59 | .first = 0x01, | ||
60 | .last = 0x01, | ||
61 | .perm = AB5500_PERM_RW, | ||
62 | }, | ||
63 | { | ||
64 | .first = 0x80, | ||
65 | .last = 0x83, | ||
66 | .perm = AB5500_PERM_RW, | ||
67 | }, | ||
68 | { | ||
69 | .first = 0x87, | ||
70 | .last = 0x8A, | ||
71 | .perm = AB5500_PERM_RW, | ||
72 | }, | ||
73 | { | ||
74 | .first = 0x8B, | ||
75 | .last = 0x8B, | ||
76 | .perm = AB5500_PERM_RO, | ||
77 | }, | ||
78 | { | ||
79 | .first = 0x91, | ||
80 | .last = 0x92, | ||
81 | .perm = AB5500_PERM_RO, | ||
82 | }, | ||
83 | { | ||
84 | .first = 0x93, | ||
85 | .last = 0x93, | ||
86 | .perm = AB5500_PERM_RW, | ||
87 | }, | ||
88 | { | ||
89 | .first = 0x94, | ||
90 | .last = 0x94, | ||
91 | .perm = AB5500_PERM_RO, | ||
92 | }, | ||
93 | { | ||
94 | .first = 0xA8, | ||
95 | .last = 0xB0, | ||
96 | .perm = AB5500_PERM_RO, | ||
97 | }, | ||
98 | { | ||
99 | .first = 0xB2, | ||
100 | .last = 0xB2, | ||
101 | .perm = AB5500_PERM_RO, | ||
102 | }, | ||
103 | { | ||
104 | .first = 0xB4, | ||
105 | .last = 0xBC, | ||
106 | .perm = AB5500_PERM_RO, | ||
107 | }, | ||
108 | { | ||
109 | .first = 0xBF, | ||
110 | .last = 0xBF, | ||
111 | .perm = AB5500_PERM_RO, | ||
112 | }, | ||
113 | { | ||
114 | .first = 0xC1, | ||
115 | .last = 0xC5, | ||
116 | .perm = AB5500_PERM_RO, | ||
117 | }, | ||
118 | }, | ||
119 | }, | ||
120 | }, | ||
121 | }, | ||
122 | [AB5500_DEVID_ADC] = { | ||
123 | .nbanks = 1, | ||
124 | .bank = (struct ab5500_i2c_ranges []) { | ||
125 | { | ||
126 | .bankid = AB5500_BANK_ADC, | ||
127 | .nranges = 6, | ||
128 | .range = (struct ab5500_reg_range[]) { | ||
129 | { | ||
130 | .first = 0x1F, | ||
131 | .last = 0x22, | ||
132 | .perm = AB5500_PERM_RO, | ||
133 | }, | ||
134 | { | ||
135 | .first = 0x23, | ||
136 | .last = 0x24, | ||
137 | .perm = AB5500_PERM_RW, | ||
138 | }, | ||
139 | { | ||
140 | .first = 0x26, | ||
141 | .last = 0x2D, | ||
142 | .perm = AB5500_PERM_RO, | ||
143 | }, | ||
144 | { | ||
145 | .first = 0x2F, | ||
146 | .last = 0x34, | ||
147 | .perm = AB5500_PERM_RW, | ||
148 | }, | ||
149 | { | ||
150 | .first = 0x37, | ||
151 | .last = 0x57, | ||
152 | .perm = AB5500_PERM_RW, | ||
153 | }, | ||
154 | { | ||
155 | .first = 0x58, | ||
156 | .last = 0x58, | ||
157 | .perm = AB5500_PERM_RO, | ||
158 | }, | ||
159 | }, | ||
160 | }, | ||
161 | }, | ||
162 | }, | ||
163 | [AB5500_DEVID_LEDS] = { | ||
164 | .nbanks = 1, | ||
165 | .bank = (struct ab5500_i2c_ranges []) { | ||
166 | { | ||
167 | .bankid = AB5500_BANK_LED, | ||
168 | .nranges = 1, | ||
169 | .range = (struct ab5500_reg_range[]) { | ||
170 | { | ||
171 | .first = 0x00, | ||
172 | .last = 0x0C, | ||
173 | .perm = AB5500_PERM_RW, | ||
174 | }, | ||
175 | }, | ||
176 | }, | ||
177 | }, | ||
178 | }, | ||
179 | [AB5500_DEVID_VIDEO] = { | ||
180 | .nbanks = 1, | ||
181 | .bank = (struct ab5500_i2c_ranges []) { | ||
182 | { | ||
183 | .bankid = AB5500_BANK_VDENC, | ||
184 | .nranges = 12, | ||
185 | .range = (struct ab5500_reg_range[]) { | ||
186 | { | ||
187 | .first = 0x00, | ||
188 | .last = 0x08, | ||
189 | .perm = AB5500_PERM_RW, | ||
190 | }, | ||
191 | { | ||
192 | .first = 0x09, | ||
193 | .last = 0x09, | ||
194 | .perm = AB5500_PERM_RO, | ||
195 | }, | ||
196 | { | ||
197 | .first = 0x0A, | ||
198 | .last = 0x12, | ||
199 | .perm = AB5500_PERM_RW, | ||
200 | }, | ||
201 | { | ||
202 | .first = 0x15, | ||
203 | .last = 0x19, | ||
204 | .perm = AB5500_PERM_RW, | ||
205 | }, | ||
206 | { | ||
207 | .first = 0x1B, | ||
208 | .last = 0x21, | ||
209 | .perm = AB5500_PERM_RW, | ||
210 | }, | ||
211 | { | ||
212 | .first = 0x27, | ||
213 | .last = 0x2C, | ||
214 | .perm = AB5500_PERM_RW, | ||
215 | }, | ||
216 | { | ||
217 | .first = 0x41, | ||
218 | .last = 0x41, | ||
219 | .perm = AB5500_PERM_RW, | ||
220 | }, | ||
221 | { | ||
222 | .first = 0x45, | ||
223 | .last = 0x5B, | ||
224 | .perm = AB5500_PERM_RW, | ||
225 | }, | ||
226 | { | ||
227 | .first = 0x5D, | ||
228 | .last = 0x5D, | ||
229 | .perm = AB5500_PERM_RW, | ||
230 | }, | ||
231 | { | ||
232 | .first = 0x69, | ||
233 | .last = 0x69, | ||
234 | .perm = AB5500_PERM_RW, | ||
235 | }, | ||
236 | { | ||
237 | .first = 0x6C, | ||
238 | .last = 0x6D, | ||
239 | .perm = AB5500_PERM_RW, | ||
240 | }, | ||
241 | { | ||
242 | .first = 0x80, | ||
243 | .last = 0x81, | ||
244 | .perm = AB5500_PERM_RW, | ||
245 | }, | ||
246 | }, | ||
247 | }, | ||
248 | }, | ||
249 | }, | ||
250 | [AB5500_DEVID_REGULATORS] = { | ||
251 | .nbanks = 2, | ||
252 | .bank = (struct ab5500_i2c_ranges []) { | ||
253 | { | ||
254 | .bankid = AB5500_BANK_STARTUP, | ||
255 | .nranges = 12, | ||
256 | .range = (struct ab5500_reg_range[]) { | ||
257 | { | ||
258 | .first = 0x00, | ||
259 | .last = 0x01, | ||
260 | .perm = AB5500_PERM_RW, | ||
261 | }, | ||
262 | { | ||
263 | .first = 0x1F, | ||
264 | .last = 0x1F, | ||
265 | .perm = AB5500_PERM_RW, | ||
266 | }, | ||
267 | { | ||
268 | .first = 0x2E, | ||
269 | .last = 0x2E, | ||
270 | .perm = AB5500_PERM_RO, | ||
271 | }, | ||
272 | { | ||
273 | .first = 0x2F, | ||
274 | .last = 0x30, | ||
275 | .perm = AB5500_PERM_RW, | ||
276 | }, | ||
277 | { | ||
278 | .first = 0x50, | ||
279 | .last = 0x51, | ||
280 | .perm = AB5500_PERM_RW, | ||
281 | }, | ||
282 | { | ||
283 | .first = 0x60, | ||
284 | .last = 0x61, | ||
285 | .perm = AB5500_PERM_RW, | ||
286 | }, | ||
287 | { | ||
288 | .first = 0x66, | ||
289 | .last = 0x8A, | ||
290 | .perm = AB5500_PERM_RW, | ||
291 | }, | ||
292 | { | ||
293 | .first = 0x8C, | ||
294 | .last = 0x96, | ||
295 | .perm = AB5500_PERM_RW, | ||
296 | }, | ||
297 | { | ||
298 | .first = 0xAA, | ||
299 | .last = 0xB4, | ||
300 | .perm = AB5500_PERM_RW, | ||
301 | }, | ||
302 | { | ||
303 | .first = 0xB7, | ||
304 | .last = 0xBF, | ||
305 | .perm = AB5500_PERM_RW, | ||
306 | }, | ||
307 | { | ||
308 | .first = 0xC1, | ||
309 | .last = 0xCA, | ||
310 | .perm = AB5500_PERM_RW, | ||
311 | }, | ||
312 | { | ||
313 | .first = 0xD3, | ||
314 | .last = 0xE0, | ||
315 | .perm = AB5500_PERM_RW, | ||
316 | }, | ||
317 | }, | ||
318 | }, | ||
319 | { | ||
320 | .bankid = AB5500_BANK_SIM_USBSIM, | ||
321 | .nranges = 1, | ||
322 | .range = (struct ab5500_reg_range[]) { | ||
323 | { | ||
324 | .first = 0x13, | ||
325 | .last = 0x19, | ||
326 | .perm = AB5500_PERM_RW, | ||
327 | }, | ||
328 | }, | ||
329 | }, | ||
330 | }, | ||
331 | }, | ||
332 | [AB5500_DEVID_SIM] = { | ||
333 | .nbanks = 1, | ||
334 | .bank = (struct ab5500_i2c_ranges []) { | ||
335 | { | ||
336 | .bankid = AB5500_BANK_SIM_USBSIM, | ||
337 | .nranges = 1, | ||
338 | .range = (struct ab5500_reg_range[]) { | ||
339 | { | ||
340 | .first = 0x13, | ||
341 | .last = 0x19, | ||
342 | .perm = AB5500_PERM_RW, | ||
343 | }, | ||
344 | }, | ||
345 | }, | ||
346 | }, | ||
347 | }, | ||
348 | [AB5500_DEVID_RTC] = { | ||
349 | .nbanks = 1, | ||
350 | .bank = (struct ab5500_i2c_ranges []) { | ||
351 | { | ||
352 | .bankid = AB5500_BANK_RTC, | ||
353 | .nranges = 2, | ||
354 | .range = (struct ab5500_reg_range[]) { | ||
355 | { | ||
356 | .first = 0x00, | ||
357 | .last = 0x04, | ||
358 | .perm = AB5500_PERM_RW, | ||
359 | }, | ||
360 | { | ||
361 | .first = 0x06, | ||
362 | .last = 0x0C, | ||
363 | .perm = AB5500_PERM_RW, | ||
364 | }, | ||
365 | }, | ||
366 | }, | ||
367 | }, | ||
368 | }, | ||
369 | [AB5500_DEVID_CHARGER] = { | ||
370 | .nbanks = 1, | ||
371 | .bank = (struct ab5500_i2c_ranges []) { | ||
372 | { | ||
373 | .bankid = AB5500_BANK_CHG, | ||
374 | .nranges = 2, | ||
375 | .range = (struct ab5500_reg_range[]) { | ||
376 | { | ||
377 | .first = 0x11, | ||
378 | .last = 0x11, | ||
379 | .perm = AB5500_PERM_RO, | ||
380 | }, | ||
381 | { | ||
382 | .first = 0x12, | ||
383 | .last = 0x1B, | ||
384 | .perm = AB5500_PERM_RW, | ||
385 | }, | ||
386 | }, | ||
387 | }, | ||
388 | }, | ||
389 | }, | ||
390 | [AB5500_DEVID_FUELGAUGE] = { | ||
391 | .nbanks = 1, | ||
392 | .bank = (struct ab5500_i2c_ranges []) { | ||
393 | { | ||
394 | .bankid = AB5500_BANK_FG_BATTCOM_ACC, | ||
395 | .nranges = 2, | ||
396 | .range = (struct ab5500_reg_range[]) { | ||
397 | { | ||
398 | .first = 0x00, | ||
399 | .last = 0x0B, | ||
400 | .perm = AB5500_PERM_RO, | ||
401 | }, | ||
402 | { | ||
403 | .first = 0x0C, | ||
404 | .last = 0x10, | ||
405 | .perm = AB5500_PERM_RW, | ||
406 | }, | ||
407 | }, | ||
408 | }, | ||
409 | }, | ||
410 | }, | ||
411 | [AB5500_DEVID_VIBRATOR] = { | ||
412 | .nbanks = 1, | ||
413 | .bank = (struct ab5500_i2c_ranges []) { | ||
414 | { | ||
415 | .bankid = AB5500_BANK_VIBRA, | ||
416 | .nranges = 2, | ||
417 | .range = (struct ab5500_reg_range[]) { | ||
418 | { | ||
419 | .first = 0x10, | ||
420 | .last = 0x13, | ||
421 | .perm = AB5500_PERM_RW, | ||
422 | }, | ||
423 | { | ||
424 | .first = 0xFE, | ||
425 | .last = 0xFE, | ||
426 | .perm = AB5500_PERM_RW, | ||
427 | }, | ||
428 | }, | ||
429 | }, | ||
430 | }, | ||
431 | }, | ||
432 | [AB5500_DEVID_CODEC] = { | ||
433 | .nbanks = 1, | ||
434 | .bank = (struct ab5500_i2c_ranges []) { | ||
435 | { | ||
436 | .bankid = AB5500_BANK_AUDIO_HEADSETUSB, | ||
437 | .nranges = 2, | ||
438 | .range = (struct ab5500_reg_range[]) { | ||
439 | { | ||
440 | .first = 0x00, | ||
441 | .last = 0x48, | ||
442 | .perm = AB5500_PERM_RW, | ||
443 | }, | ||
444 | { | ||
445 | .first = 0xEB, | ||
446 | .last = 0xFB, | ||
447 | .perm = AB5500_PERM_RW, | ||
448 | }, | ||
449 | }, | ||
450 | }, | ||
451 | }, | ||
452 | }, | ||
453 | [AB5500_DEVID_POWER] = { | ||
454 | .nbanks = 2, | ||
455 | .bank = (struct ab5500_i2c_ranges []) { | ||
456 | { | ||
457 | .bankid = AB5500_BANK_STARTUP, | ||
458 | .nranges = 1, | ||
459 | .range = (struct ab5500_reg_range[]) { | ||
460 | { | ||
461 | .first = 0x30, | ||
462 | .last = 0x30, | ||
463 | .perm = AB5500_PERM_RW, | ||
464 | }, | ||
465 | }, | ||
466 | }, | ||
467 | { | ||
468 | .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, | ||
469 | .nranges = 1, | ||
470 | .range = (struct ab5500_reg_range[]) { | ||
471 | { | ||
472 | .first = 0x01, | ||
473 | .last = 0x01, | ||
474 | .perm = AB5500_PERM_RW, | ||
475 | }, | ||
476 | }, | ||
477 | }, | ||
478 | }, | ||
479 | }, | ||
480 | }; | ||
481 | |||
482 | #define AB5500_IRQ(bank, bit) ((bank) * 8 + (bit)) | ||
483 | |||
484 | /* I appologize for the resource names beeing a mix of upper case | ||
485 | * and lower case but I want them to be exact as the documentation */ | ||
486 | static struct mfd_cell ab5500_devs[AB5500_NUM_DEVICES] = { | ||
487 | [AB5500_DEVID_LEDS] = { | ||
488 | .name = "ab5500-leds", | ||
489 | .id = AB5500_DEVID_LEDS, | ||
490 | }, | ||
491 | [AB5500_DEVID_POWER] = { | ||
492 | .name = "ab5500-power", | ||
493 | .id = AB5500_DEVID_POWER, | ||
494 | }, | ||
495 | [AB5500_DEVID_REGULATORS] = { | ||
496 | .name = "ab5500-regulator", | ||
497 | .id = AB5500_DEVID_REGULATORS, | ||
498 | }, | ||
499 | [AB5500_DEVID_SIM] = { | ||
500 | .name = "ab5500-sim", | ||
501 | .id = AB5500_DEVID_SIM, | ||
502 | .num_resources = 1, | ||
503 | .resources = (struct resource[]) { | ||
504 | { | ||
505 | .name = "SIMOFF", | ||
506 | .flags = IORESOURCE_IRQ, | ||
507 | .start = AB5500_IRQ(2, 0), /*rising*/ | ||
508 | .end = AB5500_IRQ(2, 1), /*falling*/ | ||
509 | }, | ||
510 | }, | ||
511 | }, | ||
512 | [AB5500_DEVID_RTC] = { | ||
513 | .name = "ab5500-rtc", | ||
514 | .id = AB5500_DEVID_RTC, | ||
515 | .num_resources = 1, | ||
516 | .resources = (struct resource[]) { | ||
517 | { | ||
518 | .name = "RTC_Alarm", | ||
519 | .flags = IORESOURCE_IRQ, | ||
520 | .start = AB5500_IRQ(1, 7), | ||
521 | .end = AB5500_IRQ(1, 7), | ||
522 | } | ||
523 | }, | ||
524 | }, | ||
525 | [AB5500_DEVID_CHARGER] = { | ||
526 | .name = "ab5500-charger", | ||
527 | .id = AB5500_DEVID_CHARGER, | ||
528 | }, | ||
529 | [AB5500_DEVID_ADC] = { | ||
530 | .name = "ab5500-adc", | ||
531 | .id = AB5500_DEVID_ADC, | ||
532 | .num_resources = 10, | ||
533 | .resources = (struct resource[]) { | ||
534 | { | ||
535 | .name = "TRIGGER-0", | ||
536 | .flags = IORESOURCE_IRQ, | ||
537 | .start = AB5500_IRQ(0, 0), | ||
538 | .end = AB5500_IRQ(0, 0), | ||
539 | }, | ||
540 | { | ||
541 | .name = "TRIGGER-1", | ||
542 | .flags = IORESOURCE_IRQ, | ||
543 | .start = AB5500_IRQ(0, 1), | ||
544 | .end = AB5500_IRQ(0, 1), | ||
545 | }, | ||
546 | { | ||
547 | .name = "TRIGGER-2", | ||
548 | .flags = IORESOURCE_IRQ, | ||
549 | .start = AB5500_IRQ(0, 2), | ||
550 | .end = AB5500_IRQ(0, 2), | ||
551 | }, | ||
552 | { | ||
553 | .name = "TRIGGER-3", | ||
554 | .flags = IORESOURCE_IRQ, | ||
555 | .start = AB5500_IRQ(0, 3), | ||
556 | .end = AB5500_IRQ(0, 3), | ||
557 | }, | ||
558 | { | ||
559 | .name = "TRIGGER-4", | ||
560 | .flags = IORESOURCE_IRQ, | ||
561 | .start = AB5500_IRQ(0, 4), | ||
562 | .end = AB5500_IRQ(0, 4), | ||
563 | }, | ||
564 | { | ||
565 | .name = "TRIGGER-5", | ||
566 | .flags = IORESOURCE_IRQ, | ||
567 | .start = AB5500_IRQ(0, 5), | ||
568 | .end = AB5500_IRQ(0, 5), | ||
569 | }, | ||
570 | { | ||
571 | .name = "TRIGGER-6", | ||
572 | .flags = IORESOURCE_IRQ, | ||
573 | .start = AB5500_IRQ(0, 6), | ||
574 | .end = AB5500_IRQ(0, 6), | ||
575 | }, | ||
576 | { | ||
577 | .name = "TRIGGER-7", | ||
578 | .flags = IORESOURCE_IRQ, | ||
579 | .start = AB5500_IRQ(0, 7), | ||
580 | .end = AB5500_IRQ(0, 7), | ||
581 | }, | ||
582 | { | ||
583 | .name = "TRIGGER-VBAT", | ||
584 | .flags = IORESOURCE_IRQ, | ||
585 | .start = AB5500_IRQ(0, 8), | ||
586 | .end = AB5500_IRQ(0, 8), | ||
587 | }, | ||
588 | { | ||
589 | .name = "TRIGGER-VBAT-TXON", | ||
590 | .flags = IORESOURCE_IRQ, | ||
591 | .start = AB5500_IRQ(0, 9), | ||
592 | .end = AB5500_IRQ(0, 9), | ||
593 | }, | ||
594 | }, | ||
595 | }, | ||
596 | [AB5500_DEVID_FUELGAUGE] = { | ||
597 | .name = "ab5500-fuelgauge", | ||
598 | .id = AB5500_DEVID_FUELGAUGE, | ||
599 | .num_resources = 6, | ||
600 | .resources = (struct resource[]) { | ||
601 | { | ||
602 | .name = "Batt_attach", | ||
603 | .flags = IORESOURCE_IRQ, | ||
604 | .start = AB5500_IRQ(7, 5), | ||
605 | .end = AB5500_IRQ(7, 5), | ||
606 | }, | ||
607 | { | ||
608 | .name = "Batt_removal", | ||
609 | .flags = IORESOURCE_IRQ, | ||
610 | .start = AB5500_IRQ(7, 6), | ||
611 | .end = AB5500_IRQ(7, 6), | ||
612 | }, | ||
613 | { | ||
614 | .name = "UART_framing", | ||
615 | .flags = IORESOURCE_IRQ, | ||
616 | .start = AB5500_IRQ(7, 7), | ||
617 | .end = AB5500_IRQ(7, 7), | ||
618 | }, | ||
619 | { | ||
620 | .name = "UART_overrun", | ||
621 | .flags = IORESOURCE_IRQ, | ||
622 | .start = AB5500_IRQ(8, 0), | ||
623 | .end = AB5500_IRQ(8, 0), | ||
624 | }, | ||
625 | { | ||
626 | .name = "UART_Rdy_RX", | ||
627 | .flags = IORESOURCE_IRQ, | ||
628 | .start = AB5500_IRQ(8, 1), | ||
629 | .end = AB5500_IRQ(8, 1), | ||
630 | }, | ||
631 | { | ||
632 | .name = "UART_Rdy_TX", | ||
633 | .flags = IORESOURCE_IRQ, | ||
634 | .start = AB5500_IRQ(8, 2), | ||
635 | .end = AB5500_IRQ(8, 2), | ||
636 | }, | ||
637 | }, | ||
638 | }, | ||
639 | [AB5500_DEVID_VIBRATOR] = { | ||
640 | .name = "ab5500-vibrator", | ||
641 | .id = AB5500_DEVID_VIBRATOR, | ||
642 | }, | ||
643 | [AB5500_DEVID_CODEC] = { | ||
644 | .name = "ab5500-codec", | ||
645 | .id = AB5500_DEVID_CODEC, | ||
646 | .num_resources = 3, | ||
647 | .resources = (struct resource[]) { | ||
648 | { | ||
649 | .name = "audio_spkr1_ovc", | ||
650 | .flags = IORESOURCE_IRQ, | ||
651 | .start = AB5500_IRQ(9, 5), | ||
652 | .end = AB5500_IRQ(9, 5), | ||
653 | }, | ||
654 | { | ||
655 | .name = "audio_plllocked", | ||
656 | .flags = IORESOURCE_IRQ, | ||
657 | .start = AB5500_IRQ(9, 6), | ||
658 | .end = AB5500_IRQ(9, 6), | ||
659 | }, | ||
660 | { | ||
661 | .name = "audio_spkr2_ovc", | ||
662 | .flags = IORESOURCE_IRQ, | ||
663 | .start = AB5500_IRQ(17, 4), | ||
664 | .end = AB5500_IRQ(17, 4), | ||
665 | }, | ||
666 | }, | ||
667 | }, | ||
668 | [AB5500_DEVID_USB] = { | ||
669 | .name = "ab5500-usb", | ||
670 | .id = AB5500_DEVID_USB, | ||
671 | .num_resources = 36, | ||
672 | .resources = (struct resource[]) { | ||
673 | { | ||
674 | .name = "Link_Update", | ||
675 | .flags = IORESOURCE_IRQ, | ||
676 | .start = AB5500_IRQ(22, 1), | ||
677 | .end = AB5500_IRQ(22, 1), | ||
678 | }, | ||
679 | { | ||
680 | .name = "DCIO", | ||
681 | .flags = IORESOURCE_IRQ, | ||
682 | .start = AB5500_IRQ(8, 3), | ||
683 | .end = AB5500_IRQ(8, 4), | ||
684 | }, | ||
685 | { | ||
686 | .name = "VBUS_R", | ||
687 | .flags = IORESOURCE_IRQ, | ||
688 | .start = AB5500_IRQ(8, 5), | ||
689 | .end = AB5500_IRQ(8, 5), | ||
690 | }, | ||
691 | { | ||
692 | .name = "VBUS_F", | ||
693 | .flags = IORESOURCE_IRQ, | ||
694 | .start = AB5500_IRQ(8, 6), | ||
695 | .end = AB5500_IRQ(8, 6), | ||
696 | }, | ||
697 | { | ||
698 | .name = "CHGstate_10_PCVBUSchg", | ||
699 | .flags = IORESOURCE_IRQ, | ||
700 | .start = AB5500_IRQ(8, 7), | ||
701 | .end = AB5500_IRQ(8, 7), | ||
702 | }, | ||
703 | { | ||
704 | .name = "DCIOreverse_ovc", | ||
705 | .flags = IORESOURCE_IRQ, | ||
706 | .start = AB5500_IRQ(9, 0), | ||
707 | .end = AB5500_IRQ(9, 0), | ||
708 | }, | ||
709 | { | ||
710 | .name = "USBCharDetDone", | ||
711 | .flags = IORESOURCE_IRQ, | ||
712 | .start = AB5500_IRQ(9, 1), | ||
713 | .end = AB5500_IRQ(9, 1), | ||
714 | }, | ||
715 | { | ||
716 | .name = "DCIO_no_limit", | ||
717 | .flags = IORESOURCE_IRQ, | ||
718 | .start = AB5500_IRQ(9, 2), | ||
719 | .end = AB5500_IRQ(9, 2), | ||
720 | }, | ||
721 | { | ||
722 | .name = "USB_suspend", | ||
723 | .flags = IORESOURCE_IRQ, | ||
724 | .start = AB5500_IRQ(9, 3), | ||
725 | .end = AB5500_IRQ(9, 3), | ||
726 | }, | ||
727 | { | ||
728 | .name = "DCIOreverse_fwdcurrent", | ||
729 | .flags = IORESOURCE_IRQ, | ||
730 | .start = AB5500_IRQ(9, 4), | ||
731 | .end = AB5500_IRQ(9, 4), | ||
732 | }, | ||
733 | { | ||
734 | .name = "Vbus_Imeasmax_change", | ||
735 | .flags = IORESOURCE_IRQ, | ||
736 | .start = AB5500_IRQ(9, 5), | ||
737 | .end = AB5500_IRQ(9, 6), | ||
738 | }, | ||
739 | { | ||
740 | .name = "OVV", | ||
741 | .flags = IORESOURCE_IRQ, | ||
742 | .start = AB5500_IRQ(14, 5), | ||
743 | .end = AB5500_IRQ(14, 5), | ||
744 | }, | ||
745 | { | ||
746 | .name = "USBcharging_NOTok", | ||
747 | .flags = IORESOURCE_IRQ, | ||
748 | .start = AB5500_IRQ(15, 3), | ||
749 | .end = AB5500_IRQ(15, 3), | ||
750 | }, | ||
751 | { | ||
752 | .name = "usb_adp_sensoroff", | ||
753 | .flags = IORESOURCE_IRQ, | ||
754 | .start = AB5500_IRQ(15, 6), | ||
755 | .end = AB5500_IRQ(15, 6), | ||
756 | }, | ||
757 | { | ||
758 | .name = "usb_adp_probeplug", | ||
759 | .flags = IORESOURCE_IRQ, | ||
760 | .start = AB5500_IRQ(15, 7), | ||
761 | .end = AB5500_IRQ(15, 7), | ||
762 | }, | ||
763 | { | ||
764 | .name = "usb_adp_sinkerror", | ||
765 | .flags = IORESOURCE_IRQ, | ||
766 | .start = AB5500_IRQ(16, 0), | ||
767 | .end = AB5500_IRQ(16, 6), | ||
768 | }, | ||
769 | { | ||
770 | .name = "usb_adp_sourceerror", | ||
771 | .flags = IORESOURCE_IRQ, | ||
772 | .start = AB5500_IRQ(16, 1), | ||
773 | .end = AB5500_IRQ(16, 1), | ||
774 | }, | ||
775 | { | ||
776 | .name = "usb_idgnd_r", | ||
777 | .flags = IORESOURCE_IRQ, | ||
778 | .start = AB5500_IRQ(16, 2), | ||
779 | .end = AB5500_IRQ(16, 2), | ||
780 | }, | ||
781 | { | ||
782 | .name = "usb_idgnd_f", | ||
783 | .flags = IORESOURCE_IRQ, | ||
784 | .start = AB5500_IRQ(16, 3), | ||
785 | .end = AB5500_IRQ(16, 3), | ||
786 | }, | ||
787 | { | ||
788 | .name = "usb_iddetR1", | ||
789 | .flags = IORESOURCE_IRQ, | ||
790 | .start = AB5500_IRQ(16, 4), | ||
791 | .end = AB5500_IRQ(16, 5), | ||
792 | }, | ||
793 | { | ||
794 | .name = "usb_iddetR2", | ||
795 | .flags = IORESOURCE_IRQ, | ||
796 | .start = AB5500_IRQ(16, 6), | ||
797 | .end = AB5500_IRQ(16, 7), | ||
798 | }, | ||
799 | { | ||
800 | .name = "usb_iddetR3", | ||
801 | .flags = IORESOURCE_IRQ, | ||
802 | .start = AB5500_IRQ(17, 0), | ||
803 | .end = AB5500_IRQ(17, 1), | ||
804 | }, | ||
805 | { | ||
806 | .name = "usb_iddetR4", | ||
807 | .flags = IORESOURCE_IRQ, | ||
808 | .start = AB5500_IRQ(17, 2), | ||
809 | .end = AB5500_IRQ(17, 3), | ||
810 | }, | ||
811 | { | ||
812 | .name = "CharTempWindowOk", | ||
813 | .flags = IORESOURCE_IRQ, | ||
814 | .start = AB5500_IRQ(17, 7), | ||
815 | .end = AB5500_IRQ(18, 0), | ||
816 | }, | ||
817 | { | ||
818 | .name = "USB_SprDetect", | ||
819 | .flags = IORESOURCE_IRQ, | ||
820 | .start = AB5500_IRQ(18, 1), | ||
821 | .end = AB5500_IRQ(18, 1), | ||
822 | }, | ||
823 | { | ||
824 | .name = "usb_adp_probe_unplug", | ||
825 | .flags = IORESOURCE_IRQ, | ||
826 | .start = AB5500_IRQ(18, 2), | ||
827 | .end = AB5500_IRQ(18, 2), | ||
828 | }, | ||
829 | { | ||
830 | .name = "VBUSChDrop", | ||
831 | .flags = IORESOURCE_IRQ, | ||
832 | .start = AB5500_IRQ(18, 3), | ||
833 | .end = AB5500_IRQ(18, 4), | ||
834 | }, | ||
835 | { | ||
836 | .name = "dcio_char_rec_done", | ||
837 | .flags = IORESOURCE_IRQ, | ||
838 | .start = AB5500_IRQ(18, 5), | ||
839 | .end = AB5500_IRQ(18, 5), | ||
840 | }, | ||
841 | { | ||
842 | .name = "Charging_stopped_by_temp", | ||
843 | .flags = IORESOURCE_IRQ, | ||
844 | .start = AB5500_IRQ(18, 6), | ||
845 | .end = AB5500_IRQ(18, 6), | ||
846 | }, | ||
847 | { | ||
848 | .name = "CHGstate_11_SafeModeVBUS", | ||
849 | .flags = IORESOURCE_IRQ, | ||
850 | .start = AB5500_IRQ(21, 1), | ||
851 | .end = AB5500_IRQ(21, 2), | ||
852 | }, | ||
853 | { | ||
854 | .name = "CHGstate_12_comletedVBUS", | ||
855 | .flags = IORESOURCE_IRQ, | ||
856 | .start = AB5500_IRQ(21, 2), | ||
857 | .end = AB5500_IRQ(21, 2), | ||
858 | }, | ||
859 | { | ||
860 | .name = "CHGstate_13_completedVBUS", | ||
861 | .flags = IORESOURCE_IRQ, | ||
862 | .start = AB5500_IRQ(21, 3), | ||
863 | .end = AB5500_IRQ(21, 3), | ||
864 | }, | ||
865 | { | ||
866 | .name = "CHGstate_14_FullChgDCIO", | ||
867 | .flags = IORESOURCE_IRQ, | ||
868 | .start = AB5500_IRQ(21, 4), | ||
869 | .end = AB5500_IRQ(21, 4), | ||
870 | }, | ||
871 | { | ||
872 | .name = "CHGstate_15_SafeModeDCIO", | ||
873 | .flags = IORESOURCE_IRQ, | ||
874 | .start = AB5500_IRQ(21, 5), | ||
875 | .end = AB5500_IRQ(21, 5), | ||
876 | }, | ||
877 | { | ||
878 | .name = "CHGstate_16_OFFsuspendDCIO", | ||
879 | .flags = IORESOURCE_IRQ, | ||
880 | .start = AB5500_IRQ(21, 6), | ||
881 | .end = AB5500_IRQ(21, 6), | ||
882 | }, | ||
883 | { | ||
884 | .name = "CHGstate_17_completedDCIO", | ||
885 | .flags = IORESOURCE_IRQ, | ||
886 | .start = AB5500_IRQ(21, 7), | ||
887 | .end = AB5500_IRQ(21, 7), | ||
888 | }, | ||
889 | }, | ||
890 | }, | ||
891 | [AB5500_DEVID_OTP] = { | ||
892 | .name = "ab5500-otp", | ||
893 | .id = AB5500_DEVID_OTP, | ||
894 | }, | ||
895 | [AB5500_DEVID_VIDEO] = { | ||
896 | .name = "ab5500-video", | ||
897 | .id = AB5500_DEVID_VIDEO, | ||
898 | .num_resources = 1, | ||
899 | .resources = (struct resource[]) { | ||
900 | { | ||
901 | .name = "plugTVdet", | ||
902 | .flags = IORESOURCE_IRQ, | ||
903 | .start = AB5500_IRQ(22, 2), | ||
904 | .end = AB5500_IRQ(22, 2), | ||
905 | }, | ||
906 | }, | ||
907 | }, | ||
908 | [AB5500_DEVID_DBIECI] = { | ||
909 | .name = "ab5500-dbieci", | ||
910 | .id = AB5500_DEVID_DBIECI, | ||
911 | .num_resources = 10, | ||
912 | .resources = (struct resource[]) { | ||
913 | { | ||
914 | .name = "COLL", | ||
915 | .flags = IORESOURCE_IRQ, | ||
916 | .start = AB5500_IRQ(14, 0), | ||
917 | .end = AB5500_IRQ(14, 0), | ||
918 | }, | ||
919 | { | ||
920 | .name = "RESERR", | ||
921 | .flags = IORESOURCE_IRQ, | ||
922 | .start = AB5500_IRQ(14, 1), | ||
923 | .end = AB5500_IRQ(14, 1), | ||
924 | }, | ||
925 | { | ||
926 | .name = "FRAERR", | ||
927 | .flags = IORESOURCE_IRQ, | ||
928 | .start = AB5500_IRQ(14, 2), | ||
929 | .end = AB5500_IRQ(14, 2), | ||
930 | }, | ||
931 | { | ||
932 | .name = "COMERR", | ||
933 | .flags = IORESOURCE_IRQ, | ||
934 | .start = AB5500_IRQ(14, 3), | ||
935 | .end = AB5500_IRQ(14, 3), | ||
936 | }, | ||
937 | { | ||
938 | .name = "BSI_indicator", | ||
939 | .flags = IORESOURCE_IRQ, | ||
940 | .start = AB5500_IRQ(14, 4), | ||
941 | .end = AB5500_IRQ(14, 4), | ||
942 | }, | ||
943 | { | ||
944 | .name = "SPDSET", | ||
945 | .flags = IORESOURCE_IRQ, | ||
946 | .start = AB5500_IRQ(14, 6), | ||
947 | .end = AB5500_IRQ(14, 6), | ||
948 | }, | ||
949 | { | ||
950 | .name = "DSENT", | ||
951 | .flags = IORESOURCE_IRQ, | ||
952 | .start = AB5500_IRQ(14, 7), | ||
953 | .end = AB5500_IRQ(14, 7), | ||
954 | }, | ||
955 | { | ||
956 | .name = "DREC", | ||
957 | .flags = IORESOURCE_IRQ, | ||
958 | .start = AB5500_IRQ(15, 0), | ||
959 | .end = AB5500_IRQ(15, 0), | ||
960 | }, | ||
961 | { | ||
962 | .name = "ACCINT", | ||
963 | .flags = IORESOURCE_IRQ, | ||
964 | .start = AB5500_IRQ(15, 1), | ||
965 | .end = AB5500_IRQ(15, 1), | ||
966 | }, | ||
967 | { | ||
968 | .name = "NOPINT", | ||
969 | .flags = IORESOURCE_IRQ, | ||
970 | .start = AB5500_IRQ(15, 2), | ||
971 | .end = AB5500_IRQ(15, 2), | ||
972 | }, | ||
973 | }, | ||
974 | }, | ||
975 | [AB5500_DEVID_ONSWA] = { | ||
976 | .name = "ab5500-onswa", | ||
977 | .id = AB5500_DEVID_ONSWA, | ||
978 | .num_resources = 2, | ||
979 | .resources = (struct resource[]) { | ||
980 | { | ||
981 | .name = "ONSWAn_rising", | ||
982 | .flags = IORESOURCE_IRQ, | ||
983 | .start = AB5500_IRQ(1, 3), | ||
984 | .end = AB5500_IRQ(1, 3), | ||
985 | }, | ||
986 | { | ||
987 | .name = "ONSWAn_falling", | ||
988 | .flags = IORESOURCE_IRQ, | ||
989 | .start = AB5500_IRQ(1, 4), | ||
990 | .end = AB5500_IRQ(1, 4), | ||
991 | }, | ||
992 | }, | ||
993 | }, | ||
994 | }; | ||
995 | |||
996 | /* | ||
997 | * Functionality for getting/setting register values. | ||
998 | */ | ||
999 | int ab5500_get_register_interruptible_raw(struct ab5500 *ab, | ||
1000 | u8 bank, u8 reg, | ||
1001 | u8 *value) | ||
1002 | { | ||
1003 | int err; | ||
1004 | |||
1005 | if (bank >= AB5500_NUM_BANKS) | ||
1006 | return -EINVAL; | ||
1007 | |||
1008 | err = mutex_lock_interruptible(&ab->access_mutex); | ||
1009 | if (err) | ||
1010 | return err; | ||
1011 | err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, reg, value, 1); | ||
1012 | |||
1013 | mutex_unlock(&ab->access_mutex); | ||
1014 | return err; | ||
1015 | } | ||
1016 | |||
1017 | static int get_register_page_interruptible(struct ab5500 *ab, u8 bank, | ||
1018 | u8 first_reg, u8 *regvals, u8 numregs) | ||
1019 | { | ||
1020 | int err; | ||
1021 | |||
1022 | if (bank >= AB5500_NUM_BANKS) | ||
1023 | return -EINVAL; | ||
1024 | |||
1025 | err = mutex_lock_interruptible(&ab->access_mutex); | ||
1026 | if (err) | ||
1027 | return err; | ||
1028 | |||
1029 | while (numregs) { | ||
1030 | /* The hardware limit for get page is 4 */ | ||
1031 | u8 curnum = min_t(u8, numregs, 4u); | ||
1032 | |||
1033 | err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, | ||
1034 | first_reg, regvals, curnum); | ||
1035 | if (err) | ||
1036 | goto out; | ||
1037 | |||
1038 | numregs -= curnum; | ||
1039 | first_reg += curnum; | ||
1040 | regvals += curnum; | ||
1041 | } | ||
1042 | |||
1043 | out: | ||
1044 | mutex_unlock(&ab->access_mutex); | ||
1045 | return err; | ||
1046 | } | ||
1047 | |||
1048 | int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank, | ||
1049 | u8 reg, u8 bitmask, u8 bitvalues) | ||
1050 | { | ||
1051 | int err = 0; | ||
1052 | |||
1053 | if (bank >= AB5500_NUM_BANKS) | ||
1054 | return -EINVAL; | ||
1055 | |||
1056 | if (bitmask) { | ||
1057 | u8 buf; | ||
1058 | |||
1059 | err = mutex_lock_interruptible(&ab->access_mutex); | ||
1060 | if (err) | ||
1061 | return err; | ||
1062 | |||
1063 | if (bitmask == 0xFF) /* No need to read in this case. */ | ||
1064 | buf = bitvalues; | ||
1065 | else { /* Read and modify the register value. */ | ||
1066 | err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, | ||
1067 | reg, &buf, 1); | ||
1068 | if (err) | ||
1069 | return err; | ||
1070 | |||
1071 | buf = ((~bitmask & buf) | (bitmask & bitvalues)); | ||
1072 | } | ||
1073 | /* Write the new value. */ | ||
1074 | err = db5500_prcmu_abb_write(bankinfo[bank].slave_addr, reg, | ||
1075 | &buf, 1); | ||
1076 | |||
1077 | mutex_unlock(&ab->access_mutex); | ||
1078 | } | ||
1079 | return err; | ||
1080 | } | ||
1081 | |||
1082 | static int | ||
1083 | set_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg, u8 value) | ||
1084 | { | ||
1085 | return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, | ||
1086 | 0xff, value); | ||
1087 | } | ||
1088 | |||
1089 | /* | ||
1090 | * Read/write permission checking functions. | ||
1091 | */ | ||
1092 | static const struct ab5500_i2c_ranges *get_bankref(u8 devid, u8 bank) | ||
1093 | { | ||
1094 | u8 i; | ||
1095 | |||
1096 | if (devid < AB5500_NUM_DEVICES) { | ||
1097 | for (i = 0; i < ab5500_bank_ranges[devid].nbanks; i++) { | ||
1098 | if (ab5500_bank_ranges[devid].bank[i].bankid == bank) | ||
1099 | return &ab5500_bank_ranges[devid].bank[i]; | ||
1100 | } | ||
1101 | } | ||
1102 | return NULL; | ||
1103 | } | ||
1104 | |||
1105 | static bool page_write_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg) | ||
1106 | { | ||
1107 | u8 i; /* range loop index */ | ||
1108 | const struct ab5500_i2c_ranges *bankref; | ||
1109 | |||
1110 | bankref = get_bankref(devid, bank); | ||
1111 | if (bankref == NULL || last_reg < first_reg) | ||
1112 | return false; | ||
1113 | |||
1114 | for (i = 0; i < bankref->nranges; i++) { | ||
1115 | if (first_reg < bankref->range[i].first) | ||
1116 | break; | ||
1117 | if ((last_reg <= bankref->range[i].last) && | ||
1118 | (bankref->range[i].perm & AB5500_PERM_WR)) | ||
1119 | return true; | ||
1120 | } | ||
1121 | return false; | ||
1122 | } | ||
1123 | |||
1124 | static bool reg_write_allowed(u8 devid, u8 bank, u8 reg) | ||
1125 | { | ||
1126 | return page_write_allowed(devid, bank, reg, reg); | ||
1127 | } | ||
1128 | |||
1129 | static bool page_read_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg) | ||
1130 | { | ||
1131 | u8 i; | ||
1132 | const struct ab5500_i2c_ranges *bankref; | ||
1133 | |||
1134 | bankref = get_bankref(devid, bank); | ||
1135 | if (bankref == NULL || last_reg < first_reg) | ||
1136 | return false; | ||
1137 | |||
1138 | |||
1139 | /* Find the range (if it exists in the list) that includes first_reg. */ | ||
1140 | for (i = 0; i < bankref->nranges; i++) { | ||
1141 | if (first_reg < bankref->range[i].first) | ||
1142 | return false; | ||
1143 | if (first_reg <= bankref->range[i].last) | ||
1144 | break; | ||
1145 | } | ||
1146 | /* Make sure that the entire range up to and including last_reg is | ||
1147 | * readable. This may span several of the ranges in the list. | ||
1148 | */ | ||
1149 | while ((i < bankref->nranges) && | ||
1150 | (bankref->range[i].perm & AB5500_PERM_RD)) { | ||
1151 | if (last_reg <= bankref->range[i].last) | ||
1152 | return true; | ||
1153 | if ((++i >= bankref->nranges) || | ||
1154 | (bankref->range[i].first != | ||
1155 | (bankref->range[i - 1].last + 1))) { | ||
1156 | break; | ||
1157 | } | ||
1158 | } | ||
1159 | return false; | ||
1160 | } | ||
1161 | |||
1162 | static bool reg_read_allowed(u8 devid, u8 bank, u8 reg) | ||
1163 | { | ||
1164 | return page_read_allowed(devid, bank, reg, reg); | ||
1165 | } | ||
1166 | |||
1167 | |||
1168 | /* | ||
1169 | * The exported register access functionality. | ||
1170 | */ | ||
1171 | static int ab5500_get_chip_id(struct device *dev) | ||
1172 | { | ||
1173 | struct ab5500 *ab = dev_get_drvdata(dev->parent); | ||
1174 | |||
1175 | return (int)ab->chip_id; | ||
1176 | } | ||
1177 | |||
1178 | static int ab5500_mask_and_set_register_interruptible(struct device *dev, | ||
1179 | u8 bank, u8 reg, u8 bitmask, u8 bitvalues) | ||
1180 | { | ||
1181 | struct ab5500 *ab; | ||
1182 | struct platform_device *pdev = to_platform_device(dev); | ||
1183 | |||
1184 | if ((AB5500_NUM_BANKS <= bank) || | ||
1185 | !reg_write_allowed(pdev->id, bank, reg)) | ||
1186 | return -EINVAL; | ||
1187 | |||
1188 | ab = dev_get_drvdata(dev->parent); | ||
1189 | return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, | ||
1190 | bitmask, bitvalues); | ||
1191 | } | ||
1192 | |||
1193 | static int ab5500_set_register_interruptible(struct device *dev, u8 bank, | ||
1194 | u8 reg, u8 value) | ||
1195 | { | ||
1196 | return ab5500_mask_and_set_register_interruptible(dev, bank, reg, 0xFF, | ||
1197 | value); | ||
1198 | } | ||
1199 | |||
1200 | static int ab5500_get_register_interruptible(struct device *dev, u8 bank, | ||
1201 | u8 reg, u8 *value) | ||
1202 | { | ||
1203 | struct ab5500 *ab; | ||
1204 | struct platform_device *pdev = to_platform_device(dev); | ||
1205 | |||
1206 | if ((AB5500_NUM_BANKS <= bank) || | ||
1207 | !reg_read_allowed(pdev->id, bank, reg)) | ||
1208 | return -EINVAL; | ||
1209 | |||
1210 | ab = dev_get_drvdata(dev->parent); | ||
1211 | return ab5500_get_register_interruptible_raw(ab, bank, reg, value); | ||
1212 | } | ||
1213 | |||
1214 | static int ab5500_get_register_page_interruptible(struct device *dev, u8 bank, | ||
1215 | u8 first_reg, u8 *regvals, u8 numregs) | ||
1216 | { | ||
1217 | struct ab5500 *ab; | ||
1218 | struct platform_device *pdev = to_platform_device(dev); | ||
1219 | |||
1220 | if ((AB5500_NUM_BANKS <= bank) || | ||
1221 | !page_read_allowed(pdev->id, bank, | ||
1222 | first_reg, (first_reg + numregs - 1))) | ||
1223 | return -EINVAL; | ||
1224 | |||
1225 | ab = dev_get_drvdata(dev->parent); | ||
1226 | return get_register_page_interruptible(ab, bank, first_reg, regvals, | ||
1227 | numregs); | ||
1228 | } | ||
1229 | |||
1230 | static int | ||
1231 | ab5500_event_registers_startup_state_get(struct device *dev, u8 *event) | ||
1232 | { | ||
1233 | struct ab5500 *ab; | ||
1234 | |||
1235 | ab = dev_get_drvdata(dev->parent); | ||
1236 | if (!ab->startup_events_read) | ||
1237 | return -EAGAIN; /* Try again later */ | ||
1238 | |||
1239 | memcpy(event, ab->startup_events, AB5500_NUM_EVENT_REG); | ||
1240 | return 0; | ||
1241 | } | ||
1242 | |||
1243 | static struct abx500_ops ab5500_ops = { | ||
1244 | .get_chip_id = ab5500_get_chip_id, | ||
1245 | .get_register = ab5500_get_register_interruptible, | ||
1246 | .set_register = ab5500_set_register_interruptible, | ||
1247 | .get_register_page = ab5500_get_register_page_interruptible, | ||
1248 | .set_register_page = NULL, | ||
1249 | .mask_and_set_register = ab5500_mask_and_set_register_interruptible, | ||
1250 | .event_registers_startup_state_get = | ||
1251 | ab5500_event_registers_startup_state_get, | ||
1252 | .startup_irq_enabled = NULL, | ||
1253 | }; | ||
1254 | |||
1255 | /* | ||
1256 | * ab5500_setup : Basic set-up, datastructure creation/destruction | ||
1257 | * and I2C interface.This sets up a default config | ||
1258 | * in the AB5500 chip so that it will work as expected. | ||
1259 | * @ab : Pointer to ab5500 structure | ||
1260 | * @settings : Pointer to struct abx500_init_settings | ||
1261 | * @size : Size of init data | ||
1262 | */ | ||
1263 | static int __init ab5500_setup(struct ab5500 *ab, | ||
1264 | struct abx500_init_settings *settings, unsigned int size) | ||
1265 | { | ||
1266 | int err = 0; | ||
1267 | int i; | ||
1268 | |||
1269 | for (i = 0; i < size; i++) { | ||
1270 | err = ab5500_mask_and_set_register_interruptible_raw(ab, | ||
1271 | settings[i].bank, | ||
1272 | settings[i].reg, | ||
1273 | 0xFF, settings[i].setting); | ||
1274 | if (err) | ||
1275 | goto exit_no_setup; | ||
1276 | |||
1277 | /* If event mask register update the event mask in ab5500 */ | ||
1278 | if ((settings[i].bank == AB5500_BANK_IT) && | ||
1279 | (AB5500_MASK_BASE <= settings[i].reg) && | ||
1280 | (settings[i].reg <= AB5500_MASK_END)) { | ||
1281 | ab->mask[settings[i].reg - AB5500_MASK_BASE] = | ||
1282 | settings[i].setting; | ||
1283 | } | ||
1284 | } | ||
1285 | exit_no_setup: | ||
1286 | return err; | ||
1287 | } | ||
1288 | |||
1289 | struct ab_family_id { | ||
1290 | u8 id; | ||
1291 | char *name; | ||
1292 | }; | ||
1293 | |||
1294 | static const struct ab_family_id ids[] __initdata = { | ||
1295 | /* AB5500 */ | ||
1296 | { | ||
1297 | .id = AB5500_1_0, | ||
1298 | .name = "1.0" | ||
1299 | }, | ||
1300 | { | ||
1301 | .id = AB5500_1_1, | ||
1302 | .name = "1.1" | ||
1303 | }, | ||
1304 | /* Terminator */ | ||
1305 | { | ||
1306 | .id = 0x00, | ||
1307 | } | ||
1308 | }; | ||
1309 | |||
1310 | static int __init ab5500_probe(struct platform_device *pdev) | ||
1311 | { | ||
1312 | struct ab5500 *ab; | ||
1313 | struct ab5500_platform_data *ab5500_plf_data = | ||
1314 | pdev->dev.platform_data; | ||
1315 | int err; | ||
1316 | int i; | ||
1317 | |||
1318 | ab = kzalloc(sizeof(struct ab5500), GFP_KERNEL); | ||
1319 | if (!ab) { | ||
1320 | dev_err(&pdev->dev, | ||
1321 | "could not allocate ab5500 device\n"); | ||
1322 | return -ENOMEM; | ||
1323 | } | ||
1324 | |||
1325 | /* Initialize data structure */ | ||
1326 | mutex_init(&ab->access_mutex); | ||
1327 | mutex_init(&ab->irq_lock); | ||
1328 | ab->dev = &pdev->dev; | ||
1329 | |||
1330 | platform_set_drvdata(pdev, ab); | ||
1331 | |||
1332 | /* Read chip ID register */ | ||
1333 | err = ab5500_get_register_interruptible_raw(ab, | ||
1334 | AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, | ||
1335 | AB5500_CHIP_ID, &ab->chip_id); | ||
1336 | if (err) { | ||
1337 | dev_err(&pdev->dev, "could not communicate with the analog " | ||
1338 | "baseband chip\n"); | ||
1339 | goto exit_no_detect; | ||
1340 | } | ||
1341 | |||
1342 | for (i = 0; ids[i].id != 0x0; i++) { | ||
1343 | if (ids[i].id == ab->chip_id) { | ||
1344 | snprintf(&ab->chip_name[0], sizeof(ab->chip_name) - 1, | ||
1345 | "AB5500 %s", ids[i].name); | ||
1346 | break; | ||
1347 | } | ||
1348 | } | ||
1349 | if (ids[i].id == 0x0) { | ||
1350 | dev_err(&pdev->dev, "unknown analog baseband chip id: 0x%x\n", | ||
1351 | ab->chip_id); | ||
1352 | dev_err(&pdev->dev, "driver not started!\n"); | ||
1353 | goto exit_no_detect; | ||
1354 | } | ||
1355 | |||
1356 | /* Clear and mask all interrupts */ | ||
1357 | for (i = 0; i < AB5500_NUM_IRQ_REGS; i++) { | ||
1358 | u8 latchreg = AB5500_IT_LATCH0_REG + i; | ||
1359 | u8 maskreg = AB5500_IT_MASK0_REG + i; | ||
1360 | u8 val; | ||
1361 | |||
1362 | ab5500_get_register_interruptible_raw(ab, AB5500_BANK_IT, | ||
1363 | latchreg, &val); | ||
1364 | set_register_interruptible(ab, AB5500_BANK_IT, maskreg, 0xff); | ||
1365 | ab->mask[i] = ab->oldmask[i] = 0xff; | ||
1366 | } | ||
1367 | |||
1368 | err = abx500_register_ops(&pdev->dev, &ab5500_ops); | ||
1369 | if (err) { | ||
1370 | dev_err(&pdev->dev, "ab5500_register ops error\n"); | ||
1371 | goto exit_no_detect; | ||
1372 | } | ||
1373 | |||
1374 | /* Set up and register the platform devices. */ | ||
1375 | for (i = 0; i < AB5500_NUM_DEVICES; i++) { | ||
1376 | ab5500_devs[i].platform_data = ab5500_plf_data->dev_data[i]; | ||
1377 | ab5500_devs[i].pdata_size = | ||
1378 | sizeof(ab5500_plf_data->dev_data[i]); | ||
1379 | } | ||
1380 | |||
1381 | err = mfd_add_devices(&pdev->dev, 0, ab5500_devs, | ||
1382 | ARRAY_SIZE(ab5500_devs), NULL, | ||
1383 | ab5500_plf_data->irq.base); | ||
1384 | if (err) { | ||
1385 | dev_err(&pdev->dev, "ab5500_mfd_add_device error\n"); | ||
1386 | goto exit_no_detect; | ||
1387 | } | ||
1388 | |||
1389 | err = ab5500_setup(ab, ab5500_plf_data->init_settings, | ||
1390 | ab5500_plf_data->init_settings_sz); | ||
1391 | if (err) { | ||
1392 | dev_err(&pdev->dev, "ab5500_setup error\n"); | ||
1393 | goto exit_no_detect; | ||
1394 | } | ||
1395 | |||
1396 | ab5500_setup_debugfs(ab); | ||
1397 | |||
1398 | dev_info(&pdev->dev, "detected AB chip: %s\n", &ab->chip_name[0]); | ||
1399 | return 0; | ||
1400 | |||
1401 | exit_no_detect: | ||
1402 | kfree(ab); | ||
1403 | return err; | ||
1404 | } | ||
1405 | |||
1406 | static int __exit ab5500_remove(struct platform_device *pdev) | ||
1407 | { | ||
1408 | struct ab5500 *ab = platform_get_drvdata(pdev); | ||
1409 | |||
1410 | ab5500_remove_debugfs(); | ||
1411 | mfd_remove_devices(&pdev->dev); | ||
1412 | kfree(ab); | ||
1413 | return 0; | ||
1414 | } | ||
1415 | |||
1416 | static struct platform_driver ab5500_driver = { | ||
1417 | .driver = { | ||
1418 | .name = "ab5500-core", | ||
1419 | .owner = THIS_MODULE, | ||
1420 | }, | ||
1421 | .remove = __exit_p(ab5500_remove), | ||
1422 | }; | ||
1423 | |||
1424 | static int __init ab5500_core_init(void) | ||
1425 | { | ||
1426 | return platform_driver_probe(&ab5500_driver, ab5500_probe); | ||
1427 | } | ||
1428 | |||
1429 | static void __exit ab5500_core_exit(void) | ||
1430 | { | ||
1431 | platform_driver_unregister(&ab5500_driver); | ||
1432 | } | ||
1433 | |||
1434 | subsys_initcall(ab5500_core_init); | ||
1435 | module_exit(ab5500_core_exit); | ||
1436 | |||
1437 | MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>"); | ||
1438 | MODULE_DESCRIPTION("AB5500 core driver"); | ||
1439 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/ab5500-core.h b/drivers/mfd/ab5500-core.h new file mode 100644 index 000000000000..63b30b17e4f3 --- /dev/null +++ b/drivers/mfd/ab5500-core.h | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 ST-Ericsson | ||
3 | * License terms: GNU General Public License (GPL) version 2 | ||
4 | * Shared definitions and data structures for the AB5500 MFD driver | ||
5 | */ | ||
6 | |||
7 | /* Read/write operation values. */ | ||
8 | #define AB5500_PERM_RD (0x01) | ||
9 | #define AB5500_PERM_WR (0x02) | ||
10 | |||
11 | /* Read/write permissions. */ | ||
12 | #define AB5500_PERM_RO (AB5500_PERM_RD) | ||
13 | #define AB5500_PERM_RW (AB5500_PERM_RD | AB5500_PERM_WR) | ||
14 | |||
15 | #define AB5500_MASK_BASE (0x60) | ||
16 | #define AB5500_MASK_END (0x79) | ||
17 | #define AB5500_CHIP_ID (0x20) | ||
18 | |||
19 | /** | ||
20 | * struct ab5500_reg_range | ||
21 | * @first: the first address of the range | ||
22 | * @last: the last address of the range | ||
23 | * @perm: access permissions for the range | ||
24 | */ | ||
25 | struct ab5500_reg_range { | ||
26 | u8 first; | ||
27 | u8 last; | ||
28 | u8 perm; | ||
29 | }; | ||
30 | |||
31 | /** | ||
32 | * struct ab5500_i2c_ranges | ||
33 | * @count: the number of ranges in the list | ||
34 | * @range: the list of register ranges | ||
35 | */ | ||
36 | struct ab5500_i2c_ranges { | ||
37 | u8 nranges; | ||
38 | u8 bankid; | ||
39 | const struct ab5500_reg_range *range; | ||
40 | }; | ||
41 | |||
42 | /** | ||
43 | * struct ab5500_i2c_banks | ||
44 | * @count: the number of ranges in the list | ||
45 | * @range: the list of register ranges | ||
46 | */ | ||
47 | struct ab5500_i2c_banks { | ||
48 | u8 nbanks; | ||
49 | const struct ab5500_i2c_ranges *bank; | ||
50 | }; | ||
51 | |||
52 | /** | ||
53 | * struct ab5500_bank | ||
54 | * @slave_addr: I2C slave_addr found in AB5500 specification | ||
55 | * @name: Documentation name of the bank. For reference | ||
56 | */ | ||
57 | struct ab5500_bank { | ||
58 | u8 slave_addr; | ||
59 | const char *name; | ||
60 | }; | ||
61 | |||
62 | static const struct ab5500_bank bankinfo[AB5500_NUM_BANKS] = { | ||
63 | [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { | ||
64 | AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP, "VIT_IO_I2C_CLK_TST_OTP"}, | ||
65 | [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { | ||
66 | AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST, "VDDDIG_IO_I2C_CLK_TST"}, | ||
67 | [AB5500_BANK_VDENC] = {AB5500_ADDR_VDENC, "VDENC"}, | ||
68 | [AB5500_BANK_SIM_USBSIM] = {AB5500_ADDR_SIM_USBSIM, "SIM_USBSIM"}, | ||
69 | [AB5500_BANK_LED] = {AB5500_ADDR_LED, "LED"}, | ||
70 | [AB5500_BANK_ADC] = {AB5500_ADDR_ADC, "ADC"}, | ||
71 | [AB5500_BANK_RTC] = {AB5500_ADDR_RTC, "RTC"}, | ||
72 | [AB5500_BANK_STARTUP] = {AB5500_ADDR_STARTUP, "STARTUP"}, | ||
73 | [AB5500_BANK_DBI_ECI] = {AB5500_ADDR_DBI_ECI, "DBI-ECI"}, | ||
74 | [AB5500_BANK_CHG] = {AB5500_ADDR_CHG, "CHG"}, | ||
75 | [AB5500_BANK_FG_BATTCOM_ACC] = { | ||
76 | AB5500_ADDR_FG_BATTCOM_ACC, "FG_BATCOM_ACC"}, | ||
77 | [AB5500_BANK_USB] = {AB5500_ADDR_USB, "USB"}, | ||
78 | [AB5500_BANK_IT] = {AB5500_ADDR_IT, "IT"}, | ||
79 | [AB5500_BANK_VIBRA] = {AB5500_ADDR_VIBRA, "VIBRA"}, | ||
80 | [AB5500_BANK_AUDIO_HEADSETUSB] = { | ||
81 | AB5500_ADDR_AUDIO_HEADSETUSB, "AUDIO_HEADSETUSB"}, | ||
82 | }; | ||
83 | |||
84 | int ab5500_get_register_interruptible_raw(struct ab5500 *ab, u8 bank, u8 reg, | ||
85 | u8 *value); | ||
86 | int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank, | ||
87 | u8 reg, u8 bitmask, u8 bitvalues); | ||
diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c new file mode 100644 index 000000000000..6be1fe6b5f9a --- /dev/null +++ b/drivers/mfd/ab5500-debugfs.c | |||
@@ -0,0 +1,806 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 ST-Ericsson | ||
3 | * License terms: GNU General Public License (GPL) version 2 | ||
4 | * Debugfs support for the AB5500 MFD driver | ||
5 | */ | ||
6 | |||
7 | #include <linux/debugfs.h> | ||
8 | #include <linux/seq_file.h> | ||
9 | #include <linux/mfd/ab5500/ab5500.h> | ||
10 | #include <linux/mfd/abx500.h> | ||
11 | #include <linux/uaccess.h> | ||
12 | |||
13 | #include "ab5500-core.h" | ||
14 | #include "ab5500-debugfs.h" | ||
15 | |||
16 | static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = { | ||
17 | [AB5500_BANK_LED] = { | ||
18 | .bankid = AB5500_BANK_LED, | ||
19 | .nranges = 1, | ||
20 | .range = (struct ab5500_reg_range[]) { | ||
21 | { | ||
22 | .first = 0x00, | ||
23 | .last = 0x0C, | ||
24 | .perm = AB5500_PERM_RW, | ||
25 | }, | ||
26 | }, | ||
27 | }, | ||
28 | [AB5500_BANK_ADC] = { | ||
29 | .bankid = AB5500_BANK_ADC, | ||
30 | .nranges = 6, | ||
31 | .range = (struct ab5500_reg_range[]) { | ||
32 | { | ||
33 | .first = 0x1F, | ||
34 | .last = 0x22, | ||
35 | .perm = AB5500_PERM_RO, | ||
36 | }, | ||
37 | { | ||
38 | .first = 0x23, | ||
39 | .last = 0x24, | ||
40 | .perm = AB5500_PERM_RW, | ||
41 | }, | ||
42 | { | ||
43 | .first = 0x26, | ||
44 | .last = 0x2D, | ||
45 | .perm = AB5500_PERM_RO, | ||
46 | }, | ||
47 | { | ||
48 | .first = 0x2F, | ||
49 | .last = 0x34, | ||
50 | .perm = AB5500_PERM_RW, | ||
51 | }, | ||
52 | { | ||
53 | .first = 0x37, | ||
54 | .last = 0x57, | ||
55 | .perm = AB5500_PERM_RW, | ||
56 | }, | ||
57 | { | ||
58 | .first = 0x58, | ||
59 | .last = 0x58, | ||
60 | .perm = AB5500_PERM_RO, | ||
61 | }, | ||
62 | }, | ||
63 | }, | ||
64 | [AB5500_BANK_RTC] = { | ||
65 | .bankid = AB5500_BANK_RTC, | ||
66 | .nranges = 2, | ||
67 | .range = (struct ab5500_reg_range[]) { | ||
68 | { | ||
69 | .first = 0x00, | ||
70 | .last = 0x04, | ||
71 | .perm = AB5500_PERM_RW, | ||
72 | }, | ||
73 | { | ||
74 | .first = 0x06, | ||
75 | .last = 0x0C, | ||
76 | .perm = AB5500_PERM_RW, | ||
77 | }, | ||
78 | }, | ||
79 | }, | ||
80 | [AB5500_BANK_STARTUP] = { | ||
81 | .bankid = AB5500_BANK_STARTUP, | ||
82 | .nranges = 12, | ||
83 | .range = (struct ab5500_reg_range[]) { | ||
84 | { | ||
85 | .first = 0x00, | ||
86 | .last = 0x01, | ||
87 | .perm = AB5500_PERM_RW, | ||
88 | }, | ||
89 | { | ||
90 | .first = 0x1F, | ||
91 | .last = 0x1F, | ||
92 | .perm = AB5500_PERM_RW, | ||
93 | }, | ||
94 | { | ||
95 | .first = 0x2E, | ||
96 | .last = 0x2E, | ||
97 | .perm = AB5500_PERM_RO, | ||
98 | }, | ||
99 | { | ||
100 | .first = 0x2F, | ||
101 | .last = 0x30, | ||
102 | .perm = AB5500_PERM_RW, | ||
103 | }, | ||
104 | { | ||
105 | .first = 0x50, | ||
106 | .last = 0x51, | ||
107 | .perm = AB5500_PERM_RW, | ||
108 | }, | ||
109 | { | ||
110 | .first = 0x60, | ||
111 | .last = 0x61, | ||
112 | .perm = AB5500_PERM_RW, | ||
113 | }, | ||
114 | { | ||
115 | .first = 0x66, | ||
116 | .last = 0x8A, | ||
117 | .perm = AB5500_PERM_RW, | ||
118 | }, | ||
119 | { | ||
120 | .first = 0x8C, | ||
121 | .last = 0x96, | ||
122 | .perm = AB5500_PERM_RW, | ||
123 | }, | ||
124 | { | ||
125 | .first = 0xAA, | ||
126 | .last = 0xB4, | ||
127 | .perm = AB5500_PERM_RW, | ||
128 | }, | ||
129 | { | ||
130 | .first = 0xB7, | ||
131 | .last = 0xBF, | ||
132 | .perm = AB5500_PERM_RW, | ||
133 | }, | ||
134 | { | ||
135 | .first = 0xC1, | ||
136 | .last = 0xCA, | ||
137 | .perm = AB5500_PERM_RW, | ||
138 | }, | ||
139 | { | ||
140 | .first = 0xD3, | ||
141 | .last = 0xE0, | ||
142 | .perm = AB5500_PERM_RW, | ||
143 | }, | ||
144 | }, | ||
145 | }, | ||
146 | [AB5500_BANK_DBI_ECI] = { | ||
147 | .bankid = AB5500_BANK_DBI_ECI, | ||
148 | .nranges = 3, | ||
149 | .range = (struct ab5500_reg_range[]) { | ||
150 | { | ||
151 | .first = 0x00, | ||
152 | .last = 0x07, | ||
153 | .perm = AB5500_PERM_RW, | ||
154 | }, | ||
155 | { | ||
156 | .first = 0x10, | ||
157 | .last = 0x10, | ||
158 | .perm = AB5500_PERM_RW, | ||
159 | }, | ||
160 | { | ||
161 | .first = 0x13, | ||
162 | .last = 0x13, | ||
163 | .perm = AB5500_PERM_RW, | ||
164 | }, | ||
165 | }, | ||
166 | }, | ||
167 | [AB5500_BANK_CHG] = { | ||
168 | .bankid = AB5500_BANK_CHG, | ||
169 | .nranges = 2, | ||
170 | .range = (struct ab5500_reg_range[]) { | ||
171 | { | ||
172 | .first = 0x11, | ||
173 | .last = 0x11, | ||
174 | .perm = AB5500_PERM_RO, | ||
175 | }, | ||
176 | { | ||
177 | .first = 0x12, | ||
178 | .last = 0x1B, | ||
179 | .perm = AB5500_PERM_RW, | ||
180 | }, | ||
181 | }, | ||
182 | }, | ||
183 | [AB5500_BANK_FG_BATTCOM_ACC] = { | ||
184 | .bankid = AB5500_BANK_FG_BATTCOM_ACC, | ||
185 | .nranges = 2, | ||
186 | .range = (struct ab5500_reg_range[]) { | ||
187 | { | ||
188 | .first = 0x00, | ||
189 | .last = 0x0B, | ||
190 | .perm = AB5500_PERM_RO, | ||
191 | }, | ||
192 | { | ||
193 | .first = 0x0C, | ||
194 | .last = 0x10, | ||
195 | .perm = AB5500_PERM_RW, | ||
196 | }, | ||
197 | }, | ||
198 | }, | ||
199 | [AB5500_BANK_USB] = { | ||
200 | .bankid = AB5500_BANK_USB, | ||
201 | .nranges = 12, | ||
202 | .range = (struct ab5500_reg_range[]) { | ||
203 | { | ||
204 | .first = 0x01, | ||
205 | .last = 0x01, | ||
206 | .perm = AB5500_PERM_RW, | ||
207 | }, | ||
208 | { | ||
209 | .first = 0x80, | ||
210 | .last = 0x83, | ||
211 | .perm = AB5500_PERM_RW, | ||
212 | }, | ||
213 | { | ||
214 | .first = 0x87, | ||
215 | .last = 0x8A, | ||
216 | .perm = AB5500_PERM_RW, | ||
217 | }, | ||
218 | { | ||
219 | .first = 0x8B, | ||
220 | .last = 0x8B, | ||
221 | .perm = AB5500_PERM_RO, | ||
222 | }, | ||
223 | { | ||
224 | .first = 0x91, | ||
225 | .last = 0x92, | ||
226 | .perm = AB5500_PERM_RO, | ||
227 | }, | ||
228 | { | ||
229 | .first = 0x93, | ||
230 | .last = 0x93, | ||
231 | .perm = AB5500_PERM_RW, | ||
232 | }, | ||
233 | { | ||
234 | .first = 0x94, | ||
235 | .last = 0x94, | ||
236 | .perm = AB5500_PERM_RO, | ||
237 | }, | ||
238 | { | ||
239 | .first = 0xA8, | ||
240 | .last = 0xB0, | ||
241 | .perm = AB5500_PERM_RO, | ||
242 | }, | ||
243 | { | ||
244 | .first = 0xB2, | ||
245 | .last = 0xB2, | ||
246 | .perm = AB5500_PERM_RO, | ||
247 | }, | ||
248 | { | ||
249 | .first = 0xB4, | ||
250 | .last = 0xBC, | ||
251 | .perm = AB5500_PERM_RO, | ||
252 | }, | ||
253 | { | ||
254 | .first = 0xBF, | ||
255 | .last = 0xBF, | ||
256 | .perm = AB5500_PERM_RO, | ||
257 | }, | ||
258 | { | ||
259 | .first = 0xC1, | ||
260 | .last = 0xC5, | ||
261 | .perm = AB5500_PERM_RO, | ||
262 | }, | ||
263 | }, | ||
264 | }, | ||
265 | [AB5500_BANK_IT] = { | ||
266 | .bankid = AB5500_BANK_IT, | ||
267 | .nranges = 4, | ||
268 | .range = (struct ab5500_reg_range[]) { | ||
269 | { | ||
270 | .first = 0x00, | ||
271 | .last = 0x02, | ||
272 | .perm = AB5500_PERM_RO, | ||
273 | }, | ||
274 | { | ||
275 | .first = 0x20, | ||
276 | .last = 0x36, | ||
277 | .perm = AB5500_PERM_RO, | ||
278 | }, | ||
279 | { | ||
280 | .first = 0x40, | ||
281 | .last = 0x56, | ||
282 | .perm = AB5500_PERM_RO, | ||
283 | }, | ||
284 | { | ||
285 | .first = 0x60, | ||
286 | .last = 0x76, | ||
287 | .perm = AB5500_PERM_RO, | ||
288 | }, | ||
289 | }, | ||
290 | }, | ||
291 | [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { | ||
292 | .bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST, | ||
293 | .nranges = 7, | ||
294 | .range = (struct ab5500_reg_range[]) { | ||
295 | { | ||
296 | .first = 0x02, | ||
297 | .last = 0x02, | ||
298 | .perm = AB5500_PERM_RW, | ||
299 | }, | ||
300 | { | ||
301 | .first = 0x12, | ||
302 | .last = 0x12, | ||
303 | .perm = AB5500_PERM_RW, | ||
304 | }, | ||
305 | { | ||
306 | .first = 0x30, | ||
307 | .last = 0x34, | ||
308 | .perm = AB5500_PERM_RW, | ||
309 | }, | ||
310 | { | ||
311 | .first = 0x40, | ||
312 | .last = 0x44, | ||
313 | .perm = AB5500_PERM_RW, | ||
314 | }, | ||
315 | { | ||
316 | .first = 0x50, | ||
317 | .last = 0x54, | ||
318 | .perm = AB5500_PERM_RW, | ||
319 | }, | ||
320 | { | ||
321 | .first = 0x60, | ||
322 | .last = 0x64, | ||
323 | .perm = AB5500_PERM_RW, | ||
324 | }, | ||
325 | { | ||
326 | .first = 0x70, | ||
327 | .last = 0x74, | ||
328 | .perm = AB5500_PERM_RW, | ||
329 | }, | ||
330 | }, | ||
331 | }, | ||
332 | [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { | ||
333 | .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, | ||
334 | .nranges = 13, | ||
335 | .range = (struct ab5500_reg_range[]) { | ||
336 | { | ||
337 | .first = 0x01, | ||
338 | .last = 0x01, | ||
339 | .perm = AB5500_PERM_RW, | ||
340 | }, | ||
341 | { | ||
342 | .first = 0x02, | ||
343 | .last = 0x02, | ||
344 | .perm = AB5500_PERM_RO, | ||
345 | }, | ||
346 | { | ||
347 | .first = 0x0D, | ||
348 | .last = 0x0F, | ||
349 | .perm = AB5500_PERM_RW, | ||
350 | }, | ||
351 | { | ||
352 | .first = 0x1C, | ||
353 | .last = 0x1C, | ||
354 | .perm = AB5500_PERM_RW, | ||
355 | }, | ||
356 | { | ||
357 | .first = 0x1E, | ||
358 | .last = 0x1E, | ||
359 | .perm = AB5500_PERM_RW, | ||
360 | }, | ||
361 | { | ||
362 | .first = 0x20, | ||
363 | .last = 0x21, | ||
364 | .perm = AB5500_PERM_RW, | ||
365 | }, | ||
366 | { | ||
367 | .first = 0x25, | ||
368 | .last = 0x25, | ||
369 | .perm = AB5500_PERM_RW, | ||
370 | }, | ||
371 | { | ||
372 | .first = 0x28, | ||
373 | .last = 0x2A, | ||
374 | .perm = AB5500_PERM_RW, | ||
375 | }, | ||
376 | { | ||
377 | .first = 0x30, | ||
378 | .last = 0x33, | ||
379 | .perm = AB5500_PERM_RW, | ||
380 | }, | ||
381 | { | ||
382 | .first = 0x40, | ||
383 | .last = 0x43, | ||
384 | .perm = AB5500_PERM_RW, | ||
385 | }, | ||
386 | { | ||
387 | .first = 0x50, | ||
388 | .last = 0x53, | ||
389 | .perm = AB5500_PERM_RW, | ||
390 | }, | ||
391 | { | ||
392 | .first = 0x60, | ||
393 | .last = 0x63, | ||
394 | .perm = AB5500_PERM_RW, | ||
395 | }, | ||
396 | { | ||
397 | .first = 0x70, | ||
398 | .last = 0x73, | ||
399 | .perm = AB5500_PERM_RW, | ||
400 | }, | ||
401 | }, | ||
402 | }, | ||
403 | [AB5500_BANK_VIBRA] = { | ||
404 | .bankid = AB5500_BANK_VIBRA, | ||
405 | .nranges = 2, | ||
406 | .range = (struct ab5500_reg_range[]) { | ||
407 | { | ||
408 | .first = 0x10, | ||
409 | .last = 0x13, | ||
410 | .perm = AB5500_PERM_RW, | ||
411 | }, | ||
412 | { | ||
413 | .first = 0xFE, | ||
414 | .last = 0xFE, | ||
415 | .perm = AB5500_PERM_RW, | ||
416 | }, | ||
417 | }, | ||
418 | }, | ||
419 | [AB5500_BANK_AUDIO_HEADSETUSB] = { | ||
420 | .bankid = AB5500_BANK_AUDIO_HEADSETUSB, | ||
421 | .nranges = 2, | ||
422 | .range = (struct ab5500_reg_range[]) { | ||
423 | { | ||
424 | .first = 0x00, | ||
425 | .last = 0x48, | ||
426 | .perm = AB5500_PERM_RW, | ||
427 | }, | ||
428 | { | ||
429 | .first = 0xEB, | ||
430 | .last = 0xFB, | ||
431 | .perm = AB5500_PERM_RW, | ||
432 | }, | ||
433 | }, | ||
434 | }, | ||
435 | [AB5500_BANK_SIM_USBSIM] = { | ||
436 | .bankid = AB5500_BANK_SIM_USBSIM, | ||
437 | .nranges = 1, | ||
438 | .range = (struct ab5500_reg_range[]) { | ||
439 | { | ||
440 | .first = 0x13, | ||
441 | .last = 0x19, | ||
442 | .perm = AB5500_PERM_RW, | ||
443 | }, | ||
444 | }, | ||
445 | }, | ||
446 | [AB5500_BANK_VDENC] = { | ||
447 | .bankid = AB5500_BANK_VDENC, | ||
448 | .nranges = 12, | ||
449 | .range = (struct ab5500_reg_range[]) { | ||
450 | { | ||
451 | .first = 0x00, | ||
452 | .last = 0x08, | ||
453 | .perm = AB5500_PERM_RW, | ||
454 | }, | ||
455 | { | ||
456 | .first = 0x09, | ||
457 | .last = 0x09, | ||
458 | .perm = AB5500_PERM_RO, | ||
459 | }, | ||
460 | { | ||
461 | .first = 0x0A, | ||
462 | .last = 0x12, | ||
463 | .perm = AB5500_PERM_RW, | ||
464 | }, | ||
465 | { | ||
466 | .first = 0x15, | ||
467 | .last = 0x19, | ||
468 | .perm = AB5500_PERM_RW, | ||
469 | }, | ||
470 | { | ||
471 | .first = 0x1B, | ||
472 | .last = 0x21, | ||
473 | .perm = AB5500_PERM_RW, | ||
474 | }, | ||
475 | { | ||
476 | .first = 0x27, | ||
477 | .last = 0x2C, | ||
478 | .perm = AB5500_PERM_RW, | ||
479 | }, | ||
480 | { | ||
481 | .first = 0x41, | ||
482 | .last = 0x41, | ||
483 | .perm = AB5500_PERM_RW, | ||
484 | }, | ||
485 | { | ||
486 | .first = 0x45, | ||
487 | .last = 0x5B, | ||
488 | .perm = AB5500_PERM_RW, | ||
489 | }, | ||
490 | { | ||
491 | .first = 0x5D, | ||
492 | .last = 0x5D, | ||
493 | .perm = AB5500_PERM_RW, | ||
494 | }, | ||
495 | { | ||
496 | .first = 0x69, | ||
497 | .last = 0x69, | ||
498 | .perm = AB5500_PERM_RW, | ||
499 | }, | ||
500 | { | ||
501 | .first = 0x6C, | ||
502 | .last = 0x6D, | ||
503 | .perm = AB5500_PERM_RW, | ||
504 | }, | ||
505 | { | ||
506 | .first = 0x80, | ||
507 | .last = 0x81, | ||
508 | .perm = AB5500_PERM_RW, | ||
509 | }, | ||
510 | }, | ||
511 | }, | ||
512 | }; | ||
513 | |||
514 | static int ab5500_registers_print(struct seq_file *s, void *p) | ||
515 | { | ||
516 | struct ab5500 *ab = s->private; | ||
517 | unsigned int i; | ||
518 | u8 bank = (u8)ab->debug_bank; | ||
519 | |||
520 | seq_printf(s, "ab5500 register values:\n"); | ||
521 | for (bank = 0; bank < AB5500_NUM_BANKS; bank++) { | ||
522 | seq_printf(s, " bank %u, %s (0x%x):\n", bank, | ||
523 | bankinfo[bank].name, | ||
524 | bankinfo[bank].slave_addr); | ||
525 | for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) { | ||
526 | u8 reg; | ||
527 | int err; | ||
528 | |||
529 | for (reg = ab5500_reg_ranges[bank].range[i].first; | ||
530 | reg <= ab5500_reg_ranges[bank].range[i].last; | ||
531 | reg++) { | ||
532 | u8 value; | ||
533 | |||
534 | err = ab5500_get_register_interruptible_raw(ab, | ||
535 | bank, reg, | ||
536 | &value); | ||
537 | if (err < 0) { | ||
538 | dev_err(ab->dev, "get_reg failed %d" | ||
539 | "bank 0x%x reg 0x%x\n", | ||
540 | err, bank, reg); | ||
541 | return err; | ||
542 | } | ||
543 | |||
544 | err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n", | ||
545 | bank, reg, value); | ||
546 | if (err < 0) { | ||
547 | dev_err(ab->dev, | ||
548 | "seq_printf overflow\n"); | ||
549 | /* | ||
550 | * Error is not returned here since | ||
551 | * the output is wanted in any case | ||
552 | */ | ||
553 | return 0; | ||
554 | } | ||
555 | } | ||
556 | } | ||
557 | } | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int ab5500_registers_open(struct inode *inode, struct file *file) | ||
562 | { | ||
563 | return single_open(file, ab5500_registers_print, inode->i_private); | ||
564 | } | ||
565 | |||
566 | static const struct file_operations ab5500_registers_fops = { | ||
567 | .open = ab5500_registers_open, | ||
568 | .read = seq_read, | ||
569 | .llseek = seq_lseek, | ||
570 | .release = single_release, | ||
571 | .owner = THIS_MODULE, | ||
572 | }; | ||
573 | |||
574 | static int ab5500_bank_print(struct seq_file *s, void *p) | ||
575 | { | ||
576 | struct ab5500 *ab = s->private; | ||
577 | |||
578 | seq_printf(s, "%d\n", ab->debug_bank); | ||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | static int ab5500_bank_open(struct inode *inode, struct file *file) | ||
583 | { | ||
584 | return single_open(file, ab5500_bank_print, inode->i_private); | ||
585 | } | ||
586 | |||
587 | static ssize_t ab5500_bank_write(struct file *file, | ||
588 | const char __user *user_buf, | ||
589 | size_t count, loff_t *ppos) | ||
590 | { | ||
591 | struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; | ||
592 | char buf[32]; | ||
593 | int buf_size; | ||
594 | unsigned long user_bank; | ||
595 | int err; | ||
596 | |||
597 | /* Get userspace string and assure termination */ | ||
598 | buf_size = min(count, (sizeof(buf) - 1)); | ||
599 | if (copy_from_user(buf, user_buf, buf_size)) | ||
600 | return -EFAULT; | ||
601 | buf[buf_size] = 0; | ||
602 | |||
603 | err = strict_strtoul(buf, 0, &user_bank); | ||
604 | if (err) | ||
605 | return -EINVAL; | ||
606 | |||
607 | if (user_bank >= AB5500_NUM_BANKS) { | ||
608 | dev_err(ab->dev, | ||
609 | "debugfs error input > number of banks\n"); | ||
610 | return -EINVAL; | ||
611 | } | ||
612 | |||
613 | ab->debug_bank = user_bank; | ||
614 | |||
615 | return buf_size; | ||
616 | } | ||
617 | |||
618 | static int ab5500_address_print(struct seq_file *s, void *p) | ||
619 | { | ||
620 | struct ab5500 *ab = s->private; | ||
621 | |||
622 | seq_printf(s, "0x%02X\n", ab->debug_address); | ||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static int ab5500_address_open(struct inode *inode, struct file *file) | ||
627 | { | ||
628 | return single_open(file, ab5500_address_print, inode->i_private); | ||
629 | } | ||
630 | |||
631 | static ssize_t ab5500_address_write(struct file *file, | ||
632 | const char __user *user_buf, | ||
633 | size_t count, loff_t *ppos) | ||
634 | { | ||
635 | struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; | ||
636 | char buf[32]; | ||
637 | int buf_size; | ||
638 | unsigned long user_address; | ||
639 | int err; | ||
640 | |||
641 | /* Get userspace string and assure termination */ | ||
642 | buf_size = min(count, (sizeof(buf) - 1)); | ||
643 | if (copy_from_user(buf, user_buf, buf_size)) | ||
644 | return -EFAULT; | ||
645 | buf[buf_size] = 0; | ||
646 | |||
647 | err = strict_strtoul(buf, 0, &user_address); | ||
648 | if (err) | ||
649 | return -EINVAL; | ||
650 | if (user_address > 0xff) { | ||
651 | dev_err(ab->dev, | ||
652 | "debugfs error input > 0xff\n"); | ||
653 | return -EINVAL; | ||
654 | } | ||
655 | ab->debug_address = user_address; | ||
656 | return buf_size; | ||
657 | } | ||
658 | |||
659 | static int ab5500_val_print(struct seq_file *s, void *p) | ||
660 | { | ||
661 | struct ab5500 *ab = s->private; | ||
662 | int err; | ||
663 | u8 regvalue; | ||
664 | |||
665 | err = ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank, | ||
666 | (u8)ab->debug_address, ®value); | ||
667 | if (err) { | ||
668 | dev_err(ab->dev, "get_reg failed %d, bank 0x%x" | ||
669 | ", reg 0x%x\n", err, ab->debug_bank, | ||
670 | ab->debug_address); | ||
671 | return -EINVAL; | ||
672 | } | ||
673 | seq_printf(s, "0x%02X\n", regvalue); | ||
674 | |||
675 | return 0; | ||
676 | } | ||
677 | |||
678 | static int ab5500_val_open(struct inode *inode, struct file *file) | ||
679 | { | ||
680 | return single_open(file, ab5500_val_print, inode->i_private); | ||
681 | } | ||
682 | |||
683 | static ssize_t ab5500_val_write(struct file *file, | ||
684 | const char __user *user_buf, | ||
685 | size_t count, loff_t *ppos) | ||
686 | { | ||
687 | struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; | ||
688 | char buf[32]; | ||
689 | int buf_size; | ||
690 | unsigned long user_val; | ||
691 | int err; | ||
692 | u8 regvalue; | ||
693 | |||
694 | /* Get userspace string and assure termination */ | ||
695 | buf_size = min(count, (sizeof(buf)-1)); | ||
696 | if (copy_from_user(buf, user_buf, buf_size)) | ||
697 | return -EFAULT; | ||
698 | buf[buf_size] = 0; | ||
699 | |||
700 | err = strict_strtoul(buf, 0, &user_val); | ||
701 | if (err) | ||
702 | return -EINVAL; | ||
703 | if (user_val > 0xff) { | ||
704 | dev_err(ab->dev, | ||
705 | "debugfs error input > 0xff\n"); | ||
706 | return -EINVAL; | ||
707 | } | ||
708 | err = ab5500_mask_and_set_register_interruptible_raw( | ||
709 | ab, (u8)ab->debug_bank, | ||
710 | (u8)ab->debug_address, 0xFF, (u8)user_val); | ||
711 | if (err) | ||
712 | return -EINVAL; | ||
713 | |||
714 | ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank, | ||
715 | (u8)ab->debug_address, ®value); | ||
716 | if (err) | ||
717 | return -EINVAL; | ||
718 | |||
719 | return buf_size; | ||
720 | } | ||
721 | |||
722 | static const struct file_operations ab5500_bank_fops = { | ||
723 | .open = ab5500_bank_open, | ||
724 | .write = ab5500_bank_write, | ||
725 | .read = seq_read, | ||
726 | .llseek = seq_lseek, | ||
727 | .release = single_release, | ||
728 | .owner = THIS_MODULE, | ||
729 | }; | ||
730 | |||
731 | static const struct file_operations ab5500_address_fops = { | ||
732 | .open = ab5500_address_open, | ||
733 | .write = ab5500_address_write, | ||
734 | .read = seq_read, | ||
735 | .llseek = seq_lseek, | ||
736 | .release = single_release, | ||
737 | .owner = THIS_MODULE, | ||
738 | }; | ||
739 | |||
740 | static const struct file_operations ab5500_val_fops = { | ||
741 | .open = ab5500_val_open, | ||
742 | .write = ab5500_val_write, | ||
743 | .read = seq_read, | ||
744 | .llseek = seq_lseek, | ||
745 | .release = single_release, | ||
746 | .owner = THIS_MODULE, | ||
747 | }; | ||
748 | |||
749 | static struct dentry *ab5500_dir; | ||
750 | static struct dentry *ab5500_reg_file; | ||
751 | static struct dentry *ab5500_bank_file; | ||
752 | static struct dentry *ab5500_address_file; | ||
753 | static struct dentry *ab5500_val_file; | ||
754 | |||
755 | void __init ab5500_setup_debugfs(struct ab5500 *ab) | ||
756 | { | ||
757 | ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP; | ||
758 | ab->debug_address = AB5500_CHIP_ID; | ||
759 | |||
760 | ab5500_dir = debugfs_create_dir("ab5500", NULL); | ||
761 | if (!ab5500_dir) | ||
762 | goto exit_no_debugfs; | ||
763 | |||
764 | ab5500_reg_file = debugfs_create_file("all-bank-registers", | ||
765 | S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops); | ||
766 | if (!ab5500_reg_file) | ||
767 | goto exit_destroy_dir; | ||
768 | |||
769 | ab5500_bank_file = debugfs_create_file("register-bank", | ||
770 | (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops); | ||
771 | if (!ab5500_bank_file) | ||
772 | goto exit_destroy_reg; | ||
773 | |||
774 | ab5500_address_file = debugfs_create_file("register-address", | ||
775 | (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops); | ||
776 | if (!ab5500_address_file) | ||
777 | goto exit_destroy_bank; | ||
778 | |||
779 | ab5500_val_file = debugfs_create_file("register-value", | ||
780 | (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops); | ||
781 | if (!ab5500_val_file) | ||
782 | goto exit_destroy_address; | ||
783 | |||
784 | return; | ||
785 | |||
786 | exit_destroy_address: | ||
787 | debugfs_remove(ab5500_address_file); | ||
788 | exit_destroy_bank: | ||
789 | debugfs_remove(ab5500_bank_file); | ||
790 | exit_destroy_reg: | ||
791 | debugfs_remove(ab5500_reg_file); | ||
792 | exit_destroy_dir: | ||
793 | debugfs_remove(ab5500_dir); | ||
794 | exit_no_debugfs: | ||
795 | dev_err(ab->dev, "failed to create debugfs entries.\n"); | ||
796 | return; | ||
797 | } | ||
798 | |||
799 | void __exit ab5500_remove_debugfs(void) | ||
800 | { | ||
801 | debugfs_remove(ab5500_val_file); | ||
802 | debugfs_remove(ab5500_address_file); | ||
803 | debugfs_remove(ab5500_bank_file); | ||
804 | debugfs_remove(ab5500_reg_file); | ||
805 | debugfs_remove(ab5500_dir); | ||
806 | } | ||
diff --git a/drivers/mfd/ab5500-debugfs.h b/drivers/mfd/ab5500-debugfs.h new file mode 100644 index 000000000000..7330a9b6afa6 --- /dev/null +++ b/drivers/mfd/ab5500-debugfs.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 ST-Ericsson | ||
3 | * License terms: GNU General Public License (GPL) version 2 | ||
4 | * Debugfs interface to the AB5500 core driver | ||
5 | */ | ||
6 | |||
7 | #ifdef CONFIG_DEBUG_FS | ||
8 | |||
9 | void ab5500_setup_debugfs(struct ab5500 *ab); | ||
10 | void ab5500_remove_debugfs(void); | ||
11 | |||
12 | #else /* !CONFIG_DEBUG_FS */ | ||
13 | |||
14 | static inline void ab5500_setup_debugfs(struct ab5500 *ab) | ||
15 | { | ||
16 | } | ||
17 | |||
18 | static inline void ab5500_remove_debugfs(void) | ||
19 | { | ||
20 | } | ||
21 | |||
22 | #endif | ||
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 387705e494b9..1e9173804ede 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -92,6 +92,8 @@ | |||
92 | #define AB8500_REV_REG 0x80 | 92 | #define AB8500_REV_REG 0x80 |
93 | #define AB8500_SWITCH_OFF_STATUS 0x00 | 93 | #define AB8500_SWITCH_OFF_STATUS 0x00 |
94 | 94 | ||
95 | #define AB8500_TURN_ON_STATUS 0x00 | ||
96 | |||
95 | /* | 97 | /* |
96 | * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt | 98 | * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt |
97 | * numbers are indexed into this array with (num / 8). | 99 | * numbers are indexed into this array with (num / 8). |
@@ -293,6 +295,7 @@ static struct irq_chip ab8500_irq_chip = { | |||
293 | .irq_bus_lock = ab8500_irq_lock, | 295 | .irq_bus_lock = ab8500_irq_lock, |
294 | .irq_bus_sync_unlock = ab8500_irq_sync_unlock, | 296 | .irq_bus_sync_unlock = ab8500_irq_sync_unlock, |
295 | .irq_mask = ab8500_irq_mask, | 297 | .irq_mask = ab8500_irq_mask, |
298 | .irq_disable = ab8500_irq_mask, | ||
296 | .irq_unmask = ab8500_irq_unmask, | 299 | .irq_unmask = ab8500_irq_unmask, |
297 | }; | 300 | }; |
298 | 301 | ||
@@ -811,12 +814,40 @@ static ssize_t show_switch_off_status(struct device *dev, | |||
811 | return sprintf(buf, "%#x\n", value); | 814 | return sprintf(buf, "%#x\n", value); |
812 | } | 815 | } |
813 | 816 | ||
817 | /* | ||
818 | * ab8500 has turned on due to (TURN_ON_STATUS): | ||
819 | * 0x01 PORnVbat | ||
820 | * 0x02 PonKey1dbF | ||
821 | * 0x04 PonKey2dbF | ||
822 | * 0x08 RTCAlarm | ||
823 | * 0x10 MainChDet | ||
824 | * 0x20 VbusDet | ||
825 | * 0x40 UsbIDDetect | ||
826 | * 0x80 Reserved | ||
827 | */ | ||
828 | static ssize_t show_turn_on_status(struct device *dev, | ||
829 | struct device_attribute *attr, char *buf) | ||
830 | { | ||
831 | int ret; | ||
832 | u8 value; | ||
833 | struct ab8500 *ab8500; | ||
834 | |||
835 | ab8500 = dev_get_drvdata(dev); | ||
836 | ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK, | ||
837 | AB8500_TURN_ON_STATUS, &value); | ||
838 | if (ret < 0) | ||
839 | return ret; | ||
840 | return sprintf(buf, "%#x\n", value); | ||
841 | } | ||
842 | |||
814 | static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); | 843 | static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); |
815 | static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL); | 844 | static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL); |
845 | static DEVICE_ATTR(turn_on_status, S_IRUGO, show_turn_on_status, NULL); | ||
816 | 846 | ||
817 | static struct attribute *ab8500_sysfs_entries[] = { | 847 | static struct attribute *ab8500_sysfs_entries[] = { |
818 | &dev_attr_chip_id.attr, | 848 | &dev_attr_chip_id.attr, |
819 | &dev_attr_switch_off_status.attr, | 849 | &dev_attr_switch_off_status.attr, |
850 | &dev_attr_turn_on_status.attr, | ||
820 | NULL, | 851 | NULL, |
821 | }; | 852 | }; |
822 | 853 | ||
@@ -843,11 +874,11 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
843 | return ret; | 874 | return ret; |
844 | 875 | ||
845 | switch (value) { | 876 | switch (value) { |
846 | case AB8500_CUTEARLY: | ||
847 | case AB8500_CUT1P0: | 877 | case AB8500_CUT1P0: |
848 | case AB8500_CUT1P1: | 878 | case AB8500_CUT1P1: |
849 | case AB8500_CUT2P0: | 879 | case AB8500_CUT2P0: |
850 | case AB8500_CUT3P0: | 880 | case AB8500_CUT3P0: |
881 | case AB8500_CUT3P3: | ||
851 | dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); | 882 | dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); |
852 | break; | 883 | break; |
853 | default: | 884 | default: |
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index f16afb234ff9..e985d1701a83 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c | |||
@@ -143,12 +143,15 @@ struct ab8500_gpadc *ab8500_gpadc_get(char *name) | |||
143 | } | 143 | } |
144 | EXPORT_SYMBOL(ab8500_gpadc_get); | 144 | EXPORT_SYMBOL(ab8500_gpadc_get); |
145 | 145 | ||
146 | static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input, | 146 | /** |
147 | * ab8500_gpadc_ad_to_voltage() - Convert a raw ADC value to a voltage | ||
148 | */ | ||
149 | int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, | ||
147 | int ad_value) | 150 | int ad_value) |
148 | { | 151 | { |
149 | int res; | 152 | int res; |
150 | 153 | ||
151 | switch (input) { | 154 | switch (channel) { |
152 | case MAIN_CHARGER_V: | 155 | case MAIN_CHARGER_V: |
153 | /* For some reason we don't have calibrated data */ | 156 | /* For some reason we don't have calibrated data */ |
154 | if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) { | 157 | if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) { |
@@ -232,18 +235,46 @@ static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input, | |||
232 | } | 235 | } |
233 | return res; | 236 | return res; |
234 | } | 237 | } |
238 | EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage); | ||
235 | 239 | ||
236 | /** | 240 | /** |
237 | * ab8500_gpadc_convert() - gpadc conversion | 241 | * ab8500_gpadc_convert() - gpadc conversion |
238 | * @input: analog input to be converted to digital data | 242 | * @channel: analog channel to be converted to digital data |
239 | * | 243 | * |
240 | * This function converts the selected analog i/p to digital | 244 | * This function converts the selected analog i/p to digital |
241 | * data. | 245 | * data. |
242 | */ | 246 | */ |
243 | int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input) | 247 | int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel) |
248 | { | ||
249 | int ad_value; | ||
250 | int voltage; | ||
251 | |||
252 | ad_value = ab8500_gpadc_read_raw(gpadc, channel); | ||
253 | if (ad_value < 0) { | ||
254 | dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", channel); | ||
255 | return ad_value; | ||
256 | } | ||
257 | |||
258 | voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value); | ||
259 | |||
260 | if (voltage < 0) | ||
261 | dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:" | ||
262 | " %d AD: 0x%x\n", channel, ad_value); | ||
263 | |||
264 | return voltage; | ||
265 | } | ||
266 | EXPORT_SYMBOL(ab8500_gpadc_convert); | ||
267 | |||
268 | /** | ||
269 | * ab8500_gpadc_read_raw() - gpadc read | ||
270 | * @channel: analog channel to be read | ||
271 | * | ||
272 | * This function obtains the raw ADC value, this then needs | ||
273 | * to be converted by calling ab8500_gpadc_ad_to_voltage() | ||
274 | */ | ||
275 | int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) | ||
244 | { | 276 | { |
245 | int ret; | 277 | int ret; |
246 | u16 data = 0; | ||
247 | int looplimit = 0; | 278 | int looplimit = 0; |
248 | u8 val, low_data, high_data; | 279 | u8 val, low_data, high_data; |
249 | 280 | ||
@@ -278,9 +309,9 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input) | |||
278 | goto out; | 309 | goto out; |
279 | } | 310 | } |
280 | 311 | ||
281 | /* Select the input source and set average samples to 16 */ | 312 | /* Select the channel source and set average samples to 16 */ |
282 | ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, | 313 | ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, |
283 | AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16)); | 314 | AB8500_GPADC_CTRL2_REG, (channel | SW_AVG_16)); |
284 | if (ret < 0) { | 315 | if (ret < 0) { |
285 | dev_err(gpadc->dev, | 316 | dev_err(gpadc->dev, |
286 | "gpadc_conversion: set avg samples failed\n"); | 317 | "gpadc_conversion: set avg samples failed\n"); |
@@ -292,7 +323,7 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input) | |||
292 | * charging current sense if it needed, ABB 3.0 needs some special | 323 | * charging current sense if it needed, ABB 3.0 needs some special |
293 | * treatment too. | 324 | * treatment too. |
294 | */ | 325 | */ |
295 | switch (input) { | 326 | switch (channel) { |
296 | case MAIN_CHARGER_C: | 327 | case MAIN_CHARGER_C: |
297 | case USB_CHARGER_C: | 328 | case USB_CHARGER_C: |
298 | ret = abx500_mask_and_set_register_interruptible(gpadc->dev, | 329 | ret = abx500_mask_and_set_register_interruptible(gpadc->dev, |
@@ -359,7 +390,6 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input) | |||
359 | goto out; | 390 | goto out; |
360 | } | 391 | } |
361 | 392 | ||
362 | data = (high_data << 8) | low_data; | ||
363 | /* Disable GPADC */ | 393 | /* Disable GPADC */ |
364 | ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, | 394 | ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, |
365 | AB8500_GPADC_CTRL1_REG, DIS_GPADC); | 395 | AB8500_GPADC_CTRL1_REG, DIS_GPADC); |
@@ -370,8 +400,8 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input) | |||
370 | /* Disable VTVout LDO this is required for GPADC */ | 400 | /* Disable VTVout LDO this is required for GPADC */ |
371 | regulator_disable(gpadc->regu); | 401 | regulator_disable(gpadc->regu); |
372 | mutex_unlock(&gpadc->ab8500_gpadc_lock); | 402 | mutex_unlock(&gpadc->ab8500_gpadc_lock); |
373 | ret = ab8500_gpadc_ad_to_voltage(gpadc, input, data); | 403 | |
374 | return ret; | 404 | return (high_data << 8) | low_data; |
375 | 405 | ||
376 | out: | 406 | out: |
377 | /* | 407 | /* |
@@ -385,10 +415,10 @@ out: | |||
385 | regulator_disable(gpadc->regu); | 415 | regulator_disable(gpadc->regu); |
386 | mutex_unlock(&gpadc->ab8500_gpadc_lock); | 416 | mutex_unlock(&gpadc->ab8500_gpadc_lock); |
387 | dev_err(gpadc->dev, | 417 | dev_err(gpadc->dev, |
388 | "gpadc_conversion: Failed to AD convert channel %d\n", input); | 418 | "gpadc_conversion: Failed to AD convert channel %d\n", channel); |
389 | return ret; | 419 | return ret; |
390 | } | 420 | } |
391 | EXPORT_SYMBOL(ab8500_gpadc_convert); | 421 | EXPORT_SYMBOL(ab8500_gpadc_read_raw); |
392 | 422 | ||
393 | /** | 423 | /** |
394 | * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion | 424 | * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index c71ae09430c5..3bd85bddf6e3 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -584,7 +584,7 @@ static int asic3_gpio_remove(struct platform_device *pdev) | |||
584 | return gpiochip_remove(&asic->gpio); | 584 | return gpiochip_remove(&asic->gpio); |
585 | } | 585 | } |
586 | 586 | ||
587 | static int asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk) | 587 | static void asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk) |
588 | { | 588 | { |
589 | unsigned long flags; | 589 | unsigned long flags; |
590 | u32 cdex; | 590 | u32 cdex; |
@@ -596,8 +596,6 @@ static int asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk) | |||
596 | asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex); | 596 | asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex); |
597 | } | 597 | } |
598 | spin_unlock_irqrestore(&asic->lock, flags); | 598 | spin_unlock_irqrestore(&asic->lock, flags); |
599 | |||
600 | return 0; | ||
601 | } | 599 | } |
602 | 600 | ||
603 | static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk) | 601 | static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk) |
@@ -779,6 +777,8 @@ static struct mfd_cell asic3_cell_mmc = { | |||
779 | .name = "tmio-mmc", | 777 | .name = "tmio-mmc", |
780 | .enable = asic3_mmc_enable, | 778 | .enable = asic3_mmc_enable, |
781 | .disable = asic3_mmc_disable, | 779 | .disable = asic3_mmc_disable, |
780 | .suspend = asic3_mmc_disable, | ||
781 | .resume = asic3_mmc_enable, | ||
782 | .platform_data = &asic3_mmc_data, | 782 | .platform_data = &asic3_mmc_data, |
783 | .pdata_size = sizeof(asic3_mmc_data), | 783 | .pdata_size = sizeof(asic3_mmc_data), |
784 | .num_resources = ARRAY_SIZE(asic3_mmc_resources), | 784 | .num_resources = ARRAY_SIZE(asic3_mmc_resources), |
@@ -811,24 +811,43 @@ static int asic3_leds_disable(struct platform_device *pdev) | |||
811 | return 0; | 811 | return 0; |
812 | } | 812 | } |
813 | 813 | ||
814 | static int asic3_leds_suspend(struct platform_device *pdev) | ||
815 | { | ||
816 | const struct mfd_cell *cell = mfd_get_cell(pdev); | ||
817 | struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); | ||
818 | |||
819 | while (asic3_gpio_get(&asic->gpio, ASIC3_GPIO(C, cell->id)) != 0) | ||
820 | msleep(1); | ||
821 | |||
822 | asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]); | ||
823 | |||
824 | return 0; | ||
825 | } | ||
826 | |||
814 | static struct mfd_cell asic3_cell_leds[ASIC3_NUM_LEDS] = { | 827 | static struct mfd_cell asic3_cell_leds[ASIC3_NUM_LEDS] = { |
815 | [0] = { | 828 | [0] = { |
816 | .name = "leds-asic3", | 829 | .name = "leds-asic3", |
817 | .id = 0, | 830 | .id = 0, |
818 | .enable = asic3_leds_enable, | 831 | .enable = asic3_leds_enable, |
819 | .disable = asic3_leds_disable, | 832 | .disable = asic3_leds_disable, |
833 | .suspend = asic3_leds_suspend, | ||
834 | .resume = asic3_leds_enable, | ||
820 | }, | 835 | }, |
821 | [1] = { | 836 | [1] = { |
822 | .name = "leds-asic3", | 837 | .name = "leds-asic3", |
823 | .id = 1, | 838 | .id = 1, |
824 | .enable = asic3_leds_enable, | 839 | .enable = asic3_leds_enable, |
825 | .disable = asic3_leds_disable, | 840 | .disable = asic3_leds_disable, |
841 | .suspend = asic3_leds_suspend, | ||
842 | .resume = asic3_leds_enable, | ||
826 | }, | 843 | }, |
827 | [2] = { | 844 | [2] = { |
828 | .name = "leds-asic3", | 845 | .name = "leds-asic3", |
829 | .id = 2, | 846 | .id = 2, |
830 | .enable = asic3_leds_enable, | 847 | .enable = asic3_leds_enable, |
831 | .disable = asic3_leds_disable, | 848 | .disable = asic3_leds_disable, |
849 | .suspend = asic3_leds_suspend, | ||
850 | .resume = asic3_leds_enable, | ||
832 | }, | 851 | }, |
833 | }; | 852 | }; |
834 | 853 | ||
@@ -949,6 +968,7 @@ static int __init asic3_probe(struct platform_device *pdev) | |||
949 | goto out_unmap; | 968 | goto out_unmap; |
950 | } | 969 | } |
951 | 970 | ||
971 | asic->gpio.label = "asic3"; | ||
952 | asic->gpio.base = pdata->gpio_base; | 972 | asic->gpio.base = pdata->gpio_base; |
953 | asic->gpio.ngpio = ASIC3_NUM_GPIOS; | 973 | asic->gpio.ngpio = ASIC3_NUM_GPIOS; |
954 | asic->gpio.get = asic3_gpio_get; | 974 | asic->gpio.get = asic3_gpio_get; |
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index 2fadbaeb1cb1..1b79c37fd599 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c | |||
@@ -523,7 +523,7 @@ static int __devinit da903x_probe(struct i2c_client *client, | |||
523 | chip->ops->read_events(chip, &tmp); | 523 | chip->ops->read_events(chip, &tmp); |
524 | 524 | ||
525 | ret = request_irq(client->irq, da903x_irq_handler, | 525 | ret = request_irq(client->irq, da903x_irq_handler, |
526 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | 526 | IRQF_TRIGGER_FALLING, |
527 | "da903x", chip); | 527 | "da903x", chip); |
528 | if (ret) { | 528 | if (ret) { |
529 | dev_err(&client->dev, "failed to request irq %d\n", | 529 | dev_err(&client->dev, "failed to request irq %d\n", |
diff --git a/drivers/mfd/db5500-prcmu.c b/drivers/mfd/db5500-prcmu.c index 9dbb3cab4a6f..bb115b2f04e9 100644 --- a/drivers/mfd/db5500-prcmu.c +++ b/drivers/mfd/db5500-prcmu.c | |||
@@ -20,11 +20,11 @@ | |||
20 | #include <linux/jiffies.h> | 20 | #include <linux/jiffies.h> |
21 | #include <linux/bitops.h> | 21 | #include <linux/bitops.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/mfd/db5500-prcmu.h> | 23 | #include <linux/mfd/dbx500-prcmu.h> |
24 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
25 | #include <mach/irqs.h> | 25 | #include <mach/irqs.h> |
26 | #include <mach/db5500-regs.h> | 26 | #include <mach/db5500-regs.h> |
27 | #include "db5500-prcmu-regs.h" | 27 | #include "dbx500-prcmu-regs.h" |
28 | 28 | ||
29 | #define _PRCM_MB_HEADER (tcdm_base + 0xFE8) | 29 | #define _PRCM_MB_HEADER (tcdm_base + 0xFE8) |
30 | #define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0) | 30 | #define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0) |
@@ -109,15 +109,18 @@ enum mb5_header { | |||
109 | #define PRCMU_DSI_CLOCK_SETTING 0x00000128 | 109 | #define PRCMU_DSI_CLOCK_SETTING 0x00000128 |
110 | /* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */ | 110 | /* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */ |
111 | #define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135 | 111 | #define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135 |
112 | #define PRCMU_PLLDSI_FREQ_SETTING 0x0004013C | 112 | #define PRCMU_PLLDSI_FREQ_SETTING 0x00020121 |
113 | #define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002 | 113 | #define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002 |
114 | #define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000101 | 114 | #define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000201 |
115 | #define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101 | 115 | #define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101 |
116 | 116 | ||
117 | #define PRCMU_ENABLE_PLLDSI 0x00000001 | 117 | #define PRCMU_ENABLE_PLLDSI 0x00000001 |
118 | #define PRCMU_DISABLE_PLLDSI 0x00000000 | 118 | #define PRCMU_DISABLE_PLLDSI 0x00000000 |
119 | 119 | ||
120 | #define PRCMU_DSI_RESET_SW 0x00000003 | 120 | #define PRCMU_DSI_RESET_SW 0x00000003 |
121 | #define PRCMU_RESOUTN0_PIN 0x00000001 | ||
122 | #define PRCMU_RESOUTN1_PIN 0x00000002 | ||
123 | #define PRCMU_RESOUTN2_PIN 0x00000004 | ||
121 | 124 | ||
122 | #define PRCMU_PLLDSI_LOCKP_LOCKED 0x3 | 125 | #define PRCMU_PLLDSI_LOCKP_LOCKED 0x3 |
123 | 126 | ||
@@ -315,31 +318,31 @@ static bool read_mailbox_0(void) | |||
315 | r = false; | 318 | r = false; |
316 | break; | 319 | break; |
317 | } | 320 | } |
318 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); | 321 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLR); |
319 | return r; | 322 | return r; |
320 | } | 323 | } |
321 | 324 | ||
322 | static bool read_mailbox_1(void) | 325 | static bool read_mailbox_1(void) |
323 | { | 326 | { |
324 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); | 327 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLR); |
325 | return false; | 328 | return false; |
326 | } | 329 | } |
327 | 330 | ||
328 | static bool read_mailbox_2(void) | 331 | static bool read_mailbox_2(void) |
329 | { | 332 | { |
330 | writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR); | 333 | writel(MBOX_BIT(2), PRCM_ARM_IT1_CLR); |
331 | return false; | 334 | return false; |
332 | } | 335 | } |
333 | 336 | ||
334 | static bool read_mailbox_3(void) | 337 | static bool read_mailbox_3(void) |
335 | { | 338 | { |
336 | writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR); | 339 | writel(MBOX_BIT(3), PRCM_ARM_IT1_CLR); |
337 | return false; | 340 | return false; |
338 | } | 341 | } |
339 | 342 | ||
340 | static bool read_mailbox_4(void) | 343 | static bool read_mailbox_4(void) |
341 | { | 344 | { |
342 | writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR); | 345 | writel(MBOX_BIT(4), PRCM_ARM_IT1_CLR); |
343 | return false; | 346 | return false; |
344 | } | 347 | } |
345 | 348 | ||
@@ -360,19 +363,19 @@ static bool read_mailbox_5(void) | |||
360 | print_unknown_header_warning(5, header); | 363 | print_unknown_header_warning(5, header); |
361 | break; | 364 | break; |
362 | } | 365 | } |
363 | writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR); | 366 | writel(MBOX_BIT(5), PRCM_ARM_IT1_CLR); |
364 | return false; | 367 | return false; |
365 | } | 368 | } |
366 | 369 | ||
367 | static bool read_mailbox_6(void) | 370 | static bool read_mailbox_6(void) |
368 | { | 371 | { |
369 | writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR); | 372 | writel(MBOX_BIT(6), PRCM_ARM_IT1_CLR); |
370 | return false; | 373 | return false; |
371 | } | 374 | } |
372 | 375 | ||
373 | static bool read_mailbox_7(void) | 376 | static bool read_mailbox_7(void) |
374 | { | 377 | { |
375 | writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR); | 378 | writel(MBOX_BIT(7), PRCM_ARM_IT1_CLR); |
376 | return false; | 379 | return false; |
377 | } | 380 | } |
378 | 381 | ||
@@ -434,7 +437,7 @@ int __init db5500_prcmu_init(void) | |||
434 | return -ENODEV; | 437 | return -ENODEV; |
435 | 438 | ||
436 | /* Clean up the mailbox interrupts after pre-kernel code. */ | 439 | /* Clean up the mailbox interrupts after pre-kernel code. */ |
437 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLEAR); | 440 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); |
438 | 441 | ||
439 | r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler, | 442 | r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler, |
440 | prcmu_irq_thread_fn, 0, "prcmu", NULL); | 443 | prcmu_irq_thread_fn, 0, "prcmu", NULL); |
diff --git a/drivers/mfd/db8500-prcmu-regs.h b/drivers/mfd/db8500-prcmu-regs.h deleted file mode 100644 index 3bbf04d58043..000000000000 --- a/drivers/mfd/db8500-prcmu-regs.h +++ /dev/null | |||
@@ -1,166 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) STMicroelectronics 2009 | ||
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
4 | * | ||
5 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> | ||
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
7 | * | ||
8 | * License Terms: GNU General Public License v2 | ||
9 | * | ||
10 | * PRCM Unit registers | ||
11 | */ | ||
12 | #ifndef __DB8500_PRCMU_REGS_H | ||
13 | #define __DB8500_PRCMU_REGS_H | ||
14 | |||
15 | #include <linux/bitops.h> | ||
16 | #include <mach/hardware.h> | ||
17 | |||
18 | #define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end)) | ||
19 | |||
20 | #define PRCM_ARM_PLLDIVPS 0x118 | ||
21 | #define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE BITS(0, 5) | ||
22 | #define PRCM_ARM_PLLDIVPS_MAX_MASK 0xF | ||
23 | |||
24 | #define PRCM_PLLARM_LOCKP 0x0A8 | ||
25 | #define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 BIT(1) | ||
26 | |||
27 | #define PRCM_ARM_CHGCLKREQ 0x114 | ||
28 | #define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0) | ||
29 | |||
30 | #define PRCM_PLLARM_ENABLE 0x98 | ||
31 | #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE BIT(0) | ||
32 | #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON BIT(8) | ||
33 | |||
34 | #define PRCM_ARMCLKFIX_MGT 0x0 | ||
35 | #define PRCM_A9_RESETN_CLR 0x1f4 | ||
36 | #define PRCM_A9_RESETN_SET 0x1f0 | ||
37 | #define PRCM_ARM_LS_CLAMP 0x30C | ||
38 | #define PRCM_SRAM_A9 0x308 | ||
39 | |||
40 | /* ARM WFI Standby signal register */ | ||
41 | #define PRCM_ARM_WFI_STANDBY 0x130 | ||
42 | #define PRCM_IOCR 0x310 | ||
43 | #define PRCM_IOCR_IOFORCE BIT(0) | ||
44 | |||
45 | /* CPU mailbox registers */ | ||
46 | #define PRCM_MBOX_CPU_VAL 0x0FC | ||
47 | #define PRCM_MBOX_CPU_SET 0x100 | ||
48 | |||
49 | /* Dual A9 core interrupt management unit registers */ | ||
50 | #define PRCM_A9_MASK_REQ 0x328 | ||
51 | #define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ BIT(0) | ||
52 | |||
53 | #define PRCM_A9_MASK_ACK 0x32C | ||
54 | #define PRCM_ARMITMSK31TO0 0x11C | ||
55 | #define PRCM_ARMITMSK63TO32 0x120 | ||
56 | #define PRCM_ARMITMSK95TO64 0x124 | ||
57 | #define PRCM_ARMITMSK127TO96 0x128 | ||
58 | #define PRCM_POWER_STATE_VAL 0x25C | ||
59 | #define PRCM_ARMITVAL31TO0 0x260 | ||
60 | #define PRCM_ARMITVAL63TO32 0x264 | ||
61 | #define PRCM_ARMITVAL95TO64 0x268 | ||
62 | #define PRCM_ARMITVAL127TO96 0x26C | ||
63 | |||
64 | #define PRCM_HOSTACCESS_REQ 0x334 | ||
65 | #define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ BIT(0) | ||
66 | |||
67 | #define PRCM_ARM_IT1_CLR 0x48C | ||
68 | #define PRCM_ARM_IT1_VAL 0x494 | ||
69 | |||
70 | #define PRCM_ITSTATUS0 0x148 | ||
71 | #define PRCM_ITSTATUS1 0x150 | ||
72 | #define PRCM_ITSTATUS2 0x158 | ||
73 | #define PRCM_ITSTATUS3 0x160 | ||
74 | #define PRCM_ITSTATUS4 0x168 | ||
75 | #define PRCM_ITSTATUS5 0x484 | ||
76 | #define PRCM_ITCLEAR5 0x488 | ||
77 | #define PRCM_ARMIT_MASKXP70_IT 0x1018 | ||
78 | |||
79 | /* System reset register */ | ||
80 | #define PRCM_APE_SOFTRST 0x228 | ||
81 | |||
82 | /* Level shifter and clamp control registers */ | ||
83 | #define PRCM_MMIP_LS_CLAMP_SET 0x420 | ||
84 | #define PRCM_MMIP_LS_CLAMP_CLR 0x424 | ||
85 | |||
86 | /* PRCMU HW semaphore */ | ||
87 | #define PRCM_SEM 0x400 | ||
88 | #define PRCM_SEM_PRCM_SEM BIT(0) | ||
89 | |||
90 | /* PRCMU clock/PLL/reset registers */ | ||
91 | #define PRCM_PLLDSI_FREQ 0x500 | ||
92 | #define PRCM_PLLDSI_ENABLE 0x504 | ||
93 | #define PRCM_PLLDSI_LOCKP 0x508 | ||
94 | #define PRCM_DSI_PLLOUT_SEL 0x530 | ||
95 | #define PRCM_DSITVCLK_DIV 0x52C | ||
96 | #define PRCM_APE_RESETN_SET 0x1E4 | ||
97 | #define PRCM_APE_RESETN_CLR 0x1E8 | ||
98 | |||
99 | #define PRCM_TCR 0x1C8 | ||
100 | #define PRCM_TCR_TENSEL_MASK BITS(0, 7) | ||
101 | #define PRCM_TCR_STOP_TIMERS BIT(16) | ||
102 | #define PRCM_TCR_DOZE_MODE BIT(17) | ||
103 | |||
104 | #define PRCM_CLKOCR 0x1CC | ||
105 | #define PRCM_CLKOCR_CLKODIV0_SHIFT 0 | ||
106 | #define PRCM_CLKOCR_CLKODIV0_MASK BITS(0, 5) | ||
107 | #define PRCM_CLKOCR_CLKOSEL0_SHIFT 6 | ||
108 | #define PRCM_CLKOCR_CLKOSEL0_MASK BITS(6, 8) | ||
109 | #define PRCM_CLKOCR_CLKODIV1_SHIFT 16 | ||
110 | #define PRCM_CLKOCR_CLKODIV1_MASK BITS(16, 21) | ||
111 | #define PRCM_CLKOCR_CLKOSEL1_SHIFT 22 | ||
112 | #define PRCM_CLKOCR_CLKOSEL1_MASK BITS(22, 24) | ||
113 | #define PRCM_CLKOCR_CLK1TYPE BIT(28) | ||
114 | |||
115 | #define PRCM_SGACLK_MGT 0x014 | ||
116 | #define PRCM_UARTCLK_MGT 0x018 | ||
117 | #define PRCM_MSP02CLK_MGT 0x01C | ||
118 | #define PRCM_MSP1CLK_MGT 0x288 | ||
119 | #define PRCM_I2CCLK_MGT 0x020 | ||
120 | #define PRCM_SDMMCCLK_MGT 0x024 | ||
121 | #define PRCM_SLIMCLK_MGT 0x028 | ||
122 | #define PRCM_PER1CLK_MGT 0x02C | ||
123 | #define PRCM_PER2CLK_MGT 0x030 | ||
124 | #define PRCM_PER3CLK_MGT 0x034 | ||
125 | #define PRCM_PER5CLK_MGT 0x038 | ||
126 | #define PRCM_PER6CLK_MGT 0x03C | ||
127 | #define PRCM_PER7CLK_MGT 0x040 | ||
128 | #define PRCM_LCDCLK_MGT 0x044 | ||
129 | #define PRCM_BMLCLK_MGT 0x04C | ||
130 | #define PRCM_HSITXCLK_MGT 0x050 | ||
131 | #define PRCM_HSIRXCLK_MGT 0x054 | ||
132 | #define PRCM_HDMICLK_MGT 0x058 | ||
133 | #define PRCM_APEATCLK_MGT 0x05C | ||
134 | #define PRCM_APETRACECLK_MGT 0x060 | ||
135 | #define PRCM_MCDECLK_MGT 0x064 | ||
136 | #define PRCM_IPI2CCLK_MGT 0x068 | ||
137 | #define PRCM_DSIALTCLK_MGT 0x06C | ||
138 | #define PRCM_DMACLK_MGT 0x074 | ||
139 | #define PRCM_B2R2CLK_MGT 0x078 | ||
140 | #define PRCM_TVCLK_MGT 0x07C | ||
141 | #define PRCM_UNIPROCLK_MGT 0x278 | ||
142 | #define PRCM_SSPCLK_MGT 0x280 | ||
143 | #define PRCM_RNGCLK_MGT 0x284 | ||
144 | #define PRCM_UICCCLK_MGT 0x27C | ||
145 | |||
146 | #define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4) | ||
147 | #define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7) | ||
148 | #define PRCM_CLK_MGT_CLKEN BIT(8) | ||
149 | |||
150 | /* ePOD and memory power signal control registers */ | ||
151 | #define PRCM_EPOD_C_SET 0x410 | ||
152 | #define PRCM_SRAM_LS_SLEEP 0x304 | ||
153 | |||
154 | /* Debug power control unit registers */ | ||
155 | #define PRCM_POWER_STATE_SET 0x254 | ||
156 | |||
157 | /* Miscellaneous unit registers */ | ||
158 | #define PRCM_DSI_SW_RESET 0x324 | ||
159 | #define PRCM_GPIOCR 0x138 | ||
160 | |||
161 | /* GPIOCR register */ | ||
162 | #define PRCM_GPIOCR_SPI2_SELECT BIT(23) | ||
163 | |||
164 | #define PRCM_DDR_SUBSYS_APE_MINBW 0x438 | ||
165 | |||
166 | #endif /* __DB8500_PRCMU_REGS_H */ | ||
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 02a15d7cb3b0..a25ab9c6b5af 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -27,14 +27,14 @@ | |||
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/uaccess.h> | 28 | #include <linux/uaccess.h> |
29 | #include <linux/mfd/core.h> | 29 | #include <linux/mfd/core.h> |
30 | #include <linux/mfd/db8500-prcmu.h> | 30 | #include <linux/mfd/dbx500-prcmu.h> |
31 | #include <linux/regulator/db8500-prcmu.h> | 31 | #include <linux/regulator/db8500-prcmu.h> |
32 | #include <linux/regulator/machine.h> | 32 | #include <linux/regulator/machine.h> |
33 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
34 | #include <mach/irqs.h> | 34 | #include <mach/irqs.h> |
35 | #include <mach/db8500-regs.h> | 35 | #include <mach/db8500-regs.h> |
36 | #include <mach/id.h> | 36 | #include <mach/id.h> |
37 | #include "db8500-prcmu-regs.h" | 37 | #include "dbx500-prcmu-regs.h" |
38 | 38 | ||
39 | /* Offset for the firmware version within the TCPM */ | 39 | /* Offset for the firmware version within the TCPM */ |
40 | #define PRCMU_FW_VERSION_OFFSET 0xA4 | 40 | #define PRCMU_FW_VERSION_OFFSET 0xA4 |
@@ -131,12 +131,14 @@ | |||
131 | #define MB1H_REQUEST_APE_OPP_100_VOLT 0x3 | 131 | #define MB1H_REQUEST_APE_OPP_100_VOLT 0x3 |
132 | #define MB1H_RELEASE_APE_OPP_100_VOLT 0x4 | 132 | #define MB1H_RELEASE_APE_OPP_100_VOLT 0x4 |
133 | #define MB1H_RELEASE_USB_WAKEUP 0x5 | 133 | #define MB1H_RELEASE_USB_WAKEUP 0x5 |
134 | #define MB1H_PLL_ON_OFF 0x6 | ||
134 | 135 | ||
135 | /* Mailbox 1 Requests */ | 136 | /* Mailbox 1 Requests */ |
136 | #define PRCM_REQ_MB1_ARM_OPP (PRCM_REQ_MB1 + 0x0) | 137 | #define PRCM_REQ_MB1_ARM_OPP (PRCM_REQ_MB1 + 0x0) |
137 | #define PRCM_REQ_MB1_APE_OPP (PRCM_REQ_MB1 + 0x1) | 138 | #define PRCM_REQ_MB1_APE_OPP (PRCM_REQ_MB1 + 0x1) |
138 | #define PRCM_REQ_MB1_APE_OPP_100_RESTORE (PRCM_REQ_MB1 + 0x4) | 139 | #define PRCM_REQ_MB1_PLL_ON_OFF (PRCM_REQ_MB1 + 0x4) |
139 | #define PRCM_REQ_MB1_ARM_OPP_100_RESTORE (PRCM_REQ_MB1 + 0x8) | 140 | #define PLL_SOC1_OFF 0x4 |
141 | #define PLL_SOC1_ON 0x8 | ||
140 | 142 | ||
141 | /* Mailbox 1 ACKs */ | 143 | /* Mailbox 1 ACKs */ |
142 | #define PRCM_ACK_MB1_CURRENT_ARM_OPP (PRCM_ACK_MB1 + 0x0) | 144 | #define PRCM_ACK_MB1_CURRENT_ARM_OPP (PRCM_ACK_MB1 + 0x0) |
@@ -184,6 +186,11 @@ | |||
184 | #define MB4H_HOTDOG 0x12 | 186 | #define MB4H_HOTDOG 0x12 |
185 | #define MB4H_HOTMON 0x13 | 187 | #define MB4H_HOTMON 0x13 |
186 | #define MB4H_HOT_PERIOD 0x14 | 188 | #define MB4H_HOT_PERIOD 0x14 |
189 | #define MB4H_A9WDOG_CONF 0x16 | ||
190 | #define MB4H_A9WDOG_EN 0x17 | ||
191 | #define MB4H_A9WDOG_DIS 0x18 | ||
192 | #define MB4H_A9WDOG_LOAD 0x19 | ||
193 | #define MB4H_A9WDOG_KICK 0x20 | ||
187 | 194 | ||
188 | /* Mailbox 4 Requests */ | 195 | /* Mailbox 4 Requests */ |
189 | #define PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE (PRCM_REQ_MB4 + 0x0) | 196 | #define PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE (PRCM_REQ_MB4 + 0x0) |
@@ -196,6 +203,13 @@ | |||
196 | #define PRCM_REQ_MB4_HOT_PERIOD (PRCM_REQ_MB4 + 0x0) | 203 | #define PRCM_REQ_MB4_HOT_PERIOD (PRCM_REQ_MB4 + 0x0) |
197 | #define HOTMON_CONFIG_LOW BIT(0) | 204 | #define HOTMON_CONFIG_LOW BIT(0) |
198 | #define HOTMON_CONFIG_HIGH BIT(1) | 205 | #define HOTMON_CONFIG_HIGH BIT(1) |
206 | #define PRCM_REQ_MB4_A9WDOG_0 (PRCM_REQ_MB4 + 0x0) | ||
207 | #define PRCM_REQ_MB4_A9WDOG_1 (PRCM_REQ_MB4 + 0x1) | ||
208 | #define PRCM_REQ_MB4_A9WDOG_2 (PRCM_REQ_MB4 + 0x2) | ||
209 | #define PRCM_REQ_MB4_A9WDOG_3 (PRCM_REQ_MB4 + 0x3) | ||
210 | #define A9WDOG_AUTO_OFF_EN BIT(7) | ||
211 | #define A9WDOG_AUTO_OFF_DIS 0 | ||
212 | #define A9WDOG_ID_MASK 0xf | ||
199 | 213 | ||
200 | /* Mailbox 5 Requests */ | 214 | /* Mailbox 5 Requests */ |
201 | #define PRCM_REQ_MB5_I2C_SLAVE_OP (PRCM_REQ_MB5 + 0x0) | 215 | #define PRCM_REQ_MB5_I2C_SLAVE_OP (PRCM_REQ_MB5 + 0x0) |
@@ -412,7 +426,7 @@ struct clk_mgt { | |||
412 | 426 | ||
413 | static DEFINE_SPINLOCK(clk_mgt_lock); | 427 | static DEFINE_SPINLOCK(clk_mgt_lock); |
414 | 428 | ||
415 | #define CLK_MGT_ENTRY(_name)[PRCMU_##_name] = { (PRCM_##_name##_MGT), 0 } | 429 | #define CLK_MGT_ENTRY(_name)[PRCMU_##_name] = { (PRCM_##_name##_MGT_OFF), 0 } |
416 | struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = { | 430 | struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = { |
417 | CLK_MGT_ENTRY(SGACLK), | 431 | CLK_MGT_ENTRY(SGACLK), |
418 | CLK_MGT_ENTRY(UARTCLK), | 432 | CLK_MGT_ENTRY(UARTCLK), |
@@ -445,6 +459,35 @@ struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = { | |||
445 | CLK_MGT_ENTRY(UICCCLK), | 459 | CLK_MGT_ENTRY(UICCCLK), |
446 | }; | 460 | }; |
447 | 461 | ||
462 | static struct regulator *hwacc_regulator[NUM_HW_ACC]; | ||
463 | static struct regulator *hwacc_ret_regulator[NUM_HW_ACC]; | ||
464 | |||
465 | static bool hwacc_enabled[NUM_HW_ACC]; | ||
466 | static bool hwacc_ret_enabled[NUM_HW_ACC]; | ||
467 | |||
468 | static const char *hwacc_regulator_name[NUM_HW_ACC] = { | ||
469 | [HW_ACC_SVAMMDSP] = "hwacc-sva-mmdsp", | ||
470 | [HW_ACC_SVAPIPE] = "hwacc-sva-pipe", | ||
471 | [HW_ACC_SIAMMDSP] = "hwacc-sia-mmdsp", | ||
472 | [HW_ACC_SIAPIPE] = "hwacc-sia-pipe", | ||
473 | [HW_ACC_SGA] = "hwacc-sga", | ||
474 | [HW_ACC_B2R2] = "hwacc-b2r2", | ||
475 | [HW_ACC_MCDE] = "hwacc-mcde", | ||
476 | [HW_ACC_ESRAM1] = "hwacc-esram1", | ||
477 | [HW_ACC_ESRAM2] = "hwacc-esram2", | ||
478 | [HW_ACC_ESRAM3] = "hwacc-esram3", | ||
479 | [HW_ACC_ESRAM4] = "hwacc-esram4", | ||
480 | }; | ||
481 | |||
482 | static const char *hwacc_ret_regulator_name[NUM_HW_ACC] = { | ||
483 | [HW_ACC_SVAMMDSP] = "hwacc-sva-mmdsp-ret", | ||
484 | [HW_ACC_SIAMMDSP] = "hwacc-sia-mmdsp-ret", | ||
485 | [HW_ACC_ESRAM1] = "hwacc-esram1-ret", | ||
486 | [HW_ACC_ESRAM2] = "hwacc-esram2-ret", | ||
487 | [HW_ACC_ESRAM3] = "hwacc-esram3-ret", | ||
488 | [HW_ACC_ESRAM4] = "hwacc-esram4-ret", | ||
489 | }; | ||
490 | |||
448 | /* | 491 | /* |
449 | * Used by MCDE to setup all necessary PRCMU registers | 492 | * Used by MCDE to setup all necessary PRCMU registers |
450 | */ | 493 | */ |
@@ -493,55 +536,51 @@ static struct { | |||
493 | } prcmu_version; | 536 | } prcmu_version; |
494 | 537 | ||
495 | 538 | ||
496 | int prcmu_enable_dsipll(void) | 539 | int db8500_prcmu_enable_dsipll(void) |
497 | { | 540 | { |
498 | int i; | 541 | int i; |
499 | unsigned int plldsifreq; | 542 | unsigned int plldsifreq; |
500 | 543 | ||
501 | /* Clear DSIPLL_RESETN */ | 544 | /* Clear DSIPLL_RESETN */ |
502 | writel(PRCMU_RESET_DSIPLL, (_PRCMU_BASE + PRCM_APE_RESETN_CLR)); | 545 | writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR); |
503 | /* Unclamp DSIPLL in/out */ | 546 | /* Unclamp DSIPLL in/out */ |
504 | writel(PRCMU_UNCLAMP_DSIPLL, (_PRCMU_BASE + PRCM_MMIP_LS_CLAMP_CLR)); | 547 | writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR); |
505 | 548 | ||
506 | if (prcmu_is_u8400()) | 549 | if (prcmu_is_u8400()) |
507 | plldsifreq = PRCMU_PLLDSI_FREQ_SETTING_U8400; | 550 | plldsifreq = PRCMU_PLLDSI_FREQ_SETTING_U8400; |
508 | else | 551 | else |
509 | plldsifreq = PRCMU_PLLDSI_FREQ_SETTING; | 552 | plldsifreq = PRCMU_PLLDSI_FREQ_SETTING; |
510 | /* Set DSI PLL FREQ */ | 553 | /* Set DSI PLL FREQ */ |
511 | writel(plldsifreq, (_PRCMU_BASE + PRCM_PLLDSI_FREQ)); | 554 | writel(plldsifreq, PRCM_PLLDSI_FREQ); |
512 | writel(PRCMU_DSI_PLLOUT_SEL_SETTING, | 555 | writel(PRCMU_DSI_PLLOUT_SEL_SETTING, PRCM_DSI_PLLOUT_SEL); |
513 | (_PRCMU_BASE + PRCM_DSI_PLLOUT_SEL)); | ||
514 | /* Enable Escape clocks */ | 556 | /* Enable Escape clocks */ |
515 | writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, | 557 | writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); |
516 | (_PRCMU_BASE + PRCM_DSITVCLK_DIV)); | ||
517 | 558 | ||
518 | /* Start DSI PLL */ | 559 | /* Start DSI PLL */ |
519 | writel(PRCMU_ENABLE_PLLDSI, (_PRCMU_BASE + PRCM_PLLDSI_ENABLE)); | 560 | writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE); |
520 | /* Reset DSI PLL */ | 561 | /* Reset DSI PLL */ |
521 | writel(PRCMU_DSI_RESET_SW, (_PRCMU_BASE + PRCM_DSI_SW_RESET)); | 562 | writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET); |
522 | for (i = 0; i < 10; i++) { | 563 | for (i = 0; i < 10; i++) { |
523 | if ((readl(_PRCMU_BASE + PRCM_PLLDSI_LOCKP) & | 564 | if ((readl(PRCM_PLLDSI_LOCKP) & PRCMU_PLLDSI_LOCKP_LOCKED) |
524 | PRCMU_PLLDSI_LOCKP_LOCKED) | ||
525 | == PRCMU_PLLDSI_LOCKP_LOCKED) | 565 | == PRCMU_PLLDSI_LOCKP_LOCKED) |
526 | break; | 566 | break; |
527 | udelay(100); | 567 | udelay(100); |
528 | } | 568 | } |
529 | /* Set DSIPLL_RESETN */ | 569 | /* Set DSIPLL_RESETN */ |
530 | writel(PRCMU_RESET_DSIPLL, (_PRCMU_BASE + PRCM_APE_RESETN_SET)); | 570 | writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET); |
531 | return 0; | 571 | return 0; |
532 | } | 572 | } |
533 | 573 | ||
534 | int prcmu_disable_dsipll(void) | 574 | int db8500_prcmu_disable_dsipll(void) |
535 | { | 575 | { |
536 | /* Disable dsi pll */ | 576 | /* Disable dsi pll */ |
537 | writel(PRCMU_DISABLE_PLLDSI, (_PRCMU_BASE + PRCM_PLLDSI_ENABLE)); | 577 | writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE); |
538 | /* Disable escapeclock */ | 578 | /* Disable escapeclock */ |
539 | writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, | 579 | writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); |
540 | (_PRCMU_BASE + PRCM_DSITVCLK_DIV)); | ||
541 | return 0; | 580 | return 0; |
542 | } | 581 | } |
543 | 582 | ||
544 | int prcmu_set_display_clocks(void) | 583 | int db8500_prcmu_set_display_clocks(void) |
545 | { | 584 | { |
546 | unsigned long flags; | 585 | unsigned long flags; |
547 | unsigned int dsiclk; | 586 | unsigned int dsiclk; |
@@ -554,15 +593,15 @@ int prcmu_set_display_clocks(void) | |||
554 | spin_lock_irqsave(&clk_mgt_lock, flags); | 593 | spin_lock_irqsave(&clk_mgt_lock, flags); |
555 | 594 | ||
556 | /* Grab the HW semaphore. */ | 595 | /* Grab the HW semaphore. */ |
557 | while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) | 596 | while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) |
558 | cpu_relax(); | 597 | cpu_relax(); |
559 | 598 | ||
560 | writel(dsiclk, (_PRCMU_BASE + PRCM_HDMICLK_MGT)); | 599 | writel(dsiclk, PRCM_HDMICLK_MGT); |
561 | writel(PRCMU_DSI_LP_CLOCK_SETTING, (_PRCMU_BASE + PRCM_TVCLK_MGT)); | 600 | writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT); |
562 | writel(PRCMU_DPI_CLOCK_SETTING, (_PRCMU_BASE + PRCM_LCDCLK_MGT)); | 601 | writel(PRCMU_DPI_CLOCK_SETTING, PRCM_LCDCLK_MGT); |
563 | 602 | ||
564 | /* Release the HW semaphore. */ | 603 | /* Release the HW semaphore. */ |
565 | writel(0, (_PRCMU_BASE + PRCM_SEM)); | 604 | writel(0, PRCM_SEM); |
566 | 605 | ||
567 | spin_unlock_irqrestore(&clk_mgt_lock, flags); | 606 | spin_unlock_irqrestore(&clk_mgt_lock, flags); |
568 | 607 | ||
@@ -578,8 +617,8 @@ void prcmu_enable_spi2(void) | |||
578 | unsigned long flags; | 617 | unsigned long flags; |
579 | 618 | ||
580 | spin_lock_irqsave(&gpiocr_lock, flags); | 619 | spin_lock_irqsave(&gpiocr_lock, flags); |
581 | reg = readl(_PRCMU_BASE + PRCM_GPIOCR); | 620 | reg = readl(PRCM_GPIOCR); |
582 | writel(reg | PRCM_GPIOCR_SPI2_SELECT, _PRCMU_BASE + PRCM_GPIOCR); | 621 | writel(reg | PRCM_GPIOCR_SPI2_SELECT, PRCM_GPIOCR); |
583 | spin_unlock_irqrestore(&gpiocr_lock, flags); | 622 | spin_unlock_irqrestore(&gpiocr_lock, flags); |
584 | } | 623 | } |
585 | 624 | ||
@@ -592,8 +631,8 @@ void prcmu_disable_spi2(void) | |||
592 | unsigned long flags; | 631 | unsigned long flags; |
593 | 632 | ||
594 | spin_lock_irqsave(&gpiocr_lock, flags); | 633 | spin_lock_irqsave(&gpiocr_lock, flags); |
595 | reg = readl(_PRCMU_BASE + PRCM_GPIOCR); | 634 | reg = readl(PRCM_GPIOCR); |
596 | writel(reg & ~PRCM_GPIOCR_SPI2_SELECT, _PRCMU_BASE + PRCM_GPIOCR); | 635 | writel(reg & ~PRCM_GPIOCR_SPI2_SELECT, PRCM_GPIOCR); |
597 | spin_unlock_irqrestore(&gpiocr_lock, flags); | 636 | spin_unlock_irqrestore(&gpiocr_lock, flags); |
598 | } | 637 | } |
599 | 638 | ||
@@ -701,7 +740,7 @@ int prcmu_config_clkout(u8 clkout, u8 source, u8 div) | |||
701 | 740 | ||
702 | spin_lock_irqsave(&clkout_lock, flags); | 741 | spin_lock_irqsave(&clkout_lock, flags); |
703 | 742 | ||
704 | val = readl(_PRCMU_BASE + PRCM_CLKOCR); | 743 | val = readl(PRCM_CLKOCR); |
705 | if (val & div_mask) { | 744 | if (val & div_mask) { |
706 | if (div) { | 745 | if (div) { |
707 | if ((val & mask) != bits) { | 746 | if ((val & mask) != bits) { |
@@ -715,7 +754,7 @@ int prcmu_config_clkout(u8 clkout, u8 source, u8 div) | |||
715 | } | 754 | } |
716 | } | 755 | } |
717 | } | 756 | } |
718 | writel((bits | (val & ~mask)), (_PRCMU_BASE + PRCM_CLKOCR)); | 757 | writel((bits | (val & ~mask)), PRCM_CLKOCR); |
719 | requests[clkout] += (div ? 1 : -1); | 758 | requests[clkout] += (div ? 1 : -1); |
720 | 759 | ||
721 | unlock_and_return: | 760 | unlock_and_return: |
@@ -724,7 +763,7 @@ unlock_and_return: | |||
724 | return r; | 763 | return r; |
725 | } | 764 | } |
726 | 765 | ||
727 | int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) | 766 | int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) |
728 | { | 767 | { |
729 | unsigned long flags; | 768 | unsigned long flags; |
730 | 769 | ||
@@ -732,7 +771,7 @@ int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) | |||
732 | 771 | ||
733 | spin_lock_irqsave(&mb0_transfer.lock, flags); | 772 | spin_lock_irqsave(&mb0_transfer.lock, flags); |
734 | 773 | ||
735 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) | 774 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) |
736 | cpu_relax(); | 775 | cpu_relax(); |
737 | 776 | ||
738 | writeb(MB0H_POWER_STATE_TRANS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); | 777 | writeb(MB0H_POWER_STATE_TRANS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); |
@@ -741,7 +780,7 @@ int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) | |||
741 | writeb((keep_ulp_clk ? 1 : 0), | 780 | writeb((keep_ulp_clk ? 1 : 0), |
742 | (tcdm_base + PRCM_REQ_MB0_ULP_CLOCK_STATE)); | 781 | (tcdm_base + PRCM_REQ_MB0_ULP_CLOCK_STATE)); |
743 | writeb(0, (tcdm_base + PRCM_REQ_MB0_DO_NOT_WFI)); | 782 | writeb(0, (tcdm_base + PRCM_REQ_MB0_DO_NOT_WFI)); |
744 | writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 783 | writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); |
745 | 784 | ||
746 | spin_unlock_irqrestore(&mb0_transfer.lock, flags); | 785 | spin_unlock_irqrestore(&mb0_transfer.lock, flags); |
747 | 786 | ||
@@ -770,18 +809,18 @@ static void config_wakeups(void) | |||
770 | return; | 809 | return; |
771 | 810 | ||
772 | for (i = 0; i < 2; i++) { | 811 | for (i = 0; i < 2; i++) { |
773 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) | 812 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) |
774 | cpu_relax(); | 813 | cpu_relax(); |
775 | writel(dbb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_8500)); | 814 | writel(dbb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_8500)); |
776 | writel(abb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_4500)); | 815 | writel(abb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_4500)); |
777 | writeb(header[i], (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); | 816 | writeb(header[i], (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); |
778 | writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 817 | writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); |
779 | } | 818 | } |
780 | last_dbb_events = dbb_events; | 819 | last_dbb_events = dbb_events; |
781 | last_abb_events = abb_events; | 820 | last_abb_events = abb_events; |
782 | } | 821 | } |
783 | 822 | ||
784 | void prcmu_enable_wakeups(u32 wakeups) | 823 | void db8500_prcmu_enable_wakeups(u32 wakeups) |
785 | { | 824 | { |
786 | unsigned long flags; | 825 | unsigned long flags; |
787 | u32 bits; | 826 | u32 bits; |
@@ -802,7 +841,7 @@ void prcmu_enable_wakeups(u32 wakeups) | |||
802 | spin_unlock_irqrestore(&mb0_transfer.lock, flags); | 841 | spin_unlock_irqrestore(&mb0_transfer.lock, flags); |
803 | } | 842 | } |
804 | 843 | ||
805 | void prcmu_config_abb_event_readout(u32 abb_events) | 844 | void db8500_prcmu_config_abb_event_readout(u32 abb_events) |
806 | { | 845 | { |
807 | unsigned long flags; | 846 | unsigned long flags; |
808 | 847 | ||
@@ -814,7 +853,7 @@ void prcmu_config_abb_event_readout(u32 abb_events) | |||
814 | spin_unlock_irqrestore(&mb0_transfer.lock, flags); | 853 | spin_unlock_irqrestore(&mb0_transfer.lock, flags); |
815 | } | 854 | } |
816 | 855 | ||
817 | void prcmu_get_abb_event_buffer(void __iomem **buf) | 856 | void db8500_prcmu_get_abb_event_buffer(void __iomem **buf) |
818 | { | 857 | { |
819 | if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1) | 858 | if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1) |
820 | *buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_1_4500); | 859 | *buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_1_4500); |
@@ -823,13 +862,13 @@ void prcmu_get_abb_event_buffer(void __iomem **buf) | |||
823 | } | 862 | } |
824 | 863 | ||
825 | /** | 864 | /** |
826 | * prcmu_set_arm_opp - set the appropriate ARM OPP | 865 | * db8500_prcmu_set_arm_opp - set the appropriate ARM OPP |
827 | * @opp: The new ARM operating point to which transition is to be made | 866 | * @opp: The new ARM operating point to which transition is to be made |
828 | * Returns: 0 on success, non-zero on failure | 867 | * Returns: 0 on success, non-zero on failure |
829 | * | 868 | * |
830 | * This function sets the the operating point of the ARM. | 869 | * This function sets the the operating point of the ARM. |
831 | */ | 870 | */ |
832 | int prcmu_set_arm_opp(u8 opp) | 871 | int db8500_prcmu_set_arm_opp(u8 opp) |
833 | { | 872 | { |
834 | int r; | 873 | int r; |
835 | 874 | ||
@@ -840,14 +879,14 @@ int prcmu_set_arm_opp(u8 opp) | |||
840 | 879 | ||
841 | mutex_lock(&mb1_transfer.lock); | 880 | mutex_lock(&mb1_transfer.lock); |
842 | 881 | ||
843 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) | 882 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) |
844 | cpu_relax(); | 883 | cpu_relax(); |
845 | 884 | ||
846 | writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); | 885 | writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); |
847 | writeb(opp, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); | 886 | writeb(opp, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); |
848 | writeb(APE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_APE_OPP)); | 887 | writeb(APE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_APE_OPP)); |
849 | 888 | ||
850 | writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 889 | writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); |
851 | wait_for_completion(&mb1_transfer.work); | 890 | wait_for_completion(&mb1_transfer.work); |
852 | 891 | ||
853 | if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || | 892 | if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || |
@@ -860,11 +899,11 @@ int prcmu_set_arm_opp(u8 opp) | |||
860 | } | 899 | } |
861 | 900 | ||
862 | /** | 901 | /** |
863 | * prcmu_get_arm_opp - get the current ARM OPP | 902 | * db8500_prcmu_get_arm_opp - get the current ARM OPP |
864 | * | 903 | * |
865 | * Returns: the current ARM OPP | 904 | * Returns: the current ARM OPP |
866 | */ | 905 | */ |
867 | int prcmu_get_arm_opp(void) | 906 | int db8500_prcmu_get_arm_opp(void) |
868 | { | 907 | { |
869 | return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_ARM_OPP); | 908 | return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_ARM_OPP); |
870 | } | 909 | } |
@@ -876,7 +915,7 @@ int prcmu_get_arm_opp(void) | |||
876 | */ | 915 | */ |
877 | int prcmu_get_ddr_opp(void) | 916 | int prcmu_get_ddr_opp(void) |
878 | { | 917 | { |
879 | return readb(_PRCMU_BASE + PRCM_DDR_SUBSYS_APE_MINBW); | 918 | return readb(PRCM_DDR_SUBSYS_APE_MINBW); |
880 | } | 919 | } |
881 | 920 | ||
882 | /** | 921 | /** |
@@ -892,7 +931,7 @@ int prcmu_set_ddr_opp(u8 opp) | |||
892 | return -EINVAL; | 931 | return -EINVAL; |
893 | /* Changing the DDR OPP can hang the hardware pre-v21 */ | 932 | /* Changing the DDR OPP can hang the hardware pre-v21 */ |
894 | if (cpu_is_u8500v20_or_later() && !cpu_is_u8500v20()) | 933 | if (cpu_is_u8500v20_or_later() && !cpu_is_u8500v20()) |
895 | writeb(opp, (_PRCMU_BASE + PRCM_DDR_SUBSYS_APE_MINBW)); | 934 | writeb(opp, PRCM_DDR_SUBSYS_APE_MINBW); |
896 | 935 | ||
897 | return 0; | 936 | return 0; |
898 | } | 937 | } |
@@ -909,14 +948,14 @@ int prcmu_set_ape_opp(u8 opp) | |||
909 | 948 | ||
910 | mutex_lock(&mb1_transfer.lock); | 949 | mutex_lock(&mb1_transfer.lock); |
911 | 950 | ||
912 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) | 951 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) |
913 | cpu_relax(); | 952 | cpu_relax(); |
914 | 953 | ||
915 | writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); | 954 | writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); |
916 | writeb(ARM_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); | 955 | writeb(ARM_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); |
917 | writeb(opp, (tcdm_base + PRCM_REQ_MB1_APE_OPP)); | 956 | writeb(opp, (tcdm_base + PRCM_REQ_MB1_APE_OPP)); |
918 | 957 | ||
919 | writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 958 | writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); |
920 | wait_for_completion(&mb1_transfer.work); | 959 | wait_for_completion(&mb1_transfer.work); |
921 | 960 | ||
922 | if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || | 961 | if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || |
@@ -966,12 +1005,12 @@ int prcmu_request_ape_opp_100_voltage(bool enable) | |||
966 | header = MB1H_RELEASE_APE_OPP_100_VOLT; | 1005 | header = MB1H_RELEASE_APE_OPP_100_VOLT; |
967 | } | 1006 | } |
968 | 1007 | ||
969 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) | 1008 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) |
970 | cpu_relax(); | 1009 | cpu_relax(); |
971 | 1010 | ||
972 | writeb(header, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); | 1011 | writeb(header, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); |
973 | 1012 | ||
974 | writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1013 | writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); |
975 | wait_for_completion(&mb1_transfer.work); | 1014 | wait_for_completion(&mb1_transfer.work); |
976 | 1015 | ||
977 | if ((mb1_transfer.ack.header != header) || | 1016 | if ((mb1_transfer.ack.header != header) || |
@@ -995,13 +1034,13 @@ int prcmu_release_usb_wakeup_state(void) | |||
995 | 1034 | ||
996 | mutex_lock(&mb1_transfer.lock); | 1035 | mutex_lock(&mb1_transfer.lock); |
997 | 1036 | ||
998 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) | 1037 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) |
999 | cpu_relax(); | 1038 | cpu_relax(); |
1000 | 1039 | ||
1001 | writeb(MB1H_RELEASE_USB_WAKEUP, | 1040 | writeb(MB1H_RELEASE_USB_WAKEUP, |
1002 | (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); | 1041 | (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); |
1003 | 1042 | ||
1004 | writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1043 | writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); |
1005 | wait_for_completion(&mb1_transfer.work); | 1044 | wait_for_completion(&mb1_transfer.work); |
1006 | 1045 | ||
1007 | if ((mb1_transfer.ack.header != MB1H_RELEASE_USB_WAKEUP) || | 1046 | if ((mb1_transfer.ack.header != MB1H_RELEASE_USB_WAKEUP) || |
@@ -1013,15 +1052,169 @@ int prcmu_release_usb_wakeup_state(void) | |||
1013 | return r; | 1052 | return r; |
1014 | } | 1053 | } |
1015 | 1054 | ||
1055 | static int request_pll(u8 clock, bool enable) | ||
1056 | { | ||
1057 | int r = 0; | ||
1058 | |||
1059 | if (clock == PRCMU_PLLSOC1) | ||
1060 | clock = (enable ? PLL_SOC1_ON : PLL_SOC1_OFF); | ||
1061 | else | ||
1062 | return -EINVAL; | ||
1063 | |||
1064 | mutex_lock(&mb1_transfer.lock); | ||
1065 | |||
1066 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) | ||
1067 | cpu_relax(); | ||
1068 | |||
1069 | writeb(MB1H_PLL_ON_OFF, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); | ||
1070 | writeb(clock, (tcdm_base + PRCM_REQ_MB1_PLL_ON_OFF)); | ||
1071 | |||
1072 | writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); | ||
1073 | wait_for_completion(&mb1_transfer.work); | ||
1074 | |||
1075 | if (mb1_transfer.ack.header != MB1H_PLL_ON_OFF) | ||
1076 | r = -EIO; | ||
1077 | |||
1078 | mutex_unlock(&mb1_transfer.lock); | ||
1079 | |||
1080 | return r; | ||
1081 | } | ||
1082 | |||
1016 | /** | 1083 | /** |
1017 | * prcmu_set_epod - set the state of a EPOD (power domain) | 1084 | * prcmu_set_hwacc - set the power state of a h/w accelerator |
1085 | * @hwacc_dev: The hardware accelerator (enum hw_acc_dev). | ||
1086 | * @state: The new power state (enum hw_acc_state). | ||
1087 | * | ||
1088 | * This function sets the power state of a hardware accelerator. | ||
1089 | * This function should not be called from interrupt context. | ||
1090 | * | ||
1091 | * NOTE! Deprecated, to be removed when all users switched over to use the | ||
1092 | * regulator framework API. | ||
1093 | */ | ||
1094 | int prcmu_set_hwacc(u16 hwacc_dev, u8 state) | ||
1095 | { | ||
1096 | int r = 0; | ||
1097 | bool ram_retention = false; | ||
1098 | bool enable, enable_ret; | ||
1099 | |||
1100 | /* check argument */ | ||
1101 | BUG_ON(hwacc_dev >= NUM_HW_ACC); | ||
1102 | |||
1103 | /* get state of switches */ | ||
1104 | enable = hwacc_enabled[hwacc_dev]; | ||
1105 | enable_ret = hwacc_ret_enabled[hwacc_dev]; | ||
1106 | |||
1107 | /* set flag if retention is possible */ | ||
1108 | switch (hwacc_dev) { | ||
1109 | case HW_ACC_SVAMMDSP: | ||
1110 | case HW_ACC_SIAMMDSP: | ||
1111 | case HW_ACC_ESRAM1: | ||
1112 | case HW_ACC_ESRAM2: | ||
1113 | case HW_ACC_ESRAM3: | ||
1114 | case HW_ACC_ESRAM4: | ||
1115 | ram_retention = true; | ||
1116 | break; | ||
1117 | } | ||
1118 | |||
1119 | /* check argument */ | ||
1120 | BUG_ON(state > HW_ON); | ||
1121 | BUG_ON(state == HW_OFF_RAMRET && !ram_retention); | ||
1122 | |||
1123 | /* modify enable flags */ | ||
1124 | switch (state) { | ||
1125 | case HW_OFF: | ||
1126 | enable_ret = false; | ||
1127 | enable = false; | ||
1128 | break; | ||
1129 | case HW_ON: | ||
1130 | enable = true; | ||
1131 | break; | ||
1132 | case HW_OFF_RAMRET: | ||
1133 | enable_ret = true; | ||
1134 | enable = false; | ||
1135 | break; | ||
1136 | } | ||
1137 | |||
1138 | /* get regulator (lazy) */ | ||
1139 | if (hwacc_regulator[hwacc_dev] == NULL) { | ||
1140 | hwacc_regulator[hwacc_dev] = regulator_get(NULL, | ||
1141 | hwacc_regulator_name[hwacc_dev]); | ||
1142 | if (IS_ERR(hwacc_regulator[hwacc_dev])) { | ||
1143 | pr_err("prcmu: failed to get supply %s\n", | ||
1144 | hwacc_regulator_name[hwacc_dev]); | ||
1145 | r = PTR_ERR(hwacc_regulator[hwacc_dev]); | ||
1146 | goto out; | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | if (ram_retention) { | ||
1151 | if (hwacc_ret_regulator[hwacc_dev] == NULL) { | ||
1152 | hwacc_ret_regulator[hwacc_dev] = regulator_get(NULL, | ||
1153 | hwacc_ret_regulator_name[hwacc_dev]); | ||
1154 | if (IS_ERR(hwacc_ret_regulator[hwacc_dev])) { | ||
1155 | pr_err("prcmu: failed to get supply %s\n", | ||
1156 | hwacc_ret_regulator_name[hwacc_dev]); | ||
1157 | r = PTR_ERR(hwacc_ret_regulator[hwacc_dev]); | ||
1158 | goto out; | ||
1159 | } | ||
1160 | } | ||
1161 | } | ||
1162 | |||
1163 | /* set regulators */ | ||
1164 | if (ram_retention) { | ||
1165 | if (enable_ret && !hwacc_ret_enabled[hwacc_dev]) { | ||
1166 | r = regulator_enable(hwacc_ret_regulator[hwacc_dev]); | ||
1167 | if (r < 0) { | ||
1168 | pr_err("prcmu_set_hwacc: ret enable failed\n"); | ||
1169 | goto out; | ||
1170 | } | ||
1171 | hwacc_ret_enabled[hwacc_dev] = true; | ||
1172 | } | ||
1173 | } | ||
1174 | |||
1175 | if (enable && !hwacc_enabled[hwacc_dev]) { | ||
1176 | r = regulator_enable(hwacc_regulator[hwacc_dev]); | ||
1177 | if (r < 0) { | ||
1178 | pr_err("prcmu_set_hwacc: enable failed\n"); | ||
1179 | goto out; | ||
1180 | } | ||
1181 | hwacc_enabled[hwacc_dev] = true; | ||
1182 | } | ||
1183 | |||
1184 | if (!enable && hwacc_enabled[hwacc_dev]) { | ||
1185 | r = regulator_disable(hwacc_regulator[hwacc_dev]); | ||
1186 | if (r < 0) { | ||
1187 | pr_err("prcmu_set_hwacc: disable failed\n"); | ||
1188 | goto out; | ||
1189 | } | ||
1190 | hwacc_enabled[hwacc_dev] = false; | ||
1191 | } | ||
1192 | |||
1193 | if (ram_retention) { | ||
1194 | if (!enable_ret && hwacc_ret_enabled[hwacc_dev]) { | ||
1195 | r = regulator_disable(hwacc_ret_regulator[hwacc_dev]); | ||
1196 | if (r < 0) { | ||
1197 | pr_err("prcmu_set_hwacc: ret disable failed\n"); | ||
1198 | goto out; | ||
1199 | } | ||
1200 | hwacc_ret_enabled[hwacc_dev] = false; | ||
1201 | } | ||
1202 | } | ||
1203 | |||
1204 | out: | ||
1205 | return r; | ||
1206 | } | ||
1207 | EXPORT_SYMBOL(prcmu_set_hwacc); | ||
1208 | |||
1209 | /** | ||
1210 | * db8500_prcmu_set_epod - set the state of a EPOD (power domain) | ||
1018 | * @epod_id: The EPOD to set | 1211 | * @epod_id: The EPOD to set |
1019 | * @epod_state: The new EPOD state | 1212 | * @epod_state: The new EPOD state |
1020 | * | 1213 | * |
1021 | * This function sets the state of a EPOD (power domain). It may not be called | 1214 | * This function sets the state of a EPOD (power domain). It may not be called |
1022 | * from interrupt context. | 1215 | * from interrupt context. |
1023 | */ | 1216 | */ |
1024 | int prcmu_set_epod(u16 epod_id, u8 epod_state) | 1217 | int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state) |
1025 | { | 1218 | { |
1026 | int r = 0; | 1219 | int r = 0; |
1027 | bool ram_retention = false; | 1220 | bool ram_retention = false; |
@@ -1048,7 +1241,7 @@ int prcmu_set_epod(u16 epod_id, u8 epod_state) | |||
1048 | mutex_lock(&mb2_transfer.lock); | 1241 | mutex_lock(&mb2_transfer.lock); |
1049 | 1242 | ||
1050 | /* wait for mailbox */ | 1243 | /* wait for mailbox */ |
1051 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(2)) | 1244 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(2)) |
1052 | cpu_relax(); | 1245 | cpu_relax(); |
1053 | 1246 | ||
1054 | /* fill in mailbox */ | 1247 | /* fill in mailbox */ |
@@ -1058,7 +1251,7 @@ int prcmu_set_epod(u16 epod_id, u8 epod_state) | |||
1058 | 1251 | ||
1059 | writeb(MB2H_DPS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB2)); | 1252 | writeb(MB2H_DPS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB2)); |
1060 | 1253 | ||
1061 | writel(MBOX_BIT(2), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1254 | writel(MBOX_BIT(2), PRCM_MBOX_CPU_SET); |
1062 | 1255 | ||
1063 | /* | 1256 | /* |
1064 | * The current firmware version does not handle errors correctly, | 1257 | * The current firmware version does not handle errors correctly, |
@@ -1145,13 +1338,13 @@ static int request_sysclk(bool enable) | |||
1145 | 1338 | ||
1146 | spin_lock_irqsave(&mb3_transfer.lock, flags); | 1339 | spin_lock_irqsave(&mb3_transfer.lock, flags); |
1147 | 1340 | ||
1148 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(3)) | 1341 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(3)) |
1149 | cpu_relax(); | 1342 | cpu_relax(); |
1150 | 1343 | ||
1151 | writeb((enable ? ON : OFF), (tcdm_base + PRCM_REQ_MB3_SYSCLK_MGT)); | 1344 | writeb((enable ? ON : OFF), (tcdm_base + PRCM_REQ_MB3_SYSCLK_MGT)); |
1152 | 1345 | ||
1153 | writeb(MB3H_SYSCLK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB3)); | 1346 | writeb(MB3H_SYSCLK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB3)); |
1154 | writel(MBOX_BIT(3), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1347 | writel(MBOX_BIT(3), PRCM_MBOX_CPU_SET); |
1155 | 1348 | ||
1156 | spin_unlock_irqrestore(&mb3_transfer.lock, flags); | 1349 | spin_unlock_irqrestore(&mb3_transfer.lock, flags); |
1157 | 1350 | ||
@@ -1177,7 +1370,7 @@ static int request_timclk(bool enable) | |||
1177 | 1370 | ||
1178 | if (!enable) | 1371 | if (!enable) |
1179 | val |= PRCM_TCR_STOP_TIMERS; | 1372 | val |= PRCM_TCR_STOP_TIMERS; |
1180 | writel(val, (_PRCMU_BASE + PRCM_TCR)); | 1373 | writel(val, PRCM_TCR); |
1181 | 1374 | ||
1182 | return 0; | 1375 | return 0; |
1183 | } | 1376 | } |
@@ -1190,7 +1383,7 @@ static int request_reg_clock(u8 clock, bool enable) | |||
1190 | spin_lock_irqsave(&clk_mgt_lock, flags); | 1383 | spin_lock_irqsave(&clk_mgt_lock, flags); |
1191 | 1384 | ||
1192 | /* Grab the HW semaphore. */ | 1385 | /* Grab the HW semaphore. */ |
1193 | while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) | 1386 | while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) |
1194 | cpu_relax(); | 1387 | cpu_relax(); |
1195 | 1388 | ||
1196 | val = readl(_PRCMU_BASE + clk_mgt[clock].offset); | 1389 | val = readl(_PRCMU_BASE + clk_mgt[clock].offset); |
@@ -1203,34 +1396,61 @@ static int request_reg_clock(u8 clock, bool enable) | |||
1203 | writel(val, (_PRCMU_BASE + clk_mgt[clock].offset)); | 1396 | writel(val, (_PRCMU_BASE + clk_mgt[clock].offset)); |
1204 | 1397 | ||
1205 | /* Release the HW semaphore. */ | 1398 | /* Release the HW semaphore. */ |
1206 | writel(0, (_PRCMU_BASE + PRCM_SEM)); | 1399 | writel(0, PRCM_SEM); |
1207 | 1400 | ||
1208 | spin_unlock_irqrestore(&clk_mgt_lock, flags); | 1401 | spin_unlock_irqrestore(&clk_mgt_lock, flags); |
1209 | 1402 | ||
1210 | return 0; | 1403 | return 0; |
1211 | } | 1404 | } |
1212 | 1405 | ||
1406 | static int request_sga_clock(u8 clock, bool enable) | ||
1407 | { | ||
1408 | u32 val; | ||
1409 | int ret; | ||
1410 | |||
1411 | if (enable) { | ||
1412 | val = readl(PRCM_CGATING_BYPASS); | ||
1413 | writel(val | PRCM_CGATING_BYPASS_ICN2, PRCM_CGATING_BYPASS); | ||
1414 | } | ||
1415 | |||
1416 | ret = request_reg_clock(clock, enable); | ||
1417 | |||
1418 | if (!ret && !enable) { | ||
1419 | val = readl(PRCM_CGATING_BYPASS); | ||
1420 | writel(val & ~PRCM_CGATING_BYPASS_ICN2, PRCM_CGATING_BYPASS); | ||
1421 | } | ||
1422 | |||
1423 | return ret; | ||
1424 | } | ||
1425 | |||
1213 | /** | 1426 | /** |
1214 | * prcmu_request_clock() - Request for a clock to be enabled or disabled. | 1427 | * db8500_prcmu_request_clock() - Request for a clock to be enabled or disabled. |
1215 | * @clock: The clock for which the request is made. | 1428 | * @clock: The clock for which the request is made. |
1216 | * @enable: Whether the clock should be enabled (true) or disabled (false). | 1429 | * @enable: Whether the clock should be enabled (true) or disabled (false). |
1217 | * | 1430 | * |
1218 | * This function should only be used by the clock implementation. | 1431 | * This function should only be used by the clock implementation. |
1219 | * Do not use it from any other place! | 1432 | * Do not use it from any other place! |
1220 | */ | 1433 | */ |
1221 | int prcmu_request_clock(u8 clock, bool enable) | 1434 | int db8500_prcmu_request_clock(u8 clock, bool enable) |
1222 | { | 1435 | { |
1223 | if (clock < PRCMU_NUM_REG_CLOCKS) | 1436 | switch(clock) { |
1224 | return request_reg_clock(clock, enable); | 1437 | case PRCMU_SGACLK: |
1225 | else if (clock == PRCMU_TIMCLK) | 1438 | return request_sga_clock(clock, enable); |
1439 | case PRCMU_TIMCLK: | ||
1226 | return request_timclk(enable); | 1440 | return request_timclk(enable); |
1227 | else if (clock == PRCMU_SYSCLK) | 1441 | case PRCMU_SYSCLK: |
1228 | return request_sysclk(enable); | 1442 | return request_sysclk(enable); |
1229 | else | 1443 | case PRCMU_PLLSOC1: |
1230 | return -EINVAL; | 1444 | return request_pll(clock, enable); |
1445 | default: | ||
1446 | break; | ||
1447 | } | ||
1448 | if (clock < PRCMU_NUM_REG_CLOCKS) | ||
1449 | return request_reg_clock(clock, enable); | ||
1450 | return -EINVAL; | ||
1231 | } | 1451 | } |
1232 | 1452 | ||
1233 | int prcmu_config_esram0_deep_sleep(u8 state) | 1453 | int db8500_prcmu_config_esram0_deep_sleep(u8 state) |
1234 | { | 1454 | { |
1235 | if ((state > ESRAM0_DEEP_SLEEP_STATE_RET) || | 1455 | if ((state > ESRAM0_DEEP_SLEEP_STATE_RET) || |
1236 | (state < ESRAM0_DEEP_SLEEP_STATE_OFF)) | 1456 | (state < ESRAM0_DEEP_SLEEP_STATE_OFF)) |
@@ -1238,7 +1458,7 @@ int prcmu_config_esram0_deep_sleep(u8 state) | |||
1238 | 1458 | ||
1239 | mutex_lock(&mb4_transfer.lock); | 1459 | mutex_lock(&mb4_transfer.lock); |
1240 | 1460 | ||
1241 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) | 1461 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) |
1242 | cpu_relax(); | 1462 | cpu_relax(); |
1243 | 1463 | ||
1244 | writeb(MB4H_MEM_ST, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); | 1464 | writeb(MB4H_MEM_ST, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); |
@@ -1248,7 +1468,7 @@ int prcmu_config_esram0_deep_sleep(u8 state) | |||
1248 | (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE)); | 1468 | (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE)); |
1249 | writeb(state, (tcdm_base + PRCM_REQ_MB4_ESRAM0_ST)); | 1469 | writeb(state, (tcdm_base + PRCM_REQ_MB4_ESRAM0_ST)); |
1250 | 1470 | ||
1251 | writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1471 | writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); |
1252 | wait_for_completion(&mb4_transfer.work); | 1472 | wait_for_completion(&mb4_transfer.work); |
1253 | 1473 | ||
1254 | mutex_unlock(&mb4_transfer.lock); | 1474 | mutex_unlock(&mb4_transfer.lock); |
@@ -1260,13 +1480,13 @@ int prcmu_config_hotdog(u8 threshold) | |||
1260 | { | 1480 | { |
1261 | mutex_lock(&mb4_transfer.lock); | 1481 | mutex_lock(&mb4_transfer.lock); |
1262 | 1482 | ||
1263 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) | 1483 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) |
1264 | cpu_relax(); | 1484 | cpu_relax(); |
1265 | 1485 | ||
1266 | writeb(threshold, (tcdm_base + PRCM_REQ_MB4_HOTDOG_THRESHOLD)); | 1486 | writeb(threshold, (tcdm_base + PRCM_REQ_MB4_HOTDOG_THRESHOLD)); |
1267 | writeb(MB4H_HOTDOG, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); | 1487 | writeb(MB4H_HOTDOG, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); |
1268 | 1488 | ||
1269 | writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1489 | writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); |
1270 | wait_for_completion(&mb4_transfer.work); | 1490 | wait_for_completion(&mb4_transfer.work); |
1271 | 1491 | ||
1272 | mutex_unlock(&mb4_transfer.lock); | 1492 | mutex_unlock(&mb4_transfer.lock); |
@@ -1278,7 +1498,7 @@ int prcmu_config_hotmon(u8 low, u8 high) | |||
1278 | { | 1498 | { |
1279 | mutex_lock(&mb4_transfer.lock); | 1499 | mutex_lock(&mb4_transfer.lock); |
1280 | 1500 | ||
1281 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) | 1501 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) |
1282 | cpu_relax(); | 1502 | cpu_relax(); |
1283 | 1503 | ||
1284 | writeb(low, (tcdm_base + PRCM_REQ_MB4_HOTMON_LOW)); | 1504 | writeb(low, (tcdm_base + PRCM_REQ_MB4_HOTMON_LOW)); |
@@ -1287,7 +1507,7 @@ int prcmu_config_hotmon(u8 low, u8 high) | |||
1287 | (tcdm_base + PRCM_REQ_MB4_HOTMON_CONFIG)); | 1507 | (tcdm_base + PRCM_REQ_MB4_HOTMON_CONFIG)); |
1288 | writeb(MB4H_HOTMON, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); | 1508 | writeb(MB4H_HOTMON, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); |
1289 | 1509 | ||
1290 | writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1510 | writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); |
1291 | wait_for_completion(&mb4_transfer.work); | 1511 | wait_for_completion(&mb4_transfer.work); |
1292 | 1512 | ||
1293 | mutex_unlock(&mb4_transfer.lock); | 1513 | mutex_unlock(&mb4_transfer.lock); |
@@ -1299,13 +1519,13 @@ static int config_hot_period(u16 val) | |||
1299 | { | 1519 | { |
1300 | mutex_lock(&mb4_transfer.lock); | 1520 | mutex_lock(&mb4_transfer.lock); |
1301 | 1521 | ||
1302 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) | 1522 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) |
1303 | cpu_relax(); | 1523 | cpu_relax(); |
1304 | 1524 | ||
1305 | writew(val, (tcdm_base + PRCM_REQ_MB4_HOT_PERIOD)); | 1525 | writew(val, (tcdm_base + PRCM_REQ_MB4_HOT_PERIOD)); |
1306 | writeb(MB4H_HOT_PERIOD, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); | 1526 | writeb(MB4H_HOT_PERIOD, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); |
1307 | 1527 | ||
1308 | writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1528 | writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); |
1309 | wait_for_completion(&mb4_transfer.work); | 1529 | wait_for_completion(&mb4_transfer.work); |
1310 | 1530 | ||
1311 | mutex_unlock(&mb4_transfer.lock); | 1531 | mutex_unlock(&mb4_transfer.lock); |
@@ -1326,6 +1546,78 @@ int prcmu_stop_temp_sense(void) | |||
1326 | return config_hot_period(0xFFFF); | 1546 | return config_hot_period(0xFFFF); |
1327 | } | 1547 | } |
1328 | 1548 | ||
1549 | static int prcmu_a9wdog(u8 cmd, u8 d0, u8 d1, u8 d2, u8 d3) | ||
1550 | { | ||
1551 | |||
1552 | mutex_lock(&mb4_transfer.lock); | ||
1553 | |||
1554 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) | ||
1555 | cpu_relax(); | ||
1556 | |||
1557 | writeb(d0, (tcdm_base + PRCM_REQ_MB4_A9WDOG_0)); | ||
1558 | writeb(d1, (tcdm_base + PRCM_REQ_MB4_A9WDOG_1)); | ||
1559 | writeb(d2, (tcdm_base + PRCM_REQ_MB4_A9WDOG_2)); | ||
1560 | writeb(d3, (tcdm_base + PRCM_REQ_MB4_A9WDOG_3)); | ||
1561 | |||
1562 | writeb(cmd, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); | ||
1563 | |||
1564 | writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET); | ||
1565 | wait_for_completion(&mb4_transfer.work); | ||
1566 | |||
1567 | mutex_unlock(&mb4_transfer.lock); | ||
1568 | |||
1569 | return 0; | ||
1570 | |||
1571 | } | ||
1572 | |||
1573 | int prcmu_config_a9wdog(u8 num, bool sleep_auto_off) | ||
1574 | { | ||
1575 | BUG_ON(num == 0 || num > 0xf); | ||
1576 | return prcmu_a9wdog(MB4H_A9WDOG_CONF, num, 0, 0, | ||
1577 | sleep_auto_off ? A9WDOG_AUTO_OFF_EN : | ||
1578 | A9WDOG_AUTO_OFF_DIS); | ||
1579 | } | ||
1580 | |||
1581 | int prcmu_enable_a9wdog(u8 id) | ||
1582 | { | ||
1583 | return prcmu_a9wdog(MB4H_A9WDOG_EN, id, 0, 0, 0); | ||
1584 | } | ||
1585 | |||
1586 | int prcmu_disable_a9wdog(u8 id) | ||
1587 | { | ||
1588 | return prcmu_a9wdog(MB4H_A9WDOG_DIS, id, 0, 0, 0); | ||
1589 | } | ||
1590 | |||
1591 | int prcmu_kick_a9wdog(u8 id) | ||
1592 | { | ||
1593 | return prcmu_a9wdog(MB4H_A9WDOG_KICK, id, 0, 0, 0); | ||
1594 | } | ||
1595 | |||
1596 | /* | ||
1597 | * timeout is 28 bit, in ms. | ||
1598 | */ | ||
1599 | #define MAX_WATCHDOG_TIMEOUT 131000 | ||
1600 | int prcmu_load_a9wdog(u8 id, u32 timeout) | ||
1601 | { | ||
1602 | if (timeout > MAX_WATCHDOG_TIMEOUT) | ||
1603 | /* | ||
1604 | * Due to calculation bug in prcmu fw, timeouts | ||
1605 | * can't be bigger than 131 seconds. | ||
1606 | */ | ||
1607 | return -EINVAL; | ||
1608 | |||
1609 | return prcmu_a9wdog(MB4H_A9WDOG_LOAD, | ||
1610 | (id & A9WDOG_ID_MASK) | | ||
1611 | /* | ||
1612 | * Put the lowest 28 bits of timeout at | ||
1613 | * offset 4. Four first bits are used for id. | ||
1614 | */ | ||
1615 | (u8)((timeout << 4) & 0xf0), | ||
1616 | (u8)((timeout >> 4) & 0xff), | ||
1617 | (u8)((timeout >> 12) & 0xff), | ||
1618 | (u8)((timeout >> 20) & 0xff)); | ||
1619 | } | ||
1620 | |||
1329 | /** | 1621 | /** |
1330 | * prcmu_set_clock_divider() - Configure the clock divider. | 1622 | * prcmu_set_clock_divider() - Configure the clock divider. |
1331 | * @clock: The clock for which the request is made. | 1623 | * @clock: The clock for which the request is made. |
@@ -1345,7 +1637,7 @@ int prcmu_set_clock_divider(u8 clock, u8 divider) | |||
1345 | spin_lock_irqsave(&clk_mgt_lock, flags); | 1637 | spin_lock_irqsave(&clk_mgt_lock, flags); |
1346 | 1638 | ||
1347 | /* Grab the HW semaphore. */ | 1639 | /* Grab the HW semaphore. */ |
1348 | while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) | 1640 | while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) |
1349 | cpu_relax(); | 1641 | cpu_relax(); |
1350 | 1642 | ||
1351 | val = readl(_PRCMU_BASE + clk_mgt[clock].offset); | 1643 | val = readl(_PRCMU_BASE + clk_mgt[clock].offset); |
@@ -1354,7 +1646,7 @@ int prcmu_set_clock_divider(u8 clock, u8 divider) | |||
1354 | writel(val, (_PRCMU_BASE + clk_mgt[clock].offset)); | 1646 | writel(val, (_PRCMU_BASE + clk_mgt[clock].offset)); |
1355 | 1647 | ||
1356 | /* Release the HW semaphore. */ | 1648 | /* Release the HW semaphore. */ |
1357 | writel(0, (_PRCMU_BASE + PRCM_SEM)); | 1649 | writel(0, PRCM_SEM); |
1358 | 1650 | ||
1359 | spin_unlock_irqrestore(&clk_mgt_lock, flags); | 1651 | spin_unlock_irqrestore(&clk_mgt_lock, flags); |
1360 | 1652 | ||
@@ -1380,7 +1672,7 @@ int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) | |||
1380 | 1672 | ||
1381 | mutex_lock(&mb5_transfer.lock); | 1673 | mutex_lock(&mb5_transfer.lock); |
1382 | 1674 | ||
1383 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) | 1675 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) |
1384 | cpu_relax(); | 1676 | cpu_relax(); |
1385 | 1677 | ||
1386 | writeb(PRCMU_I2C_READ(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); | 1678 | writeb(PRCMU_I2C_READ(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); |
@@ -1388,7 +1680,7 @@ int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) | |||
1388 | writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); | 1680 | writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); |
1389 | writeb(0, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); | 1681 | writeb(0, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); |
1390 | 1682 | ||
1391 | writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1683 | writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); |
1392 | 1684 | ||
1393 | if (!wait_for_completion_timeout(&mb5_transfer.work, | 1685 | if (!wait_for_completion_timeout(&mb5_transfer.work, |
1394 | msecs_to_jiffies(20000))) { | 1686 | msecs_to_jiffies(20000))) { |
@@ -1426,7 +1718,7 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | |||
1426 | 1718 | ||
1427 | mutex_lock(&mb5_transfer.lock); | 1719 | mutex_lock(&mb5_transfer.lock); |
1428 | 1720 | ||
1429 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) | 1721 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) |
1430 | cpu_relax(); | 1722 | cpu_relax(); |
1431 | 1723 | ||
1432 | writeb(PRCMU_I2C_WRITE(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); | 1724 | writeb(PRCMU_I2C_WRITE(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); |
@@ -1434,7 +1726,7 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | |||
1434 | writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); | 1726 | writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); |
1435 | writeb(*value, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); | 1727 | writeb(*value, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); |
1436 | 1728 | ||
1437 | writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1729 | writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); |
1438 | 1730 | ||
1439 | if (!wait_for_completion_timeout(&mb5_transfer.work, | 1731 | if (!wait_for_completion_timeout(&mb5_transfer.work, |
1440 | msecs_to_jiffies(20000))) { | 1732 | msecs_to_jiffies(20000))) { |
@@ -1456,21 +1748,44 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | |||
1456 | void prcmu_ac_wake_req(void) | 1748 | void prcmu_ac_wake_req(void) |
1457 | { | 1749 | { |
1458 | u32 val; | 1750 | u32 val; |
1751 | u32 status; | ||
1459 | 1752 | ||
1460 | mutex_lock(&mb0_transfer.ac_wake_lock); | 1753 | mutex_lock(&mb0_transfer.ac_wake_lock); |
1461 | 1754 | ||
1462 | val = readl(_PRCMU_BASE + PRCM_HOSTACCESS_REQ); | 1755 | val = readl(PRCM_HOSTACCESS_REQ); |
1463 | if (val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ) | 1756 | if (val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ) |
1464 | goto unlock_and_return; | 1757 | goto unlock_and_return; |
1465 | 1758 | ||
1466 | atomic_set(&ac_wake_req_state, 1); | 1759 | atomic_set(&ac_wake_req_state, 1); |
1467 | 1760 | ||
1468 | writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), | 1761 | retry: |
1469 | (_PRCMU_BASE + PRCM_HOSTACCESS_REQ)); | 1762 | writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), PRCM_HOSTACCESS_REQ); |
1470 | 1763 | ||
1471 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, | 1764 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, |
1472 | msecs_to_jiffies(20000))) { | 1765 | msecs_to_jiffies(5000))) { |
1473 | pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", | 1766 | pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", |
1767 | __func__); | ||
1768 | goto unlock_and_return; | ||
1769 | } | ||
1770 | |||
1771 | /* | ||
1772 | * The modem can generate an AC_WAKE_ACK, and then still go to sleep. | ||
1773 | * As a workaround, we wait, and then check that the modem is indeed | ||
1774 | * awake (in terms of the value of the PRCM_MOD_AWAKE_STATUS | ||
1775 | * register, which may not be the whole truth). | ||
1776 | */ | ||
1777 | udelay(400); | ||
1778 | status = (readl(PRCM_MOD_AWAKE_STATUS) & BITS(0, 2)); | ||
1779 | if (status != (PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE | | ||
1780 | PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE)) { | ||
1781 | pr_err("prcmu: %s received ack, but modem not awake (0x%X).\n", | ||
1782 | __func__, status); | ||
1783 | udelay(1200); | ||
1784 | writel(val, PRCM_HOSTACCESS_REQ); | ||
1785 | if (wait_for_completion_timeout(&mb0_transfer.ac_wake_work, | ||
1786 | msecs_to_jiffies(5000))) | ||
1787 | goto retry; | ||
1788 | pr_crit("prcmu: %s timed out (5 s) waiting for AC_SLEEP_ACK.\n", | ||
1474 | __func__); | 1789 | __func__); |
1475 | } | 1790 | } |
1476 | 1791 | ||
@@ -1487,16 +1802,16 @@ void prcmu_ac_sleep_req() | |||
1487 | 1802 | ||
1488 | mutex_lock(&mb0_transfer.ac_wake_lock); | 1803 | mutex_lock(&mb0_transfer.ac_wake_lock); |
1489 | 1804 | ||
1490 | val = readl(_PRCMU_BASE + PRCM_HOSTACCESS_REQ); | 1805 | val = readl(PRCM_HOSTACCESS_REQ); |
1491 | if (!(val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ)) | 1806 | if (!(val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ)) |
1492 | goto unlock_and_return; | 1807 | goto unlock_and_return; |
1493 | 1808 | ||
1494 | writel((val & ~PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), | 1809 | writel((val & ~PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), |
1495 | (_PRCMU_BASE + PRCM_HOSTACCESS_REQ)); | 1810 | PRCM_HOSTACCESS_REQ); |
1496 | 1811 | ||
1497 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, | 1812 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, |
1498 | msecs_to_jiffies(20000))) { | 1813 | msecs_to_jiffies(5000))) { |
1499 | pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", | 1814 | pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", |
1500 | __func__); | 1815 | __func__); |
1501 | } | 1816 | } |
1502 | 1817 | ||
@@ -1506,21 +1821,32 @@ unlock_and_return: | |||
1506 | mutex_unlock(&mb0_transfer.ac_wake_lock); | 1821 | mutex_unlock(&mb0_transfer.ac_wake_lock); |
1507 | } | 1822 | } |
1508 | 1823 | ||
1509 | bool prcmu_is_ac_wake_requested(void) | 1824 | bool db8500_prcmu_is_ac_wake_requested(void) |
1510 | { | 1825 | { |
1511 | return (atomic_read(&ac_wake_req_state) != 0); | 1826 | return (atomic_read(&ac_wake_req_state) != 0); |
1512 | } | 1827 | } |
1513 | 1828 | ||
1514 | /** | 1829 | /** |
1515 | * prcmu_system_reset - System reset | 1830 | * db8500_prcmu_system_reset - System reset |
1516 | * | 1831 | * |
1517 | * Saves the reset reason code and then sets the APE_SOFRST register which | 1832 | * Saves the reset reason code and then sets the APE_SOFTRST register which |
1518 | * fires interrupt to fw | 1833 | * fires interrupt to fw |
1519 | */ | 1834 | */ |
1520 | void prcmu_system_reset(u16 reset_code) | 1835 | void db8500_prcmu_system_reset(u16 reset_code) |
1521 | { | 1836 | { |
1522 | writew(reset_code, (tcdm_base + PRCM_SW_RST_REASON)); | 1837 | writew(reset_code, (tcdm_base + PRCM_SW_RST_REASON)); |
1523 | writel(1, (_PRCMU_BASE + PRCM_APE_SOFTRST)); | 1838 | writel(1, PRCM_APE_SOFTRST); |
1839 | } | ||
1840 | |||
1841 | /** | ||
1842 | * db8500_prcmu_get_reset_code - Retrieve SW reset reason code | ||
1843 | * | ||
1844 | * Retrieves the reset reason code stored by prcmu_system_reset() before | ||
1845 | * last restart. | ||
1846 | */ | ||
1847 | u16 db8500_prcmu_get_reset_code(void) | ||
1848 | { | ||
1849 | return readw(tcdm_base + PRCM_SW_RST_REASON); | ||
1524 | } | 1850 | } |
1525 | 1851 | ||
1526 | /** | 1852 | /** |
@@ -1530,11 +1856,11 @@ void prcmu_modem_reset(void) | |||
1530 | { | 1856 | { |
1531 | mutex_lock(&mb1_transfer.lock); | 1857 | mutex_lock(&mb1_transfer.lock); |
1532 | 1858 | ||
1533 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) | 1859 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) |
1534 | cpu_relax(); | 1860 | cpu_relax(); |
1535 | 1861 | ||
1536 | writeb(MB1H_RESET_MODEM, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); | 1862 | writeb(MB1H_RESET_MODEM, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); |
1537 | writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1863 | writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); |
1538 | wait_for_completion(&mb1_transfer.work); | 1864 | wait_for_completion(&mb1_transfer.work); |
1539 | 1865 | ||
1540 | /* | 1866 | /* |
@@ -1551,11 +1877,11 @@ static void ack_dbb_wakeup(void) | |||
1551 | 1877 | ||
1552 | spin_lock_irqsave(&mb0_transfer.lock, flags); | 1878 | spin_lock_irqsave(&mb0_transfer.lock, flags); |
1553 | 1879 | ||
1554 | while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) | 1880 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) |
1555 | cpu_relax(); | 1881 | cpu_relax(); |
1556 | 1882 | ||
1557 | writeb(MB0H_READ_WAKEUP_ACK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); | 1883 | writeb(MB0H_READ_WAKEUP_ACK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); |
1558 | writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); | 1884 | writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); |
1559 | 1885 | ||
1560 | spin_unlock_irqrestore(&mb0_transfer.lock, flags); | 1886 | spin_unlock_irqrestore(&mb0_transfer.lock, flags); |
1561 | } | 1887 | } |
@@ -1600,7 +1926,7 @@ static bool read_mailbox_0(void) | |||
1600 | r = false; | 1926 | r = false; |
1601 | break; | 1927 | break; |
1602 | } | 1928 | } |
1603 | writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); | 1929 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLR); |
1604 | return r; | 1930 | return r; |
1605 | } | 1931 | } |
1606 | 1932 | ||
@@ -1613,7 +1939,7 @@ static bool read_mailbox_1(void) | |||
1613 | PRCM_ACK_MB1_CURRENT_APE_OPP); | 1939 | PRCM_ACK_MB1_CURRENT_APE_OPP); |
1614 | mb1_transfer.ack.ape_voltage_status = readb(tcdm_base + | 1940 | mb1_transfer.ack.ape_voltage_status = readb(tcdm_base + |
1615 | PRCM_ACK_MB1_APE_VOLTAGE_STATUS); | 1941 | PRCM_ACK_MB1_APE_VOLTAGE_STATUS); |
1616 | writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); | 1942 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLR); |
1617 | complete(&mb1_transfer.work); | 1943 | complete(&mb1_transfer.work); |
1618 | return false; | 1944 | return false; |
1619 | } | 1945 | } |
@@ -1621,14 +1947,14 @@ static bool read_mailbox_1(void) | |||
1621 | static bool read_mailbox_2(void) | 1947 | static bool read_mailbox_2(void) |
1622 | { | 1948 | { |
1623 | mb2_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB2_DPS_STATUS); | 1949 | mb2_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB2_DPS_STATUS); |
1624 | writel(MBOX_BIT(2), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); | 1950 | writel(MBOX_BIT(2), PRCM_ARM_IT1_CLR); |
1625 | complete(&mb2_transfer.work); | 1951 | complete(&mb2_transfer.work); |
1626 | return false; | 1952 | return false; |
1627 | } | 1953 | } |
1628 | 1954 | ||
1629 | static bool read_mailbox_3(void) | 1955 | static bool read_mailbox_3(void) |
1630 | { | 1956 | { |
1631 | writel(MBOX_BIT(3), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); | 1957 | writel(MBOX_BIT(3), PRCM_ARM_IT1_CLR); |
1632 | return false; | 1958 | return false; |
1633 | } | 1959 | } |
1634 | 1960 | ||
@@ -1643,6 +1969,11 @@ static bool read_mailbox_4(void) | |||
1643 | case MB4H_HOTDOG: | 1969 | case MB4H_HOTDOG: |
1644 | case MB4H_HOTMON: | 1970 | case MB4H_HOTMON: |
1645 | case MB4H_HOT_PERIOD: | 1971 | case MB4H_HOT_PERIOD: |
1972 | case MB4H_A9WDOG_CONF: | ||
1973 | case MB4H_A9WDOG_EN: | ||
1974 | case MB4H_A9WDOG_DIS: | ||
1975 | case MB4H_A9WDOG_LOAD: | ||
1976 | case MB4H_A9WDOG_KICK: | ||
1646 | break; | 1977 | break; |
1647 | default: | 1978 | default: |
1648 | print_unknown_header_warning(4, header); | 1979 | print_unknown_header_warning(4, header); |
@@ -1650,7 +1981,7 @@ static bool read_mailbox_4(void) | |||
1650 | break; | 1981 | break; |
1651 | } | 1982 | } |
1652 | 1983 | ||
1653 | writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); | 1984 | writel(MBOX_BIT(4), PRCM_ARM_IT1_CLR); |
1654 | 1985 | ||
1655 | if (do_complete) | 1986 | if (do_complete) |
1656 | complete(&mb4_transfer.work); | 1987 | complete(&mb4_transfer.work); |
@@ -1662,20 +1993,20 @@ static bool read_mailbox_5(void) | |||
1662 | { | 1993 | { |
1663 | mb5_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB5_I2C_STATUS); | 1994 | mb5_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB5_I2C_STATUS); |
1664 | mb5_transfer.ack.value = readb(tcdm_base + PRCM_ACK_MB5_I2C_VAL); | 1995 | mb5_transfer.ack.value = readb(tcdm_base + PRCM_ACK_MB5_I2C_VAL); |
1665 | writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); | 1996 | writel(MBOX_BIT(5), PRCM_ARM_IT1_CLR); |
1666 | complete(&mb5_transfer.work); | 1997 | complete(&mb5_transfer.work); |
1667 | return false; | 1998 | return false; |
1668 | } | 1999 | } |
1669 | 2000 | ||
1670 | static bool read_mailbox_6(void) | 2001 | static bool read_mailbox_6(void) |
1671 | { | 2002 | { |
1672 | writel(MBOX_BIT(6), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); | 2003 | writel(MBOX_BIT(6), PRCM_ARM_IT1_CLR); |
1673 | return false; | 2004 | return false; |
1674 | } | 2005 | } |
1675 | 2006 | ||
1676 | static bool read_mailbox_7(void) | 2007 | static bool read_mailbox_7(void) |
1677 | { | 2008 | { |
1678 | writel(MBOX_BIT(7), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); | 2009 | writel(MBOX_BIT(7), PRCM_ARM_IT1_CLR); |
1679 | return false; | 2010 | return false; |
1680 | } | 2011 | } |
1681 | 2012 | ||
@@ -1696,7 +2027,7 @@ static irqreturn_t prcmu_irq_handler(int irq, void *data) | |||
1696 | u8 n; | 2027 | u8 n; |
1697 | irqreturn_t r; | 2028 | irqreturn_t r; |
1698 | 2029 | ||
1699 | bits = (readl(_PRCMU_BASE + PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); | 2030 | bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); |
1700 | if (unlikely(!bits)) | 2031 | if (unlikely(!bits)) |
1701 | return IRQ_NONE; | 2032 | return IRQ_NONE; |
1702 | 2033 | ||
@@ -1768,7 +2099,7 @@ static struct irq_chip prcmu_irq_chip = { | |||
1768 | .irq_unmask = prcmu_irq_unmask, | 2099 | .irq_unmask = prcmu_irq_unmask, |
1769 | }; | 2100 | }; |
1770 | 2101 | ||
1771 | void __init prcmu_early_init(void) | 2102 | void __init db8500_prcmu_early_init(void) |
1772 | { | 2103 | { |
1773 | unsigned int i; | 2104 | unsigned int i; |
1774 | 2105 | ||
@@ -1826,6 +2157,16 @@ void __init prcmu_early_init(void) | |||
1826 | } | 2157 | } |
1827 | } | 2158 | } |
1828 | 2159 | ||
2160 | static void __init db8500_prcmu_init_clkforce(void) | ||
2161 | { | ||
2162 | u32 val; | ||
2163 | |||
2164 | val = readl(PRCM_A9PL_FORCE_CLKEN); | ||
2165 | val &= ~(PRCM_A9PL_FORCE_CLKEN_PRCM_A9PL_FORCE_CLKEN | | ||
2166 | PRCM_A9PL_FORCE_CLKEN_PRCM_A9AXI_FORCE_CLKEN); | ||
2167 | writel(val, (PRCM_A9PL_FORCE_CLKEN)); | ||
2168 | } | ||
2169 | |||
1829 | /* | 2170 | /* |
1830 | * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC | 2171 | * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC |
1831 | */ | 2172 | */ |
@@ -1861,7 +2202,42 @@ static struct regulator_consumer_supply db8500_vsmps2_consumers[] = { | |||
1861 | 2202 | ||
1862 | static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = { | 2203 | static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = { |
1863 | REGULATOR_SUPPLY("vsupply", "b2r2.0"), | 2204 | REGULATOR_SUPPLY("vsupply", "b2r2.0"), |
1864 | REGULATOR_SUPPLY("vsupply", "mcde.0"), | 2205 | REGULATOR_SUPPLY("vsupply", "mcde"), |
2206 | }; | ||
2207 | |||
2208 | /* SVA MMDSP regulator switch */ | ||
2209 | static struct regulator_consumer_supply db8500_svammdsp_consumers[] = { | ||
2210 | REGULATOR_SUPPLY("sva-mmdsp", "cm_control"), | ||
2211 | }; | ||
2212 | |||
2213 | /* SVA pipe regulator switch */ | ||
2214 | static struct regulator_consumer_supply db8500_svapipe_consumers[] = { | ||
2215 | REGULATOR_SUPPLY("sva-pipe", "cm_control"), | ||
2216 | }; | ||
2217 | |||
2218 | /* SIA MMDSP regulator switch */ | ||
2219 | static struct regulator_consumer_supply db8500_siammdsp_consumers[] = { | ||
2220 | REGULATOR_SUPPLY("sia-mmdsp", "cm_control"), | ||
2221 | }; | ||
2222 | |||
2223 | /* SIA pipe regulator switch */ | ||
2224 | static struct regulator_consumer_supply db8500_siapipe_consumers[] = { | ||
2225 | REGULATOR_SUPPLY("sia-pipe", "cm_control"), | ||
2226 | }; | ||
2227 | |||
2228 | static struct regulator_consumer_supply db8500_sga_consumers[] = { | ||
2229 | REGULATOR_SUPPLY("v-mali", NULL), | ||
2230 | }; | ||
2231 | |||
2232 | /* ESRAM1 and 2 regulator switch */ | ||
2233 | static struct regulator_consumer_supply db8500_esram12_consumers[] = { | ||
2234 | REGULATOR_SUPPLY("esram12", "cm_control"), | ||
2235 | }; | ||
2236 | |||
2237 | /* ESRAM3 and 4 regulator switch */ | ||
2238 | static struct regulator_consumer_supply db8500_esram34_consumers[] = { | ||
2239 | REGULATOR_SUPPLY("v-esram34", "mcde"), | ||
2240 | REGULATOR_SUPPLY("esram34", "cm_control"), | ||
1865 | }; | 2241 | }; |
1866 | 2242 | ||
1867 | static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | 2243 | static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { |
@@ -1923,6 +2299,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
1923 | .name = "db8500-sva-mmdsp", | 2299 | .name = "db8500-sva-mmdsp", |
1924 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 2300 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
1925 | }, | 2301 | }, |
2302 | .consumer_supplies = db8500_svammdsp_consumers, | ||
2303 | .num_consumer_supplies = ARRAY_SIZE(db8500_svammdsp_consumers), | ||
1926 | }, | 2304 | }, |
1927 | [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { | 2305 | [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { |
1928 | .constraints = { | 2306 | .constraints = { |
@@ -1937,6 +2315,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
1937 | .name = "db8500-sva-pipe", | 2315 | .name = "db8500-sva-pipe", |
1938 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 2316 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
1939 | }, | 2317 | }, |
2318 | .consumer_supplies = db8500_svapipe_consumers, | ||
2319 | .num_consumer_supplies = ARRAY_SIZE(db8500_svapipe_consumers), | ||
1940 | }, | 2320 | }, |
1941 | [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { | 2321 | [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { |
1942 | .supply_regulator = "db8500-vape", | 2322 | .supply_regulator = "db8500-vape", |
@@ -1944,6 +2324,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
1944 | .name = "db8500-sia-mmdsp", | 2324 | .name = "db8500-sia-mmdsp", |
1945 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 2325 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
1946 | }, | 2326 | }, |
2327 | .consumer_supplies = db8500_siammdsp_consumers, | ||
2328 | .num_consumer_supplies = ARRAY_SIZE(db8500_siammdsp_consumers), | ||
1947 | }, | 2329 | }, |
1948 | [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { | 2330 | [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { |
1949 | .constraints = { | 2331 | .constraints = { |
@@ -1957,6 +2339,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
1957 | .name = "db8500-sia-pipe", | 2339 | .name = "db8500-sia-pipe", |
1958 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 2340 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
1959 | }, | 2341 | }, |
2342 | .consumer_supplies = db8500_siapipe_consumers, | ||
2343 | .num_consumer_supplies = ARRAY_SIZE(db8500_siapipe_consumers), | ||
1960 | }, | 2344 | }, |
1961 | [DB8500_REGULATOR_SWITCH_SGA] = { | 2345 | [DB8500_REGULATOR_SWITCH_SGA] = { |
1962 | .supply_regulator = "db8500-vape", | 2346 | .supply_regulator = "db8500-vape", |
@@ -1964,6 +2348,9 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
1964 | .name = "db8500-sga", | 2348 | .name = "db8500-sga", |
1965 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 2349 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
1966 | }, | 2350 | }, |
2351 | .consumer_supplies = db8500_sga_consumers, | ||
2352 | .num_consumer_supplies = ARRAY_SIZE(db8500_sga_consumers), | ||
2353 | |||
1967 | }, | 2354 | }, |
1968 | [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { | 2355 | [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { |
1969 | .supply_regulator = "db8500-vape", | 2356 | .supply_regulator = "db8500-vape", |
@@ -1980,6 +2367,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
1980 | .name = "db8500-esram12", | 2367 | .name = "db8500-esram12", |
1981 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 2368 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
1982 | }, | 2369 | }, |
2370 | .consumer_supplies = db8500_esram12_consumers, | ||
2371 | .num_consumer_supplies = ARRAY_SIZE(db8500_esram12_consumers), | ||
1983 | }, | 2372 | }, |
1984 | [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { | 2373 | [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { |
1985 | .constraints = { | 2374 | .constraints = { |
@@ -1993,6 +2382,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
1993 | .name = "db8500-esram34", | 2382 | .name = "db8500-esram34", |
1994 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 2383 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
1995 | }, | 2384 | }, |
2385 | .consumer_supplies = db8500_esram34_consumers, | ||
2386 | .num_consumer_supplies = ARRAY_SIZE(db8500_esram34_consumers), | ||
1996 | }, | 2387 | }, |
1997 | [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { | 2388 | [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { |
1998 | .constraints = { | 2389 | .constraints = { |
@@ -2024,8 +2415,10 @@ static int __init db8500_prcmu_probe(struct platform_device *pdev) | |||
2024 | if (ux500_is_svp()) | 2415 | if (ux500_is_svp()) |
2025 | return -ENODEV; | 2416 | return -ENODEV; |
2026 | 2417 | ||
2418 | db8500_prcmu_init_clkforce(); | ||
2419 | |||
2027 | /* Clean up the mailbox interrupts after pre-kernel code. */ | 2420 | /* Clean up the mailbox interrupts after pre-kernel code. */ |
2028 | writel(ALL_MBOX_BITS, (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); | 2421 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); |
2029 | 2422 | ||
2030 | err = request_threaded_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, | 2423 | err = request_threaded_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, |
2031 | prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); | 2424 | prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); |
diff --git a/drivers/mfd/db5500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h index 9a8e9e4ddd33..ec22e9f15d32 100644 --- a/drivers/mfd/db5500-prcmu-regs.h +++ b/drivers/mfd/dbx500-prcmu-regs.h | |||
@@ -10,11 +10,49 @@ | |||
10 | * PRCM Unit registers | 10 | * PRCM Unit registers |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef __MACH_PRCMU_REGS_H | 13 | #ifndef __DB8500_PRCMU_REGS_H |
14 | #define __MACH_PRCMU_REGS_H | 14 | #define __DB8500_PRCMU_REGS_H |
15 | 15 | ||
16 | #include <mach/hardware.h> | 16 | #include <mach/hardware.h> |
17 | 17 | ||
18 | #define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end)) | ||
19 | |||
20 | #define PRCM_SVACLK_MGT_OFF 0x008 | ||
21 | #define PRCM_SIACLK_MGT_OFF 0x00C | ||
22 | #define PRCM_SGACLK_MGT_OFF 0x014 | ||
23 | #define PRCM_UARTCLK_MGT_OFF 0x018 | ||
24 | #define PRCM_MSP02CLK_MGT_OFF 0x01C | ||
25 | #define PRCM_I2CCLK_MGT_OFF 0x020 | ||
26 | #define PRCM_SDMMCCLK_MGT_OFF 0x024 | ||
27 | #define PRCM_SLIMCLK_MGT_OFF 0x028 | ||
28 | #define PRCM_PER1CLK_MGT_OFF 0x02C | ||
29 | #define PRCM_PER2CLK_MGT_OFF 0x030 | ||
30 | #define PRCM_PER3CLK_MGT_OFF 0x034 | ||
31 | #define PRCM_PER5CLK_MGT_OFF 0x038 | ||
32 | #define PRCM_PER6CLK_MGT_OFF 0x03C | ||
33 | #define PRCM_PER7CLK_MGT_OFF 0x040 | ||
34 | #define PRCM_PWMCLK_MGT_OFF 0x044 /* for DB5500 */ | ||
35 | #define PRCM_IRDACLK_MGT_OFF 0x048 /* for DB5500 */ | ||
36 | #define PRCM_IRRCCLK_MGT_OFF 0x04C /* for DB5500 */ | ||
37 | #define PRCM_LCDCLK_MGT_OFF 0x044 | ||
38 | #define PRCM_BMLCLK_MGT_OFF 0x04C | ||
39 | #define PRCM_HSITXCLK_MGT_OFF 0x050 | ||
40 | #define PRCM_HSIRXCLK_MGT_OFF 0x054 | ||
41 | #define PRCM_HDMICLK_MGT_OFF 0x058 | ||
42 | #define PRCM_APEATCLK_MGT_OFF 0x05C | ||
43 | #define PRCM_APETRACECLK_MGT_OFF 0x060 | ||
44 | #define PRCM_MCDECLK_MGT_OFF 0x064 | ||
45 | #define PRCM_IPI2CCLK_MGT_OFF 0x068 | ||
46 | #define PRCM_DSIALTCLK_MGT_OFF 0x06C | ||
47 | #define PRCM_DMACLK_MGT_OFF 0x074 | ||
48 | #define PRCM_B2R2CLK_MGT_OFF 0x078 | ||
49 | #define PRCM_TVCLK_MGT_OFF 0x07C | ||
50 | #define PRCM_UNIPROCLK_MGT_OFF 0x278 | ||
51 | #define PRCM_SSPCLK_MGT_OFF 0x280 | ||
52 | #define PRCM_RNGCLK_MGT_OFF 0x284 | ||
53 | #define PRCM_UICCCLK_MGT_OFF 0x27C | ||
54 | #define PRCM_MSP1CLK_MGT_OFF 0x288 | ||
55 | |||
18 | #define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) | 56 | #define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) |
19 | #define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f | 57 | #define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f |
20 | #define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf | 58 | #define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf |
@@ -30,11 +68,15 @@ | |||
30 | #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100 | 68 | #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100 |
31 | 69 | ||
32 | #define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0) | 70 | #define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0) |
71 | #define PRCM_A9PL_FORCE_CLKEN (_PRCMU_BASE + 0x19C) | ||
33 | #define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4) | 72 | #define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4) |
34 | #define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0) | 73 | #define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0) |
35 | #define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c) | 74 | #define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c) |
36 | #define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308) | 75 | #define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308) |
37 | 76 | ||
77 | #define PRCM_A9PL_FORCE_CLKEN_PRCM_A9PL_FORCE_CLKEN BIT(0) | ||
78 | #define PRCM_A9PL_FORCE_CLKEN_PRCM_A9AXI_FORCE_CLKEN BIT(1) | ||
79 | |||
38 | /* ARM WFI Standby signal register */ | 80 | /* ARM WFI Standby signal register */ |
39 | #define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) | 81 | #define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) |
40 | #define PRCM_IOCR (_PRCMU_BASE + 0x310) | 82 | #define PRCM_IOCR (_PRCMU_BASE + 0x310) |
@@ -61,12 +103,18 @@ | |||
61 | #define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C) | 103 | #define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C) |
62 | 104 | ||
63 | #define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) | 105 | #define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) |
106 | #define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ 0x1 | ||
64 | #define ARM_WAKEUP_MODEM 0x1 | 107 | #define ARM_WAKEUP_MODEM 0x1 |
65 | 108 | ||
66 | #define PRCM_ARM_IT1_CLEAR (_PRCMU_BASE + 0x48C) | 109 | #define PRCM_ARM_IT1_CLR (_PRCMU_BASE + 0x48C) |
67 | #define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494) | 110 | #define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494) |
68 | #define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174) | 111 | #define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174) |
69 | 112 | ||
113 | #define PRCM_MOD_AWAKE_STATUS (_PRCMU_BASE + 0x4A0) | ||
114 | #define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE BIT(0) | ||
115 | #define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE BIT(1) | ||
116 | #define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_VMODEM_OFF_ISO BIT(2) | ||
117 | |||
70 | #define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148) | 118 | #define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148) |
71 | #define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150) | 119 | #define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150) |
72 | #define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158) | 120 | #define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158) |
@@ -87,16 +135,21 @@ | |||
87 | #define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) | 135 | #define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) |
88 | #define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) | 136 | #define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) |
89 | #define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) | 137 | #define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) |
90 | #define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044) | 138 | #define PRCM_LCDCLK_MGT (_PRCMU_BASE + PRCM_LCDCLK_MGT_OFF) |
91 | #define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064) | 139 | #define PRCM_MCDECLK_MGT (_PRCMU_BASE + PRCM_MCDECLK_MGT_OFF) |
92 | #define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058) | 140 | #define PRCM_HDMICLK_MGT (_PRCMU_BASE + PRCM_HDMICLK_MGT_OFF) |
93 | #define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c) | 141 | #define PRCM_TVCLK_MGT (_PRCMU_BASE + PRCM_TVCLK_MGT_OFF) |
94 | #define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) | 142 | #define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) |
95 | #define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) | 143 | #define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) |
96 | #define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) | 144 | #define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) |
97 | #define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) | 145 | #define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) |
98 | #define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) | 146 | #define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) |
147 | |||
99 | #define PRCM_CLKOCR (_PRCMU_BASE + 0x1CC) | 148 | #define PRCM_CLKOCR (_PRCMU_BASE + 0x1CC) |
149 | #define PRCM_CLKOCR_CLKOUT0_REF_CLK (1 << 0) | ||
150 | #define PRCM_CLKOCR_CLKOUT0_MASK BITS(0, 13) | ||
151 | #define PRCM_CLKOCR_CLKOUT1_REF_CLK (1 << 16) | ||
152 | #define PRCM_CLKOCR_CLKOUT1_MASK BITS(16, 29) | ||
100 | 153 | ||
101 | /* ePOD and memory power signal control registers */ | 154 | /* ePOD and memory power signal control registers */ |
102 | #define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) | 155 | #define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) |
@@ -111,5 +164,41 @@ | |||
111 | #define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800 | 164 | #define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800 |
112 | #define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1 | 165 | #define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1 |
113 | 166 | ||
167 | /* PRCMU HW semaphore */ | ||
168 | #define PRCM_SEM (_PRCMU_BASE + 0x400) | ||
169 | #define PRCM_SEM_PRCM_SEM BIT(0) | ||
170 | |||
171 | #define PRCM_TCR (_PRCMU_BASE + 0x1C8) | ||
172 | #define PRCM_TCR_TENSEL_MASK BITS(0, 7) | ||
173 | #define PRCM_TCR_STOP_TIMERS BIT(16) | ||
174 | #define PRCM_TCR_DOZE_MODE BIT(17) | ||
175 | |||
176 | #define PRCM_CLKOCR_CLKODIV0_SHIFT 0 | ||
177 | #define PRCM_CLKOCR_CLKODIV0_MASK BITS(0, 5) | ||
178 | #define PRCM_CLKOCR_CLKOSEL0_SHIFT 6 | ||
179 | #define PRCM_CLKOCR_CLKOSEL0_MASK BITS(6, 8) | ||
180 | #define PRCM_CLKOCR_CLKODIV1_SHIFT 16 | ||
181 | #define PRCM_CLKOCR_CLKODIV1_MASK BITS(16, 21) | ||
182 | #define PRCM_CLKOCR_CLKOSEL1_SHIFT 22 | ||
183 | #define PRCM_CLKOCR_CLKOSEL1_MASK BITS(22, 24) | ||
184 | #define PRCM_CLKOCR_CLK1TYPE BIT(28) | ||
185 | |||
186 | #define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4) | ||
187 | #define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7) | ||
188 | #define PRCM_CLK_MGT_CLKEN BIT(8) | ||
189 | |||
190 | /* GPIOCR register */ | ||
191 | #define PRCM_GPIOCR_SPI2_SELECT BIT(23) | ||
192 | |||
193 | #define PRCM_DDR_SUBSYS_APE_MINBW (_PRCMU_BASE + 0x438) | ||
194 | #define PRCM_CGATING_BYPASS (_PRCMU_BASE + 0x134) | ||
195 | #define PRCM_CGATING_BYPASS_ICN2 BIT(6) | ||
196 | |||
197 | /* Miscellaneous unit registers */ | ||
198 | #define PRCM_RESOUTN_SET (_PRCMU_BASE + 0x214) | ||
199 | #define PRCM_RESOUTN_CLR (_PRCMU_BASE + 0x218) | ||
200 | |||
201 | /* System reset register */ | ||
202 | #define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228) | ||
114 | 203 | ||
115 | #endif /* __MACH_PRCMU__REGS_H */ | 204 | #endif /* __DB8500_PRCMU_REGS_H */ |
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c new file mode 100644 index 000000000000..97c27762174f --- /dev/null +++ b/drivers/mfd/intel_msic.c | |||
@@ -0,0 +1,502 @@ | |||
1 | /* | ||
2 | * Driver for Intel MSIC | ||
3 | * | ||
4 | * Copyright (C) 2011, Intel Corporation | ||
5 | * Author: Mika Westerberg <mika.westerberg@linux.intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/mfd/core.h> | ||
16 | #include <linux/mfd/intel_msic.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/slab.h> | ||
19 | |||
20 | #include <asm/intel_scu_ipc.h> | ||
21 | |||
22 | #define MSIC_VENDOR(id) ((id >> 6) & 3) | ||
23 | #define MSIC_VERSION(id) (id & 0x3f) | ||
24 | #define MSIC_MAJOR(id) ('A' + ((id >> 3) & 7)) | ||
25 | #define MSIC_MINOR(id) (id & 7) | ||
26 | |||
27 | /* | ||
28 | * MSIC interrupt tree is readable from SRAM at INTEL_MSIC_IRQ_PHYS_BASE. | ||
29 | * Since IRQ block starts from address 0x002 we need to substract that from | ||
30 | * the actual IRQ status register address. | ||
31 | */ | ||
32 | #define MSIC_IRQ_STATUS(x) (INTEL_MSIC_IRQ_PHYS_BASE + ((x) - 2)) | ||
33 | #define MSIC_IRQ_STATUS_ACCDET MSIC_IRQ_STATUS(INTEL_MSIC_ACCDET) | ||
34 | |||
35 | /* | ||
36 | * The SCU hardware has limitation of 16 bytes per read/write buffer on | ||
37 | * Medfield. | ||
38 | */ | ||
39 | #define SCU_IPC_RWBUF_LIMIT 16 | ||
40 | |||
41 | /** | ||
42 | * struct intel_msic - an MSIC MFD instance | ||
43 | * @pdev: pointer to the platform device | ||
44 | * @vendor: vendor ID | ||
45 | * @version: chip version | ||
46 | * @irq_base: base address of the mapped MSIC SRAM interrupt tree | ||
47 | */ | ||
48 | struct intel_msic { | ||
49 | struct platform_device *pdev; | ||
50 | unsigned vendor; | ||
51 | unsigned version; | ||
52 | void __iomem *irq_base; | ||
53 | }; | ||
54 | |||
55 | static struct resource msic_touch_resources[] = { | ||
56 | { | ||
57 | .flags = IORESOURCE_IRQ, | ||
58 | }, | ||
59 | }; | ||
60 | |||
61 | static struct resource msic_adc_resources[] = { | ||
62 | { | ||
63 | .flags = IORESOURCE_IRQ, | ||
64 | }, | ||
65 | }; | ||
66 | |||
67 | static struct resource msic_battery_resources[] = { | ||
68 | { | ||
69 | .flags = IORESOURCE_IRQ, | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | static struct resource msic_gpio_resources[] = { | ||
74 | { | ||
75 | .flags = IORESOURCE_IRQ, | ||
76 | }, | ||
77 | }; | ||
78 | |||
79 | static struct resource msic_audio_resources[] = { | ||
80 | { | ||
81 | .name = "IRQ", | ||
82 | .flags = IORESOURCE_IRQ, | ||
83 | }, | ||
84 | /* | ||
85 | * We will pass IRQ_BASE to the driver now but this can be removed | ||
86 | * when/if the driver starts to use intel_msic_irq_read(). | ||
87 | */ | ||
88 | { | ||
89 | .name = "IRQ_BASE", | ||
90 | .flags = IORESOURCE_MEM, | ||
91 | .start = MSIC_IRQ_STATUS_ACCDET, | ||
92 | .end = MSIC_IRQ_STATUS_ACCDET, | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | static struct resource msic_hdmi_resources[] = { | ||
97 | { | ||
98 | .flags = IORESOURCE_IRQ, | ||
99 | }, | ||
100 | }; | ||
101 | |||
102 | static struct resource msic_thermal_resources[] = { | ||
103 | { | ||
104 | .flags = IORESOURCE_IRQ, | ||
105 | }, | ||
106 | }; | ||
107 | |||
108 | static struct resource msic_power_btn_resources[] = { | ||
109 | { | ||
110 | .flags = IORESOURCE_IRQ, | ||
111 | }, | ||
112 | }; | ||
113 | |||
114 | static struct resource msic_ocd_resources[] = { | ||
115 | { | ||
116 | .flags = IORESOURCE_IRQ, | ||
117 | }, | ||
118 | }; | ||
119 | |||
120 | /* | ||
121 | * Devices that are part of the MSIC and are available via firmware | ||
122 | * populated SFI DEVS table. | ||
123 | */ | ||
124 | static struct mfd_cell msic_devs[] = { | ||
125 | [INTEL_MSIC_BLOCK_TOUCH] = { | ||
126 | .name = "msic_touch", | ||
127 | .num_resources = ARRAY_SIZE(msic_touch_resources), | ||
128 | .resources = msic_touch_resources, | ||
129 | }, | ||
130 | [INTEL_MSIC_BLOCK_ADC] = { | ||
131 | .name = "msic_adc", | ||
132 | .num_resources = ARRAY_SIZE(msic_adc_resources), | ||
133 | .resources = msic_adc_resources, | ||
134 | }, | ||
135 | [INTEL_MSIC_BLOCK_BATTERY] = { | ||
136 | .name = "msic_battery", | ||
137 | .num_resources = ARRAY_SIZE(msic_battery_resources), | ||
138 | .resources = msic_battery_resources, | ||
139 | }, | ||
140 | [INTEL_MSIC_BLOCK_GPIO] = { | ||
141 | .name = "msic_gpio", | ||
142 | .num_resources = ARRAY_SIZE(msic_gpio_resources), | ||
143 | .resources = msic_gpio_resources, | ||
144 | }, | ||
145 | [INTEL_MSIC_BLOCK_AUDIO] = { | ||
146 | .name = "msic_audio", | ||
147 | .num_resources = ARRAY_SIZE(msic_audio_resources), | ||
148 | .resources = msic_audio_resources, | ||
149 | }, | ||
150 | [INTEL_MSIC_BLOCK_HDMI] = { | ||
151 | .name = "msic_hdmi", | ||
152 | .num_resources = ARRAY_SIZE(msic_hdmi_resources), | ||
153 | .resources = msic_hdmi_resources, | ||
154 | }, | ||
155 | [INTEL_MSIC_BLOCK_THERMAL] = { | ||
156 | .name = "msic_thermal", | ||
157 | .num_resources = ARRAY_SIZE(msic_thermal_resources), | ||
158 | .resources = msic_thermal_resources, | ||
159 | }, | ||
160 | [INTEL_MSIC_BLOCK_POWER_BTN] = { | ||
161 | .name = "msic_power_btn", | ||
162 | .num_resources = ARRAY_SIZE(msic_power_btn_resources), | ||
163 | .resources = msic_power_btn_resources, | ||
164 | }, | ||
165 | [INTEL_MSIC_BLOCK_OCD] = { | ||
166 | .name = "msic_ocd", | ||
167 | .num_resources = ARRAY_SIZE(msic_ocd_resources), | ||
168 | .resources = msic_ocd_resources, | ||
169 | }, | ||
170 | }; | ||
171 | |||
172 | /* | ||
173 | * Other MSIC related devices which are not directly available via SFI DEVS | ||
174 | * table. These can be pseudo devices, regulators etc. which are needed for | ||
175 | * different purposes. | ||
176 | * | ||
177 | * These devices appear only after the MSIC driver itself is initialized so | ||
178 | * we can guarantee that the SCU IPC interface is ready. | ||
179 | */ | ||
180 | static struct mfd_cell msic_other_devs[] = { | ||
181 | /* Audio codec in the MSIC */ | ||
182 | { | ||
183 | .id = -1, | ||
184 | .name = "sn95031", | ||
185 | }, | ||
186 | }; | ||
187 | |||
188 | /** | ||
189 | * intel_msic_reg_read - read a single MSIC register | ||
190 | * @reg: register to read | ||
191 | * @val: register value is placed here | ||
192 | * | ||
193 | * Read a single register from MSIC. Returns %0 on success and negative | ||
194 | * errno in case of failure. | ||
195 | * | ||
196 | * Function may sleep. | ||
197 | */ | ||
198 | int intel_msic_reg_read(unsigned short reg, u8 *val) | ||
199 | { | ||
200 | return intel_scu_ipc_ioread8(reg, val); | ||
201 | } | ||
202 | EXPORT_SYMBOL_GPL(intel_msic_reg_read); | ||
203 | |||
204 | /** | ||
205 | * intel_msic_reg_write - write a single MSIC register | ||
206 | * @reg: register to write | ||
207 | * @val: value to write to that register | ||
208 | * | ||
209 | * Write a single MSIC register. Returns 0 on success and negative | ||
210 | * errno in case of failure. | ||
211 | * | ||
212 | * Function may sleep. | ||
213 | */ | ||
214 | int intel_msic_reg_write(unsigned short reg, u8 val) | ||
215 | { | ||
216 | return intel_scu_ipc_iowrite8(reg, val); | ||
217 | } | ||
218 | EXPORT_SYMBOL_GPL(intel_msic_reg_write); | ||
219 | |||
220 | /** | ||
221 | * intel_msic_reg_update - update a single MSIC register | ||
222 | * @reg: register to update | ||
223 | * @val: value to write to the register | ||
224 | * @mask: specifies which of the bits are updated (%0 = don't update, | ||
225 | * %1 = update) | ||
226 | * | ||
227 | * Perform an update to a register @reg. @mask is used to specify which | ||
228 | * bits are updated. Returns %0 in case of success and negative errno in | ||
229 | * case of failure. | ||
230 | * | ||
231 | * Function may sleep. | ||
232 | */ | ||
233 | int intel_msic_reg_update(unsigned short reg, u8 val, u8 mask) | ||
234 | { | ||
235 | return intel_scu_ipc_update_register(reg, val, mask); | ||
236 | } | ||
237 | EXPORT_SYMBOL_GPL(intel_msic_reg_update); | ||
238 | |||
239 | /** | ||
240 | * intel_msic_bulk_read - read an array of registers | ||
241 | * @reg: array of register addresses to read | ||
242 | * @buf: array where the read values are placed | ||
243 | * @count: number of registers to read | ||
244 | * | ||
245 | * Function reads @count registers from the MSIC using addresses passed in | ||
246 | * @reg. Read values are placed in @buf. Reads are performed atomically | ||
247 | * wrt. MSIC. | ||
248 | * | ||
249 | * Returns %0 in case of success and negative errno in case of failure. | ||
250 | * | ||
251 | * Function may sleep. | ||
252 | */ | ||
253 | int intel_msic_bulk_read(unsigned short *reg, u8 *buf, size_t count) | ||
254 | { | ||
255 | if (WARN_ON(count > SCU_IPC_RWBUF_LIMIT)) | ||
256 | return -EINVAL; | ||
257 | |||
258 | return intel_scu_ipc_readv(reg, buf, count); | ||
259 | } | ||
260 | EXPORT_SYMBOL_GPL(intel_msic_bulk_read); | ||
261 | |||
262 | /** | ||
263 | * intel_msic_bulk_write - write an array of values to the MSIC registers | ||
264 | * @reg: array of registers to write | ||
265 | * @buf: values to write to each register | ||
266 | * @count: number of registers to write | ||
267 | * | ||
268 | * Function writes @count registers in @buf to MSIC. Writes are performed | ||
269 | * atomically wrt MSIC. Returns %0 in case of success and negative errno in | ||
270 | * case of failure. | ||
271 | * | ||
272 | * Function may sleep. | ||
273 | */ | ||
274 | int intel_msic_bulk_write(unsigned short *reg, u8 *buf, size_t count) | ||
275 | { | ||
276 | if (WARN_ON(count > SCU_IPC_RWBUF_LIMIT)) | ||
277 | return -EINVAL; | ||
278 | |||
279 | return intel_scu_ipc_writev(reg, buf, count); | ||
280 | } | ||
281 | EXPORT_SYMBOL_GPL(intel_msic_bulk_write); | ||
282 | |||
283 | /** | ||
284 | * intel_msic_irq_read - read a register from an MSIC interrupt tree | ||
285 | * @msic: MSIC instance | ||
286 | * @reg: interrupt register (between %INTEL_MSIC_IRQLVL1 and | ||
287 | * %INTEL_MSIC_RESETIRQ2) | ||
288 | * @val: value of the register is placed here | ||
289 | * | ||
290 | * This function can be used by an MSIC subdevice interrupt handler to read | ||
291 | * a register value from the MSIC interrupt tree. In this way subdevice | ||
292 | * drivers don't have to map in the interrupt tree themselves but can just | ||
293 | * call this function instead. | ||
294 | * | ||
295 | * Function doesn't sleep and is callable from interrupt context. | ||
296 | * | ||
297 | * Returns %-EINVAL if @reg is outside of the allowed register region. | ||
298 | */ | ||
299 | int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg, u8 *val) | ||
300 | { | ||
301 | if (WARN_ON(reg < INTEL_MSIC_IRQLVL1 || reg > INTEL_MSIC_RESETIRQ2)) | ||
302 | return -EINVAL; | ||
303 | |||
304 | *val = readb(msic->irq_base + (reg - INTEL_MSIC_IRQLVL1)); | ||
305 | return 0; | ||
306 | } | ||
307 | EXPORT_SYMBOL_GPL(intel_msic_irq_read); | ||
308 | |||
309 | static int __devinit intel_msic_init_devices(struct intel_msic *msic) | ||
310 | { | ||
311 | struct platform_device *pdev = msic->pdev; | ||
312 | struct intel_msic_platform_data *pdata = pdev->dev.platform_data; | ||
313 | int ret, i; | ||
314 | |||
315 | if (pdata->gpio) { | ||
316 | struct mfd_cell *cell = &msic_devs[INTEL_MSIC_BLOCK_GPIO]; | ||
317 | |||
318 | cell->platform_data = pdata->gpio; | ||
319 | cell->pdata_size = sizeof(*pdata->gpio); | ||
320 | } | ||
321 | |||
322 | if (pdata->ocd) { | ||
323 | unsigned gpio = pdata->ocd->gpio; | ||
324 | |||
325 | ret = gpio_request_one(gpio, GPIOF_IN, "ocd_gpio"); | ||
326 | if (ret) { | ||
327 | dev_err(&pdev->dev, "failed to register OCD GPIO\n"); | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | ret = gpio_to_irq(gpio); | ||
332 | if (ret < 0) { | ||
333 | dev_err(&pdev->dev, "no IRQ number for OCD GPIO\n"); | ||
334 | gpio_free(gpio); | ||
335 | return ret; | ||
336 | } | ||
337 | |||
338 | /* Update the IRQ number for the OCD */ | ||
339 | pdata->irq[INTEL_MSIC_BLOCK_OCD] = ret; | ||
340 | } | ||
341 | |||
342 | for (i = 0; i < ARRAY_SIZE(msic_devs); i++) { | ||
343 | if (!pdata->irq[i]) | ||
344 | continue; | ||
345 | |||
346 | ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, | ||
347 | pdata->irq[i]); | ||
348 | if (ret) | ||
349 | goto fail; | ||
350 | } | ||
351 | |||
352 | ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, | ||
353 | ARRAY_SIZE(msic_other_devs), NULL, 0); | ||
354 | if (ret) | ||
355 | goto fail; | ||
356 | |||
357 | return 0; | ||
358 | |||
359 | fail: | ||
360 | mfd_remove_devices(&pdev->dev); | ||
361 | if (pdata->ocd) | ||
362 | gpio_free(pdata->ocd->gpio); | ||
363 | |||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | static void __devexit intel_msic_remove_devices(struct intel_msic *msic) | ||
368 | { | ||
369 | struct platform_device *pdev = msic->pdev; | ||
370 | struct intel_msic_platform_data *pdata = pdev->dev.platform_data; | ||
371 | |||
372 | mfd_remove_devices(&pdev->dev); | ||
373 | |||
374 | if (pdata->ocd) | ||
375 | gpio_free(pdata->ocd->gpio); | ||
376 | } | ||
377 | |||
378 | static int __devinit intel_msic_probe(struct platform_device *pdev) | ||
379 | { | ||
380 | struct intel_msic_platform_data *pdata = pdev->dev.platform_data; | ||
381 | struct intel_msic *msic; | ||
382 | struct resource *res; | ||
383 | u8 id0, id1; | ||
384 | int ret; | ||
385 | |||
386 | if (!pdata) { | ||
387 | dev_err(&pdev->dev, "no platform data passed\n"); | ||
388 | return -EINVAL; | ||
389 | } | ||
390 | |||
391 | /* First validate that we have an MSIC in place */ | ||
392 | ret = intel_scu_ipc_ioread8(INTEL_MSIC_ID0, &id0); | ||
393 | if (ret) { | ||
394 | dev_err(&pdev->dev, "failed to identify the MSIC chip (ID0)\n"); | ||
395 | return -ENXIO; | ||
396 | } | ||
397 | |||
398 | ret = intel_scu_ipc_ioread8(INTEL_MSIC_ID1, &id1); | ||
399 | if (ret) { | ||
400 | dev_err(&pdev->dev, "failed to identify the MSIC chip (ID1)\n"); | ||
401 | return -ENXIO; | ||
402 | } | ||
403 | |||
404 | if (MSIC_VENDOR(id0) != MSIC_VENDOR(id1)) { | ||
405 | dev_err(&pdev->dev, "invalid vendor ID: %x, %x\n", id0, id1); | ||
406 | return -ENXIO; | ||
407 | } | ||
408 | |||
409 | msic = kzalloc(sizeof(*msic), GFP_KERNEL); | ||
410 | if (!msic) | ||
411 | return -ENOMEM; | ||
412 | |||
413 | msic->vendor = MSIC_VENDOR(id0); | ||
414 | msic->version = MSIC_VERSION(id0); | ||
415 | msic->pdev = pdev; | ||
416 | |||
417 | /* | ||
418 | * Map in the MSIC interrupt tree area in SRAM. This is exposed to | ||
419 | * the clients via intel_msic_irq_read(). | ||
420 | */ | ||
421 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
422 | if (!res) { | ||
423 | dev_err(&pdev->dev, "failed to get SRAM iomem resource\n"); | ||
424 | ret = -ENODEV; | ||
425 | goto fail_free_msic; | ||
426 | } | ||
427 | |||
428 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
429 | if (!res) { | ||
430 | ret = -EBUSY; | ||
431 | goto fail_free_msic; | ||
432 | } | ||
433 | |||
434 | msic->irq_base = ioremap_nocache(res->start, resource_size(res)); | ||
435 | if (!msic->irq_base) { | ||
436 | dev_err(&pdev->dev, "failed to map SRAM memory\n"); | ||
437 | ret = -ENOMEM; | ||
438 | goto fail_release_region; | ||
439 | } | ||
440 | |||
441 | platform_set_drvdata(pdev, msic); | ||
442 | |||
443 | ret = intel_msic_init_devices(msic); | ||
444 | if (ret) { | ||
445 | dev_err(&pdev->dev, "failed to initialize MSIC devices\n"); | ||
446 | goto fail_unmap_mem; | ||
447 | } | ||
448 | |||
449 | dev_info(&pdev->dev, "Intel MSIC version %c%d (vendor %#x)\n", | ||
450 | MSIC_MAJOR(msic->version), MSIC_MINOR(msic->version), | ||
451 | msic->vendor); | ||
452 | |||
453 | return 0; | ||
454 | |||
455 | fail_unmap_mem: | ||
456 | iounmap(msic->irq_base); | ||
457 | fail_release_region: | ||
458 | release_mem_region(res->start, resource_size(res)); | ||
459 | fail_free_msic: | ||
460 | kfree(msic); | ||
461 | |||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | static int __devexit intel_msic_remove(struct platform_device *pdev) | ||
466 | { | ||
467 | struct intel_msic *msic = platform_get_drvdata(pdev); | ||
468 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
469 | |||
470 | intel_msic_remove_devices(msic); | ||
471 | platform_set_drvdata(pdev, NULL); | ||
472 | iounmap(msic->irq_base); | ||
473 | release_mem_region(res->start, resource_size(res)); | ||
474 | kfree(msic); | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static struct platform_driver intel_msic_driver = { | ||
480 | .probe = intel_msic_probe, | ||
481 | .remove = __devexit_p(intel_msic_remove), | ||
482 | .driver = { | ||
483 | .name = "intel_msic", | ||
484 | .owner = THIS_MODULE, | ||
485 | }, | ||
486 | }; | ||
487 | |||
488 | static int __init intel_msic_init(void) | ||
489 | { | ||
490 | return platform_driver_register(&intel_msic_driver); | ||
491 | } | ||
492 | module_init(intel_msic_init); | ||
493 | |||
494 | static void __exit intel_msic_exit(void) | ||
495 | { | ||
496 | platform_driver_unregister(&intel_msic_driver); | ||
497 | } | ||
498 | module_exit(intel_msic_exit); | ||
499 | |||
500 | MODULE_DESCRIPTION("Driver for Intel MSIC"); | ||
501 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); | ||
502 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 563654c9b19e..1e9ee533eacb 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c | |||
@@ -328,7 +328,7 @@ static int __devexit jz4740_adc_remove(struct platform_device *pdev) | |||
328 | return 0; | 328 | return 0; |
329 | } | 329 | } |
330 | 330 | ||
331 | struct platform_driver jz4740_adc_driver = { | 331 | static struct platform_driver jz4740_adc_driver = { |
332 | .probe = jz4740_adc_probe, | 332 | .probe = jz4740_adc_probe, |
333 | .remove = __devexit_p(jz4740_adc_remove), | 333 | .remove = __devexit_p(jz4740_adc_remove), |
334 | .driver = { | 334 | .driver = { |
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index f83103b8970d..dc58750bb71b 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/interrupt.h> | ||
26 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
27 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
28 | #include <linux/mfd/core.h> | 29 | #include <linux/mfd/core.h> |
@@ -142,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c, | |||
142 | 143 | ||
143 | max8997->irq_base = pdata->irq_base; | 144 | max8997->irq_base = pdata->irq_base; |
144 | max8997->ono = pdata->ono; | 145 | max8997->ono = pdata->ono; |
145 | max8997->wakeup = pdata->wakeup; | ||
146 | 146 | ||
147 | mutex_init(&max8997->iolock); | 147 | mutex_init(&max8997->iolock); |
148 | 148 | ||
@@ -169,6 +169,9 @@ static int max8997_i2c_probe(struct i2c_client *i2c, | |||
169 | if (ret < 0) | 169 | if (ret < 0) |
170 | goto err_mfd; | 170 | goto err_mfd; |
171 | 171 | ||
172 | /* MAX8997 has a power button input. */ | ||
173 | device_init_wakeup(max8997->dev, pdata->wakeup); | ||
174 | |||
172 | return ret; | 175 | return ret; |
173 | 176 | ||
174 | err_mfd: | 177 | err_mfd: |
@@ -398,7 +401,29 @@ static int max8997_restore(struct device *dev) | |||
398 | return 0; | 401 | return 0; |
399 | } | 402 | } |
400 | 403 | ||
404 | static int max8997_suspend(struct device *dev) | ||
405 | { | ||
406 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
407 | struct max8997_dev *max8997 = i2c_get_clientdata(i2c); | ||
408 | |||
409 | if (device_may_wakeup(dev)) | ||
410 | irq_set_irq_wake(max8997->irq, 1); | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static int max8997_resume(struct device *dev) | ||
415 | { | ||
416 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
417 | struct max8997_dev *max8997 = i2c_get_clientdata(i2c); | ||
418 | |||
419 | if (device_may_wakeup(dev)) | ||
420 | irq_set_irq_wake(max8997->irq, 0); | ||
421 | return max8997_irq_resume(max8997); | ||
422 | } | ||
423 | |||
401 | const struct dev_pm_ops max8997_pm = { | 424 | const struct dev_pm_ops max8997_pm = { |
425 | .suspend = max8997_suspend, | ||
426 | .resume = max8997_resume, | ||
402 | .freeze = max8997_freeze, | 427 | .freeze = max8997_freeze, |
403 | .restore = max8997_restore, | 428 | .restore = max8997_restore, |
404 | }; | 429 | }; |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index 7e4d44bf92ab..e9619acc0237 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -26,20 +26,10 @@ struct mc13xxx { | |||
26 | 26 | ||
27 | irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; | 27 | irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; |
28 | void *irqdata[MC13XXX_NUM_IRQ]; | 28 | void *irqdata[MC13XXX_NUM_IRQ]; |
29 | }; | ||
30 | |||
31 | struct mc13783 { | ||
32 | struct mc13xxx mc13xxx; | ||
33 | 29 | ||
34 | int adcflags; | 30 | int adcflags; |
35 | }; | 31 | }; |
36 | 32 | ||
37 | struct mc13xxx *mc13783_to_mc13xxx(struct mc13783 *mc13783) | ||
38 | { | ||
39 | return &mc13783->mc13xxx; | ||
40 | } | ||
41 | EXPORT_SYMBOL(mc13783_to_mc13xxx); | ||
42 | |||
43 | #define MC13XXX_IRQSTAT0 0 | 33 | #define MC13XXX_IRQSTAT0 0 |
44 | #define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0) | 34 | #define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0) |
45 | #define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1) | 35 | #define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1) |
@@ -136,14 +126,14 @@ EXPORT_SYMBOL(mc13783_to_mc13xxx); | |||
136 | #define MC13XXX_REVISION_FAB (0x03 << 11) | 126 | #define MC13XXX_REVISION_FAB (0x03 << 11) |
137 | #define MC13XXX_REVISION_ICIDCODE (0x3f << 13) | 127 | #define MC13XXX_REVISION_ICIDCODE (0x3f << 13) |
138 | 128 | ||
139 | #define MC13783_ADC1 44 | 129 | #define MC13XXX_ADC1 44 |
140 | #define MC13783_ADC1_ADEN (1 << 0) | 130 | #define MC13XXX_ADC1_ADEN (1 << 0) |
141 | #define MC13783_ADC1_RAND (1 << 1) | 131 | #define MC13XXX_ADC1_RAND (1 << 1) |
142 | #define MC13783_ADC1_ADSEL (1 << 3) | 132 | #define MC13XXX_ADC1_ADSEL (1 << 3) |
143 | #define MC13783_ADC1_ASC (1 << 20) | 133 | #define MC13XXX_ADC1_ASC (1 << 20) |
144 | #define MC13783_ADC1_ADTRIGIGN (1 << 21) | 134 | #define MC13XXX_ADC1_ADTRIGIGN (1 << 21) |
145 | 135 | ||
146 | #define MC13783_ADC2 45 | 136 | #define MC13XXX_ADC2 45 |
147 | 137 | ||
148 | #define MC13XXX_NUMREGS 0x3f | 138 | #define MC13XXX_NUMREGS 0x3f |
149 | 139 | ||
@@ -487,7 +477,7 @@ enum mc13xxx_id { | |||
487 | MC13XXX_ID_INVALID, | 477 | MC13XXX_ID_INVALID, |
488 | }; | 478 | }; |
489 | 479 | ||
490 | const char *mc13xxx_chipname[] = { | 480 | static const char *mc13xxx_chipname[] = { |
491 | [MC13XXX_ID_MC13783] = "mc13783", | 481 | [MC13XXX_ID_MC13783] = "mc13783", |
492 | [MC13XXX_ID_MC13892] = "mc13892", | 482 | [MC13XXX_ID_MC13892] = "mc13892", |
493 | }; | 483 | }; |
@@ -558,8 +548,6 @@ static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx) | |||
558 | return mc13xxx_chipname[devid->driver_data]; | 548 | return mc13xxx_chipname[devid->driver_data]; |
559 | } | 549 | } |
560 | 550 | ||
561 | #include <linux/mfd/mc13783.h> | ||
562 | |||
563 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) | 551 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) |
564 | { | 552 | { |
565 | struct mc13xxx_platform_data *pdata = | 553 | struct mc13xxx_platform_data *pdata = |
@@ -569,15 +557,15 @@ int mc13xxx_get_flags(struct mc13xxx *mc13xxx) | |||
569 | } | 557 | } |
570 | EXPORT_SYMBOL(mc13xxx_get_flags); | 558 | EXPORT_SYMBOL(mc13xxx_get_flags); |
571 | 559 | ||
572 | #define MC13783_ADC1_CHAN0_SHIFT 5 | 560 | #define MC13XXX_ADC1_CHAN0_SHIFT 5 |
573 | #define MC13783_ADC1_CHAN1_SHIFT 8 | 561 | #define MC13XXX_ADC1_CHAN1_SHIFT 8 |
574 | 562 | ||
575 | struct mc13xxx_adcdone_data { | 563 | struct mc13xxx_adcdone_data { |
576 | struct mc13xxx *mc13xxx; | 564 | struct mc13xxx *mc13xxx; |
577 | struct completion done; | 565 | struct completion done; |
578 | }; | 566 | }; |
579 | 567 | ||
580 | static irqreturn_t mc13783_handler_adcdone(int irq, void *data) | 568 | static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data) |
581 | { | 569 | { |
582 | struct mc13xxx_adcdone_data *adcdone_data = data; | 570 | struct mc13xxx_adcdone_data *adcdone_data = data; |
583 | 571 | ||
@@ -588,12 +576,11 @@ static irqreturn_t mc13783_handler_adcdone(int irq, void *data) | |||
588 | return IRQ_HANDLED; | 576 | return IRQ_HANDLED; |
589 | } | 577 | } |
590 | 578 | ||
591 | #define MC13783_ADC_WORKING (1 << 0) | 579 | #define MC13XXX_ADC_WORKING (1 << 0) |
592 | 580 | ||
593 | int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode, | 581 | int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, |
594 | unsigned int channel, unsigned int *sample) | 582 | unsigned int channel, unsigned int *sample) |
595 | { | 583 | { |
596 | struct mc13xxx *mc13xxx = &mc13783->mc13xxx; | ||
597 | u32 adc0, adc1, old_adc0; | 584 | u32 adc0, adc1, old_adc0; |
598 | int i, ret; | 585 | int i, ret; |
599 | struct mc13xxx_adcdone_data adcdone_data = { | 586 | struct mc13xxx_adcdone_data adcdone_data = { |
@@ -605,51 +592,51 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode, | |||
605 | 592 | ||
606 | mc13xxx_lock(mc13xxx); | 593 | mc13xxx_lock(mc13xxx); |
607 | 594 | ||
608 | if (mc13783->adcflags & MC13783_ADC_WORKING) { | 595 | if (mc13xxx->adcflags & MC13XXX_ADC_WORKING) { |
609 | ret = -EBUSY; | 596 | ret = -EBUSY; |
610 | goto out; | 597 | goto out; |
611 | } | 598 | } |
612 | 599 | ||
613 | mc13783->adcflags |= MC13783_ADC_WORKING; | 600 | mc13xxx->adcflags |= MC13XXX_ADC_WORKING; |
614 | 601 | ||
615 | mc13xxx_reg_read(mc13xxx, MC13783_ADC0, &old_adc0); | 602 | mc13xxx_reg_read(mc13xxx, MC13XXX_ADC0, &old_adc0); |
616 | 603 | ||
617 | adc0 = MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2; | 604 | adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2; |
618 | adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN | MC13783_ADC1_ASC; | 605 | adc1 = MC13XXX_ADC1_ADEN | MC13XXX_ADC1_ADTRIGIGN | MC13XXX_ADC1_ASC; |
619 | 606 | ||
620 | if (channel > 7) | 607 | if (channel > 7) |
621 | adc1 |= MC13783_ADC1_ADSEL; | 608 | adc1 |= MC13XXX_ADC1_ADSEL; |
622 | 609 | ||
623 | switch (mode) { | 610 | switch (mode) { |
624 | case MC13783_ADC_MODE_TS: | 611 | case MC13XXX_ADC_MODE_TS: |
625 | adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_TSMOD0 | | 612 | adc0 |= MC13XXX_ADC0_ADREFEN | MC13XXX_ADC0_TSMOD0 | |
626 | MC13783_ADC0_TSMOD1; | 613 | MC13XXX_ADC0_TSMOD1; |
627 | adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT; | 614 | adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT; |
628 | break; | 615 | break; |
629 | 616 | ||
630 | case MC13783_ADC_MODE_SINGLE_CHAN: | 617 | case MC13XXX_ADC_MODE_SINGLE_CHAN: |
631 | adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK; | 618 | adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK; |
632 | adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT; | 619 | adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT; |
633 | adc1 |= MC13783_ADC1_RAND; | 620 | adc1 |= MC13XXX_ADC1_RAND; |
634 | break; | 621 | break; |
635 | 622 | ||
636 | case MC13783_ADC_MODE_MULT_CHAN: | 623 | case MC13XXX_ADC_MODE_MULT_CHAN: |
637 | adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK; | 624 | adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK; |
638 | adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT; | 625 | adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT; |
639 | break; | 626 | break; |
640 | 627 | ||
641 | default: | 628 | default: |
642 | mc13783_unlock(mc13783); | 629 | mc13xxx_unlock(mc13xxx); |
643 | return -EINVAL; | 630 | return -EINVAL; |
644 | } | 631 | } |
645 | 632 | ||
646 | dev_dbg(&mc13783->mc13xxx.spidev->dev, "%s: request irq\n", __func__); | 633 | dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__); |
647 | mc13xxx_irq_request(mc13xxx, MC13783_IRQ_ADCDONE, | 634 | mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, |
648 | mc13783_handler_adcdone, __func__, &adcdone_data); | 635 | mc13xxx_handler_adcdone, __func__, &adcdone_data); |
649 | mc13xxx_irq_ack(mc13xxx, MC13783_IRQ_ADCDONE); | 636 | mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE); |
650 | 637 | ||
651 | mc13xxx_reg_write(mc13xxx, MC13783_ADC0, adc0); | 638 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); |
652 | mc13xxx_reg_write(mc13xxx, MC13783_ADC1, adc1); | 639 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); |
653 | 640 | ||
654 | mc13xxx_unlock(mc13xxx); | 641 | mc13xxx_unlock(mc13xxx); |
655 | 642 | ||
@@ -660,27 +647,27 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode, | |||
660 | 647 | ||
661 | mc13xxx_lock(mc13xxx); | 648 | mc13xxx_lock(mc13xxx); |
662 | 649 | ||
663 | mc13xxx_irq_free(mc13xxx, MC13783_IRQ_ADCDONE, &adcdone_data); | 650 | mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_ADCDONE, &adcdone_data); |
664 | 651 | ||
665 | if (ret > 0) | 652 | if (ret > 0) |
666 | for (i = 0; i < 4; ++i) { | 653 | for (i = 0; i < 4; ++i) { |
667 | ret = mc13xxx_reg_read(mc13xxx, | 654 | ret = mc13xxx_reg_read(mc13xxx, |
668 | MC13783_ADC2, &sample[i]); | 655 | MC13XXX_ADC2, &sample[i]); |
669 | if (ret) | 656 | if (ret) |
670 | break; | 657 | break; |
671 | } | 658 | } |
672 | 659 | ||
673 | if (mode == MC13783_ADC_MODE_TS) | 660 | if (mode == MC13XXX_ADC_MODE_TS) |
674 | /* restore TSMOD */ | 661 | /* restore TSMOD */ |
675 | mc13xxx_reg_write(mc13xxx, MC13783_ADC0, old_adc0); | 662 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, old_adc0); |
676 | 663 | ||
677 | mc13783->adcflags &= ~MC13783_ADC_WORKING; | 664 | mc13xxx->adcflags &= ~MC13XXX_ADC_WORKING; |
678 | out: | 665 | out: |
679 | mc13xxx_unlock(mc13xxx); | 666 | mc13xxx_unlock(mc13xxx); |
680 | 667 | ||
681 | return ret; | 668 | return ret; |
682 | } | 669 | } |
683 | EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion); | 670 | EXPORT_SYMBOL_GPL(mc13xxx_adc_do_conversion); |
684 | 671 | ||
685 | static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, | 672 | static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, |
686 | const char *format, void *pdata, size_t pdata_size) | 673 | const char *format, void *pdata, size_t pdata_size) |
@@ -716,6 +703,11 @@ static int mc13xxx_probe(struct spi_device *spi) | |||
716 | enum mc13xxx_id id; | 703 | enum mc13xxx_id id; |
717 | int ret; | 704 | int ret; |
718 | 705 | ||
706 | if (!pdata) { | ||
707 | dev_err(&spi->dev, "invalid platform data\n"); | ||
708 | return -EINVAL; | ||
709 | } | ||
710 | |||
719 | mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); | 711 | mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); |
720 | if (!mc13xxx) | 712 | if (!mc13xxx) |
721 | return -ENOMEM; | 713 | return -ENOMEM; |
@@ -763,10 +755,8 @@ err_revision: | |||
763 | if (pdata->flags & MC13XXX_USE_CODEC) | 755 | if (pdata->flags & MC13XXX_USE_CODEC) |
764 | mc13xxx_add_subdevice(mc13xxx, "%s-codec"); | 756 | mc13xxx_add_subdevice(mc13xxx, "%s-codec"); |
765 | 757 | ||
766 | if (pdata->flags & MC13XXX_USE_REGULATOR) { | 758 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", |
767 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", | 759 | &pdata->regulators, sizeof(pdata->regulators)); |
768 | &pdata->regulators, sizeof(pdata->regulators)); | ||
769 | } | ||
770 | 760 | ||
771 | if (pdata->flags & MC13XXX_USE_RTC) | 761 | if (pdata->flags & MC13XXX_USE_RTC) |
772 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); | 762 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); |
@@ -774,10 +764,14 @@ err_revision: | |||
774 | if (pdata->flags & MC13XXX_USE_TOUCHSCREEN) | 764 | if (pdata->flags & MC13XXX_USE_TOUCHSCREEN) |
775 | mc13xxx_add_subdevice(mc13xxx, "%s-ts"); | 765 | mc13xxx_add_subdevice(mc13xxx, "%s-ts"); |
776 | 766 | ||
777 | if (pdata->flags & MC13XXX_USE_LED) | 767 | if (pdata->leds) |
778 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", | 768 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", |
779 | pdata->leds, sizeof(*pdata->leds)); | 769 | pdata->leds, sizeof(*pdata->leds)); |
780 | 770 | ||
771 | if (pdata->buttons) | ||
772 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", | ||
773 | pdata->buttons, sizeof(*pdata->buttons)); | ||
774 | |||
781 | return 0; | 775 | return 0; |
782 | } | 776 | } |
783 | 777 | ||
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c index af5d9d061371..cb4910ac4d12 100644 --- a/drivers/mfd/menelaus.c +++ b/drivers/mfd/menelaus.c | |||
@@ -1226,7 +1226,7 @@ static int menelaus_probe(struct i2c_client *client, | |||
1226 | menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73); | 1226 | menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73); |
1227 | 1227 | ||
1228 | if (client->irq > 0) { | 1228 | if (client->irq > 0) { |
1229 | err = request_irq(client->irq, menelaus_irq, IRQF_DISABLED, | 1229 | err = request_irq(client->irq, menelaus_irq, 0, |
1230 | DRIVER_NAME, menelaus); | 1230 | DRIVER_NAME, menelaus); |
1231 | if (err) { | 1231 | if (err) { |
1232 | dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", | 1232 | dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", |
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 57868416c760..ff1a7e741ecd 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c | |||
@@ -23,45 +23,22 @@ | |||
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/regmap.h> | ||
27 | #include <linux/err.h> | ||
26 | 28 | ||
27 | #include <linux/mfd/pcf50633/core.h> | 29 | #include <linux/mfd/pcf50633/core.h> |
28 | 30 | ||
29 | static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data) | ||
30 | { | ||
31 | int ret; | ||
32 | |||
33 | ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client, reg, | ||
34 | num, data); | ||
35 | if (ret < 0) | ||
36 | dev_err(pcf->dev, "Error reading %d regs at %d\n", num, reg); | ||
37 | |||
38 | return ret; | ||
39 | } | ||
40 | |||
41 | static int __pcf50633_write(struct pcf50633 *pcf, u8 reg, int num, u8 *data) | ||
42 | { | ||
43 | int ret; | ||
44 | |||
45 | ret = i2c_smbus_write_i2c_block_data(pcf->i2c_client, reg, | ||
46 | num, data); | ||
47 | if (ret < 0) | ||
48 | dev_err(pcf->dev, "Error writing %d regs at %d\n", num, reg); | ||
49 | |||
50 | return ret; | ||
51 | |||
52 | } | ||
53 | |||
54 | /* Read a block of up to 32 regs */ | 31 | /* Read a block of up to 32 regs */ |
55 | int pcf50633_read_block(struct pcf50633 *pcf, u8 reg, | 32 | int pcf50633_read_block(struct pcf50633 *pcf, u8 reg, |
56 | int nr_regs, u8 *data) | 33 | int nr_regs, u8 *data) |
57 | { | 34 | { |
58 | int ret; | 35 | int ret; |
59 | 36 | ||
60 | mutex_lock(&pcf->lock); | 37 | ret = regmap_raw_read(pcf->regmap, reg, data, nr_regs); |
61 | ret = __pcf50633_read(pcf, reg, nr_regs, data); | 38 | if (ret != 0) |
62 | mutex_unlock(&pcf->lock); | 39 | return ret; |
63 | 40 | ||
64 | return ret; | 41 | return nr_regs; |
65 | } | 42 | } |
66 | EXPORT_SYMBOL_GPL(pcf50633_read_block); | 43 | EXPORT_SYMBOL_GPL(pcf50633_read_block); |
67 | 44 | ||
@@ -71,21 +48,22 @@ int pcf50633_write_block(struct pcf50633 *pcf , u8 reg, | |||
71 | { | 48 | { |
72 | int ret; | 49 | int ret; |
73 | 50 | ||
74 | mutex_lock(&pcf->lock); | 51 | ret = regmap_raw_write(pcf->regmap, reg, data, nr_regs); |
75 | ret = __pcf50633_write(pcf, reg, nr_regs, data); | 52 | if (ret != 0) |
76 | mutex_unlock(&pcf->lock); | 53 | return ret; |
77 | 54 | ||
78 | return ret; | 55 | return nr_regs; |
79 | } | 56 | } |
80 | EXPORT_SYMBOL_GPL(pcf50633_write_block); | 57 | EXPORT_SYMBOL_GPL(pcf50633_write_block); |
81 | 58 | ||
82 | u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg) | 59 | u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg) |
83 | { | 60 | { |
84 | u8 val; | 61 | unsigned int val; |
62 | int ret; | ||
85 | 63 | ||
86 | mutex_lock(&pcf->lock); | 64 | ret = regmap_read(pcf->regmap, reg, &val); |
87 | __pcf50633_read(pcf, reg, 1, &val); | 65 | if (ret < 0) |
88 | mutex_unlock(&pcf->lock); | 66 | return -1; |
89 | 67 | ||
90 | return val; | 68 | return val; |
91 | } | 69 | } |
@@ -93,56 +71,19 @@ EXPORT_SYMBOL_GPL(pcf50633_reg_read); | |||
93 | 71 | ||
94 | int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val) | 72 | int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val) |
95 | { | 73 | { |
96 | int ret; | 74 | return regmap_write(pcf->regmap, reg, val); |
97 | |||
98 | mutex_lock(&pcf->lock); | ||
99 | ret = __pcf50633_write(pcf, reg, 1, &val); | ||
100 | mutex_unlock(&pcf->lock); | ||
101 | |||
102 | return ret; | ||
103 | } | 75 | } |
104 | EXPORT_SYMBOL_GPL(pcf50633_reg_write); | 76 | EXPORT_SYMBOL_GPL(pcf50633_reg_write); |
105 | 77 | ||
106 | int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val) | 78 | int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val) |
107 | { | 79 | { |
108 | int ret; | 80 | return regmap_update_bits(pcf->regmap, reg, mask, val); |
109 | u8 tmp; | ||
110 | |||
111 | val &= mask; | ||
112 | |||
113 | mutex_lock(&pcf->lock); | ||
114 | ret = __pcf50633_read(pcf, reg, 1, &tmp); | ||
115 | if (ret < 0) | ||
116 | goto out; | ||
117 | |||
118 | tmp &= ~mask; | ||
119 | tmp |= val; | ||
120 | ret = __pcf50633_write(pcf, reg, 1, &tmp); | ||
121 | |||
122 | out: | ||
123 | mutex_unlock(&pcf->lock); | ||
124 | |||
125 | return ret; | ||
126 | } | 81 | } |
127 | EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask); | 82 | EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask); |
128 | 83 | ||
129 | int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val) | 84 | int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val) |
130 | { | 85 | { |
131 | int ret; | 86 | return regmap_update_bits(pcf->regmap, reg, val, 0); |
132 | u8 tmp; | ||
133 | |||
134 | mutex_lock(&pcf->lock); | ||
135 | ret = __pcf50633_read(pcf, reg, 1, &tmp); | ||
136 | if (ret < 0) | ||
137 | goto out; | ||
138 | |||
139 | tmp &= ~val; | ||
140 | ret = __pcf50633_write(pcf, reg, 1, &tmp); | ||
141 | |||
142 | out: | ||
143 | mutex_unlock(&pcf->lock); | ||
144 | |||
145 | return ret; | ||
146 | } | 87 | } |
147 | EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits); | 88 | EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits); |
148 | 89 | ||
@@ -251,6 +192,11 @@ static int pcf50633_resume(struct device *dev) | |||
251 | 192 | ||
252 | static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume); | 193 | static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume); |
253 | 194 | ||
195 | static struct regmap_config pcf50633_regmap_config = { | ||
196 | .reg_bits = 8, | ||
197 | .val_bits = 8, | ||
198 | }; | ||
199 | |||
254 | static int __devinit pcf50633_probe(struct i2c_client *client, | 200 | static int __devinit pcf50633_probe(struct i2c_client *client, |
255 | const struct i2c_device_id *ids) | 201 | const struct i2c_device_id *ids) |
256 | { | 202 | { |
@@ -272,16 +218,23 @@ static int __devinit pcf50633_probe(struct i2c_client *client, | |||
272 | 218 | ||
273 | mutex_init(&pcf->lock); | 219 | mutex_init(&pcf->lock); |
274 | 220 | ||
221 | pcf->regmap = regmap_init_i2c(client, &pcf50633_regmap_config); | ||
222 | if (IS_ERR(pcf->regmap)) { | ||
223 | ret = PTR_ERR(pcf->regmap); | ||
224 | dev_err(pcf->dev, "Failed to allocate register map: %d\n", | ||
225 | ret); | ||
226 | goto err_free; | ||
227 | } | ||
228 | |||
275 | i2c_set_clientdata(client, pcf); | 229 | i2c_set_clientdata(client, pcf); |
276 | pcf->dev = &client->dev; | 230 | pcf->dev = &client->dev; |
277 | pcf->i2c_client = client; | ||
278 | 231 | ||
279 | version = pcf50633_reg_read(pcf, 0); | 232 | version = pcf50633_reg_read(pcf, 0); |
280 | variant = pcf50633_reg_read(pcf, 1); | 233 | variant = pcf50633_reg_read(pcf, 1); |
281 | if (version < 0 || variant < 0) { | 234 | if (version < 0 || variant < 0) { |
282 | dev_err(pcf->dev, "Unable to probe pcf50633\n"); | 235 | dev_err(pcf->dev, "Unable to probe pcf50633\n"); |
283 | ret = -ENODEV; | 236 | ret = -ENODEV; |
284 | goto err_free; | 237 | goto err_regmap; |
285 | } | 238 | } |
286 | 239 | ||
287 | dev_info(pcf->dev, "Probed device version %d variant %d\n", | 240 | dev_info(pcf->dev, "Probed device version %d variant %d\n", |
@@ -328,6 +281,8 @@ static int __devinit pcf50633_probe(struct i2c_client *client, | |||
328 | 281 | ||
329 | return 0; | 282 | return 0; |
330 | 283 | ||
284 | err_regmap: | ||
285 | regmap_exit(pcf->regmap); | ||
331 | err_free: | 286 | err_free: |
332 | kfree(pcf); | 287 | kfree(pcf); |
333 | 288 | ||
@@ -351,6 +306,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client) | |||
351 | for (i = 0; i < PCF50633_NUM_REGULATORS; i++) | 306 | for (i = 0; i < PCF50633_NUM_REGULATORS; i++) |
352 | platform_device_unregister(pcf->regulator_pdev[i]); | 307 | platform_device_unregister(pcf->regulator_pdev[i]); |
353 | 308 | ||
309 | regmap_exit(pcf->regmap); | ||
354 | kfree(pcf); | 310 | kfree(pcf); |
355 | 311 | ||
356 | return 0; | 312 | return 0; |
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index c27e515b0722..de979742c6fc 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c | |||
@@ -357,6 +357,7 @@ static int __devexit tc3589x_remove(struct i2c_client *client) | |||
357 | return 0; | 357 | return 0; |
358 | } | 358 | } |
359 | 359 | ||
360 | #ifdef CONFIG_PM | ||
360 | static int tc3589x_suspend(struct device *dev) | 361 | static int tc3589x_suspend(struct device *dev) |
361 | { | 362 | { |
362 | struct tc3589x *tc3589x = dev_get_drvdata(dev); | 363 | struct tc3589x *tc3589x = dev_get_drvdata(dev); |
@@ -387,6 +388,7 @@ static int tc3589x_resume(struct device *dev) | |||
387 | 388 | ||
388 | static const SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, | 389 | static const SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, |
389 | tc3589x_resume); | 390 | tc3589x_resume); |
391 | #endif | ||
390 | 392 | ||
391 | static const struct i2c_device_id tc3589x_id[] = { | 393 | static const struct i2c_device_id tc3589x_id[] = { |
392 | { "tc3589x", 24 }, | 394 | { "tc3589x", 24 }, |
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index 696879e2eef7..02d65692ceb4 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c | |||
@@ -697,7 +697,7 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
697 | dev_err(&dev->dev, "The driver supports an older " | 697 | dev_err(&dev->dev, "The driver supports an older " |
698 | "version of the FPGA, please update the driver to " | 698 | "version of the FPGA, please update the driver to " |
699 | "support %d.%d\n", priv->fw.major, priv->fw.minor); | 699 | "support %d.%d\n", priv->fw.major, priv->fw.minor); |
700 | goto err_ioremap; | 700 | goto err_config; |
701 | } | 701 | } |
702 | if (priv->fw.major < TIMB_SUPPORTED_MAJOR || | 702 | if (priv->fw.major < TIMB_SUPPORTED_MAJOR || |
703 | priv->fw.minor < TIMB_REQUIRED_MINOR) { | 703 | priv->fw.minor < TIMB_REQUIRED_MINOR) { |
@@ -705,13 +705,13 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
705 | "please upgrade the FPGA to at least: %d.%d\n", | 705 | "please upgrade the FPGA to at least: %d.%d\n", |
706 | priv->fw.major, priv->fw.minor, | 706 | priv->fw.major, priv->fw.minor, |
707 | TIMB_SUPPORTED_MAJOR, TIMB_REQUIRED_MINOR); | 707 | TIMB_SUPPORTED_MAJOR, TIMB_REQUIRED_MINOR); |
708 | goto err_ioremap; | 708 | goto err_config; |
709 | } | 709 | } |
710 | 710 | ||
711 | msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries), | 711 | msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries), |
712 | GFP_KERNEL); | 712 | GFP_KERNEL); |
713 | if (!msix_entries) | 713 | if (!msix_entries) |
714 | goto err_ioremap; | 714 | goto err_config; |
715 | 715 | ||
716 | for (i = 0; i < TIMBERDALE_NR_IRQS; i++) | 716 | for (i = 0; i < TIMBERDALE_NR_IRQS; i++) |
717 | msix_entries[i].entry = i; | 717 | msix_entries[i].entry = i; |
@@ -825,6 +825,8 @@ err_mfd: | |||
825 | err_create_file: | 825 | err_create_file: |
826 | pci_disable_msix(dev); | 826 | pci_disable_msix(dev); |
827 | err_msix: | 827 | err_msix: |
828 | kfree(msix_entries); | ||
829 | err_config: | ||
828 | iounmap(priv->ctl_membase); | 830 | iounmap(priv->ctl_membase); |
829 | err_ioremap: | 831 | err_ioremap: |
830 | release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE); | 832 | release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE); |
@@ -833,7 +835,6 @@ err_request: | |||
833 | err_start: | 835 | err_start: |
834 | pci_disable_device(dev); | 836 | pci_disable_device(dev); |
835 | err_enable: | 837 | err_enable: |
836 | kfree(msix_entries); | ||
837 | kfree(priv); | 838 | kfree(priv); |
838 | pci_set_drvdata(dev, NULL); | 839 | pci_set_drvdata(dev, NULL); |
839 | return -ENODEV; | 840 | return -ENODEV; |
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 955bc00e4b20..5fec23a9ac03 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c | |||
@@ -131,9 +131,6 @@ int tps65912_device_init(struct tps65912 *tps65912) | |||
131 | if (init_data == NULL) | 131 | if (init_data == NULL) |
132 | return -ENOMEM; | 132 | return -ENOMEM; |
133 | 133 | ||
134 | init_data->irq = pmic_plat_data->irq; | ||
135 | init_data->irq_base = pmic_plat_data->irq; | ||
136 | |||
137 | mutex_init(&tps65912->io_mutex); | 134 | mutex_init(&tps65912->io_mutex); |
138 | dev_set_drvdata(tps65912->dev, tps65912); | 135 | dev_set_drvdata(tps65912->dev, tps65912); |
139 | 136 | ||
@@ -153,10 +150,13 @@ int tps65912_device_init(struct tps65912 *tps65912) | |||
153 | if (ret < 0) | 150 | if (ret < 0) |
154 | goto err; | 151 | goto err; |
155 | 152 | ||
153 | init_data->irq = pmic_plat_data->irq; | ||
154 | init_data->irq_base = pmic_plat_data->irq; | ||
156 | ret = tps65912_irq_init(tps65912, init_data->irq, init_data); | 155 | ret = tps65912_irq_init(tps65912, init_data->irq, init_data); |
157 | if (ret < 0) | 156 | if (ret < 0) |
158 | goto err; | 157 | goto err; |
159 | 158 | ||
159 | kfree(init_data); | ||
160 | return ret; | 160 | return ret; |
161 | 161 | ||
162 | err: | 162 | err: |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 01ecfeee6524..b8eef462737a 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -109,7 +109,7 @@ | |||
109 | #define twl_has_watchdog() false | 109 | #define twl_has_watchdog() false |
110 | #endif | 110 | #endif |
111 | 111 | ||
112 | #if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\ | 112 | #if defined(CONFIG_MFD_TWL4030_AUDIO) || defined(CONFIG_MFD_TWL4030_AUDIO_MODULE) ||\ |
113 | defined(CONFIG_TWL6040_CORE) || defined(CONFIG_TWL6040_CORE_MODULE) | 113 | defined(CONFIG_TWL6040_CORE) || defined(CONFIG_TWL6040_CORE_MODULE) |
114 | #define twl_has_codec() true | 114 | #define twl_has_codec() true |
115 | #else | 115 | #else |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 8a7ee3139b86..f062c8cc6c38 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/irq.h> | 32 | #include <linux/irq.h> |
33 | #include <linux/kthread.h> | ||
34 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
35 | 34 | ||
36 | #include <linux/i2c/twl.h> | 35 | #include <linux/i2c/twl.h> |
@@ -278,59 +277,6 @@ static const struct sih sih_modules_twl5031[8] = { | |||
278 | 277 | ||
279 | static unsigned twl4030_irq_base; | 278 | static unsigned twl4030_irq_base; |
280 | 279 | ||
281 | static struct completion irq_event; | ||
282 | |||
283 | /* | ||
284 | * This thread processes interrupts reported by the Primary Interrupt Handler. | ||
285 | */ | ||
286 | static int twl4030_irq_thread(void *data) | ||
287 | { | ||
288 | long irq = (long)data; | ||
289 | static unsigned i2c_errors; | ||
290 | static const unsigned max_i2c_errors = 100; | ||
291 | |||
292 | |||
293 | current->flags |= PF_NOFREEZE; | ||
294 | |||
295 | while (!kthread_should_stop()) { | ||
296 | int ret; | ||
297 | int module_irq; | ||
298 | u8 pih_isr; | ||
299 | |||
300 | /* Wait for IRQ, then read PIH irq status (also blocking) */ | ||
301 | wait_for_completion_interruptible(&irq_event); | ||
302 | |||
303 | ret = twl_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr, | ||
304 | REG_PIH_ISR_P1); | ||
305 | if (ret) { | ||
306 | pr_warning("twl4030: I2C error %d reading PIH ISR\n", | ||
307 | ret); | ||
308 | if (++i2c_errors >= max_i2c_errors) { | ||
309 | printk(KERN_ERR "Maximum I2C error count" | ||
310 | " exceeded. Terminating %s.\n", | ||
311 | __func__); | ||
312 | break; | ||
313 | } | ||
314 | complete(&irq_event); | ||
315 | continue; | ||
316 | } | ||
317 | |||
318 | /* these handlers deal with the relevant SIH irq status */ | ||
319 | local_irq_disable(); | ||
320 | for (module_irq = twl4030_irq_base; | ||
321 | pih_isr; | ||
322 | pih_isr >>= 1, module_irq++) { | ||
323 | if (pih_isr & 0x1) | ||
324 | generic_handle_irq(module_irq); | ||
325 | } | ||
326 | local_irq_enable(); | ||
327 | |||
328 | enable_irq(irq); | ||
329 | } | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | /* | 280 | /* |
335 | * handle_twl4030_pih() is the desc->handle method for the twl4030 interrupt. | 281 | * handle_twl4030_pih() is the desc->handle method for the twl4030 interrupt. |
336 | * This is a chained interrupt, so there is no desc->action method for it. | 282 | * This is a chained interrupt, so there is no desc->action method for it. |
@@ -342,9 +288,25 @@ static int twl4030_irq_thread(void *data) | |||
342 | */ | 288 | */ |
343 | static irqreturn_t handle_twl4030_pih(int irq, void *devid) | 289 | static irqreturn_t handle_twl4030_pih(int irq, void *devid) |
344 | { | 290 | { |
345 | /* Acknowledge, clear *AND* mask the interrupt... */ | 291 | int module_irq; |
346 | disable_irq_nosync(irq); | 292 | irqreturn_t ret; |
347 | complete(devid); | 293 | u8 pih_isr; |
294 | |||
295 | ret = twl_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr, | ||
296 | REG_PIH_ISR_P1); | ||
297 | if (ret) { | ||
298 | pr_warning("twl4030: I2C error %d reading PIH ISR\n", ret); | ||
299 | return IRQ_NONE; | ||
300 | } | ||
301 | |||
302 | /* these handlers deal with the relevant SIH irq status */ | ||
303 | for (module_irq = twl4030_irq_base; | ||
304 | pih_isr; | ||
305 | pih_isr >>= 1, module_irq++) { | ||
306 | if (pih_isr & 0x1) | ||
307 | handle_nested_irq(module_irq); | ||
308 | } | ||
309 | |||
348 | return IRQ_HANDLED; | 310 | return IRQ_HANDLED; |
349 | } | 311 | } |
350 | /*----------------------------------------------------------------------*/ | 312 | /*----------------------------------------------------------------------*/ |
@@ -460,113 +422,17 @@ static inline void activate_irq(int irq) | |||
460 | 422 | ||
461 | /*----------------------------------------------------------------------*/ | 423 | /*----------------------------------------------------------------------*/ |
462 | 424 | ||
463 | static DEFINE_SPINLOCK(sih_agent_lock); | ||
464 | |||
465 | static struct workqueue_struct *wq; | ||
466 | |||
467 | struct sih_agent { | 425 | struct sih_agent { |
468 | int irq_base; | 426 | int irq_base; |
469 | const struct sih *sih; | 427 | const struct sih *sih; |
470 | 428 | ||
471 | u32 imr; | 429 | u32 imr; |
472 | bool imr_change_pending; | 430 | bool imr_change_pending; |
473 | struct work_struct mask_work; | ||
474 | |||
475 | u32 edge_change; | ||
476 | struct work_struct edge_work; | ||
477 | }; | ||
478 | |||
479 | static void twl4030_sih_do_mask(struct work_struct *work) | ||
480 | { | ||
481 | struct sih_agent *agent; | ||
482 | const struct sih *sih; | ||
483 | union { | ||
484 | u8 bytes[4]; | ||
485 | u32 word; | ||
486 | } imr; | ||
487 | int status; | ||
488 | 431 | ||
489 | agent = container_of(work, struct sih_agent, mask_work); | ||
490 | |||
491 | /* see what work we have */ | ||
492 | spin_lock_irq(&sih_agent_lock); | ||
493 | if (agent->imr_change_pending) { | ||
494 | sih = agent->sih; | ||
495 | /* byte[0] gets overwritten as we write ... */ | ||
496 | imr.word = cpu_to_le32(agent->imr << 8); | ||
497 | agent->imr_change_pending = false; | ||
498 | } else | ||
499 | sih = NULL; | ||
500 | spin_unlock_irq(&sih_agent_lock); | ||
501 | if (!sih) | ||
502 | return; | ||
503 | |||
504 | /* write the whole mask ... simpler than subsetting it */ | ||
505 | status = twl_i2c_write(sih->module, imr.bytes, | ||
506 | sih->mask[irq_line].imr_offset, sih->bytes_ixr); | ||
507 | if (status) | ||
508 | pr_err("twl4030: %s, %s --> %d\n", __func__, | ||
509 | "write", status); | ||
510 | } | ||
511 | |||
512 | static void twl4030_sih_do_edge(struct work_struct *work) | ||
513 | { | ||
514 | struct sih_agent *agent; | ||
515 | const struct sih *sih; | ||
516 | u8 bytes[6]; | ||
517 | u32 edge_change; | 432 | u32 edge_change; |
518 | int status; | ||
519 | |||
520 | agent = container_of(work, struct sih_agent, edge_work); | ||
521 | |||
522 | /* see what work we have */ | ||
523 | spin_lock_irq(&sih_agent_lock); | ||
524 | edge_change = agent->edge_change; | ||
525 | agent->edge_change = 0; | ||
526 | sih = edge_change ? agent->sih : NULL; | ||
527 | spin_unlock_irq(&sih_agent_lock); | ||
528 | if (!sih) | ||
529 | return; | ||
530 | |||
531 | /* Read, reserving first byte for write scratch. Yes, this | ||
532 | * could be cached for some speedup ... but be careful about | ||
533 | * any processor on the other IRQ line, EDR registers are | ||
534 | * shared. | ||
535 | */ | ||
536 | status = twl_i2c_read(sih->module, bytes + 1, | ||
537 | sih->edr_offset, sih->bytes_edr); | ||
538 | if (status) { | ||
539 | pr_err("twl4030: %s, %s --> %d\n", __func__, | ||
540 | "read", status); | ||
541 | return; | ||
542 | } | ||
543 | |||
544 | /* Modify only the bits we know must change */ | ||
545 | while (edge_change) { | ||
546 | int i = fls(edge_change) - 1; | ||
547 | struct irq_data *idata = irq_get_irq_data(i + agent->irq_base); | ||
548 | int byte = 1 + (i >> 2); | ||
549 | int off = (i & 0x3) * 2; | ||
550 | unsigned int type; | ||
551 | |||
552 | bytes[byte] &= ~(0x03 << off); | ||
553 | 433 | ||
554 | type = irqd_get_trigger_type(idata); | 434 | struct mutex irq_lock; |
555 | if (type & IRQ_TYPE_EDGE_RISING) | 435 | }; |
556 | bytes[byte] |= BIT(off + 1); | ||
557 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
558 | bytes[byte] |= BIT(off + 0); | ||
559 | |||
560 | edge_change &= ~BIT(i); | ||
561 | } | ||
562 | |||
563 | /* Write */ | ||
564 | status = twl_i2c_write(sih->module, bytes, | ||
565 | sih->edr_offset, sih->bytes_edr); | ||
566 | if (status) | ||
567 | pr_err("twl4030: %s, %s --> %d\n", __func__, | ||
568 | "write", status); | ||
569 | } | ||
570 | 436 | ||
571 | /*----------------------------------------------------------------------*/ | 437 | /*----------------------------------------------------------------------*/ |
572 | 438 | ||
@@ -579,50 +445,125 @@ static void twl4030_sih_do_edge(struct work_struct *work) | |||
579 | 445 | ||
580 | static void twl4030_sih_mask(struct irq_data *data) | 446 | static void twl4030_sih_mask(struct irq_data *data) |
581 | { | 447 | { |
582 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); | 448 | struct sih_agent *agent = irq_data_get_irq_chip_data(data); |
583 | unsigned long flags; | 449 | |
584 | 450 | agent->imr |= BIT(data->irq - agent->irq_base); | |
585 | spin_lock_irqsave(&sih_agent_lock, flags); | 451 | agent->imr_change_pending = true; |
586 | sih->imr |= BIT(data->irq - sih->irq_base); | ||
587 | sih->imr_change_pending = true; | ||
588 | queue_work(wq, &sih->mask_work); | ||
589 | spin_unlock_irqrestore(&sih_agent_lock, flags); | ||
590 | } | 452 | } |
591 | 453 | ||
592 | static void twl4030_sih_unmask(struct irq_data *data) | 454 | static void twl4030_sih_unmask(struct irq_data *data) |
593 | { | 455 | { |
594 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); | 456 | struct sih_agent *agent = irq_data_get_irq_chip_data(data); |
595 | unsigned long flags; | 457 | |
596 | 458 | agent->imr &= ~BIT(data->irq - agent->irq_base); | |
597 | spin_lock_irqsave(&sih_agent_lock, flags); | 459 | agent->imr_change_pending = true; |
598 | sih->imr &= ~BIT(data->irq - sih->irq_base); | ||
599 | sih->imr_change_pending = true; | ||
600 | queue_work(wq, &sih->mask_work); | ||
601 | spin_unlock_irqrestore(&sih_agent_lock, flags); | ||
602 | } | 460 | } |
603 | 461 | ||
604 | static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) | 462 | static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) |
605 | { | 463 | { |
606 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); | 464 | struct sih_agent *agent = irq_data_get_irq_chip_data(data); |
607 | unsigned long flags; | ||
608 | 465 | ||
609 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 466 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
610 | return -EINVAL; | 467 | return -EINVAL; |
611 | 468 | ||
612 | spin_lock_irqsave(&sih_agent_lock, flags); | 469 | if (irqd_get_trigger_type(data) != trigger) |
613 | if (irqd_get_trigger_type(data) != trigger) { | 470 | agent->edge_change |= BIT(data->irq - agent->irq_base); |
614 | sih->edge_change |= BIT(data->irq - sih->irq_base); | 471 | |
615 | queue_work(wq, &sih->edge_work); | ||
616 | } | ||
617 | spin_unlock_irqrestore(&sih_agent_lock, flags); | ||
618 | return 0; | 472 | return 0; |
619 | } | 473 | } |
620 | 474 | ||
475 | static void twl4030_sih_bus_lock(struct irq_data *data) | ||
476 | { | ||
477 | struct sih_agent *agent = irq_data_get_irq_chip_data(data); | ||
478 | |||
479 | mutex_lock(&agent->irq_lock); | ||
480 | } | ||
481 | |||
482 | static void twl4030_sih_bus_sync_unlock(struct irq_data *data) | ||
483 | { | ||
484 | struct sih_agent *agent = irq_data_get_irq_chip_data(data); | ||
485 | const struct sih *sih = agent->sih; | ||
486 | int status; | ||
487 | |||
488 | if (agent->imr_change_pending) { | ||
489 | union { | ||
490 | u32 word; | ||
491 | u8 bytes[4]; | ||
492 | } imr; | ||
493 | |||
494 | /* byte[0] gets overwriten as we write ... */ | ||
495 | imr.word = cpu_to_le32(agent->imr << 8); | ||
496 | agent->imr_change_pending = false; | ||
497 | |||
498 | /* write the whole mask ... simpler than subsetting it */ | ||
499 | status = twl_i2c_write(sih->module, imr.bytes, | ||
500 | sih->mask[irq_line].imr_offset, | ||
501 | sih->bytes_ixr); | ||
502 | if (status) | ||
503 | pr_err("twl4030: %s, %s --> %d\n", __func__, | ||
504 | "write", status); | ||
505 | } | ||
506 | |||
507 | if (agent->edge_change) { | ||
508 | u32 edge_change; | ||
509 | u8 bytes[6]; | ||
510 | |||
511 | edge_change = agent->edge_change; | ||
512 | agent->edge_change = 0; | ||
513 | |||
514 | /* | ||
515 | * Read, reserving first byte for write scratch. Yes, this | ||
516 | * could be cached for some speedup ... but be careful about | ||
517 | * any processor on the other IRQ line, EDR registers are | ||
518 | * shared. | ||
519 | */ | ||
520 | status = twl_i2c_read(sih->module, bytes + 1, | ||
521 | sih->edr_offset, sih->bytes_edr); | ||
522 | if (status) { | ||
523 | pr_err("twl4030: %s, %s --> %d\n", __func__, | ||
524 | "read", status); | ||
525 | return; | ||
526 | } | ||
527 | |||
528 | /* Modify only the bits we know must change */ | ||
529 | while (edge_change) { | ||
530 | int i = fls(edge_change) - 1; | ||
531 | struct irq_data *idata; | ||
532 | int byte = 1 + (i >> 2); | ||
533 | int off = (i & 0x3) * 2; | ||
534 | unsigned int type; | ||
535 | |||
536 | idata = irq_get_irq_data(i + agent->irq_base); | ||
537 | |||
538 | bytes[byte] &= ~(0x03 << off); | ||
539 | |||
540 | type = irqd_get_trigger_type(idata); | ||
541 | if (type & IRQ_TYPE_EDGE_RISING) | ||
542 | bytes[byte] |= BIT(off + 1); | ||
543 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
544 | bytes[byte] |= BIT(off + 0); | ||
545 | |||
546 | edge_change &= ~BIT(i); | ||
547 | } | ||
548 | |||
549 | /* Write */ | ||
550 | status = twl_i2c_write(sih->module, bytes, | ||
551 | sih->edr_offset, sih->bytes_edr); | ||
552 | if (status) | ||
553 | pr_err("twl4030: %s, %s --> %d\n", __func__, | ||
554 | "write", status); | ||
555 | } | ||
556 | |||
557 | mutex_unlock(&agent->irq_lock); | ||
558 | } | ||
559 | |||
621 | static struct irq_chip twl4030_sih_irq_chip = { | 560 | static struct irq_chip twl4030_sih_irq_chip = { |
622 | .name = "twl4030", | 561 | .name = "twl4030", |
623 | .irq_mask = twl4030_sih_mask, | 562 | .irq_mask = twl4030_sih_mask, |
624 | .irq_unmask = twl4030_sih_unmask, | 563 | .irq_unmask = twl4030_sih_unmask, |
625 | .irq_set_type = twl4030_sih_set_type, | 564 | .irq_set_type = twl4030_sih_set_type, |
565 | .irq_bus_lock = twl4030_sih_bus_lock, | ||
566 | .irq_bus_sync_unlock = twl4030_sih_bus_sync_unlock, | ||
626 | }; | 567 | }; |
627 | 568 | ||
628 | /*----------------------------------------------------------------------*/ | 569 | /*----------------------------------------------------------------------*/ |
@@ -655,9 +596,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) | |||
655 | int isr; | 596 | int isr; |
656 | 597 | ||
657 | /* reading ISR acks the IRQs, using clear-on-read mode */ | 598 | /* reading ISR acks the IRQs, using clear-on-read mode */ |
658 | local_irq_enable(); | ||
659 | isr = sih_read_isr(sih); | 599 | isr = sih_read_isr(sih); |
660 | local_irq_disable(); | ||
661 | 600 | ||
662 | if (isr < 0) { | 601 | if (isr < 0) { |
663 | pr_err("twl4030: %s SIH, read ISR error %d\n", | 602 | pr_err("twl4030: %s SIH, read ISR error %d\n", |
@@ -672,7 +611,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) | |||
672 | isr &= ~BIT(irq); | 611 | isr &= ~BIT(irq); |
673 | 612 | ||
674 | if (irq < sih->bits) | 613 | if (irq < sih->bits) |
675 | generic_handle_irq(agent->irq_base + irq); | 614 | handle_nested_irq(agent->irq_base + irq); |
676 | else | 615 | else |
677 | pr_err("twl4030: %s SIH, invalid ISR bit %d\n", | 616 | pr_err("twl4030: %s SIH, invalid ISR bit %d\n", |
678 | sih->name, irq); | 617 | sih->name, irq); |
@@ -718,15 +657,14 @@ int twl4030_sih_setup(int module) | |||
718 | agent->irq_base = irq_base; | 657 | agent->irq_base = irq_base; |
719 | agent->sih = sih; | 658 | agent->sih = sih; |
720 | agent->imr = ~0; | 659 | agent->imr = ~0; |
721 | INIT_WORK(&agent->mask_work, twl4030_sih_do_mask); | 660 | mutex_init(&agent->irq_lock); |
722 | INIT_WORK(&agent->edge_work, twl4030_sih_do_edge); | ||
723 | 661 | ||
724 | for (i = 0; i < sih->bits; i++) { | 662 | for (i = 0; i < sih->bits; i++) { |
725 | irq = irq_base + i; | 663 | irq = irq_base + i; |
726 | 664 | ||
665 | irq_set_chip_data(irq, agent); | ||
727 | irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip, | 666 | irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip, |
728 | handle_edge_irq); | 667 | handle_edge_irq); |
729 | irq_set_chip_data(irq, agent); | ||
730 | activate_irq(irq); | 668 | activate_irq(irq); |
731 | } | 669 | } |
732 | 670 | ||
@@ -758,7 +696,6 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
758 | 696 | ||
759 | int status; | 697 | int status; |
760 | int i; | 698 | int i; |
761 | struct task_struct *task; | ||
762 | 699 | ||
763 | /* | 700 | /* |
764 | * Mask and clear all TWL4030 interrupts since initially we do | 701 | * Mask and clear all TWL4030 interrupts since initially we do |
@@ -768,12 +705,6 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
768 | if (status < 0) | 705 | if (status < 0) |
769 | return status; | 706 | return status; |
770 | 707 | ||
771 | wq = create_singlethread_workqueue("twl4030-irqchip"); | ||
772 | if (!wq) { | ||
773 | pr_err("twl4030: workqueue FAIL\n"); | ||
774 | return -ESRCH; | ||
775 | } | ||
776 | |||
777 | twl4030_irq_base = irq_base; | 708 | twl4030_irq_base = irq_base; |
778 | 709 | ||
779 | /* install an irq handler for each of the SIH modules; | 710 | /* install an irq handler for each of the SIH modules; |
@@ -787,6 +718,7 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
787 | for (i = irq_base; i < irq_end; i++) { | 718 | for (i = irq_base; i < irq_end; i++) { |
788 | irq_set_chip_and_handler(i, &twl4030_irq_chip, | 719 | irq_set_chip_and_handler(i, &twl4030_irq_chip, |
789 | handle_simple_irq); | 720 | handle_simple_irq); |
721 | irq_set_nested_thread(i, 1); | ||
790 | activate_irq(i); | 722 | activate_irq(i); |
791 | } | 723 | } |
792 | twl4030_irq_next = i; | 724 | twl4030_irq_next = i; |
@@ -801,34 +733,22 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
801 | } | 733 | } |
802 | 734 | ||
803 | /* install an irq handler to demultiplex the TWL4030 interrupt */ | 735 | /* install an irq handler to demultiplex the TWL4030 interrupt */ |
804 | 736 | status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, 0, | |
805 | 737 | "TWL4030-PIH", NULL); | |
806 | init_completion(&irq_event); | ||
807 | |||
808 | status = request_irq(irq_num, handle_twl4030_pih, IRQF_DISABLED, | ||
809 | "TWL4030-PIH", &irq_event); | ||
810 | if (status < 0) { | 738 | if (status < 0) { |
811 | pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status); | 739 | pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status); |
812 | goto fail_rqirq; | 740 | goto fail_rqirq; |
813 | } | 741 | } |
814 | 742 | ||
815 | task = kthread_run(twl4030_irq_thread, (void *)(long)irq_num, | ||
816 | "twl4030-irq"); | ||
817 | if (IS_ERR(task)) { | ||
818 | pr_err("twl4030: could not create irq %d thread!\n", irq_num); | ||
819 | status = PTR_ERR(task); | ||
820 | goto fail_kthread; | ||
821 | } | ||
822 | return status; | 743 | return status; |
823 | fail_kthread: | ||
824 | free_irq(irq_num, &irq_event); | ||
825 | fail_rqirq: | 744 | fail_rqirq: |
826 | /* clean up twl4030_sih_setup */ | 745 | /* clean up twl4030_sih_setup */ |
827 | fail: | 746 | fail: |
828 | for (i = irq_base; i < irq_end; i++) | 747 | for (i = irq_base; i < irq_end; i++) { |
748 | irq_set_nested_thread(i, 0); | ||
829 | irq_set_chip_and_handler(i, NULL, NULL); | 749 | irq_set_chip_and_handler(i, NULL, NULL); |
830 | destroy_workqueue(wq); | 750 | } |
831 | wq = NULL; | 751 | |
832 | return status; | 752 | return status; |
833 | } | 753 | } |
834 | 754 | ||
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c index 7cbf2aa9e64f..834f824d3c11 100644 --- a/drivers/mfd/twl4030-madc.c +++ b/drivers/mfd/twl4030-madc.c | |||
@@ -740,6 +740,28 @@ static int __devinit twl4030_madc_probe(struct platform_device *pdev) | |||
740 | TWL4030_BCI_BCICTL1); | 740 | TWL4030_BCI_BCICTL1); |
741 | goto err_i2c; | 741 | goto err_i2c; |
742 | } | 742 | } |
743 | |||
744 | /* Check that MADC clock is on */ | ||
745 | ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, ®val, TWL4030_REG_GPBR1); | ||
746 | if (ret) { | ||
747 | dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n", | ||
748 | TWL4030_REG_GPBR1); | ||
749 | goto err_i2c; | ||
750 | } | ||
751 | |||
752 | /* If MADC clk is not on, turn it on */ | ||
753 | if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) { | ||
754 | dev_info(&pdev->dev, "clk disabled, enabling\n"); | ||
755 | regval |= TWL4030_GPBR1_MADC_HFCLK_EN; | ||
756 | ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval, | ||
757 | TWL4030_REG_GPBR1); | ||
758 | if (ret) { | ||
759 | dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n", | ||
760 | TWL4030_REG_GPBR1); | ||
761 | goto err_i2c; | ||
762 | } | ||
763 | } | ||
764 | |||
743 | platform_set_drvdata(pdev, madc); | 765 | platform_set_drvdata(pdev, madc); |
744 | mutex_init(&madc->lock); | 766 | mutex_init(&madc->lock); |
745 | ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL, | 767 | ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL, |
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index eb3b5f88e566..deec3ec858bf 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/kthread.h> | 37 | #include <linux/kthread.h> |
38 | #include <linux/i2c/twl.h> | 38 | #include <linux/i2c/twl.h> |
39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
40 | #include <linux/suspend.h> | ||
40 | 41 | ||
41 | #include "twl-core.h" | 42 | #include "twl-core.h" |
42 | 43 | ||
@@ -83,8 +84,48 @@ static int twl6030_interrupt_mapping[24] = { | |||
83 | /*----------------------------------------------------------------------*/ | 84 | /*----------------------------------------------------------------------*/ |
84 | 85 | ||
85 | static unsigned twl6030_irq_base; | 86 | static unsigned twl6030_irq_base; |
87 | static int twl_irq; | ||
88 | static bool twl_irq_wake_enabled; | ||
86 | 89 | ||
87 | static struct completion irq_event; | 90 | static struct completion irq_event; |
91 | static atomic_t twl6030_wakeirqs = ATOMIC_INIT(0); | ||
92 | |||
93 | static int twl6030_irq_pm_notifier(struct notifier_block *notifier, | ||
94 | unsigned long pm_event, void *unused) | ||
95 | { | ||
96 | int chained_wakeups; | ||
97 | |||
98 | switch (pm_event) { | ||
99 | case PM_SUSPEND_PREPARE: | ||
100 | chained_wakeups = atomic_read(&twl6030_wakeirqs); | ||
101 | |||
102 | if (chained_wakeups && !twl_irq_wake_enabled) { | ||
103 | if (enable_irq_wake(twl_irq)) | ||
104 | pr_err("twl6030 IRQ wake enable failed\n"); | ||
105 | else | ||
106 | twl_irq_wake_enabled = true; | ||
107 | } else if (!chained_wakeups && twl_irq_wake_enabled) { | ||
108 | disable_irq_wake(twl_irq); | ||
109 | twl_irq_wake_enabled = false; | ||
110 | } | ||
111 | |||
112 | disable_irq(twl_irq); | ||
113 | break; | ||
114 | |||
115 | case PM_POST_SUSPEND: | ||
116 | enable_irq(twl_irq); | ||
117 | break; | ||
118 | |||
119 | default: | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | return NOTIFY_DONE; | ||
124 | } | ||
125 | |||
126 | static struct notifier_block twl6030_irq_pm_notifier_block = { | ||
127 | .notifier_call = twl6030_irq_pm_notifier, | ||
128 | }; | ||
88 | 129 | ||
89 | /* | 130 | /* |
90 | * This thread processes interrupts reported by the Primary Interrupt Handler. | 131 | * This thread processes interrupts reported by the Primary Interrupt Handler. |
@@ -187,6 +228,16 @@ static inline void activate_irq(int irq) | |||
187 | #endif | 228 | #endif |
188 | } | 229 | } |
189 | 230 | ||
231 | int twl6030_irq_set_wake(struct irq_data *d, unsigned int on) | ||
232 | { | ||
233 | if (on) | ||
234 | atomic_inc(&twl6030_wakeirqs); | ||
235 | else | ||
236 | atomic_dec(&twl6030_wakeirqs); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
190 | /*----------------------------------------------------------------------*/ | 241 | /*----------------------------------------------------------------------*/ |
191 | 242 | ||
192 | static unsigned twl6030_irq_next; | 243 | static unsigned twl6030_irq_next; |
@@ -318,10 +369,12 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
318 | twl6030_irq_chip = dummy_irq_chip; | 369 | twl6030_irq_chip = dummy_irq_chip; |
319 | twl6030_irq_chip.name = "twl6030"; | 370 | twl6030_irq_chip.name = "twl6030"; |
320 | twl6030_irq_chip.irq_set_type = NULL; | 371 | twl6030_irq_chip.irq_set_type = NULL; |
372 | twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake; | ||
321 | 373 | ||
322 | for (i = irq_base; i < irq_end; i++) { | 374 | for (i = irq_base; i < irq_end; i++) { |
323 | irq_set_chip_and_handler(i, &twl6030_irq_chip, | 375 | irq_set_chip_and_handler(i, &twl6030_irq_chip, |
324 | handle_simple_irq); | 376 | handle_simple_irq); |
377 | irq_set_chip_data(i, (void *)irq_num); | ||
325 | activate_irq(i); | 378 | activate_irq(i); |
326 | } | 379 | } |
327 | 380 | ||
@@ -331,6 +384,14 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
331 | 384 | ||
332 | /* install an irq handler to demultiplex the TWL6030 interrupt */ | 385 | /* install an irq handler to demultiplex the TWL6030 interrupt */ |
333 | init_completion(&irq_event); | 386 | init_completion(&irq_event); |
387 | |||
388 | status = request_irq(irq_num, handle_twl6030_pih, 0, | ||
389 | "TWL6030-PIH", &irq_event); | ||
390 | if (status < 0) { | ||
391 | pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status); | ||
392 | goto fail_irq; | ||
393 | } | ||
394 | |||
334 | task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq"); | 395 | task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq"); |
335 | if (IS_ERR(task)) { | 396 | if (IS_ERR(task)) { |
336 | pr_err("twl6030: could not create irq %d thread!\n", irq_num); | 397 | pr_err("twl6030: could not create irq %d thread!\n", irq_num); |
@@ -338,17 +399,14 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
338 | goto fail_kthread; | 399 | goto fail_kthread; |
339 | } | 400 | } |
340 | 401 | ||
341 | status = request_irq(irq_num, handle_twl6030_pih, IRQF_DISABLED, | 402 | twl_irq = irq_num; |
342 | "TWL6030-PIH", &irq_event); | 403 | register_pm_notifier(&twl6030_irq_pm_notifier_block); |
343 | if (status < 0) { | ||
344 | pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status); | ||
345 | goto fail_irq; | ||
346 | } | ||
347 | return status; | 404 | return status; |
348 | fail_irq: | ||
349 | free_irq(irq_num, &irq_event); | ||
350 | 405 | ||
351 | fail_kthread: | 406 | fail_kthread: |
407 | free_irq(irq_num, &irq_event); | ||
408 | |||
409 | fail_irq: | ||
352 | for (i = irq_base; i < irq_end; i++) | 410 | for (i = irq_base; i < irq_end; i++) |
353 | irq_set_chip_and_handler(i, NULL, NULL); | 411 | irq_set_chip_and_handler(i, NULL, NULL); |
354 | return status; | 412 | return status; |
@@ -356,6 +414,7 @@ fail_kthread: | |||
356 | 414 | ||
357 | int twl6030_exit_irq(void) | 415 | int twl6030_exit_irq(void) |
358 | { | 416 | { |
417 | unregister_pm_notifier(&twl6030_irq_pm_notifier_block); | ||
359 | 418 | ||
360 | if (twl6030_irq_base) { | 419 | if (twl6030_irq_base) { |
361 | pr_err("twl6030: can't yet clean up IRQs?\n"); | 420 | pr_err("twl6030: can't yet clean up IRQs?\n"); |
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index ada1835a5455..f4747a4a9a93 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
@@ -420,12 +420,19 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) | |||
420 | switch (type) { | 420 | switch (type) { |
421 | case IRQ_TYPE_EDGE_BOTH: | 421 | case IRQ_TYPE_EDGE_BOTH: |
422 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE; | 422 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE; |
423 | wm831x->gpio_level[irq] = false; | ||
423 | break; | 424 | break; |
424 | case IRQ_TYPE_EDGE_RISING: | 425 | case IRQ_TYPE_EDGE_RISING: |
425 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; | 426 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; |
427 | wm831x->gpio_level[irq] = false; | ||
426 | break; | 428 | break; |
427 | case IRQ_TYPE_EDGE_FALLING: | 429 | case IRQ_TYPE_EDGE_FALLING: |
428 | wm831x->gpio_update[irq] = 0x10000; | 430 | wm831x->gpio_update[irq] = 0x10000; |
431 | wm831x->gpio_level[irq] = false; | ||
432 | break; | ||
433 | case IRQ_TYPE_LEVEL_HIGH: | ||
434 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; | ||
435 | wm831x->gpio_level[irq] = true; | ||
429 | break; | 436 | break; |
430 | default: | 437 | default: |
431 | return -EINVAL; | 438 | return -EINVAL; |
@@ -449,7 +456,7 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data) | |||
449 | { | 456 | { |
450 | struct wm831x *wm831x = data; | 457 | struct wm831x *wm831x = data; |
451 | unsigned int i; | 458 | unsigned int i; |
452 | int primary, status_addr; | 459 | int primary, status_addr, ret; |
453 | int status_regs[WM831X_NUM_IRQ_REGS] = { 0 }; | 460 | int status_regs[WM831X_NUM_IRQ_REGS] = { 0 }; |
454 | int read[WM831X_NUM_IRQ_REGS] = { 0 }; | 461 | int read[WM831X_NUM_IRQ_REGS] = { 0 }; |
455 | int *status; | 462 | int *status; |
@@ -507,6 +514,19 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data) | |||
507 | 514 | ||
508 | if (*status & wm831x_irqs[i].mask) | 515 | if (*status & wm831x_irqs[i].mask) |
509 | handle_nested_irq(wm831x->irq_base + i); | 516 | handle_nested_irq(wm831x->irq_base + i); |
517 | |||
518 | /* Simulate an edge triggered IRQ by polling the input | ||
519 | * status. This is sucky but improves interoperability. | ||
520 | */ | ||
521 | if (primary == WM831X_GP_INT && | ||
522 | wm831x->gpio_level[i - WM831X_IRQ_GPIO_1]) { | ||
523 | ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL); | ||
524 | while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) { | ||
525 | handle_nested_irq(wm831x->irq_base + i); | ||
526 | ret = wm831x_reg_read(wm831x, | ||
527 | WM831X_GPIO_LEVEL); | ||
528 | } | ||
529 | } | ||
510 | } | 530 | } |
511 | 531 | ||
512 | out: | 532 | out: |
@@ -596,8 +616,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) | |||
596 | "No interrupt specified - functionality limited\n"); | 616 | "No interrupt specified - functionality limited\n"); |
597 | } | 617 | } |
598 | 618 | ||
599 | |||
600 | |||
601 | /* Enable top level interrupts, we mask at secondary level */ | 619 | /* Enable top level interrupts, we mask at secondary level */ |
602 | wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0); | 620 | wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0); |
603 | 621 | ||
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index b03be1d4e0ca..5d6ba132837e 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -217,6 +217,47 @@ static int wm8994_suspend(struct device *dev) | |||
217 | return 0; | 217 | return 0; |
218 | } | 218 | } |
219 | 219 | ||
220 | ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_4); | ||
221 | if (ret < 0) { | ||
222 | dev_err(dev, "Failed to read power status: %d\n", ret); | ||
223 | } else if (ret & (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA | | ||
224 | WM8994_AIF1ADC2L_ENA | WM8994_AIF1ADC2R_ENA | | ||
225 | WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA)) { | ||
226 | dev_dbg(dev, "CODEC still active, ignoring suspend\n"); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_5); | ||
231 | if (ret < 0) { | ||
232 | dev_err(dev, "Failed to read power status: %d\n", ret); | ||
233 | } else if (ret & (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA | | ||
234 | WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA | | ||
235 | WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) { | ||
236 | dev_dbg(dev, "CODEC still active, ignoring suspend\n"); | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | switch (wm8994->type) { | ||
241 | case WM8958: | ||
242 | ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1); | ||
243 | if (ret < 0) { | ||
244 | dev_err(dev, "Failed to read power status: %d\n", ret); | ||
245 | } else if (ret & WM8958_MICD_ENA) { | ||
246 | dev_dbg(dev, "CODEC still active, ignoring suspend\n"); | ||
247 | return 0; | ||
248 | } | ||
249 | break; | ||
250 | default: | ||
251 | break; | ||
252 | } | ||
253 | |||
254 | /* Disable LDO pulldowns while the device is suspended if we | ||
255 | * don't know that something will be driving them. */ | ||
256 | if (!wm8994->ldo_ena_always_driven) | ||
257 | wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, | ||
258 | WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, | ||
259 | WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD); | ||
260 | |||
220 | /* GPIO configuration state is saved here since we may be configuring | 261 | /* GPIO configuration state is saved here since we may be configuring |
221 | * the GPIO alternate functions even if we're not using the gpiolib | 262 | * the GPIO alternate functions even if we're not using the gpiolib |
222 | * driver for them. | 263 | * driver for them. |
@@ -286,6 +327,11 @@ static int wm8994_resume(struct device *dev) | |||
286 | if (ret < 0) | 327 | if (ret < 0) |
287 | dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); | 328 | dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); |
288 | 329 | ||
330 | /* Disable LDO pulldowns while the device is active */ | ||
331 | wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, | ||
332 | WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, | ||
333 | 0); | ||
334 | |||
289 | wm8994->suspended = false; | 335 | wm8994->suspended = false; |
290 | 336 | ||
291 | return 0; | 337 | return 0; |
@@ -467,8 +513,15 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
467 | pdata->gpio_defaults[i]); | 513 | pdata->gpio_defaults[i]); |
468 | } | 514 | } |
469 | } | 515 | } |
516 | |||
517 | wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; | ||
470 | } | 518 | } |
471 | 519 | ||
520 | /* Disable LDO pulldowns while the device is active */ | ||
521 | wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, | ||
522 | WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, | ||
523 | 0); | ||
524 | |||
472 | /* In some system designs where the regulators are not in use, | 525 | /* In some system designs where the regulators are not in use, |
473 | * we can achieve a small reduction in leakage currents by | 526 | * we can achieve a small reduction in leakage currents by |
474 | * floating LDO outputs. This bit makes no difference if the | 527 | * floating LDO outputs. This bit makes no difference if the |
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 2bb8f451cc06..2d014a144365 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/mfd/db8500-prcmu.h> | 16 | #include <linux/mfd/dbx500-prcmu.h> |
17 | #include <linux/regulator/driver.h> | 17 | #include <linux/regulator/driver.h> |
18 | #include <linux/regulator/machine.h> | 18 | #include <linux/regulator/machine.h> |
19 | #include <linux/regulator/db8500-prcmu.h> | 19 | #include <linux/regulator/db8500-prcmu.h> |
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 730f43ad415b..cb2841feeefd 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c | |||
@@ -336,9 +336,9 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev) | |||
336 | { | 336 | { |
337 | struct mc13xxx_regulator_priv *priv; | 337 | struct mc13xxx_regulator_priv *priv; |
338 | struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); | 338 | struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); |
339 | struct mc13783_regulator_platform_data *pdata = | 339 | struct mc13xxx_regulator_platform_data *pdata = |
340 | dev_get_platdata(&pdev->dev); | 340 | dev_get_platdata(&pdev->dev); |
341 | struct mc13783_regulator_init_data *init_data; | 341 | struct mc13xxx_regulator_init_data *init_data; |
342 | int i, ret; | 342 | int i, ret; |
343 | 343 | ||
344 | dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id); | 344 | dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id); |
@@ -381,7 +381,7 @@ err: | |||
381 | static int __devexit mc13783_regulator_remove(struct platform_device *pdev) | 381 | static int __devexit mc13783_regulator_remove(struct platform_device *pdev) |
382 | { | 382 | { |
383 | struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); | 383 | struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); |
384 | struct mc13783_regulator_platform_data *pdata = | 384 | struct mc13xxx_regulator_platform_data *pdata = |
385 | dev_get_platdata(&pdev->dev); | 385 | dev_get_platdata(&pdev->dev); |
386 | int i; | 386 | int i; |
387 | 387 | ||
diff --git a/include/linux/i2c/twl4030-madc.h b/include/linux/i2c/twl4030-madc.h index 6427d298fbfc..530e11ba0738 100644 --- a/include/linux/i2c/twl4030-madc.h +++ b/include/linux/i2c/twl4030-madc.h | |||
@@ -129,6 +129,10 @@ enum sample_type { | |||
129 | #define REG_BCICTL2 0x024 | 129 | #define REG_BCICTL2 0x024 |
130 | #define TWL4030_BCI_ITHSENS 0x007 | 130 | #define TWL4030_BCI_ITHSENS 0x007 |
131 | 131 | ||
132 | /* Register and bits for GPBR1 register */ | ||
133 | #define TWL4030_REG_GPBR1 0x0c | ||
134 | #define TWL4030_GPBR1_MADC_HFCLK_EN (1 << 7) | ||
135 | |||
132 | struct twl4030_madc_user_parms { | 136 | struct twl4030_madc_user_parms { |
133 | int channel; | 137 | int channel; |
134 | int average; | 138 | int average; |
diff --git a/include/linux/mfd/ab5500/ab5500.h b/include/linux/mfd/ab5500/ab5500.h new file mode 100644 index 000000000000..a720051ae933 --- /dev/null +++ b/include/linux/mfd/ab5500/ab5500.h | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson 2011 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | */ | ||
6 | #ifndef MFD_AB5500_H | ||
7 | #define MFD_AB5500_H | ||
8 | |||
9 | #include <linux/device.h> | ||
10 | |||
11 | enum ab5500_devid { | ||
12 | AB5500_DEVID_ADC, | ||
13 | AB5500_DEVID_LEDS, | ||
14 | AB5500_DEVID_POWER, | ||
15 | AB5500_DEVID_REGULATORS, | ||
16 | AB5500_DEVID_SIM, | ||
17 | AB5500_DEVID_RTC, | ||
18 | AB5500_DEVID_CHARGER, | ||
19 | AB5500_DEVID_FUELGAUGE, | ||
20 | AB5500_DEVID_VIBRATOR, | ||
21 | AB5500_DEVID_CODEC, | ||
22 | AB5500_DEVID_USB, | ||
23 | AB5500_DEVID_OTP, | ||
24 | AB5500_DEVID_VIDEO, | ||
25 | AB5500_DEVID_DBIECI, | ||
26 | AB5500_DEVID_ONSWA, | ||
27 | AB5500_NUM_DEVICES, | ||
28 | }; | ||
29 | |||
30 | enum ab5500_banks { | ||
31 | AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP = 0, | ||
32 | AB5500_BANK_VDDDIG_IO_I2C_CLK_TST = 1, | ||
33 | AB5500_BANK_VDENC = 2, | ||
34 | AB5500_BANK_SIM_USBSIM = 3, | ||
35 | AB5500_BANK_LED = 4, | ||
36 | AB5500_BANK_ADC = 5, | ||
37 | AB5500_BANK_RTC = 6, | ||
38 | AB5500_BANK_STARTUP = 7, | ||
39 | AB5500_BANK_DBI_ECI = 8, | ||
40 | AB5500_BANK_CHG = 9, | ||
41 | AB5500_BANK_FG_BATTCOM_ACC = 10, | ||
42 | AB5500_BANK_USB = 11, | ||
43 | AB5500_BANK_IT = 12, | ||
44 | AB5500_BANK_VIBRA = 13, | ||
45 | AB5500_BANK_AUDIO_HEADSETUSB = 14, | ||
46 | AB5500_NUM_BANKS = 15, | ||
47 | }; | ||
48 | |||
49 | enum ab5500_banks_addr { | ||
50 | AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP = 0x4A, | ||
51 | AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST = 0x4B, | ||
52 | AB5500_ADDR_VDENC = 0x06, | ||
53 | AB5500_ADDR_SIM_USBSIM = 0x04, | ||
54 | AB5500_ADDR_LED = 0x10, | ||
55 | AB5500_ADDR_ADC = 0x0A, | ||
56 | AB5500_ADDR_RTC = 0x0F, | ||
57 | AB5500_ADDR_STARTUP = 0x03, | ||
58 | AB5500_ADDR_DBI_ECI = 0x07, | ||
59 | AB5500_ADDR_CHG = 0x0B, | ||
60 | AB5500_ADDR_FG_BATTCOM_ACC = 0x0C, | ||
61 | AB5500_ADDR_USB = 0x05, | ||
62 | AB5500_ADDR_IT = 0x0E, | ||
63 | AB5500_ADDR_VIBRA = 0x02, | ||
64 | AB5500_ADDR_AUDIO_HEADSETUSB = 0x0D, | ||
65 | }; | ||
66 | |||
67 | /* | ||
68 | * Interrupt register offsets | ||
69 | * Bank : 0x0E | ||
70 | */ | ||
71 | #define AB5500_IT_SOURCE0_REG 0x20 | ||
72 | #define AB5500_IT_SOURCE1_REG 0x21 | ||
73 | #define AB5500_IT_SOURCE2_REG 0x22 | ||
74 | #define AB5500_IT_SOURCE3_REG 0x23 | ||
75 | #define AB5500_IT_SOURCE4_REG 0x24 | ||
76 | #define AB5500_IT_SOURCE5_REG 0x25 | ||
77 | #define AB5500_IT_SOURCE6_REG 0x26 | ||
78 | #define AB5500_IT_SOURCE7_REG 0x27 | ||
79 | #define AB5500_IT_SOURCE8_REG 0x28 | ||
80 | #define AB5500_IT_SOURCE9_REG 0x29 | ||
81 | #define AB5500_IT_SOURCE10_REG 0x2A | ||
82 | #define AB5500_IT_SOURCE11_REG 0x2B | ||
83 | #define AB5500_IT_SOURCE12_REG 0x2C | ||
84 | #define AB5500_IT_SOURCE13_REG 0x2D | ||
85 | #define AB5500_IT_SOURCE14_REG 0x2E | ||
86 | #define AB5500_IT_SOURCE15_REG 0x2F | ||
87 | #define AB5500_IT_SOURCE16_REG 0x30 | ||
88 | #define AB5500_IT_SOURCE17_REG 0x31 | ||
89 | #define AB5500_IT_SOURCE18_REG 0x32 | ||
90 | #define AB5500_IT_SOURCE19_REG 0x33 | ||
91 | #define AB5500_IT_SOURCE20_REG 0x34 | ||
92 | #define AB5500_IT_SOURCE21_REG 0x35 | ||
93 | #define AB5500_IT_SOURCE22_REG 0x36 | ||
94 | #define AB5500_IT_SOURCE23_REG 0x37 | ||
95 | |||
96 | #define AB5500_NUM_IRQ_REGS 23 | ||
97 | |||
98 | /** | ||
99 | * struct ab5500 | ||
100 | * @access_mutex: lock out concurrent accesses to the AB registers | ||
101 | * @dev: a pointer to the device struct for this chip driver | ||
102 | * @ab5500_irq: the analog baseband irq | ||
103 | * @irq_base: the platform configuration irq base for subdevices | ||
104 | * @chip_name: name of this chip variant | ||
105 | * @chip_id: 8 bit chip ID for this chip variant | ||
106 | * @irq_lock: a lock to protect the mask | ||
107 | * @abb_events: a local bit mask of the prcmu wakeup events | ||
108 | * @event_mask: a local copy of the mask event registers | ||
109 | * @last_event_mask: a copy of the last event_mask written to hardware | ||
110 | * @startup_events: a copy of the first reading of the event registers | ||
111 | * @startup_events_read: whether the first events have been read | ||
112 | */ | ||
113 | struct ab5500 { | ||
114 | struct mutex access_mutex; | ||
115 | struct device *dev; | ||
116 | unsigned int ab5500_irq; | ||
117 | unsigned int irq_base; | ||
118 | char chip_name[32]; | ||
119 | u8 chip_id; | ||
120 | struct mutex irq_lock; | ||
121 | u32 abb_events; | ||
122 | u8 mask[AB5500_NUM_IRQ_REGS]; | ||
123 | u8 oldmask[AB5500_NUM_IRQ_REGS]; | ||
124 | u8 startup_events[AB5500_NUM_IRQ_REGS]; | ||
125 | bool startup_events_read; | ||
126 | #ifdef CONFIG_DEBUG_FS | ||
127 | unsigned int debug_bank; | ||
128 | unsigned int debug_address; | ||
129 | #endif | ||
130 | }; | ||
131 | |||
132 | struct ab5500_platform_data { | ||
133 | struct {unsigned int base; unsigned int count; } irq; | ||
134 | void *dev_data[AB5500_NUM_DEVICES]; | ||
135 | struct abx500_init_settings *init_settings; | ||
136 | unsigned int init_settings_sz; | ||
137 | bool pm_power_off; | ||
138 | }; | ||
139 | |||
140 | #endif /* MFD_AB5500_H */ | ||
diff --git a/include/linux/mfd/ab8500/gpadc.h b/include/linux/mfd/ab8500/gpadc.h index 46b954011f16..252966769d93 100644 --- a/include/linux/mfd/ab8500/gpadc.h +++ b/include/linux/mfd/ab8500/gpadc.h | |||
@@ -27,6 +27,9 @@ | |||
27 | struct ab8500_gpadc; | 27 | struct ab8500_gpadc; |
28 | 28 | ||
29 | struct ab8500_gpadc *ab8500_gpadc_get(char *name); | 29 | struct ab8500_gpadc *ab8500_gpadc_get(char *name); |
30 | int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input); | 30 | int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel); |
31 | int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel); | ||
32 | int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, | ||
33 | u8 channel, int ad_value); | ||
31 | 34 | ||
32 | #endif /* _AB8500_GPADC_H */ | 35 | #endif /* _AB8500_GPADC_H */ |
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index 896b5e47f16e..9970337ff041 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * | 6 | * |
7 | * ABX500 core access functions. | 7 | * ABX500 core access functions. |
8 | * The abx500 interface is used for the Analog Baseband chip | 8 | * The abx500 interface is used for the Analog Baseband chip |
9 | * ab3100, ab3550, ab5500, and ab8500. | 9 | * ab3100, ab5500, and ab8500. |
10 | * | 10 | * |
11 | * Author: Mattias Wallin <mattias.wallin@stericsson.com> | 11 | * Author: Mattias Wallin <mattias.wallin@stericsson.com> |
12 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | 12 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> |
@@ -29,17 +29,16 @@ | |||
29 | #define AB3100_P1G 0xc6 | 29 | #define AB3100_P1G 0xc6 |
30 | #define AB3100_R2A 0xc7 | 30 | #define AB3100_R2A 0xc7 |
31 | #define AB3100_R2B 0xc8 | 31 | #define AB3100_R2B 0xc8 |
32 | #define AB3550_P1A 0x10 | ||
33 | #define AB5500_1_0 0x20 | 32 | #define AB5500_1_0 0x20 |
34 | #define AB5500_2_0 0x21 | 33 | #define AB5500_1_1 0x21 |
35 | #define AB5500_2_1 0x22 | 34 | #define AB5500_2_0 0x24 |
36 | 35 | ||
37 | /* AB8500 CIDs*/ | 36 | /* AB8500 CIDs*/ |
38 | #define AB8500_CUTEARLY 0x00 | ||
39 | #define AB8500_CUT1P0 0x10 | 37 | #define AB8500_CUT1P0 0x10 |
40 | #define AB8500_CUT1P1 0x11 | 38 | #define AB8500_CUT1P1 0x11 |
41 | #define AB8500_CUT2P0 0x20 | 39 | #define AB8500_CUT2P0 0x20 |
42 | #define AB8500_CUT3P0 0x30 | 40 | #define AB8500_CUT3P0 0x30 |
41 | #define AB8500_CUT3P3 0x33 | ||
43 | 42 | ||
44 | /* | 43 | /* |
45 | * AB3100, EVENTA1, A2 and A3 event register flags | 44 | * AB3100, EVENTA1, A2 and A3 event register flags |
@@ -143,39 +142,6 @@ int ab3100_event_register(struct ab3100 *ab3100, | |||
143 | int ab3100_event_unregister(struct ab3100 *ab3100, | 142 | int ab3100_event_unregister(struct ab3100 *ab3100, |
144 | struct notifier_block *nb); | 143 | struct notifier_block *nb); |
145 | 144 | ||
146 | /* AB3550, STR register flags */ | ||
147 | #define AB3550_STR_ONSWA (0x01) | ||
148 | #define AB3550_STR_ONSWB (0x02) | ||
149 | #define AB3550_STR_ONSWC (0x04) | ||
150 | #define AB3550_STR_DCIO (0x08) | ||
151 | #define AB3550_STR_BOOT_MODE (0x10) | ||
152 | #define AB3550_STR_SIM_OFF (0x20) | ||
153 | #define AB3550_STR_BATT_REMOVAL (0x40) | ||
154 | #define AB3550_STR_VBUS (0x80) | ||
155 | |||
156 | /* Interrupt mask registers */ | ||
157 | #define AB3550_IMR1 0x29 | ||
158 | #define AB3550_IMR2 0x2a | ||
159 | #define AB3550_IMR3 0x2b | ||
160 | #define AB3550_IMR4 0x2c | ||
161 | #define AB3550_IMR5 0x2d | ||
162 | |||
163 | enum ab3550_devid { | ||
164 | AB3550_DEVID_ADC, | ||
165 | AB3550_DEVID_DAC, | ||
166 | AB3550_DEVID_LEDS, | ||
167 | AB3550_DEVID_POWER, | ||
168 | AB3550_DEVID_REGULATORS, | ||
169 | AB3550_DEVID_SIM, | ||
170 | AB3550_DEVID_UART, | ||
171 | AB3550_DEVID_RTC, | ||
172 | AB3550_DEVID_CHARGER, | ||
173 | AB3550_DEVID_FUELGAUGE, | ||
174 | AB3550_DEVID_VIBRATOR, | ||
175 | AB3550_DEVID_CODEC, | ||
176 | AB3550_NUM_DEVICES, | ||
177 | }; | ||
178 | |||
179 | /** | 145 | /** |
180 | * struct abx500_init_setting | 146 | * struct abx500_init_setting |
181 | * Initial value of the registers for driver to use during setup. | 147 | * Initial value of the registers for driver to use during setup. |
@@ -186,18 +152,6 @@ struct abx500_init_settings { | |||
186 | u8 setting; | 152 | u8 setting; |
187 | }; | 153 | }; |
188 | 154 | ||
189 | /** | ||
190 | * struct ab3550_platform_data | ||
191 | * Data supplied to initialize board connections to the AB3550 | ||
192 | */ | ||
193 | struct ab3550_platform_data { | ||
194 | struct {unsigned int base; unsigned int count; } irq; | ||
195 | void *dev_data[AB3550_NUM_DEVICES]; | ||
196 | size_t dev_data_sz[AB3550_NUM_DEVICES]; | ||
197 | struct abx500_init_settings *init_settings; | ||
198 | unsigned int init_settings_sz; | ||
199 | }; | ||
200 | |||
201 | int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, | 155 | int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, |
202 | u8 value); | 156 | u8 value); |
203 | int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg, | 157 | int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg, |
diff --git a/include/linux/mfd/db5500-prcmu.h b/include/linux/mfd/db5500-prcmu.h index f0977986402c..9890687f582d 100644 --- a/include/linux/mfd/db5500-prcmu.h +++ b/include/linux/mfd/db5500-prcmu.h | |||
@@ -5,21 +5,35 @@ | |||
5 | * | 5 | * |
6 | * U5500 PRCMU API. | 6 | * U5500 PRCMU API. |
7 | */ | 7 | */ |
8 | #ifndef __MACH_PRCMU_U5500_H | 8 | #ifndef __MFD_DB5500_PRCMU_H |
9 | #define __MACH_PRCMU_U5500_H | 9 | #define __MFD_DB5500_PRCMU_H |
10 | 10 | ||
11 | #ifdef CONFIG_UX500_SOC_DB5500 | 11 | #ifdef CONFIG_MFD_DB5500_PRCMU |
12 | 12 | ||
13 | void db5500_prcmu_early_init(void); | 13 | void db5500_prcmu_early_init(void); |
14 | 14 | int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state); | |
15 | int db5500_prcmu_set_display_clocks(void); | ||
16 | int db5500_prcmu_disable_dsipll(void); | ||
17 | int db5500_prcmu_enable_dsipll(void); | ||
15 | int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); | 18 | int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); |
16 | int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); | 19 | int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); |
20 | void db5500_prcmu_enable_wakeups(u32 wakeups); | ||
21 | int db5500_prcmu_request_clock(u8 clock, bool enable); | ||
22 | void db5500_prcmu_config_abb_event_readout(u32 abb_events); | ||
23 | void db5500_prcmu_get_abb_event_buffer(void __iomem **buf); | ||
24 | int prcmu_resetout(u8 resoutn, u8 state); | ||
25 | int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, | ||
26 | bool keep_ap_pll); | ||
27 | int db5500_prcmu_config_esram0_deep_sleep(u8 state); | ||
28 | void db5500_prcmu_system_reset(u16 reset_code); | ||
29 | u16 db5500_prcmu_get_reset_code(void); | ||
30 | bool db5500_prcmu_is_ac_wake_requested(void); | ||
31 | int db5500_prcmu_set_arm_opp(u8 opp); | ||
32 | int db5500_prcmu_get_arm_opp(void); | ||
17 | 33 | ||
18 | #else /* !CONFIG_UX500_SOC_DB5500 */ | 34 | #else /* !CONFIG_UX500_SOC_DB5500 */ |
19 | 35 | ||
20 | static inline void db5500_prcmu_early_init(void) | 36 | static inline void db5500_prcmu_early_init(void) {} |
21 | { | ||
22 | } | ||
23 | 37 | ||
24 | static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) | 38 | static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) |
25 | { | 39 | { |
@@ -31,15 +45,75 @@ static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | |||
31 | return -ENOSYS; | 45 | return -ENOSYS; |
32 | } | 46 | } |
33 | 47 | ||
34 | #endif /* CONFIG_UX500_SOC_DB5500 */ | 48 | static inline int db5500_prcmu_request_clock(u8 clock, bool enable) |
49 | { | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static inline int db5500_prcmu_set_display_clocks(void) | ||
54 | { | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static inline int db5500_prcmu_disable_dsipll(void) | ||
59 | { | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static inline int db5500_prcmu_enable_dsipll(void) | ||
64 | { | ||
65 | return 0; | ||
66 | } | ||
35 | 67 | ||
36 | static inline int db5500_prcmu_config_abb_event_readout(u32 abb_events) | 68 | static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state) |
37 | { | 69 | { |
38 | #ifdef CONFIG_MACH_U5500_SIMULATOR | ||
39 | return 0; | 70 | return 0; |
40 | #else | ||
41 | return -1; | ||
42 | #endif | ||
43 | } | 71 | } |
44 | 72 | ||
45 | #endif /* __MACH_PRCMU_U5500_H */ | 73 | static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} |
74 | |||
75 | static inline int prcmu_resetout(u8 resoutn, u8 state) | ||
76 | { | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state) | ||
81 | { | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {} | ||
86 | static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {} | ||
87 | |||
88 | static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, | ||
89 | bool keep_ap_pll) | ||
90 | { | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static inline void db5500_prcmu_system_reset(u16 reset_code) {} | ||
95 | |||
96 | static inline u16 db5500_prcmu_get_reset_code(void) | ||
97 | { | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static inline bool db5500_prcmu_is_ac_wake_requested(void) | ||
102 | { | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static inline int db5500_prcmu_set_arm_opp(u8 opp) | ||
107 | { | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static inline int db5500_prcmu_get_arm_opp(void) | ||
112 | { | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | |||
117 | #endif /* CONFIG_MFD_DB5500_PRCMU */ | ||
118 | |||
119 | #endif /* __MFD_DB5500_PRCMU_H */ | ||
diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h index 917dbcab701c..60d27f7bfc1f 100644 --- a/include/linux/mfd/db8500-prcmu.h +++ b/include/linux/mfd/db8500-prcmu.h | |||
@@ -11,7 +11,6 @@ | |||
11 | #define __MFD_DB8500_PRCMU_H | 11 | #define __MFD_DB8500_PRCMU_H |
12 | 12 | ||
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/notifier.h> | ||
15 | 14 | ||
16 | /* This portion previously known as <mach/prcmu-fw-defs_v1.h> */ | 15 | /* This portion previously known as <mach/prcmu-fw-defs_v1.h> */ |
17 | 16 | ||
@@ -133,7 +132,7 @@ enum ap_pwrst { | |||
133 | * @APEXECUTE_TO_APIDLE: Power state transition from ApExecute to ApIdle | 132 | * @APEXECUTE_TO_APIDLE: Power state transition from ApExecute to ApIdle |
134 | */ | 133 | */ |
135 | enum ap_pwrst_trans { | 134 | enum ap_pwrst_trans { |
136 | NO_TRANSITION = 0x00, | 135 | PRCMU_AP_NO_CHANGE = 0x00, |
137 | APEXECUTE_TO_APSLEEP = 0x01, | 136 | APEXECUTE_TO_APSLEEP = 0x01, |
138 | APIDLE_TO_APSLEEP = 0x02, /* To be removed */ | 137 | APIDLE_TO_APSLEEP = 0x02, /* To be removed */ |
139 | PRCMU_AP_SLEEP = 0x01, | 138 | PRCMU_AP_SLEEP = 0x01, |
@@ -146,54 +145,6 @@ enum ap_pwrst_trans { | |||
146 | }; | 145 | }; |
147 | 146 | ||
148 | /** | 147 | /** |
149 | * enum ddr_pwrst - DDR power states definition | ||
150 | * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged | ||
151 | * @DDR_PWR_STATE_ON: | ||
152 | * @DDR_PWR_STATE_OFFLOWLAT: | ||
153 | * @DDR_PWR_STATE_OFFHIGHLAT: | ||
154 | */ | ||
155 | enum ddr_pwrst { | ||
156 | DDR_PWR_STATE_UNCHANGED = 0x00, | ||
157 | DDR_PWR_STATE_ON = 0x01, | ||
158 | DDR_PWR_STATE_OFFLOWLAT = 0x02, | ||
159 | DDR_PWR_STATE_OFFHIGHLAT = 0x03 | ||
160 | }; | ||
161 | |||
162 | /** | ||
163 | * enum arm_opp - ARM OPP states definition | ||
164 | * @ARM_OPP_INIT: | ||
165 | * @ARM_NO_CHANGE: The ARM operating point is unchanged | ||
166 | * @ARM_100_OPP: The new ARM operating point is arm100opp | ||
167 | * @ARM_50_OPP: The new ARM operating point is arm50opp | ||
168 | * @ARM_MAX_OPP: Operating point is "max" (more than 100) | ||
169 | * @ARM_MAX_FREQ100OPP: Set max opp if available, else 100 | ||
170 | * @ARM_EXTCLK: The new ARM operating point is armExtClk | ||
171 | */ | ||
172 | enum arm_opp { | ||
173 | ARM_OPP_INIT = 0x00, | ||
174 | ARM_NO_CHANGE = 0x01, | ||
175 | ARM_100_OPP = 0x02, | ||
176 | ARM_50_OPP = 0x03, | ||
177 | ARM_MAX_OPP = 0x04, | ||
178 | ARM_MAX_FREQ100OPP = 0x05, | ||
179 | ARM_EXTCLK = 0x07 | ||
180 | }; | ||
181 | |||
182 | /** | ||
183 | * enum ape_opp - APE OPP states definition | ||
184 | * @APE_OPP_INIT: | ||
185 | * @APE_NO_CHANGE: The APE operating point is unchanged | ||
186 | * @APE_100_OPP: The new APE operating point is ape100opp | ||
187 | * @APE_50_OPP: 50% | ||
188 | */ | ||
189 | enum ape_opp { | ||
190 | APE_OPP_INIT = 0x00, | ||
191 | APE_NO_CHANGE = 0x01, | ||
192 | APE_100_OPP = 0x02, | ||
193 | APE_50_OPP = 0x03 | ||
194 | }; | ||
195 | |||
196 | /** | ||
197 | * enum hw_acc_state - State definition for hardware accelerator | 148 | * enum hw_acc_state - State definition for hardware accelerator |
198 | * @HW_NO_CHANGE: The hardware accelerator state must remain unchanged | 149 | * @HW_NO_CHANGE: The hardware accelerator state must remain unchanged |
199 | * @HW_OFF: The hardware accelerator must be switched off | 150 | * @HW_OFF: The hardware accelerator must be switched off |
@@ -469,26 +420,6 @@ enum auto_enable { | |||
469 | 420 | ||
470 | /* End of file previously known as prcmu-fw-defs_v1.h */ | 421 | /* End of file previously known as prcmu-fw-defs_v1.h */ |
471 | 422 | ||
472 | /* PRCMU Wakeup defines */ | ||
473 | enum prcmu_wakeup_index { | ||
474 | PRCMU_WAKEUP_INDEX_RTC, | ||
475 | PRCMU_WAKEUP_INDEX_RTT0, | ||
476 | PRCMU_WAKEUP_INDEX_RTT1, | ||
477 | PRCMU_WAKEUP_INDEX_HSI0, | ||
478 | PRCMU_WAKEUP_INDEX_HSI1, | ||
479 | PRCMU_WAKEUP_INDEX_USB, | ||
480 | PRCMU_WAKEUP_INDEX_ABB, | ||
481 | PRCMU_WAKEUP_INDEX_ABB_FIFO, | ||
482 | PRCMU_WAKEUP_INDEX_ARM, | ||
483 | NUM_PRCMU_WAKEUP_INDICES | ||
484 | }; | ||
485 | #define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name)) | ||
486 | |||
487 | /* PRCMU QoS APE OPP class */ | ||
488 | #define PRCMU_QOS_APE_OPP 1 | ||
489 | #define PRCMU_QOS_DDR_OPP 2 | ||
490 | #define PRCMU_QOS_DEFAULT_VALUE -1 | ||
491 | |||
492 | /** | 423 | /** |
493 | * enum hw_acc_dev - enum for hw accelerators | 424 | * enum hw_acc_dev - enum for hw accelerators |
494 | * @HW_ACC_SVAMMDSP: for SVAMMDSP | 425 | * @HW_ACC_SVAMMDSP: for SVAMMDSP |
@@ -527,64 +458,6 @@ enum hw_acc_dev { | |||
527 | }; | 458 | }; |
528 | 459 | ||
529 | /* | 460 | /* |
530 | * Ids for all EPODs (power domains) | ||
531 | * - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP | ||
532 | * - EPOD_ID_SVAPIPE: power domain for SVA pipe | ||
533 | * - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP | ||
534 | * - EPOD_ID_SIAPIPE: power domain for SIA pipe | ||
535 | * - EPOD_ID_SGA: power domain for SGA | ||
536 | * - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE | ||
537 | * - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2 | ||
538 | * - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4 | ||
539 | * - NUM_EPOD_ID: number of power domains | ||
540 | */ | ||
541 | #define EPOD_ID_SVAMMDSP 0 | ||
542 | #define EPOD_ID_SVAPIPE 1 | ||
543 | #define EPOD_ID_SIAMMDSP 2 | ||
544 | #define EPOD_ID_SIAPIPE 3 | ||
545 | #define EPOD_ID_SGA 4 | ||
546 | #define EPOD_ID_B2R2_MCDE 5 | ||
547 | #define EPOD_ID_ESRAM12 6 | ||
548 | #define EPOD_ID_ESRAM34 7 | ||
549 | #define NUM_EPOD_ID 8 | ||
550 | |||
551 | /* | ||
552 | * state definition for EPOD (power domain) | ||
553 | * - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged | ||
554 | * - EPOD_STATE_OFF: The EPOD is switched off | ||
555 | * - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in | ||
556 | * retention | ||
557 | * - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off | ||
558 | * - EPOD_STATE_ON: Same as above, but with clock enabled | ||
559 | */ | ||
560 | #define EPOD_STATE_NO_CHANGE 0x00 | ||
561 | #define EPOD_STATE_OFF 0x01 | ||
562 | #define EPOD_STATE_RAMRET 0x02 | ||
563 | #define EPOD_STATE_ON_CLK_OFF 0x03 | ||
564 | #define EPOD_STATE_ON 0x04 | ||
565 | |||
566 | /* | ||
567 | * CLKOUT sources | ||
568 | */ | ||
569 | #define PRCMU_CLKSRC_CLK38M 0x00 | ||
570 | #define PRCMU_CLKSRC_ACLK 0x01 | ||
571 | #define PRCMU_CLKSRC_SYSCLK 0x02 | ||
572 | #define PRCMU_CLKSRC_LCDCLK 0x03 | ||
573 | #define PRCMU_CLKSRC_SDMMCCLK 0x04 | ||
574 | #define PRCMU_CLKSRC_TVCLK 0x05 | ||
575 | #define PRCMU_CLKSRC_TIMCLK 0x06 | ||
576 | #define PRCMU_CLKSRC_CLK009 0x07 | ||
577 | /* These are only valid for CLKOUT1: */ | ||
578 | #define PRCMU_CLKSRC_SIAMMDSPCLK 0x40 | ||
579 | #define PRCMU_CLKSRC_I2CCLK 0x41 | ||
580 | #define PRCMU_CLKSRC_MSP02CLK 0x42 | ||
581 | #define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43 | ||
582 | #define PRCMU_CLKSRC_HSIRXCLK 0x44 | ||
583 | #define PRCMU_CLKSRC_HSITXCLK 0x45 | ||
584 | #define PRCMU_CLKSRC_ARMCLKFIX 0x46 | ||
585 | #define PRCMU_CLKSRC_HDMICLK 0x47 | ||
586 | |||
587 | /* | ||
588 | * Definitions for autonomous power management configuration. | 461 | * Definitions for autonomous power management configuration. |
589 | */ | 462 | */ |
590 | 463 | ||
@@ -620,88 +493,12 @@ struct prcmu_auto_pm_config { | |||
620 | u8 sva_policy; | 493 | u8 sva_policy; |
621 | }; | 494 | }; |
622 | 495 | ||
623 | /** | ||
624 | * enum ddr_opp - DDR OPP states definition | ||
625 | * @DDR_100_OPP: The new DDR operating point is ddr100opp | ||
626 | * @DDR_50_OPP: The new DDR operating point is ddr50opp | ||
627 | * @DDR_25_OPP: The new DDR operating point is ddr25opp | ||
628 | */ | ||
629 | enum ddr_opp { | ||
630 | DDR_100_OPP = 0x00, | ||
631 | DDR_50_OPP = 0x01, | ||
632 | DDR_25_OPP = 0x02, | ||
633 | }; | ||
634 | |||
635 | /* | ||
636 | * Clock identifiers. | ||
637 | */ | ||
638 | enum prcmu_clock { | ||
639 | PRCMU_SGACLK, | ||
640 | PRCMU_UARTCLK, | ||
641 | PRCMU_MSP02CLK, | ||
642 | PRCMU_MSP1CLK, | ||
643 | PRCMU_I2CCLK, | ||
644 | PRCMU_SDMMCCLK, | ||
645 | PRCMU_SLIMCLK, | ||
646 | PRCMU_PER1CLK, | ||
647 | PRCMU_PER2CLK, | ||
648 | PRCMU_PER3CLK, | ||
649 | PRCMU_PER5CLK, | ||
650 | PRCMU_PER6CLK, | ||
651 | PRCMU_PER7CLK, | ||
652 | PRCMU_LCDCLK, | ||
653 | PRCMU_BMLCLK, | ||
654 | PRCMU_HSITXCLK, | ||
655 | PRCMU_HSIRXCLK, | ||
656 | PRCMU_HDMICLK, | ||
657 | PRCMU_APEATCLK, | ||
658 | PRCMU_APETRACECLK, | ||
659 | PRCMU_MCDECLK, | ||
660 | PRCMU_IPI2CCLK, | ||
661 | PRCMU_DSIALTCLK, | ||
662 | PRCMU_DMACLK, | ||
663 | PRCMU_B2R2CLK, | ||
664 | PRCMU_TVCLK, | ||
665 | PRCMU_SSPCLK, | ||
666 | PRCMU_RNGCLK, | ||
667 | PRCMU_UICCCLK, | ||
668 | PRCMU_NUM_REG_CLOCKS, | ||
669 | PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS, | ||
670 | PRCMU_TIMCLK, | ||
671 | }; | ||
672 | |||
673 | /* | ||
674 | * Definitions for controlling ESRAM0 in deep sleep. | ||
675 | */ | ||
676 | #define ESRAM0_DEEP_SLEEP_STATE_OFF 1 | ||
677 | #define ESRAM0_DEEP_SLEEP_STATE_RET 2 | ||
678 | |||
679 | #ifdef CONFIG_MFD_DB8500_PRCMU | ||
680 | void __init prcmu_early_init(void); | ||
681 | int prcmu_set_display_clocks(void); | ||
682 | int prcmu_disable_dsipll(void); | ||
683 | int prcmu_enable_dsipll(void); | ||
684 | #else | ||
685 | static inline void __init prcmu_early_init(void) {} | ||
686 | #endif | ||
687 | |||
688 | #ifdef CONFIG_MFD_DB8500_PRCMU | 496 | #ifdef CONFIG_MFD_DB8500_PRCMU |
689 | 497 | ||
498 | void db8500_prcmu_early_init(void); | ||
690 | int prcmu_set_rc_a2p(enum romcode_write); | 499 | int prcmu_set_rc_a2p(enum romcode_write); |
691 | enum romcode_read prcmu_get_rc_p2a(void); | 500 | enum romcode_read prcmu_get_rc_p2a(void); |
692 | enum ap_pwrst prcmu_get_xp70_current_state(void); | 501 | enum ap_pwrst prcmu_get_xp70_current_state(void); |
693 | int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll); | ||
694 | |||
695 | void prcmu_enable_wakeups(u32 wakeups); | ||
696 | static inline void prcmu_disable_wakeups(void) | ||
697 | { | ||
698 | prcmu_enable_wakeups(0); | ||
699 | } | ||
700 | |||
701 | void prcmu_config_abb_event_readout(u32 abb_events); | ||
702 | void prcmu_get_abb_event_buffer(void __iomem **buf); | ||
703 | int prcmu_set_arm_opp(u8 opp); | ||
704 | int prcmu_get_arm_opp(void); | ||
705 | bool prcmu_has_arm_maxopp(void); | 502 | bool prcmu_has_arm_maxopp(void); |
706 | bool prcmu_is_u8400(void); | 503 | bool prcmu_is_u8400(void); |
707 | int prcmu_set_ape_opp(u8 opp); | 504 | int prcmu_set_ape_opp(u8 opp); |
@@ -710,19 +507,14 @@ int prcmu_request_ape_opp_100_voltage(bool enable); | |||
710 | int prcmu_release_usb_wakeup_state(void); | 507 | int prcmu_release_usb_wakeup_state(void); |
711 | int prcmu_set_ddr_opp(u8 opp); | 508 | int prcmu_set_ddr_opp(u8 opp); |
712 | int prcmu_get_ddr_opp(void); | 509 | int prcmu_get_ddr_opp(void); |
713 | unsigned long prcmu_qos_get_cpufreq_opp_delay(void); | ||
714 | void prcmu_qos_set_cpufreq_opp_delay(unsigned long); | ||
715 | /* NOTE! Use regulator framework instead */ | 510 | /* NOTE! Use regulator framework instead */ |
716 | int prcmu_set_hwacc(u16 hw_acc_dev, u8 state); | 511 | int prcmu_set_hwacc(u16 hw_acc_dev, u8 state); |
717 | int prcmu_set_epod(u16 epod_id, u8 epod_state); | ||
718 | void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, | 512 | void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, |
719 | struct prcmu_auto_pm_config *idle); | 513 | struct prcmu_auto_pm_config *idle); |
720 | bool prcmu_is_auto_pm_enabled(void); | 514 | bool prcmu_is_auto_pm_enabled(void); |
721 | 515 | ||
722 | int prcmu_config_clkout(u8 clkout, u8 source, u8 div); | 516 | int prcmu_config_clkout(u8 clkout, u8 source, u8 div); |
723 | int prcmu_request_clock(u8 clock, bool enable); | ||
724 | int prcmu_set_clock_divider(u8 clock, u8 divider); | 517 | int prcmu_set_clock_divider(u8 clock, u8 divider); |
725 | int prcmu_config_esram0_deep_sleep(u8 state); | ||
726 | int prcmu_config_hotdog(u8 threshold); | 518 | int prcmu_config_hotdog(u8 threshold); |
727 | int prcmu_config_hotmon(u8 low, u8 high); | 519 | int prcmu_config_hotmon(u8 low, u8 high); |
728 | int prcmu_start_temp_sense(u16 cycles32k); | 520 | int prcmu_start_temp_sense(u16 cycles32k); |
@@ -732,14 +524,36 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); | |||
732 | 524 | ||
733 | void prcmu_ac_wake_req(void); | 525 | void prcmu_ac_wake_req(void); |
734 | void prcmu_ac_sleep_req(void); | 526 | void prcmu_ac_sleep_req(void); |
735 | void prcmu_system_reset(u16 reset_code); | ||
736 | void prcmu_modem_reset(void); | 527 | void prcmu_modem_reset(void); |
737 | bool prcmu_is_ac_wake_requested(void); | ||
738 | void prcmu_enable_spi2(void); | 528 | void prcmu_enable_spi2(void); |
739 | void prcmu_disable_spi2(void); | 529 | void prcmu_disable_spi2(void); |
740 | 530 | ||
531 | int prcmu_config_a9wdog(u8 num, bool sleep_auto_off); | ||
532 | int prcmu_enable_a9wdog(u8 id); | ||
533 | int prcmu_disable_a9wdog(u8 id); | ||
534 | int prcmu_kick_a9wdog(u8 id); | ||
535 | int prcmu_load_a9wdog(u8 id, u32 val); | ||
536 | |||
537 | void db8500_prcmu_system_reset(u16 reset_code); | ||
538 | int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll); | ||
539 | void db8500_prcmu_enable_wakeups(u32 wakeups); | ||
540 | int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state); | ||
541 | int db8500_prcmu_request_clock(u8 clock, bool enable); | ||
542 | int db8500_prcmu_set_display_clocks(void); | ||
543 | int db8500_prcmu_disable_dsipll(void); | ||
544 | int db8500_prcmu_enable_dsipll(void); | ||
545 | void db8500_prcmu_config_abb_event_readout(u32 abb_events); | ||
546 | void db8500_prcmu_get_abb_event_buffer(void __iomem **buf); | ||
547 | int db8500_prcmu_config_esram0_deep_sleep(u8 state); | ||
548 | u16 db8500_prcmu_get_reset_code(void); | ||
549 | bool db8500_prcmu_is_ac_wake_requested(void); | ||
550 | int db8500_prcmu_set_arm_opp(u8 opp); | ||
551 | int db8500_prcmu_get_arm_opp(void); | ||
552 | |||
741 | #else /* !CONFIG_MFD_DB8500_PRCMU */ | 553 | #else /* !CONFIG_MFD_DB8500_PRCMU */ |
742 | 554 | ||
555 | static inline void db8500_prcmu_early_init(void) {} | ||
556 | |||
743 | static inline int prcmu_set_rc_a2p(enum romcode_write code) | 557 | static inline int prcmu_set_rc_a2p(enum romcode_write code) |
744 | { | 558 | { |
745 | return 0; | 559 | return 0; |
@@ -755,34 +569,12 @@ static inline enum ap_pwrst prcmu_get_xp70_current_state(void) | |||
755 | return AP_EXECUTE; | 569 | return AP_EXECUTE; |
756 | } | 570 | } |
757 | 571 | ||
758 | static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, | 572 | static inline bool prcmu_has_arm_maxopp(void) |
759 | bool keep_ap_pll) | ||
760 | { | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static inline void prcmu_enable_wakeups(u32 wakeups) {} | ||
765 | |||
766 | static inline void prcmu_disable_wakeups(void) {} | ||
767 | |||
768 | static inline void prcmu_config_abb_event_readout(u32 abb_events) {} | ||
769 | |||
770 | static inline int prcmu_set_arm_opp(u8 opp) | ||
771 | { | ||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static inline int prcmu_get_arm_opp(void) | ||
776 | { | ||
777 | return ARM_100_OPP; | ||
778 | } | ||
779 | |||
780 | static bool prcmu_has_arm_maxopp(void) | ||
781 | { | 573 | { |
782 | return false; | 574 | return false; |
783 | } | 575 | } |
784 | 576 | ||
785 | static bool prcmu_is_u8400(void) | 577 | static inline bool prcmu_is_u8400(void) |
786 | { | 578 | { |
787 | return false; | 579 | return false; |
788 | } | 580 | } |
@@ -817,13 +609,6 @@ static inline int prcmu_get_ddr_opp(void) | |||
817 | return DDR_100_OPP; | 609 | return DDR_100_OPP; |
818 | } | 610 | } |
819 | 611 | ||
820 | static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void) | ||
821 | { | ||
822 | return 0; | ||
823 | } | ||
824 | |||
825 | static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {} | ||
826 | |||
827 | static inline int prcmu_set_hwacc(u16 hw_acc_dev, u8 state) | 612 | static inline int prcmu_set_hwacc(u16 hw_acc_dev, u8 state) |
828 | { | 613 | { |
829 | return 0; | 614 | return 0; |
@@ -844,21 +629,11 @@ static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div) | |||
844 | return 0; | 629 | return 0; |
845 | } | 630 | } |
846 | 631 | ||
847 | static inline int prcmu_request_clock(u8 clock, bool enable) | ||
848 | { | ||
849 | return 0; | ||
850 | } | ||
851 | |||
852 | static inline int prcmu_set_clock_divider(u8 clock, u8 divider) | 632 | static inline int prcmu_set_clock_divider(u8 clock, u8 divider) |
853 | { | 633 | { |
854 | return 0; | 634 | return 0; |
855 | } | 635 | } |
856 | 636 | ||
857 | int prcmu_config_esram0_deep_sleep(u8 state) | ||
858 | { | ||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | static inline int prcmu_config_hotdog(u8 threshold) | 637 | static inline int prcmu_config_hotdog(u8 threshold) |
863 | { | 638 | { |
864 | return 0; | 639 | return 0; |
@@ -893,86 +668,107 @@ static inline void prcmu_ac_wake_req(void) {} | |||
893 | 668 | ||
894 | static inline void prcmu_ac_sleep_req(void) {} | 669 | static inline void prcmu_ac_sleep_req(void) {} |
895 | 670 | ||
896 | static inline void prcmu_system_reset(u16 reset_code) {} | ||
897 | |||
898 | static inline void prcmu_modem_reset(void) {} | 671 | static inline void prcmu_modem_reset(void) {} |
899 | 672 | ||
900 | static inline bool prcmu_is_ac_wake_requested(void) | 673 | static inline int prcmu_enable_spi2(void) |
901 | { | 674 | { |
902 | return false; | 675 | return 0; |
903 | } | 676 | } |
904 | 677 | ||
905 | #ifndef CONFIG_UX500_SOC_DB5500 | 678 | static inline int prcmu_disable_spi2(void) |
906 | static inline int prcmu_set_display_clocks(void) | ||
907 | { | 679 | { |
908 | return 0; | 680 | return 0; |
909 | } | 681 | } |
910 | 682 | ||
911 | static inline int prcmu_disable_dsipll(void) | 683 | static inline void db8500_prcmu_system_reset(u16 reset_code) {} |
684 | |||
685 | static inline int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, | ||
686 | bool keep_ap_pll) | ||
912 | { | 687 | { |
913 | return 0; | 688 | return 0; |
914 | } | 689 | } |
915 | 690 | ||
916 | static inline int prcmu_enable_dsipll(void) | 691 | static inline void db8500_prcmu_enable_wakeups(u32 wakeups) {} |
692 | |||
693 | static inline int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state) | ||
917 | { | 694 | { |
918 | return 0; | 695 | return 0; |
919 | } | 696 | } |
920 | #endif | ||
921 | 697 | ||
922 | static inline int prcmu_enable_spi2(void) | 698 | static inline int db8500_prcmu_request_clock(u8 clock, bool enable) |
923 | { | 699 | { |
924 | return 0; | 700 | return 0; |
925 | } | 701 | } |
926 | 702 | ||
927 | static inline int prcmu_disable_spi2(void) | 703 | static inline int db8500_prcmu_set_display_clocks(void) |
928 | { | 704 | { |
929 | return 0; | 705 | return 0; |
930 | } | 706 | } |
931 | 707 | ||
932 | #endif /* !CONFIG_MFD_DB8500_PRCMU */ | 708 | static inline int db8500_prcmu_disable_dsipll(void) |
709 | { | ||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static inline int db8500_prcmu_enable_dsipll(void) | ||
714 | { | ||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | static inline int db8500_prcmu_config_esram0_deep_sleep(u8 state) | ||
719 | { | ||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | static inline void db8500_prcmu_config_abb_event_readout(u32 abb_events) {} | ||
933 | 724 | ||
934 | #ifdef CONFIG_UX500_PRCMU_QOS_POWER | 725 | static inline void db8500_prcmu_get_abb_event_buffer(void __iomem **buf) {} |
935 | int prcmu_qos_requirement(int pm_qos_class); | 726 | |
936 | int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value); | 727 | static inline u16 db8500_prcmu_get_reset_code(void) |
937 | int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value); | ||
938 | void prcmu_qos_remove_requirement(int pm_qos_class, char *name); | ||
939 | int prcmu_qos_add_notifier(int prcmu_qos_class, | ||
940 | struct notifier_block *notifier); | ||
941 | int prcmu_qos_remove_notifier(int prcmu_qos_class, | ||
942 | struct notifier_block *notifier); | ||
943 | #else | ||
944 | static inline int prcmu_qos_requirement(int prcmu_qos_class) | ||
945 | { | 728 | { |
946 | return 0; | 729 | return 0; |
947 | } | 730 | } |
948 | 731 | ||
949 | static inline int prcmu_qos_add_requirement(int prcmu_qos_class, | 732 | static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off) |
950 | char *name, s32 value) | ||
951 | { | 733 | { |
952 | return 0; | 734 | return 0; |
953 | } | 735 | } |
954 | 736 | ||
955 | static inline int prcmu_qos_update_requirement(int prcmu_qos_class, | 737 | static inline int prcmu_enable_a9wdog(u8 id) |
956 | char *name, s32 new_value) | ||
957 | { | 738 | { |
958 | return 0; | 739 | return 0; |
959 | } | 740 | } |
960 | 741 | ||
961 | static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name) | 742 | static inline int prcmu_disable_a9wdog(u8 id) |
962 | { | 743 | { |
744 | return 0; | ||
963 | } | 745 | } |
964 | 746 | ||
965 | static inline int prcmu_qos_add_notifier(int prcmu_qos_class, | 747 | static inline int prcmu_kick_a9wdog(u8 id) |
966 | struct notifier_block *notifier) | ||
967 | { | 748 | { |
968 | return 0; | 749 | return 0; |
969 | } | 750 | } |
970 | static inline int prcmu_qos_remove_notifier(int prcmu_qos_class, | 751 | |
971 | struct notifier_block *notifier) | 752 | static inline int prcmu_load_a9wdog(u8 id, u32 val) |
972 | { | 753 | { |
973 | return 0; | 754 | return 0; |
974 | } | 755 | } |
975 | 756 | ||
976 | #endif | 757 | static inline bool db8500_prcmu_is_ac_wake_requested(void) |
758 | { | ||
759 | return 0; | ||
760 | } | ||
761 | |||
762 | static inline int db8500_prcmu_set_arm_opp(u8 opp) | ||
763 | { | ||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | static inline int db8500_prcmu_get_arm_opp(void) | ||
768 | { | ||
769 | return 0; | ||
770 | } | ||
771 | |||
772 | #endif /* !CONFIG_MFD_DB8500_PRCMU */ | ||
977 | 773 | ||
978 | #endif /* __MFD_DB8500_PRCMU_H */ | 774 | #endif /* __MFD_DB8500_PRCMU_H */ |
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h new file mode 100644 index 000000000000..bac942f959c1 --- /dev/null +++ b/include/linux/mfd/dbx500-prcmu.h | |||
@@ -0,0 +1,549 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST Ericsson SA 2011 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * | ||
6 | * STE Ux500 PRCMU API | ||
7 | */ | ||
8 | #ifndef __MACH_PRCMU_H | ||
9 | #define __MACH_PRCMU_H | ||
10 | |||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/notifier.h> | ||
13 | #include <asm/mach-types.h> | ||
14 | |||
15 | /* PRCMU Wakeup defines */ | ||
16 | enum prcmu_wakeup_index { | ||
17 | PRCMU_WAKEUP_INDEX_RTC, | ||
18 | PRCMU_WAKEUP_INDEX_RTT0, | ||
19 | PRCMU_WAKEUP_INDEX_RTT1, | ||
20 | PRCMU_WAKEUP_INDEX_HSI0, | ||
21 | PRCMU_WAKEUP_INDEX_HSI1, | ||
22 | PRCMU_WAKEUP_INDEX_USB, | ||
23 | PRCMU_WAKEUP_INDEX_ABB, | ||
24 | PRCMU_WAKEUP_INDEX_ABB_FIFO, | ||
25 | PRCMU_WAKEUP_INDEX_ARM, | ||
26 | PRCMU_WAKEUP_INDEX_CD_IRQ, | ||
27 | NUM_PRCMU_WAKEUP_INDICES | ||
28 | }; | ||
29 | #define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name)) | ||
30 | |||
31 | /* EPOD (power domain) IDs */ | ||
32 | |||
33 | /* | ||
34 | * DB8500 EPODs | ||
35 | * - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP | ||
36 | * - EPOD_ID_SVAPIPE: power domain for SVA pipe | ||
37 | * - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP | ||
38 | * - EPOD_ID_SIAPIPE: power domain for SIA pipe | ||
39 | * - EPOD_ID_SGA: power domain for SGA | ||
40 | * - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE | ||
41 | * - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2 | ||
42 | * - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4 | ||
43 | * - NUM_EPOD_ID: number of power domains | ||
44 | * | ||
45 | * TODO: These should be prefixed. | ||
46 | */ | ||
47 | #define EPOD_ID_SVAMMDSP 0 | ||
48 | #define EPOD_ID_SVAPIPE 1 | ||
49 | #define EPOD_ID_SIAMMDSP 2 | ||
50 | #define EPOD_ID_SIAPIPE 3 | ||
51 | #define EPOD_ID_SGA 4 | ||
52 | #define EPOD_ID_B2R2_MCDE 5 | ||
53 | #define EPOD_ID_ESRAM12 6 | ||
54 | #define EPOD_ID_ESRAM34 7 | ||
55 | #define NUM_EPOD_ID 8 | ||
56 | |||
57 | /* | ||
58 | * DB5500 EPODs | ||
59 | */ | ||
60 | #define DB5500_EPOD_ID_BASE 0x0100 | ||
61 | #define DB5500_EPOD_ID_SGA (DB5500_EPOD_ID_BASE + 0) | ||
62 | #define DB5500_EPOD_ID_HVA (DB5500_EPOD_ID_BASE + 1) | ||
63 | #define DB5500_EPOD_ID_SIA (DB5500_EPOD_ID_BASE + 2) | ||
64 | #define DB5500_EPOD_ID_DISP (DB5500_EPOD_ID_BASE + 3) | ||
65 | #define DB5500_EPOD_ID_ESRAM12 (DB5500_EPOD_ID_BASE + 6) | ||
66 | #define DB5500_NUM_EPOD_ID 7 | ||
67 | |||
68 | /* | ||
69 | * state definition for EPOD (power domain) | ||
70 | * - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged | ||
71 | * - EPOD_STATE_OFF: The EPOD is switched off | ||
72 | * - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in | ||
73 | * retention | ||
74 | * - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off | ||
75 | * - EPOD_STATE_ON: Same as above, but with clock enabled | ||
76 | */ | ||
77 | #define EPOD_STATE_NO_CHANGE 0x00 | ||
78 | #define EPOD_STATE_OFF 0x01 | ||
79 | #define EPOD_STATE_RAMRET 0x02 | ||
80 | #define EPOD_STATE_ON_CLK_OFF 0x03 | ||
81 | #define EPOD_STATE_ON 0x04 | ||
82 | |||
83 | /* | ||
84 | * CLKOUT sources | ||
85 | */ | ||
86 | #define PRCMU_CLKSRC_CLK38M 0x00 | ||
87 | #define PRCMU_CLKSRC_ACLK 0x01 | ||
88 | #define PRCMU_CLKSRC_SYSCLK 0x02 | ||
89 | #define PRCMU_CLKSRC_LCDCLK 0x03 | ||
90 | #define PRCMU_CLKSRC_SDMMCCLK 0x04 | ||
91 | #define PRCMU_CLKSRC_TVCLK 0x05 | ||
92 | #define PRCMU_CLKSRC_TIMCLK 0x06 | ||
93 | #define PRCMU_CLKSRC_CLK009 0x07 | ||
94 | /* These are only valid for CLKOUT1: */ | ||
95 | #define PRCMU_CLKSRC_SIAMMDSPCLK 0x40 | ||
96 | #define PRCMU_CLKSRC_I2CCLK 0x41 | ||
97 | #define PRCMU_CLKSRC_MSP02CLK 0x42 | ||
98 | #define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43 | ||
99 | #define PRCMU_CLKSRC_HSIRXCLK 0x44 | ||
100 | #define PRCMU_CLKSRC_HSITXCLK 0x45 | ||
101 | #define PRCMU_CLKSRC_ARMCLKFIX 0x46 | ||
102 | #define PRCMU_CLKSRC_HDMICLK 0x47 | ||
103 | |||
104 | /* | ||
105 | * Clock identifiers. | ||
106 | */ | ||
107 | enum prcmu_clock { | ||
108 | PRCMU_SGACLK, | ||
109 | PRCMU_UARTCLK, | ||
110 | PRCMU_MSP02CLK, | ||
111 | PRCMU_MSP1CLK, | ||
112 | PRCMU_I2CCLK, | ||
113 | PRCMU_SDMMCCLK, | ||
114 | PRCMU_SLIMCLK, | ||
115 | PRCMU_PER1CLK, | ||
116 | PRCMU_PER2CLK, | ||
117 | PRCMU_PER3CLK, | ||
118 | PRCMU_PER5CLK, | ||
119 | PRCMU_PER6CLK, | ||
120 | PRCMU_PER7CLK, | ||
121 | PRCMU_LCDCLK, | ||
122 | PRCMU_BMLCLK, | ||
123 | PRCMU_HSITXCLK, | ||
124 | PRCMU_HSIRXCLK, | ||
125 | PRCMU_HDMICLK, | ||
126 | PRCMU_APEATCLK, | ||
127 | PRCMU_APETRACECLK, | ||
128 | PRCMU_MCDECLK, | ||
129 | PRCMU_IPI2CCLK, | ||
130 | PRCMU_DSIALTCLK, | ||
131 | PRCMU_DMACLK, | ||
132 | PRCMU_B2R2CLK, | ||
133 | PRCMU_TVCLK, | ||
134 | PRCMU_SSPCLK, | ||
135 | PRCMU_RNGCLK, | ||
136 | PRCMU_UICCCLK, | ||
137 | PRCMU_PWMCLK, | ||
138 | PRCMU_IRDACLK, | ||
139 | PRCMU_IRRCCLK, | ||
140 | PRCMU_SIACLK, | ||
141 | PRCMU_SVACLK, | ||
142 | PRCMU_NUM_REG_CLOCKS, | ||
143 | PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS, | ||
144 | PRCMU_TIMCLK, | ||
145 | PRCMU_PLLSOC0, | ||
146 | PRCMU_PLLSOC1, | ||
147 | PRCMU_PLLDDR, | ||
148 | }; | ||
149 | |||
150 | /** | ||
151 | * enum ape_opp - APE OPP states definition | ||
152 | * @APE_OPP_INIT: | ||
153 | * @APE_NO_CHANGE: The APE operating point is unchanged | ||
154 | * @APE_100_OPP: The new APE operating point is ape100opp | ||
155 | * @APE_50_OPP: 50% | ||
156 | */ | ||
157 | enum ape_opp { | ||
158 | APE_OPP_INIT = 0x00, | ||
159 | APE_NO_CHANGE = 0x01, | ||
160 | APE_100_OPP = 0x02, | ||
161 | APE_50_OPP = 0x03 | ||
162 | }; | ||
163 | |||
164 | /** | ||
165 | * enum arm_opp - ARM OPP states definition | ||
166 | * @ARM_OPP_INIT: | ||
167 | * @ARM_NO_CHANGE: The ARM operating point is unchanged | ||
168 | * @ARM_100_OPP: The new ARM operating point is arm100opp | ||
169 | * @ARM_50_OPP: The new ARM operating point is arm50opp | ||
170 | * @ARM_MAX_OPP: Operating point is "max" (more than 100) | ||
171 | * @ARM_MAX_FREQ100OPP: Set max opp if available, else 100 | ||
172 | * @ARM_EXTCLK: The new ARM operating point is armExtClk | ||
173 | */ | ||
174 | enum arm_opp { | ||
175 | ARM_OPP_INIT = 0x00, | ||
176 | ARM_NO_CHANGE = 0x01, | ||
177 | ARM_100_OPP = 0x02, | ||
178 | ARM_50_OPP = 0x03, | ||
179 | ARM_MAX_OPP = 0x04, | ||
180 | ARM_MAX_FREQ100OPP = 0x05, | ||
181 | ARM_EXTCLK = 0x07 | ||
182 | }; | ||
183 | |||
184 | /** | ||
185 | * enum ddr_opp - DDR OPP states definition | ||
186 | * @DDR_100_OPP: The new DDR operating point is ddr100opp | ||
187 | * @DDR_50_OPP: The new DDR operating point is ddr50opp | ||
188 | * @DDR_25_OPP: The new DDR operating point is ddr25opp | ||
189 | */ | ||
190 | enum ddr_opp { | ||
191 | DDR_100_OPP = 0x00, | ||
192 | DDR_50_OPP = 0x01, | ||
193 | DDR_25_OPP = 0x02, | ||
194 | }; | ||
195 | |||
196 | /* | ||
197 | * Definitions for controlling ESRAM0 in deep sleep. | ||
198 | */ | ||
199 | #define ESRAM0_DEEP_SLEEP_STATE_OFF 1 | ||
200 | #define ESRAM0_DEEP_SLEEP_STATE_RET 2 | ||
201 | |||
202 | /** | ||
203 | * enum ddr_pwrst - DDR power states definition | ||
204 | * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged | ||
205 | * @DDR_PWR_STATE_ON: | ||
206 | * @DDR_PWR_STATE_OFFLOWLAT: | ||
207 | * @DDR_PWR_STATE_OFFHIGHLAT: | ||
208 | */ | ||
209 | enum ddr_pwrst { | ||
210 | DDR_PWR_STATE_UNCHANGED = 0x00, | ||
211 | DDR_PWR_STATE_ON = 0x01, | ||
212 | DDR_PWR_STATE_OFFLOWLAT = 0x02, | ||
213 | DDR_PWR_STATE_OFFHIGHLAT = 0x03 | ||
214 | }; | ||
215 | |||
216 | #include <linux/mfd/db8500-prcmu.h> | ||
217 | #include <linux/mfd/db5500-prcmu.h> | ||
218 | |||
219 | #if defined(CONFIG_UX500_SOC_DB8500) || defined(CONFIG_UX500_SOC_DB5500) | ||
220 | |||
221 | static inline void __init prcmu_early_init(void) | ||
222 | { | ||
223 | if (machine_is_u5500()) | ||
224 | return db5500_prcmu_early_init(); | ||
225 | else | ||
226 | return db8500_prcmu_early_init(); | ||
227 | } | ||
228 | |||
229 | static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, | ||
230 | bool keep_ap_pll) | ||
231 | { | ||
232 | if (machine_is_u5500()) | ||
233 | return db5500_prcmu_set_power_state(state, keep_ulp_clk, | ||
234 | keep_ap_pll); | ||
235 | else | ||
236 | return db8500_prcmu_set_power_state(state, keep_ulp_clk, | ||
237 | keep_ap_pll); | ||
238 | } | ||
239 | |||
240 | static inline int prcmu_set_epod(u16 epod_id, u8 epod_state) | ||
241 | { | ||
242 | if (machine_is_u5500()) | ||
243 | return -EINVAL; | ||
244 | else | ||
245 | return db8500_prcmu_set_epod(epod_id, epod_state); | ||
246 | } | ||
247 | |||
248 | static inline void prcmu_enable_wakeups(u32 wakeups) | ||
249 | { | ||
250 | if (machine_is_u5500()) | ||
251 | db5500_prcmu_enable_wakeups(wakeups); | ||
252 | else | ||
253 | db8500_prcmu_enable_wakeups(wakeups); | ||
254 | } | ||
255 | |||
256 | static inline void prcmu_disable_wakeups(void) | ||
257 | { | ||
258 | prcmu_enable_wakeups(0); | ||
259 | } | ||
260 | |||
261 | static inline void prcmu_config_abb_event_readout(u32 abb_events) | ||
262 | { | ||
263 | if (machine_is_u5500()) | ||
264 | db5500_prcmu_config_abb_event_readout(abb_events); | ||
265 | else | ||
266 | db8500_prcmu_config_abb_event_readout(abb_events); | ||
267 | } | ||
268 | |||
269 | static inline void prcmu_get_abb_event_buffer(void __iomem **buf) | ||
270 | { | ||
271 | if (machine_is_u5500()) | ||
272 | db5500_prcmu_get_abb_event_buffer(buf); | ||
273 | else | ||
274 | db8500_prcmu_get_abb_event_buffer(buf); | ||
275 | } | ||
276 | |||
277 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); | ||
278 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); | ||
279 | |||
280 | int prcmu_config_clkout(u8 clkout, u8 source, u8 div); | ||
281 | |||
282 | static inline int prcmu_request_clock(u8 clock, bool enable) | ||
283 | { | ||
284 | if (machine_is_u5500()) | ||
285 | return db5500_prcmu_request_clock(clock, enable); | ||
286 | else | ||
287 | return db8500_prcmu_request_clock(clock, enable); | ||
288 | } | ||
289 | |||
290 | int prcmu_set_ape_opp(u8 opp); | ||
291 | int prcmu_get_ape_opp(void); | ||
292 | int prcmu_set_ddr_opp(u8 opp); | ||
293 | int prcmu_get_ddr_opp(void); | ||
294 | |||
295 | static inline int prcmu_set_arm_opp(u8 opp) | ||
296 | { | ||
297 | if (machine_is_u5500()) | ||
298 | return -EINVAL; | ||
299 | else | ||
300 | return db8500_prcmu_set_arm_opp(opp); | ||
301 | } | ||
302 | |||
303 | static inline int prcmu_get_arm_opp(void) | ||
304 | { | ||
305 | if (machine_is_u5500()) | ||
306 | return -EINVAL; | ||
307 | else | ||
308 | return db8500_prcmu_get_arm_opp(); | ||
309 | } | ||
310 | |||
311 | static inline void prcmu_system_reset(u16 reset_code) | ||
312 | { | ||
313 | if (machine_is_u5500()) | ||
314 | return db5500_prcmu_system_reset(reset_code); | ||
315 | else | ||
316 | return db8500_prcmu_system_reset(reset_code); | ||
317 | } | ||
318 | |||
319 | static inline u16 prcmu_get_reset_code(void) | ||
320 | { | ||
321 | if (machine_is_u5500()) | ||
322 | return db5500_prcmu_get_reset_code(); | ||
323 | else | ||
324 | return db8500_prcmu_get_reset_code(); | ||
325 | } | ||
326 | |||
327 | void prcmu_ac_wake_req(void); | ||
328 | void prcmu_ac_sleep_req(void); | ||
329 | void prcmu_modem_reset(void); | ||
330 | static inline bool prcmu_is_ac_wake_requested(void) | ||
331 | { | ||
332 | if (machine_is_u5500()) | ||
333 | return db5500_prcmu_is_ac_wake_requested(); | ||
334 | else | ||
335 | return db8500_prcmu_is_ac_wake_requested(); | ||
336 | } | ||
337 | |||
338 | static inline int prcmu_set_display_clocks(void) | ||
339 | { | ||
340 | if (machine_is_u5500()) | ||
341 | return db5500_prcmu_set_display_clocks(); | ||
342 | else | ||
343 | return db8500_prcmu_set_display_clocks(); | ||
344 | } | ||
345 | |||
346 | static inline int prcmu_disable_dsipll(void) | ||
347 | { | ||
348 | if (machine_is_u5500()) | ||
349 | return db5500_prcmu_disable_dsipll(); | ||
350 | else | ||
351 | return db8500_prcmu_disable_dsipll(); | ||
352 | } | ||
353 | |||
354 | static inline int prcmu_enable_dsipll(void) | ||
355 | { | ||
356 | if (machine_is_u5500()) | ||
357 | return db5500_prcmu_enable_dsipll(); | ||
358 | else | ||
359 | return db8500_prcmu_enable_dsipll(); | ||
360 | } | ||
361 | |||
362 | static inline int prcmu_config_esram0_deep_sleep(u8 state) | ||
363 | { | ||
364 | if (machine_is_u5500()) | ||
365 | return -EINVAL; | ||
366 | else | ||
367 | return db8500_prcmu_config_esram0_deep_sleep(state); | ||
368 | } | ||
369 | #else | ||
370 | |||
371 | static inline void __init prcmu_early_init(void) {} | ||
372 | |||
373 | static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, | ||
374 | bool keep_ap_pll) | ||
375 | { | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static inline int prcmu_set_epod(u16 epod_id, u8 epod_state) | ||
380 | { | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static inline void prcmu_enable_wakeups(u32 wakeups) {} | ||
385 | |||
386 | static inline void prcmu_disable_wakeups(void) {} | ||
387 | |||
388 | static inline int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) | ||
389 | { | ||
390 | return -ENOSYS; | ||
391 | } | ||
392 | |||
393 | static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | ||
394 | { | ||
395 | return -ENOSYS; | ||
396 | } | ||
397 | |||
398 | static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div) | ||
399 | { | ||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static inline int prcmu_request_clock(u8 clock, bool enable) | ||
404 | { | ||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static inline int prcmu_set_ape_opp(u8 opp) | ||
409 | { | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static inline int prcmu_get_ape_opp(void) | ||
414 | { | ||
415 | return APE_100_OPP; | ||
416 | } | ||
417 | |||
418 | static inline int prcmu_set_arm_opp(u8 opp) | ||
419 | { | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static inline int prcmu_get_arm_opp(void) | ||
424 | { | ||
425 | return ARM_100_OPP; | ||
426 | } | ||
427 | |||
428 | static inline int prcmu_set_ddr_opp(u8 opp) | ||
429 | { | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static inline int prcmu_get_ddr_opp(void) | ||
434 | { | ||
435 | return DDR_100_OPP; | ||
436 | } | ||
437 | |||
438 | static inline void prcmu_system_reset(u16 reset_code) {} | ||
439 | |||
440 | static inline u16 prcmu_get_reset_code(void) | ||
441 | { | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | static inline void prcmu_ac_wake_req(void) {} | ||
446 | |||
447 | static inline void prcmu_ac_sleep_req(void) {} | ||
448 | |||
449 | static inline void prcmu_modem_reset(void) {} | ||
450 | |||
451 | static inline bool prcmu_is_ac_wake_requested(void) | ||
452 | { | ||
453 | return false; | ||
454 | } | ||
455 | |||
456 | static inline int prcmu_set_display_clocks(void) | ||
457 | { | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | static inline int prcmu_disable_dsipll(void) | ||
462 | { | ||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static inline int prcmu_enable_dsipll(void) | ||
467 | { | ||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static inline int prcmu_config_esram0_deep_sleep(u8 state) | ||
472 | { | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static inline void prcmu_config_abb_event_readout(u32 abb_events) {} | ||
477 | |||
478 | static inline void prcmu_get_abb_event_buffer(void __iomem **buf) | ||
479 | { | ||
480 | *buf = NULL; | ||
481 | } | ||
482 | |||
483 | #endif | ||
484 | |||
485 | /* PRCMU QoS APE OPP class */ | ||
486 | #define PRCMU_QOS_APE_OPP 1 | ||
487 | #define PRCMU_QOS_DDR_OPP 2 | ||
488 | #define PRCMU_QOS_DEFAULT_VALUE -1 | ||
489 | |||
490 | #ifdef CONFIG_UX500_PRCMU_QOS_POWER | ||
491 | |||
492 | unsigned long prcmu_qos_get_cpufreq_opp_delay(void); | ||
493 | void prcmu_qos_set_cpufreq_opp_delay(unsigned long); | ||
494 | void prcmu_qos_force_opp(int, s32); | ||
495 | int prcmu_qos_requirement(int pm_qos_class); | ||
496 | int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value); | ||
497 | int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value); | ||
498 | void prcmu_qos_remove_requirement(int pm_qos_class, char *name); | ||
499 | int prcmu_qos_add_notifier(int prcmu_qos_class, | ||
500 | struct notifier_block *notifier); | ||
501 | int prcmu_qos_remove_notifier(int prcmu_qos_class, | ||
502 | struct notifier_block *notifier); | ||
503 | |||
504 | #else | ||
505 | |||
506 | static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void) | ||
507 | { | ||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {} | ||
512 | |||
513 | static inline void prcmu_qos_force_opp(int prcmu_qos_class, s32 i) {} | ||
514 | |||
515 | static inline int prcmu_qos_requirement(int prcmu_qos_class) | ||
516 | { | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | static inline int prcmu_qos_add_requirement(int prcmu_qos_class, | ||
521 | char *name, s32 value) | ||
522 | { | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | static inline int prcmu_qos_update_requirement(int prcmu_qos_class, | ||
527 | char *name, s32 new_value) | ||
528 | { | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name) | ||
533 | { | ||
534 | } | ||
535 | |||
536 | static inline int prcmu_qos_add_notifier(int prcmu_qos_class, | ||
537 | struct notifier_block *notifier) | ||
538 | { | ||
539 | return 0; | ||
540 | } | ||
541 | static inline int prcmu_qos_remove_notifier(int prcmu_qos_class, | ||
542 | struct notifier_block *notifier) | ||
543 | { | ||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | #endif | ||
548 | |||
549 | #endif /* __MACH_PRCMU_H */ | ||
diff --git a/include/linux/mfd/intel_msic.h b/include/linux/mfd/intel_msic.h new file mode 100644 index 000000000000..439a7a617bc9 --- /dev/null +++ b/include/linux/mfd/intel_msic.h | |||
@@ -0,0 +1,456 @@ | |||
1 | /* | ||
2 | * include/linux/mfd/intel_msic.h - Core interface for Intel MSIC | ||
3 | * | ||
4 | * Copyright (C) 2011, Intel Corporation | ||
5 | * Author: Mika Westerberg <mika.westerberg@linux.intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __LINUX_MFD_INTEL_MSIC_H__ | ||
13 | #define __LINUX_MFD_INTEL_MSIC_H__ | ||
14 | |||
15 | /* ID */ | ||
16 | #define INTEL_MSIC_ID0 0x000 /* RO */ | ||
17 | #define INTEL_MSIC_ID1 0x001 /* RO */ | ||
18 | |||
19 | /* IRQ */ | ||
20 | #define INTEL_MSIC_IRQLVL1 0x002 | ||
21 | #define INTEL_MSIC_ADC1INT 0x003 | ||
22 | #define INTEL_MSIC_CCINT 0x004 | ||
23 | #define INTEL_MSIC_PWRSRCINT 0x005 | ||
24 | #define INTEL_MSIC_PWRSRCINT1 0x006 | ||
25 | #define INTEL_MSIC_CHRINT 0x007 | ||
26 | #define INTEL_MSIC_CHRINT1 0x008 | ||
27 | #define INTEL_MSIC_RTCIRQ 0x009 | ||
28 | #define INTEL_MSIC_GPIO0LVIRQ 0x00a | ||
29 | #define INTEL_MSIC_GPIO1LVIRQ 0x00b | ||
30 | #define INTEL_MSIC_GPIOHVIRQ 0x00c | ||
31 | #define INTEL_MSIC_VRINT 0x00d | ||
32 | #define INTEL_MSIC_OCAUDIO 0x00e | ||
33 | #define INTEL_MSIC_ACCDET 0x00f | ||
34 | #define INTEL_MSIC_RESETIRQ1 0x010 | ||
35 | #define INTEL_MSIC_RESETIRQ2 0x011 | ||
36 | #define INTEL_MSIC_MADC1INT 0x012 | ||
37 | #define INTEL_MSIC_MCCINT 0x013 | ||
38 | #define INTEL_MSIC_MPWRSRCINT 0x014 | ||
39 | #define INTEL_MSIC_MPWRSRCINT1 0x015 | ||
40 | #define INTEL_MSIC_MCHRINT 0x016 | ||
41 | #define INTEL_MSIC_MCHRINT1 0x017 | ||
42 | #define INTEL_MSIC_RTCIRQMASK 0x018 | ||
43 | #define INTEL_MSIC_GPIO0LVIRQMASK 0x019 | ||
44 | #define INTEL_MSIC_GPIO1LVIRQMASK 0x01a | ||
45 | #define INTEL_MSIC_GPIOHVIRQMASK 0x01b | ||
46 | #define INTEL_MSIC_VRINTMASK 0x01c | ||
47 | #define INTEL_MSIC_OCAUDIOMASK 0x01d | ||
48 | #define INTEL_MSIC_ACCDETMASK 0x01e | ||
49 | #define INTEL_MSIC_RESETIRQ1MASK 0x01f | ||
50 | #define INTEL_MSIC_RESETIRQ2MASK 0x020 | ||
51 | #define INTEL_MSIC_IRQLVL1MSK 0x021 | ||
52 | #define INTEL_MSIC_PBCONFIG 0x03e | ||
53 | #define INTEL_MSIC_PBSTATUS 0x03f /* RO */ | ||
54 | |||
55 | /* GPIO */ | ||
56 | #define INTEL_MSIC_GPIO0LV7CTLO 0x040 | ||
57 | #define INTEL_MSIC_GPIO0LV6CTLO 0x041 | ||
58 | #define INTEL_MSIC_GPIO0LV5CTLO 0x042 | ||
59 | #define INTEL_MSIC_GPIO0LV4CTLO 0x043 | ||
60 | #define INTEL_MSIC_GPIO0LV3CTLO 0x044 | ||
61 | #define INTEL_MSIC_GPIO0LV2CTLO 0x045 | ||
62 | #define INTEL_MSIC_GPIO0LV1CTLO 0x046 | ||
63 | #define INTEL_MSIC_GPIO0LV0CTLO 0x047 | ||
64 | #define INTEL_MSIC_GPIO1LV7CTLOS 0x048 | ||
65 | #define INTEL_MSIC_GPIO1LV6CTLO 0x049 | ||
66 | #define INTEL_MSIC_GPIO1LV5CTLO 0x04a | ||
67 | #define INTEL_MSIC_GPIO1LV4CTLO 0x04b | ||
68 | #define INTEL_MSIC_GPIO1LV3CTLO 0x04c | ||
69 | #define INTEL_MSIC_GPIO1LV2CTLO 0x04d | ||
70 | #define INTEL_MSIC_GPIO1LV1CTLO 0x04e | ||
71 | #define INTEL_MSIC_GPIO1LV0CTLO 0x04f | ||
72 | #define INTEL_MSIC_GPIO0LV7CTLI 0x050 | ||
73 | #define INTEL_MSIC_GPIO0LV6CTLI 0x051 | ||
74 | #define INTEL_MSIC_GPIO0LV5CTLI 0x052 | ||
75 | #define INTEL_MSIC_GPIO0LV4CTLI 0x053 | ||
76 | #define INTEL_MSIC_GPIO0LV3CTLI 0x054 | ||
77 | #define INTEL_MSIC_GPIO0LV2CTLI 0x055 | ||
78 | #define INTEL_MSIC_GPIO0LV1CTLI 0x056 | ||
79 | #define INTEL_MSIC_GPIO0LV0CTLI 0x057 | ||
80 | #define INTEL_MSIC_GPIO1LV7CTLIS 0x058 | ||
81 | #define INTEL_MSIC_GPIO1LV6CTLI 0x059 | ||
82 | #define INTEL_MSIC_GPIO1LV5CTLI 0x05a | ||
83 | #define INTEL_MSIC_GPIO1LV4CTLI 0x05b | ||
84 | #define INTEL_MSIC_GPIO1LV3CTLI 0x05c | ||
85 | #define INTEL_MSIC_GPIO1LV2CTLI 0x05d | ||
86 | #define INTEL_MSIC_GPIO1LV1CTLI 0x05e | ||
87 | #define INTEL_MSIC_GPIO1LV0CTLI 0x05f | ||
88 | #define INTEL_MSIC_PWM0CLKDIV1 0x061 | ||
89 | #define INTEL_MSIC_PWM0CLKDIV0 0x062 | ||
90 | #define INTEL_MSIC_PWM1CLKDIV1 0x063 | ||
91 | #define INTEL_MSIC_PWM1CLKDIV0 0x064 | ||
92 | #define INTEL_MSIC_PWM2CLKDIV1 0x065 | ||
93 | #define INTEL_MSIC_PWM2CLKDIV0 0x066 | ||
94 | #define INTEL_MSIC_PWM0DUTYCYCLE 0x067 | ||
95 | #define INTEL_MSIC_PWM1DUTYCYCLE 0x068 | ||
96 | #define INTEL_MSIC_PWM2DUTYCYCLE 0x069 | ||
97 | #define INTEL_MSIC_GPIO0HV3CTLO 0x06d | ||
98 | #define INTEL_MSIC_GPIO0HV2CTLO 0x06e | ||
99 | #define INTEL_MSIC_GPIO0HV1CTLO 0x06f | ||
100 | #define INTEL_MSIC_GPIO0HV0CTLO 0x070 | ||
101 | #define INTEL_MSIC_GPIO1HV3CTLO 0x071 | ||
102 | #define INTEL_MSIC_GPIO1HV2CTLO 0x072 | ||
103 | #define INTEL_MSIC_GPIO1HV1CTLO 0x073 | ||
104 | #define INTEL_MSIC_GPIO1HV0CTLO 0x074 | ||
105 | #define INTEL_MSIC_GPIO0HV3CTLI 0x075 | ||
106 | #define INTEL_MSIC_GPIO0HV2CTLI 0x076 | ||
107 | #define INTEL_MSIC_GPIO0HV1CTLI 0x077 | ||
108 | #define INTEL_MSIC_GPIO0HV0CTLI 0x078 | ||
109 | #define INTEL_MSIC_GPIO1HV3CTLI 0x079 | ||
110 | #define INTEL_MSIC_GPIO1HV2CTLI 0x07a | ||
111 | #define INTEL_MSIC_GPIO1HV1CTLI 0x07b | ||
112 | #define INTEL_MSIC_GPIO1HV0CTLI 0x07c | ||
113 | |||
114 | /* SVID */ | ||
115 | #define INTEL_MSIC_SVIDCTRL0 0x080 | ||
116 | #define INTEL_MSIC_SVIDCTRL1 0x081 | ||
117 | #define INTEL_MSIC_SVIDCTRL2 0x082 | ||
118 | #define INTEL_MSIC_SVIDTXLASTPKT3 0x083 /* RO */ | ||
119 | #define INTEL_MSIC_SVIDTXLASTPKT2 0x084 /* RO */ | ||
120 | #define INTEL_MSIC_SVIDTXLASTPKT1 0x085 /* RO */ | ||
121 | #define INTEL_MSIC_SVIDTXLASTPKT0 0x086 /* RO */ | ||
122 | #define INTEL_MSIC_SVIDPKTOUTBYTE3 0x087 | ||
123 | #define INTEL_MSIC_SVIDPKTOUTBYTE2 0x088 | ||
124 | #define INTEL_MSIC_SVIDPKTOUTBYTE1 0x089 | ||
125 | #define INTEL_MSIC_SVIDPKTOUTBYTE0 0x08a | ||
126 | #define INTEL_MSIC_SVIDRXVPDEBUG1 0x08b | ||
127 | #define INTEL_MSIC_SVIDRXVPDEBUG0 0x08c | ||
128 | #define INTEL_MSIC_SVIDRXLASTPKT3 0x08d /* RO */ | ||
129 | #define INTEL_MSIC_SVIDRXLASTPKT2 0x08e /* RO */ | ||
130 | #define INTEL_MSIC_SVIDRXLASTPKT1 0x08f /* RO */ | ||
131 | #define INTEL_MSIC_SVIDRXLASTPKT0 0x090 /* RO */ | ||
132 | #define INTEL_MSIC_SVIDRXCHKSTATUS3 0x091 /* RO */ | ||
133 | #define INTEL_MSIC_SVIDRXCHKSTATUS2 0x092 /* RO */ | ||
134 | #define INTEL_MSIC_SVIDRXCHKSTATUS1 0x093 /* RO */ | ||
135 | #define INTEL_MSIC_SVIDRXCHKSTATUS0 0x094 /* RO */ | ||
136 | |||
137 | /* VREG */ | ||
138 | #define INTEL_MSIC_VCCLATCH 0x0c0 | ||
139 | #define INTEL_MSIC_VNNLATCH 0x0c1 | ||
140 | #define INTEL_MSIC_VCCCNT 0x0c2 | ||
141 | #define INTEL_MSIC_SMPSRAMP 0x0c3 | ||
142 | #define INTEL_MSIC_VNNCNT 0x0c4 | ||
143 | #define INTEL_MSIC_VNNAONCNT 0x0c5 | ||
144 | #define INTEL_MSIC_VCC122AONCNT 0x0c6 | ||
145 | #define INTEL_MSIC_V180AONCNT 0x0c7 | ||
146 | #define INTEL_MSIC_V500CNT 0x0c8 | ||
147 | #define INTEL_MSIC_VIHFCNT 0x0c9 | ||
148 | #define INTEL_MSIC_LDORAMP1 0x0ca | ||
149 | #define INTEL_MSIC_LDORAMP2 0x0cb | ||
150 | #define INTEL_MSIC_VCC108AONCNT 0x0cc | ||
151 | #define INTEL_MSIC_VCC108ASCNT 0x0cd | ||
152 | #define INTEL_MSIC_VCC108CNT 0x0ce | ||
153 | #define INTEL_MSIC_VCCA100ASCNT 0x0cf | ||
154 | #define INTEL_MSIC_VCCA100CNT 0x0d0 | ||
155 | #define INTEL_MSIC_VCC180AONCNT 0x0d1 | ||
156 | #define INTEL_MSIC_VCC180CNT 0x0d2 | ||
157 | #define INTEL_MSIC_VCC330CNT 0x0d3 | ||
158 | #define INTEL_MSIC_VUSB330CNT 0x0d4 | ||
159 | #define INTEL_MSIC_VCCSDIOCNT 0x0d5 | ||
160 | #define INTEL_MSIC_VPROG1CNT 0x0d6 | ||
161 | #define INTEL_MSIC_VPROG2CNT 0x0d7 | ||
162 | #define INTEL_MSIC_VEMMCSCNT 0x0d8 | ||
163 | #define INTEL_MSIC_VEMMC1CNT 0x0d9 | ||
164 | #define INTEL_MSIC_VEMMC2CNT 0x0da | ||
165 | #define INTEL_MSIC_VAUDACNT 0x0db | ||
166 | #define INTEL_MSIC_VHSPCNT 0x0dc | ||
167 | #define INTEL_MSIC_VHSNCNT 0x0dd | ||
168 | #define INTEL_MSIC_VHDMICNT 0x0de | ||
169 | #define INTEL_MSIC_VOTGCNT 0x0df | ||
170 | #define INTEL_MSIC_V1P35CNT 0x0e0 | ||
171 | #define INTEL_MSIC_V330AONCNT 0x0e1 | ||
172 | |||
173 | /* RESET */ | ||
174 | #define INTEL_MSIC_CHIPCNTRL 0x100 /* WO */ | ||
175 | #define INTEL_MSIC_ERCONFIG 0x101 | ||
176 | |||
177 | /* BURST */ | ||
178 | #define INTEL_MSIC_BATCURRENTLIMIT12 0x102 | ||
179 | #define INTEL_MSIC_BATTIMELIMIT12 0x103 | ||
180 | #define INTEL_MSIC_BATTIMELIMIT3 0x104 | ||
181 | #define INTEL_MSIC_BATTIMEDB 0x105 | ||
182 | #define INTEL_MSIC_BRSTCONFIGOUTPUTS 0x106 | ||
183 | #define INTEL_MSIC_BRSTCONFIGACTIONS 0x107 | ||
184 | #define INTEL_MSIC_BURSTCONTROLSTATUS 0x108 | ||
185 | |||
186 | /* RTC */ | ||
187 | #define INTEL_MSIC_RTCB1 0x140 /* RO */ | ||
188 | #define INTEL_MSIC_RTCB2 0x141 /* RO */ | ||
189 | #define INTEL_MSIC_RTCB3 0x142 /* RO */ | ||
190 | #define INTEL_MSIC_RTCB4 0x143 /* RO */ | ||
191 | #define INTEL_MSIC_RTCOB1 0x144 | ||
192 | #define INTEL_MSIC_RTCOB2 0x145 | ||
193 | #define INTEL_MSIC_RTCOB3 0x146 | ||
194 | #define INTEL_MSIC_RTCOB4 0x147 | ||
195 | #define INTEL_MSIC_RTCAB1 0x148 | ||
196 | #define INTEL_MSIC_RTCAB2 0x149 | ||
197 | #define INTEL_MSIC_RTCAB3 0x14a | ||
198 | #define INTEL_MSIC_RTCAB4 0x14b | ||
199 | #define INTEL_MSIC_RTCWAB1 0x14c | ||
200 | #define INTEL_MSIC_RTCWAB2 0x14d | ||
201 | #define INTEL_MSIC_RTCWAB3 0x14e | ||
202 | #define INTEL_MSIC_RTCWAB4 0x14f | ||
203 | #define INTEL_MSIC_RTCSC1 0x150 | ||
204 | #define INTEL_MSIC_RTCSC2 0x151 | ||
205 | #define INTEL_MSIC_RTCSC3 0x152 | ||
206 | #define INTEL_MSIC_RTCSC4 0x153 | ||
207 | #define INTEL_MSIC_RTCSTATUS 0x154 /* RO */ | ||
208 | #define INTEL_MSIC_RTCCONFIG1 0x155 | ||
209 | #define INTEL_MSIC_RTCCONFIG2 0x156 | ||
210 | |||
211 | /* CHARGER */ | ||
212 | #define INTEL_MSIC_BDTIMER 0x180 | ||
213 | #define INTEL_MSIC_BATTRMV 0x181 | ||
214 | #define INTEL_MSIC_VBUSDET 0x182 | ||
215 | #define INTEL_MSIC_VBUSDET1 0x183 | ||
216 | #define INTEL_MSIC_ADPHVDET 0x184 | ||
217 | #define INTEL_MSIC_ADPLVDET 0x185 | ||
218 | #define INTEL_MSIC_ADPDETDBDM 0x186 | ||
219 | #define INTEL_MSIC_LOWBATTDET 0x187 | ||
220 | #define INTEL_MSIC_CHRCTRL 0x188 | ||
221 | #define INTEL_MSIC_CHRCVOLTAGE 0x189 | ||
222 | #define INTEL_MSIC_CHRCCURRENT 0x18a | ||
223 | #define INTEL_MSIC_SPCHARGER 0x18b | ||
224 | #define INTEL_MSIC_CHRTTIME 0x18c | ||
225 | #define INTEL_MSIC_CHRCTRL1 0x18d | ||
226 | #define INTEL_MSIC_PWRSRCLMT 0x18e | ||
227 | #define INTEL_MSIC_CHRSTWDT 0x18f | ||
228 | #define INTEL_MSIC_WDTWRITE 0x190 /* WO */ | ||
229 | #define INTEL_MSIC_CHRSAFELMT 0x191 | ||
230 | #define INTEL_MSIC_SPWRSRCINT 0x192 /* RO */ | ||
231 | #define INTEL_MSIC_SPWRSRCINT1 0x193 /* RO */ | ||
232 | #define INTEL_MSIC_CHRLEDPWM 0x194 | ||
233 | #define INTEL_MSIC_CHRLEDCTRL 0x195 | ||
234 | |||
235 | /* ADC */ | ||
236 | #define INTEL_MSIC_ADC1CNTL1 0x1c0 | ||
237 | #define INTEL_MSIC_ADC1CNTL2 0x1c1 | ||
238 | #define INTEL_MSIC_ADC1CNTL3 0x1c2 | ||
239 | #define INTEL_MSIC_ADC1OFFSETH 0x1c3 /* RO */ | ||
240 | #define INTEL_MSIC_ADC1OFFSETL 0x1c4 /* RO */ | ||
241 | #define INTEL_MSIC_ADC1ADDR0 0x1c5 | ||
242 | #define INTEL_MSIC_ADC1ADDR1 0x1c6 | ||
243 | #define INTEL_MSIC_ADC1ADDR2 0x1c7 | ||
244 | #define INTEL_MSIC_ADC1ADDR3 0x1c8 | ||
245 | #define INTEL_MSIC_ADC1ADDR4 0x1c9 | ||
246 | #define INTEL_MSIC_ADC1ADDR5 0x1ca | ||
247 | #define INTEL_MSIC_ADC1ADDR6 0x1cb | ||
248 | #define INTEL_MSIC_ADC1ADDR7 0x1cc | ||
249 | #define INTEL_MSIC_ADC1ADDR8 0x1cd | ||
250 | #define INTEL_MSIC_ADC1ADDR9 0x1ce | ||
251 | #define INTEL_MSIC_ADC1ADDR10 0x1cf | ||
252 | #define INTEL_MSIC_ADC1ADDR11 0x1d0 | ||
253 | #define INTEL_MSIC_ADC1ADDR12 0x1d1 | ||
254 | #define INTEL_MSIC_ADC1ADDR13 0x1d2 | ||
255 | #define INTEL_MSIC_ADC1ADDR14 0x1d3 | ||
256 | #define INTEL_MSIC_ADC1SNS0H 0x1d4 /* RO */ | ||
257 | #define INTEL_MSIC_ADC1SNS0L 0x1d5 /* RO */ | ||
258 | #define INTEL_MSIC_ADC1SNS1H 0x1d6 /* RO */ | ||
259 | #define INTEL_MSIC_ADC1SNS1L 0x1d7 /* RO */ | ||
260 | #define INTEL_MSIC_ADC1SNS2H 0x1d8 /* RO */ | ||
261 | #define INTEL_MSIC_ADC1SNS2L 0x1d9 /* RO */ | ||
262 | #define INTEL_MSIC_ADC1SNS3H 0x1da /* RO */ | ||
263 | #define INTEL_MSIC_ADC1SNS3L 0x1db /* RO */ | ||
264 | #define INTEL_MSIC_ADC1SNS4H 0x1dc /* RO */ | ||
265 | #define INTEL_MSIC_ADC1SNS4L 0x1dd /* RO */ | ||
266 | #define INTEL_MSIC_ADC1SNS5H 0x1de /* RO */ | ||
267 | #define INTEL_MSIC_ADC1SNS5L 0x1df /* RO */ | ||
268 | #define INTEL_MSIC_ADC1SNS6H 0x1e0 /* RO */ | ||
269 | #define INTEL_MSIC_ADC1SNS6L 0x1e1 /* RO */ | ||
270 | #define INTEL_MSIC_ADC1SNS7H 0x1e2 /* RO */ | ||
271 | #define INTEL_MSIC_ADC1SNS7L 0x1e3 /* RO */ | ||
272 | #define INTEL_MSIC_ADC1SNS8H 0x1e4 /* RO */ | ||
273 | #define INTEL_MSIC_ADC1SNS8L 0x1e5 /* RO */ | ||
274 | #define INTEL_MSIC_ADC1SNS9H 0x1e6 /* RO */ | ||
275 | #define INTEL_MSIC_ADC1SNS9L 0x1e7 /* RO */ | ||
276 | #define INTEL_MSIC_ADC1SNS10H 0x1e8 /* RO */ | ||
277 | #define INTEL_MSIC_ADC1SNS10L 0x1e9 /* RO */ | ||
278 | #define INTEL_MSIC_ADC1SNS11H 0x1ea /* RO */ | ||
279 | #define INTEL_MSIC_ADC1SNS11L 0x1eb /* RO */ | ||
280 | #define INTEL_MSIC_ADC1SNS12H 0x1ec /* RO */ | ||
281 | #define INTEL_MSIC_ADC1SNS12L 0x1ed /* RO */ | ||
282 | #define INTEL_MSIC_ADC1SNS13H 0x1ee /* RO */ | ||
283 | #define INTEL_MSIC_ADC1SNS13L 0x1ef /* RO */ | ||
284 | #define INTEL_MSIC_ADC1SNS14H 0x1f0 /* RO */ | ||
285 | #define INTEL_MSIC_ADC1SNS14L 0x1f1 /* RO */ | ||
286 | #define INTEL_MSIC_ADC1BV0H 0x1f2 /* RO */ | ||
287 | #define INTEL_MSIC_ADC1BV0L 0x1f3 /* RO */ | ||
288 | #define INTEL_MSIC_ADC1BV1H 0x1f4 /* RO */ | ||
289 | #define INTEL_MSIC_ADC1BV1L 0x1f5 /* RO */ | ||
290 | #define INTEL_MSIC_ADC1BV2H 0x1f6 /* RO */ | ||
291 | #define INTEL_MSIC_ADC1BV2L 0x1f7 /* RO */ | ||
292 | #define INTEL_MSIC_ADC1BV3H 0x1f8 /* RO */ | ||
293 | #define INTEL_MSIC_ADC1BV3L 0x1f9 /* RO */ | ||
294 | #define INTEL_MSIC_ADC1BI0H 0x1fa /* RO */ | ||
295 | #define INTEL_MSIC_ADC1BI0L 0x1fb /* RO */ | ||
296 | #define INTEL_MSIC_ADC1BI1H 0x1fc /* RO */ | ||
297 | #define INTEL_MSIC_ADC1BI1L 0x1fd /* RO */ | ||
298 | #define INTEL_MSIC_ADC1BI2H 0x1fe /* RO */ | ||
299 | #define INTEL_MSIC_ADC1BI2L 0x1ff /* RO */ | ||
300 | #define INTEL_MSIC_ADC1BI3H 0x200 /* RO */ | ||
301 | #define INTEL_MSIC_ADC1BI3L 0x201 /* RO */ | ||
302 | #define INTEL_MSIC_CCCNTL 0x202 | ||
303 | #define INTEL_MSIC_CCOFFSETH 0x203 /* RO */ | ||
304 | #define INTEL_MSIC_CCOFFSETL 0x204 /* RO */ | ||
305 | #define INTEL_MSIC_CCADCHA 0x205 /* RO */ | ||
306 | #define INTEL_MSIC_CCADCLA 0x206 /* RO */ | ||
307 | |||
308 | /* AUDIO */ | ||
309 | #define INTEL_MSIC_AUDPLLCTRL 0x240 | ||
310 | #define INTEL_MSIC_DMICBUF0123 0x241 | ||
311 | #define INTEL_MSIC_DMICBUF45 0x242 | ||
312 | #define INTEL_MSIC_DMICGPO 0x244 | ||
313 | #define INTEL_MSIC_DMICMUX 0x245 | ||
314 | #define INTEL_MSIC_DMICCLK 0x246 | ||
315 | #define INTEL_MSIC_MICBIAS 0x247 | ||
316 | #define INTEL_MSIC_ADCCONFIG 0x248 | ||
317 | #define INTEL_MSIC_MICAMP1 0x249 | ||
318 | #define INTEL_MSIC_MICAMP2 0x24a | ||
319 | #define INTEL_MSIC_NOISEMUX 0x24b | ||
320 | #define INTEL_MSIC_AUDIOMUX12 0x24c | ||
321 | #define INTEL_MSIC_AUDIOMUX34 0x24d | ||
322 | #define INTEL_MSIC_AUDIOSINC 0x24e | ||
323 | #define INTEL_MSIC_AUDIOTXEN 0x24f | ||
324 | #define INTEL_MSIC_HSEPRXCTRL 0x250 | ||
325 | #define INTEL_MSIC_IHFRXCTRL 0x251 | ||
326 | #define INTEL_MSIC_VOICETXVOL 0x252 | ||
327 | #define INTEL_MSIC_SIDETONEVOL 0x253 | ||
328 | #define INTEL_MSIC_MUSICSHARVOL 0x254 | ||
329 | #define INTEL_MSIC_VOICETXCTRL 0x255 | ||
330 | #define INTEL_MSIC_HSMIXER 0x256 | ||
331 | #define INTEL_MSIC_DACCONFIG 0x257 | ||
332 | #define INTEL_MSIC_SOFTMUTE 0x258 | ||
333 | #define INTEL_MSIC_HSLVOLCTRL 0x259 | ||
334 | #define INTEL_MSIC_HSRVOLCTRL 0x25a | ||
335 | #define INTEL_MSIC_IHFLVOLCTRL 0x25b | ||
336 | #define INTEL_MSIC_IHFRVOLCTRL 0x25c | ||
337 | #define INTEL_MSIC_DRIVEREN 0x25d | ||
338 | #define INTEL_MSIC_LINEOUTCTRL 0x25e | ||
339 | #define INTEL_MSIC_VIB1CTRL1 0x25f | ||
340 | #define INTEL_MSIC_VIB1CTRL2 0x260 | ||
341 | #define INTEL_MSIC_VIB1CTRL3 0x261 | ||
342 | #define INTEL_MSIC_VIB1SPIPCM_1 0x262 | ||
343 | #define INTEL_MSIC_VIB1SPIPCM_2 0x263 | ||
344 | #define INTEL_MSIC_VIB1CTRL5 0x264 | ||
345 | #define INTEL_MSIC_VIB2CTRL1 0x265 | ||
346 | #define INTEL_MSIC_VIB2CTRL2 0x266 | ||
347 | #define INTEL_MSIC_VIB2CTRL3 0x267 | ||
348 | #define INTEL_MSIC_VIB2SPIPCM_1 0x268 | ||
349 | #define INTEL_MSIC_VIB2SPIPCM_2 0x269 | ||
350 | #define INTEL_MSIC_VIB2CTRL5 0x26a | ||
351 | #define INTEL_MSIC_BTNCTRL1 0x26b | ||
352 | #define INTEL_MSIC_BTNCTRL2 0x26c | ||
353 | #define INTEL_MSIC_PCM1TXSLOT01 0x26d | ||
354 | #define INTEL_MSIC_PCM1TXSLOT23 0x26e | ||
355 | #define INTEL_MSIC_PCM1TXSLOT45 0x26f | ||
356 | #define INTEL_MSIC_PCM1RXSLOT0123 0x270 | ||
357 | #define INTEL_MSIC_PCM1RXSLOT045 0x271 | ||
358 | #define INTEL_MSIC_PCM2TXSLOT01 0x272 | ||
359 | #define INTEL_MSIC_PCM2TXSLOT23 0x273 | ||
360 | #define INTEL_MSIC_PCM2TXSLOT45 0x274 | ||
361 | #define INTEL_MSIC_PCM2RXSLOT01 0x275 | ||
362 | #define INTEL_MSIC_PCM2RXSLOT23 0x276 | ||
363 | #define INTEL_MSIC_PCM2RXSLOT45 0x277 | ||
364 | #define INTEL_MSIC_PCM1CTRL1 0x278 | ||
365 | #define INTEL_MSIC_PCM1CTRL2 0x279 | ||
366 | #define INTEL_MSIC_PCM1CTRL3 0x27a | ||
367 | #define INTEL_MSIC_PCM2CTRL1 0x27b | ||
368 | #define INTEL_MSIC_PCM2CTRL2 0x27c | ||
369 | |||
370 | /* HDMI */ | ||
371 | #define INTEL_MSIC_HDMIPUEN 0x280 | ||
372 | #define INTEL_MSIC_HDMISTATUS 0x281 /* RO */ | ||
373 | |||
374 | /* Physical address of the start of the MSIC interrupt tree in SRAM */ | ||
375 | #define INTEL_MSIC_IRQ_PHYS_BASE 0xffff7fc0 | ||
376 | |||
377 | /** | ||
378 | * struct intel_msic_gpio_pdata - platform data for the MSIC GPIO driver | ||
379 | * @gpio_base: base number for the GPIOs | ||
380 | */ | ||
381 | struct intel_msic_gpio_pdata { | ||
382 | unsigned gpio_base; | ||
383 | }; | ||
384 | |||
385 | /** | ||
386 | * struct intel_msic_ocd_pdata - platform data for the MSIC OCD driver | ||
387 | * @gpio: GPIO number used for OCD interrupts | ||
388 | * | ||
389 | * The MSIC MFD driver converts @gpio into an IRQ number and passes it to | ||
390 | * the OCD driver as %IORESOURCE_IRQ. | ||
391 | */ | ||
392 | struct intel_msic_ocd_pdata { | ||
393 | unsigned gpio; | ||
394 | }; | ||
395 | |||
396 | /* MSIC embedded blocks (subdevices) */ | ||
397 | enum intel_msic_block { | ||
398 | INTEL_MSIC_BLOCK_TOUCH, | ||
399 | INTEL_MSIC_BLOCK_ADC, | ||
400 | INTEL_MSIC_BLOCK_BATTERY, | ||
401 | INTEL_MSIC_BLOCK_GPIO, | ||
402 | INTEL_MSIC_BLOCK_AUDIO, | ||
403 | INTEL_MSIC_BLOCK_HDMI, | ||
404 | INTEL_MSIC_BLOCK_THERMAL, | ||
405 | INTEL_MSIC_BLOCK_POWER_BTN, | ||
406 | INTEL_MSIC_BLOCK_OCD, | ||
407 | |||
408 | INTEL_MSIC_BLOCK_LAST, | ||
409 | }; | ||
410 | |||
411 | /** | ||
412 | * struct intel_msic_platform_data - platform data for the MSIC driver | ||
413 | * @irq: array of interrupt numbers, one per device. If @irq is set to %0 | ||
414 | * for a given block, the corresponding platform device is not | ||
415 | * created. For devices which don't have an interrupt, use %0xff | ||
416 | * (this is same as in SFI spec). | ||
417 | * @gpio: platform data for the MSIC GPIO driver | ||
418 | * @ocd: platform data for the MSIC OCD driver | ||
419 | * | ||
420 | * Once the MSIC driver is initialized, the register interface is ready to | ||
421 | * use. All the platform devices for subdevices are created after the | ||
422 | * register interface is ready so that we can guarantee its availability to | ||
423 | * the subdevice drivers. | ||
424 | * | ||
425 | * Interrupt numbers are passed to the subdevices via %IORESOURCE_IRQ | ||
426 | * resources of the created platform device. | ||
427 | */ | ||
428 | struct intel_msic_platform_data { | ||
429 | int irq[INTEL_MSIC_BLOCK_LAST]; | ||
430 | struct intel_msic_gpio_pdata *gpio; | ||
431 | struct intel_msic_ocd_pdata *ocd; | ||
432 | }; | ||
433 | |||
434 | struct intel_msic; | ||
435 | |||
436 | extern int intel_msic_reg_read(unsigned short reg, u8 *val); | ||
437 | extern int intel_msic_reg_write(unsigned short reg, u8 val); | ||
438 | extern int intel_msic_reg_update(unsigned short reg, u8 val, u8 mask); | ||
439 | extern int intel_msic_bulk_read(unsigned short *reg, u8 *buf, size_t count); | ||
440 | extern int intel_msic_bulk_write(unsigned short *reg, u8 *buf, size_t count); | ||
441 | |||
442 | /* | ||
443 | * pdev_to_intel_msic - gets an MSIC instance from the platform device | ||
444 | * @pdev: platform device pointer | ||
445 | * | ||
446 | * The client drivers need to have pointer to the MSIC instance if they | ||
447 | * want to call intel_msic_irq_read(). This macro can be used for | ||
448 | * convenience to get the MSIC pointer from @pdev where needed. This is | ||
449 | * _only_ valid for devices which are managed by the MSIC. | ||
450 | */ | ||
451 | #define pdev_to_intel_msic(pdev) (dev_get_drvdata(pdev->dev.parent)) | ||
452 | |||
453 | extern int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg, | ||
454 | u8 *val); | ||
455 | |||
456 | #endif /* __LINUX_MFD_INTEL_MSIC_H__ */ | ||
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index 5ff2400ad46c..3f4deb62d6b0 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h | |||
@@ -326,7 +326,6 @@ struct max8997_dev { | |||
326 | int irq; | 326 | int irq; |
327 | int ono; | 327 | int ono; |
328 | int irq_base; | 328 | int irq_base; |
329 | bool wakeup; | ||
330 | struct mutex irqlock; | 329 | struct mutex irqlock; |
331 | int irq_masks_cur[MAX8997_IRQ_GROUP_NR]; | 330 | int irq_masks_cur[MAX8997_IRQ_GROUP_NR]; |
332 | int irq_masks_cache[MAX8997_IRQ_GROUP_NR]; | 331 | int irq_masks_cache[MAX8997_IRQ_GROUP_NR]; |
diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h index 7d0f3d6a0002..a8eeda773a7b 100644 --- a/include/linux/mfd/mc13783.h +++ b/include/linux/mfd/mc13783.h | |||
@@ -12,117 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/mfd/mc13xxx.h> | 13 | #include <linux/mfd/mc13xxx.h> |
14 | 14 | ||
15 | struct mc13783; | ||
16 | |||
17 | struct mc13xxx *mc13783_to_mc13xxx(struct mc13783 *mc13783); | ||
18 | |||
19 | static inline void mc13783_lock(struct mc13783 *mc13783) | ||
20 | { | ||
21 | mc13xxx_lock(mc13783_to_mc13xxx(mc13783)); | ||
22 | } | ||
23 | |||
24 | static inline void mc13783_unlock(struct mc13783 *mc13783) | ||
25 | { | ||
26 | mc13xxx_unlock(mc13783_to_mc13xxx(mc13783)); | ||
27 | } | ||
28 | |||
29 | static inline int mc13783_reg_read(struct mc13783 *mc13783, | ||
30 | unsigned int offset, u32 *val) | ||
31 | { | ||
32 | return mc13xxx_reg_read(mc13783_to_mc13xxx(mc13783), offset, val); | ||
33 | } | ||
34 | |||
35 | static inline int mc13783_reg_write(struct mc13783 *mc13783, | ||
36 | unsigned int offset, u32 val) | ||
37 | { | ||
38 | return mc13xxx_reg_write(mc13783_to_mc13xxx(mc13783), offset, val); | ||
39 | } | ||
40 | |||
41 | static inline int mc13783_reg_rmw(struct mc13783 *mc13783, | ||
42 | unsigned int offset, u32 mask, u32 val) | ||
43 | { | ||
44 | return mc13xxx_reg_rmw(mc13783_to_mc13xxx(mc13783), offset, mask, val); | ||
45 | } | ||
46 | |||
47 | static inline int mc13783_get_flags(struct mc13783 *mc13783) | ||
48 | { | ||
49 | return mc13xxx_get_flags(mc13783_to_mc13xxx(mc13783)); | ||
50 | } | ||
51 | |||
52 | static inline int mc13783_irq_request(struct mc13783 *mc13783, int irq, | ||
53 | irq_handler_t handler, const char *name, void *dev) | ||
54 | { | ||
55 | return mc13xxx_irq_request(mc13783_to_mc13xxx(mc13783), irq, | ||
56 | handler, name, dev); | ||
57 | } | ||
58 | |||
59 | static inline int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq, | ||
60 | irq_handler_t handler, const char *name, void *dev) | ||
61 | { | ||
62 | return mc13xxx_irq_request_nounmask(mc13783_to_mc13xxx(mc13783), irq, | ||
63 | handler, name, dev); | ||
64 | } | ||
65 | |||
66 | static inline int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev) | ||
67 | { | ||
68 | return mc13xxx_irq_free(mc13783_to_mc13xxx(mc13783), irq, dev); | ||
69 | } | ||
70 | |||
71 | static inline int mc13783_irq_mask(struct mc13783 *mc13783, int irq) | ||
72 | { | ||
73 | return mc13xxx_irq_mask(mc13783_to_mc13xxx(mc13783), irq); | ||
74 | } | ||
75 | |||
76 | static inline int mc13783_irq_unmask(struct mc13783 *mc13783, int irq) | ||
77 | { | ||
78 | return mc13xxx_irq_unmask(mc13783_to_mc13xxx(mc13783), irq); | ||
79 | } | ||
80 | static inline int mc13783_irq_status(struct mc13783 *mc13783, int irq, | ||
81 | int *enabled, int *pending) | ||
82 | { | ||
83 | return mc13xxx_irq_status(mc13783_to_mc13xxx(mc13783), | ||
84 | irq, enabled, pending); | ||
85 | } | ||
86 | |||
87 | static inline int mc13783_irq_ack(struct mc13783 *mc13783, int irq) | ||
88 | { | ||
89 | return mc13xxx_irq_ack(mc13783_to_mc13xxx(mc13783), irq); | ||
90 | } | ||
91 | |||
92 | #define MC13783_ADC0 43 | ||
93 | #define MC13783_ADC0_ADREFEN (1 << 10) | ||
94 | #define MC13783_ADC0_ADREFMODE (1 << 11) | ||
95 | #define MC13783_ADC0_TSMOD0 (1 << 12) | ||
96 | #define MC13783_ADC0_TSMOD1 (1 << 13) | ||
97 | #define MC13783_ADC0_TSMOD2 (1 << 14) | ||
98 | #define MC13783_ADC0_ADINC1 (1 << 16) | ||
99 | #define MC13783_ADC0_ADINC2 (1 << 17) | ||
100 | |||
101 | #define MC13783_ADC0_TSMOD_MASK (MC13783_ADC0_TSMOD0 | \ | ||
102 | MC13783_ADC0_TSMOD1 | \ | ||
103 | MC13783_ADC0_TSMOD2) | ||
104 | |||
105 | #define mc13783_regulator_init_data mc13xxx_regulator_init_data | ||
106 | #define mc13783_regulator_platform_data mc13xxx_regulator_platform_data | ||
107 | #define mc13783_led_platform_data mc13xxx_led_platform_data | ||
108 | #define mc13783_leds_platform_data mc13xxx_leds_platform_data | ||
109 | |||
110 | #define mc13783_platform_data mc13xxx_platform_data | ||
111 | #define MC13783_USE_TOUCHSCREEN MC13XXX_USE_TOUCHSCREEN | ||
112 | #define MC13783_USE_CODEC MC13XXX_USE_CODEC | ||
113 | #define MC13783_USE_ADC MC13XXX_USE_ADC | ||
114 | #define MC13783_USE_RTC MC13XXX_USE_RTC | ||
115 | #define MC13783_USE_REGULATOR MC13XXX_USE_REGULATOR | ||
116 | #define MC13783_USE_LED MC13XXX_USE_LED | ||
117 | |||
118 | #define MC13783_ADC_MODE_TS 1 | ||
119 | #define MC13783_ADC_MODE_SINGLE_CHAN 2 | ||
120 | #define MC13783_ADC_MODE_MULT_CHAN 3 | ||
121 | |||
122 | int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode, | ||
123 | unsigned int channel, unsigned int *sample); | ||
124 | |||
125 | |||
126 | #define MC13783_REG_SW1A 0 | 15 | #define MC13783_REG_SW1A 0 |
127 | #define MC13783_REG_SW1B 1 | 16 | #define MC13783_REG_SW1B 1 |
128 | #define MC13783_REG_SW2A 2 | 17 | #define MC13783_REG_SW2A 2 |
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h index c064beaaccb7..3816c2fac0ad 100644 --- a/include/linux/mfd/mc13xxx.h +++ b/include/linux/mfd/mc13xxx.h | |||
@@ -37,6 +37,9 @@ int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq); | |||
37 | 37 | ||
38 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx); | 38 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx); |
39 | 39 | ||
40 | int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, | ||
41 | unsigned int mode, unsigned int channel, unsigned int *sample); | ||
42 | |||
40 | #define MC13XXX_IRQ_ADCDONE 0 | 43 | #define MC13XXX_IRQ_ADCDONE 0 |
41 | #define MC13XXX_IRQ_ADCBISDONE 1 | 44 | #define MC13XXX_IRQ_ADCBISDONE 1 |
42 | #define MC13XXX_IRQ_TS 2 | 45 | #define MC13XXX_IRQ_TS 2 |
@@ -137,17 +140,48 @@ struct mc13xxx_leds_platform_data { | |||
137 | char tc3_period; | 140 | char tc3_period; |
138 | }; | 141 | }; |
139 | 142 | ||
143 | struct mc13xxx_buttons_platform_data { | ||
144 | #define MC13783_BUTTON_DBNC_0MS 0 | ||
145 | #define MC13783_BUTTON_DBNC_30MS 1 | ||
146 | #define MC13783_BUTTON_DBNC_150MS 2 | ||
147 | #define MC13783_BUTTON_DBNC_750MS 3 | ||
148 | #define MC13783_BUTTON_ENABLE (1 << 2) | ||
149 | #define MC13783_BUTTON_POL_INVERT (1 << 3) | ||
150 | #define MC13783_BUTTON_RESET_EN (1 << 4) | ||
151 | int b1on_flags; | ||
152 | unsigned short b1on_key; | ||
153 | int b2on_flags; | ||
154 | unsigned short b2on_key; | ||
155 | int b3on_flags; | ||
156 | unsigned short b3on_key; | ||
157 | }; | ||
158 | |||
140 | struct mc13xxx_platform_data { | 159 | struct mc13xxx_platform_data { |
141 | #define MC13XXX_USE_TOUCHSCREEN (1 << 0) | 160 | #define MC13XXX_USE_TOUCHSCREEN (1 << 0) |
142 | #define MC13XXX_USE_CODEC (1 << 1) | 161 | #define MC13XXX_USE_CODEC (1 << 1) |
143 | #define MC13XXX_USE_ADC (1 << 2) | 162 | #define MC13XXX_USE_ADC (1 << 2) |
144 | #define MC13XXX_USE_RTC (1 << 3) | 163 | #define MC13XXX_USE_RTC (1 << 3) |
145 | #define MC13XXX_USE_REGULATOR (1 << 4) | ||
146 | #define MC13XXX_USE_LED (1 << 5) | ||
147 | unsigned int flags; | 164 | unsigned int flags; |
148 | 165 | ||
149 | struct mc13xxx_regulator_platform_data regulators; | 166 | struct mc13xxx_regulator_platform_data regulators; |
150 | struct mc13xxx_leds_platform_data *leds; | 167 | struct mc13xxx_leds_platform_data *leds; |
168 | struct mc13xxx_buttons_platform_data *buttons; | ||
151 | }; | 169 | }; |
152 | 170 | ||
171 | #define MC13XXX_ADC_MODE_TS 1 | ||
172 | #define MC13XXX_ADC_MODE_SINGLE_CHAN 2 | ||
173 | #define MC13XXX_ADC_MODE_MULT_CHAN 3 | ||
174 | |||
175 | #define MC13XXX_ADC0 43 | ||
176 | #define MC13XXX_ADC0_ADREFEN (1 << 10) | ||
177 | #define MC13XXX_ADC0_TSMOD0 (1 << 12) | ||
178 | #define MC13XXX_ADC0_TSMOD1 (1 << 13) | ||
179 | #define MC13XXX_ADC0_TSMOD2 (1 << 14) | ||
180 | #define MC13XXX_ADC0_ADINC1 (1 << 16) | ||
181 | #define MC13XXX_ADC0_ADINC2 (1 << 17) | ||
182 | |||
183 | #define MC13XXX_ADC0_TSMOD_MASK (MC13XXX_ADC0_TSMOD0 | \ | ||
184 | MC13XXX_ADC0_TSMOD1 | \ | ||
185 | MC13XXX_ADC0_TSMOD2) | ||
186 | |||
153 | #endif /* ifndef __LINUX_MFD_MC13XXX_H */ | 187 | #endif /* ifndef __LINUX_MFD_MC13XXX_H */ |
diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h index 50d4a047118d..a80840752b4c 100644 --- a/include/linux/mfd/pcf50633/core.h +++ b/include/linux/mfd/pcf50633/core.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/mfd/pcf50633/backlight.h> | 21 | #include <linux/mfd/pcf50633/backlight.h> |
22 | 22 | ||
23 | struct pcf50633; | 23 | struct pcf50633; |
24 | struct regmap; | ||
24 | 25 | ||
25 | #define PCF50633_NUM_REGULATORS 11 | 26 | #define PCF50633_NUM_REGULATORS 11 |
26 | 27 | ||
@@ -134,7 +135,7 @@ enum { | |||
134 | 135 | ||
135 | struct pcf50633 { | 136 | struct pcf50633 { |
136 | struct device *dev; | 137 | struct device *dev; |
137 | struct i2c_client *i2c_client; | 138 | struct regmap *regmap; |
138 | 139 | ||
139 | struct pcf50633_platform_data *pdata; | 140 | struct pcf50633_platform_data *pdata; |
140 | int irq; | 141 | int irq; |
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index ed8fe0d04097..4b1211859f74 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h | |||
@@ -382,6 +382,7 @@ struct wm831x { | |||
382 | 382 | ||
383 | /* Used by the interrupt controller code to post writes */ | 383 | /* Used by the interrupt controller code to post writes */ |
384 | int gpio_update[WM831X_NUM_GPIO_REGS]; | 384 | int gpio_update[WM831X_NUM_GPIO_REGS]; |
385 | bool gpio_level[WM831X_NUM_GPIO_REGS]; | ||
385 | 386 | ||
386 | struct mutex auxadc_lock; | 387 | struct mutex auxadc_lock; |
387 | struct list_head auxadc_pending; | 388 | struct list_head auxadc_pending; |
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index 626809147624..f44bdb7273bd 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h | |||
@@ -59,6 +59,8 @@ struct wm8994 { | |||
59 | struct device *dev; | 59 | struct device *dev; |
60 | struct regmap *regmap; | 60 | struct regmap *regmap; |
61 | 61 | ||
62 | bool ldo_ena_always_driven; | ||
63 | |||
62 | int gpio_base; | 64 | int gpio_base; |
63 | int irq_base; | 65 | int irq_base; |
64 | 66 | ||
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 97cf4f27d647..ea32f306dca6 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h | |||
@@ -167,6 +167,13 @@ struct wm8994_pdata { | |||
167 | 167 | ||
168 | /* WM8958 microphone bias configuration */ | 168 | /* WM8958 microphone bias configuration */ |
169 | int micbias[2]; | 169 | int micbias[2]; |
170 | |||
171 | /* Disable the internal pull downs on the LDOs if they are | ||
172 | * always driven (eg, connected to an always on supply or | ||
173 | * GPIO that always drives an output. If they float power | ||
174 | * consumption will rise. | ||
175 | */ | ||
176 | bool ldo_ena_always_driven; | ||
170 | }; | 177 | }; |
171 | 178 | ||
172 | #endif | 179 | #endif |