diff options
33 files changed, 618 insertions, 302 deletions
diff --git a/arch/x86/platform/olpc/olpc-xo1.c b/arch/x86/platform/olpc/olpc-xo1.c index 99513642a0e6..ab81fb271760 100644 --- a/arch/x86/platform/olpc/olpc-xo1.c +++ b/arch/x86/platform/olpc/olpc-xo1.c | |||
@@ -72,9 +72,9 @@ static int __devinit olpc_xo1_probe(struct platform_device *pdev) | |||
72 | dev_err(&pdev->dev, "can't fetch device resource info\n"); | 72 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
73 | return -EIO; | 73 | return -EIO; |
74 | } | 74 | } |
75 | if (strcmp(pdev->name, "olpc-xo1-pms") == 0) | 75 | if (strcmp(pdev->name, "cs5535-pms") == 0) |
76 | pms_base = res->start; | 76 | pms_base = res->start; |
77 | else if (strcmp(pdev->name, "olpc-xo1-ac-acpi") == 0) | 77 | else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) |
78 | acpi_base = res->start; | 78 | acpi_base = res->start; |
79 | 79 | ||
80 | /* If we have both addresses, we can override the poweroff hook */ | 80 | /* If we have both addresses, we can override the poweroff hook */ |
@@ -90,9 +90,9 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev) | |||
90 | { | 90 | { |
91 | mfd_cell_disable(pdev); | 91 | mfd_cell_disable(pdev); |
92 | 92 | ||
93 | if (strcmp(pdev->name, "olpc-xo1-pms") == 0) | 93 | if (strcmp(pdev->name, "cs5535-pms") == 0) |
94 | pms_base = 0; | 94 | pms_base = 0; |
95 | else if (strcmp(pdev->name, "olpc-xo1-acpi") == 0) | 95 | else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) |
96 | acpi_base = 0; | 96 | acpi_base = 0; |
97 | 97 | ||
98 | pm_power_off = NULL; | 98 | pm_power_off = NULL; |
@@ -101,7 +101,7 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev) | |||
101 | 101 | ||
102 | static struct platform_driver cs5535_pms_drv = { | 102 | static struct platform_driver cs5535_pms_drv = { |
103 | .driver = { | 103 | .driver = { |
104 | .name = "olpc-xo1-pms", | 104 | .name = "cs5535-pms", |
105 | .owner = THIS_MODULE, | 105 | .owner = THIS_MODULE, |
106 | }, | 106 | }, |
107 | .probe = olpc_xo1_probe, | 107 | .probe = olpc_xo1_probe, |
@@ -110,7 +110,7 @@ static struct platform_driver cs5535_pms_drv = { | |||
110 | 110 | ||
111 | static struct platform_driver cs5535_acpi_drv = { | 111 | static struct platform_driver cs5535_acpi_drv = { |
112 | .driver = { | 112 | .driver = { |
113 | .name = "olpc-xo1-acpi", | 113 | .name = "olpc-xo1-pm-acpi", |
114 | .owner = THIS_MODULE, | 114 | .owner = THIS_MODULE, |
115 | }, | 115 | }, |
116 | .probe = olpc_xo1_probe, | 116 | .probe = olpc_xo1_probe, |
@@ -121,22 +121,21 @@ static int __init olpc_xo1_init(void) | |||
121 | { | 121 | { |
122 | int r; | 122 | int r; |
123 | 123 | ||
124 | r = mfd_shared_platform_driver_register(&cs5535_pms_drv, "cs5535-pms"); | 124 | r = platform_driver_register(&cs5535_pms_drv); |
125 | if (r) | 125 | if (r) |
126 | return r; | 126 | return r; |
127 | 127 | ||
128 | r = mfd_shared_platform_driver_register(&cs5535_acpi_drv, | 128 | r = platform_driver_register(&cs5535_acpi_drv); |
129 | "cs5535-acpi"); | ||
130 | if (r) | 129 | if (r) |
131 | mfd_shared_platform_driver_unregister(&cs5535_pms_drv); | 130 | platform_driver_unregister(&cs5535_pms_drv); |
132 | 131 | ||
133 | return r; | 132 | return r; |
134 | } | 133 | } |
135 | 134 | ||
136 | static void __exit olpc_xo1_exit(void) | 135 | static void __exit olpc_xo1_exit(void) |
137 | { | 136 | { |
138 | mfd_shared_platform_driver_unregister(&cs5535_acpi_drv); | 137 | platform_driver_unregister(&cs5535_acpi_drv); |
139 | mfd_shared_platform_driver_unregister(&cs5535_pms_drv); | 138 | platform_driver_unregister(&cs5535_pms_drv); |
140 | } | 139 | } |
141 | 140 | ||
142 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); | 141 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); |
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 9c511c1604a5..011cb6ce861b 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c | |||
@@ -416,7 +416,6 @@ static int __devinit device_irq_init(struct pm860x_chip *chip, | |||
416 | : chip->companion; | 416 | : chip->companion; |
417 | unsigned char status_buf[INT_STATUS_NUM]; | 417 | unsigned char status_buf[INT_STATUS_NUM]; |
418 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; | 418 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; |
419 | struct irq_desc *desc; | ||
420 | int i, data, mask, ret = -EINVAL; | 419 | int i, data, mask, ret = -EINVAL; |
421 | int __irq; | 420 | int __irq; |
422 | 421 | ||
@@ -468,19 +467,17 @@ static int __devinit device_irq_init(struct pm860x_chip *chip, | |||
468 | if (!chip->core_irq) | 467 | if (!chip->core_irq) |
469 | goto out; | 468 | goto out; |
470 | 469 | ||
471 | desc = irq_to_desc(chip->core_irq); | ||
472 | |||
473 | /* register IRQ by genirq */ | 470 | /* register IRQ by genirq */ |
474 | for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { | 471 | for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { |
475 | __irq = i + chip->irq_base; | 472 | __irq = i + chip->irq_base; |
476 | set_irq_chip_data(__irq, chip); | 473 | irq_set_chip_data(__irq, chip); |
477 | set_irq_chip_and_handler(__irq, &pm860x_irq_chip, | 474 | irq_set_chip_and_handler(__irq, &pm860x_irq_chip, |
478 | handle_edge_irq); | 475 | handle_edge_irq); |
479 | set_irq_nested_thread(__irq, 1); | 476 | irq_set_nested_thread(__irq, 1); |
480 | #ifdef CONFIG_ARM | 477 | #ifdef CONFIG_ARM |
481 | set_irq_flags(__irq, IRQF_VALID); | 478 | set_irq_flags(__irq, IRQF_VALID); |
482 | #else | 479 | #else |
483 | set_irq_noprobe(__irq); | 480 | irq_set_noprobe(__irq); |
484 | #endif | 481 | #endif |
485 | } | 482 | } |
486 | 483 | ||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index a9a1af49281e..e986f91fff9c 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -133,6 +133,7 @@ config TPS6105X | |||
133 | tristate "TPS61050/61052 Boost Converters" | 133 | tristate "TPS61050/61052 Boost Converters" |
134 | depends on I2C | 134 | depends on I2C |
135 | select REGULATOR | 135 | select REGULATOR |
136 | select MFD_CORE | ||
136 | select REGULATOR_FIXED_VOLTAGE | 137 | select REGULATOR_FIXED_VOLTAGE |
137 | help | 138 | help |
138 | This option enables a driver for the TP61050/TPS61052 | 139 | This option enables a driver for the TP61050/TPS61052 |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 47f5709f3828..ef489f253402 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -63,7 +63,7 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o | |||
63 | obj-$(CONFIG_PMIC_DA903X) += da903x.o | 63 | obj-$(CONFIG_PMIC_DA903X) += da903x.o |
64 | max8925-objs := max8925-core.o max8925-i2c.o | 64 | max8925-objs := max8925-core.o max8925-i2c.o |
65 | obj-$(CONFIG_MFD_MAX8925) += max8925.o | 65 | obj-$(CONFIG_MFD_MAX8925) += max8925.o |
66 | obj-$(CONFIG_MFD_MAX8997) += max8997.o | 66 | obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o |
67 | obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o | 67 | obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o |
68 | 68 | ||
69 | pcf50633-objs := pcf50633-core.o pcf50633-irq.o | 69 | pcf50633-objs := pcf50633-core.o pcf50633-irq.o |
diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c index c12d04285226..ff86acf3e6bd 100644 --- a/drivers/mfd/ab3550-core.c +++ b/drivers/mfd/ab3550-core.c | |||
@@ -668,7 +668,7 @@ static int ab3550_startup_irq_enabled(struct device *dev, unsigned int irq) | |||
668 | struct ab3550_platform_data *plf_data; | 668 | struct ab3550_platform_data *plf_data; |
669 | bool val; | 669 | bool val; |
670 | 670 | ||
671 | ab = get_irq_chip_data(irq); | 671 | ab = irq_get_chip_data(irq); |
672 | plf_data = ab->i2c_client[0]->dev.platform_data; | 672 | plf_data = ab->i2c_client[0]->dev.platform_data; |
673 | irq -= plf_data->irq.base; | 673 | irq -= plf_data->irq.base; |
674 | val = ((ab->startup_events[irq / 8] & BIT(irq % 8)) != 0); | 674 | val = ((ab->startup_events[irq / 8] & BIT(irq % 8)) != 0); |
@@ -1296,14 +1296,14 @@ static int __init ab3550_probe(struct i2c_client *client, | |||
1296 | unsigned int irq; | 1296 | unsigned int irq; |
1297 | 1297 | ||
1298 | irq = ab3550_plf_data->irq.base + i; | 1298 | irq = ab3550_plf_data->irq.base + i; |
1299 | set_irq_chip_data(irq, ab); | 1299 | irq_set_chip_data(irq, ab); |
1300 | set_irq_chip_and_handler(irq, &ab3550_irq_chip, | 1300 | irq_set_chip_and_handler(irq, &ab3550_irq_chip, |
1301 | handle_simple_irq); | 1301 | handle_simple_irq); |
1302 | set_irq_nested_thread(irq, 1); | 1302 | irq_set_nested_thread(irq, 1); |
1303 | #ifdef CONFIG_ARM | 1303 | #ifdef CONFIG_ARM |
1304 | set_irq_flags(irq, IRQF_VALID); | 1304 | set_irq_flags(irq, IRQF_VALID); |
1305 | #else | 1305 | #else |
1306 | set_irq_noprobe(irq); | 1306 | irq_set_noprobe(irq); |
1307 | #endif | 1307 | #endif |
1308 | } | 1308 | } |
1309 | 1309 | ||
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 6e185b272d00..62e33e2258d4 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -334,14 +334,14 @@ static int ab8500_irq_init(struct ab8500 *ab8500) | |||
334 | int irq; | 334 | int irq; |
335 | 335 | ||
336 | for (irq = base; irq < base + AB8500_NR_IRQS; irq++) { | 336 | for (irq = base; irq < base + AB8500_NR_IRQS; irq++) { |
337 | set_irq_chip_data(irq, ab8500); | 337 | irq_set_chip_data(irq, ab8500); |
338 | set_irq_chip_and_handler(irq, &ab8500_irq_chip, | 338 | irq_set_chip_and_handler(irq, &ab8500_irq_chip, |
339 | handle_simple_irq); | 339 | handle_simple_irq); |
340 | set_irq_nested_thread(irq, 1); | 340 | irq_set_nested_thread(irq, 1); |
341 | #ifdef CONFIG_ARM | 341 | #ifdef CONFIG_ARM |
342 | set_irq_flags(irq, IRQF_VALID); | 342 | set_irq_flags(irq, IRQF_VALID); |
343 | #else | 343 | #else |
344 | set_irq_noprobe(irq); | 344 | irq_set_noprobe(irq); |
345 | #endif | 345 | #endif |
346 | } | 346 | } |
347 | 347 | ||
@@ -357,8 +357,8 @@ static void ab8500_irq_remove(struct ab8500 *ab8500) | |||
357 | #ifdef CONFIG_ARM | 357 | #ifdef CONFIG_ARM |
358 | set_irq_flags(irq, 0); | 358 | set_irq_flags(irq, 0); |
359 | #endif | 359 | #endif |
360 | set_irq_chip_and_handler(irq, NULL, NULL); | 360 | irq_set_chip_and_handler(irq, NULL, NULL); |
361 | set_irq_chip_data(irq, NULL); | 361 | irq_set_chip_data(irq, NULL); |
362 | } | 362 | } |
363 | } | 363 | } |
364 | 364 | ||
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 0241f08fc00d..d4a851c6b5bf 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -139,13 +139,12 @@ static void asic3_irq_flip_edge(struct asic3 *asic, | |||
139 | 139 | ||
140 | static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | 140 | static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) |
141 | { | 141 | { |
142 | struct asic3 *asic = irq_desc_get_handler_data(desc); | ||
143 | struct irq_data *data = irq_desc_get_irq_data(desc); | ||
142 | int iter, i; | 144 | int iter, i; |
143 | unsigned long flags; | 145 | unsigned long flags; |
144 | struct asic3 *asic; | ||
145 | |||
146 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
147 | 146 | ||
148 | asic = get_irq_data(irq); | 147 | data->chip->irq_ack(irq_data); |
149 | 148 | ||
150 | for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) { | 149 | for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) { |
151 | u32 status; | 150 | u32 status; |
@@ -188,8 +187,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
188 | irqnr = asic->irq_base + | 187 | irqnr = asic->irq_base + |
189 | (ASIC3_GPIOS_PER_BANK * bank) | 188 | (ASIC3_GPIOS_PER_BANK * bank) |
190 | + i; | 189 | + i; |
191 | desc = irq_to_desc(irqnr); | 190 | generic_handle_irq(irqnr); |
192 | desc->handle_irq(irqnr, desc); | ||
193 | if (asic->irq_bothedge[bank] & bit) | 191 | if (asic->irq_bothedge[bank] & bit) |
194 | asic3_irq_flip_edge(asic, base, | 192 | asic3_irq_flip_edge(asic, base, |
195 | bit); | 193 | bit); |
@@ -200,11 +198,8 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
200 | /* Handle remaining IRQs in the status register */ | 198 | /* Handle remaining IRQs in the status register */ |
201 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { | 199 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { |
202 | /* They start at bit 4 and go up */ | 200 | /* They start at bit 4 and go up */ |
203 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { | 201 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) |
204 | desc = irq_to_desc(asic->irq_base + i); | 202 | generic_handle_irq(asic->irq_base + i); |
205 | desc->handle_irq(asic->irq_base + i, | ||
206 | desc); | ||
207 | } | ||
208 | } | 203 | } |
209 | } | 204 | } |
210 | 205 | ||
@@ -393,21 +388,21 @@ static int __init asic3_irq_probe(struct platform_device *pdev) | |||
393 | 388 | ||
394 | for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { | 389 | for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { |
395 | if (irq < asic->irq_base + ASIC3_NUM_GPIOS) | 390 | if (irq < asic->irq_base + ASIC3_NUM_GPIOS) |
396 | set_irq_chip(irq, &asic3_gpio_irq_chip); | 391 | irq_set_chip(irq, &asic3_gpio_irq_chip); |
397 | else | 392 | else |
398 | set_irq_chip(irq, &asic3_irq_chip); | 393 | irq_set_chip(irq, &asic3_irq_chip); |
399 | 394 | ||
400 | set_irq_chip_data(irq, asic); | 395 | irq_set_chip_data(irq, asic); |
401 | set_irq_handler(irq, handle_level_irq); | 396 | irq_set_handler(irq, handle_level_irq); |
402 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 397 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
403 | } | 398 | } |
404 | 399 | ||
405 | asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK), | 400 | asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK), |
406 | ASIC3_INTMASK_GINTMASK); | 401 | ASIC3_INTMASK_GINTMASK); |
407 | 402 | ||
408 | set_irq_chained_handler(asic->irq_nr, asic3_irq_demux); | 403 | irq_set_chained_handler(asic->irq_nr, asic3_irq_demux); |
409 | set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); | 404 | irq_set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); |
410 | set_irq_data(asic->irq_nr, asic); | 405 | irq_set_handler_data(asic->irq_nr, asic); |
411 | 406 | ||
412 | return 0; | 407 | return 0; |
413 | } | 408 | } |
@@ -421,11 +416,10 @@ static void asic3_irq_remove(struct platform_device *pdev) | |||
421 | 416 | ||
422 | for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { | 417 | for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { |
423 | set_irq_flags(irq, 0); | 418 | set_irq_flags(irq, 0); |
424 | set_irq_handler(irq, NULL); | 419 | irq_set_chip_and_handler(irq, NULL, NULL); |
425 | set_irq_chip(irq, NULL); | 420 | irq_set_chip_data(irq, NULL); |
426 | set_irq_chip_data(irq, NULL); | ||
427 | } | 421 | } |
428 | set_irq_chained_handler(asic->irq_nr, NULL); | 422 | irq_set_chained_handler(asic->irq_nr, NULL); |
429 | } | 423 | } |
430 | 424 | ||
431 | /* GPIOs */ | 425 | /* GPIOs */ |
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 886a06871065..155fa0407882 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/mfd/core.h> | 27 | #include <linux/mfd/core.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <asm/olpc.h> | ||
30 | 31 | ||
31 | #define DRV_NAME "cs5535-mfd" | 32 | #define DRV_NAME "cs5535-mfd" |
32 | 33 | ||
@@ -111,6 +112,20 @@ static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { | |||
111 | }, | 112 | }, |
112 | }; | 113 | }; |
113 | 114 | ||
115 | #ifdef CONFIG_OLPC | ||
116 | static void __devinit cs5535_clone_olpc_cells(void) | ||
117 | { | ||
118 | const char *acpi_clones[] = { "olpc-xo1-pm-acpi", "olpc-xo1-sci-acpi" }; | ||
119 | |||
120 | if (!machine_is_olpc()) | ||
121 | return; | ||
122 | |||
123 | mfd_clone_cell("cs5535-acpi", acpi_clones, ARRAY_SIZE(acpi_clones)); | ||
124 | } | ||
125 | #else | ||
126 | static void cs5535_clone_olpc_cells(void) { } | ||
127 | #endif | ||
128 | |||
114 | static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, | 129 | static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, |
115 | const struct pci_device_id *id) | 130 | const struct pci_device_id *id) |
116 | { | 131 | { |
@@ -139,6 +154,7 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, | |||
139 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); | 154 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); |
140 | goto err_disable; | 155 | goto err_disable; |
141 | } | 156 | } |
157 | cs5535_clone_olpc_cells(); | ||
142 | 158 | ||
143 | dev_info(&pdev->dev, "%zu devices registered.\n", | 159 | dev_info(&pdev->dev, "%zu devices registered.\n", |
144 | ARRAY_SIZE(cs5535_mfd_cells)); | 160 | ARRAY_SIZE(cs5535_mfd_cells)); |
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index 9e2d8dd5f9e5..f2f4029e21a0 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c | |||
@@ -162,6 +162,7 @@ static void pcap_unmask_irq(struct irq_data *d) | |||
162 | 162 | ||
163 | static struct irq_chip pcap_irq_chip = { | 163 | static struct irq_chip pcap_irq_chip = { |
164 | .name = "pcap", | 164 | .name = "pcap", |
165 | .irq_disable = pcap_mask_irq, | ||
165 | .irq_mask = pcap_mask_irq, | 166 | .irq_mask = pcap_mask_irq, |
166 | .irq_unmask = pcap_unmask_irq, | 167 | .irq_unmask = pcap_unmask_irq, |
167 | }; | 168 | }; |
@@ -196,17 +197,8 @@ static void pcap_isr_work(struct work_struct *work) | |||
196 | local_irq_disable(); | 197 | local_irq_disable(); |
197 | service = isr & ~msr; | 198 | service = isr & ~msr; |
198 | for (irq = pcap->irq_base; service; service >>= 1, irq++) { | 199 | for (irq = pcap->irq_base; service; service >>= 1, irq++) { |
199 | if (service & 1) { | 200 | if (service & 1) |
200 | struct irq_desc *desc = irq_to_desc(irq); | 201 | generic_handle_irq(irq); |
201 | |||
202 | if (WARN(!desc, "Invalid PCAP IRQ %d\n", irq)) | ||
203 | break; | ||
204 | |||
205 | if (desc->status & IRQ_DISABLED) | ||
206 | note_interrupt(irq, desc, IRQ_NONE); | ||
207 | else | ||
208 | desc->handle_irq(irq, desc); | ||
209 | } | ||
210 | } | 202 | } |
211 | local_irq_enable(); | 203 | local_irq_enable(); |
212 | ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); | 204 | ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); |
@@ -215,7 +207,7 @@ static void pcap_isr_work(struct work_struct *work) | |||
215 | 207 | ||
216 | static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) | 208 | static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) |
217 | { | 209 | { |
218 | struct pcap_chip *pcap = get_irq_data(irq); | 210 | struct pcap_chip *pcap = irq_get_handler_data(irq); |
219 | 211 | ||
220 | desc->irq_data.chip->irq_ack(&desc->irq_data); | 212 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
221 | queue_work(pcap->workqueue, &pcap->isr_work); | 213 | queue_work(pcap->workqueue, &pcap->isr_work); |
@@ -419,7 +411,7 @@ static int __devexit ezx_pcap_remove(struct spi_device *spi) | |||
419 | 411 | ||
420 | /* cleanup irqchip */ | 412 | /* cleanup irqchip */ |
421 | for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) | 413 | for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) |
422 | set_irq_chip_and_handler(i, NULL, NULL); | 414 | irq_set_chip_and_handler(i, NULL, NULL); |
423 | 415 | ||
424 | destroy_workqueue(pcap->workqueue); | 416 | destroy_workqueue(pcap->workqueue); |
425 | 417 | ||
@@ -476,12 +468,12 @@ static int __devinit ezx_pcap_probe(struct spi_device *spi) | |||
476 | 468 | ||
477 | /* setup irq chip */ | 469 | /* setup irq chip */ |
478 | for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) { | 470 | for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) { |
479 | set_irq_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq); | 471 | irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq); |
480 | set_irq_chip_data(i, pcap); | 472 | irq_set_chip_data(i, pcap); |
481 | #ifdef CONFIG_ARM | 473 | #ifdef CONFIG_ARM |
482 | set_irq_flags(i, IRQF_VALID); | 474 | set_irq_flags(i, IRQF_VALID); |
483 | #else | 475 | #else |
484 | set_irq_noprobe(i); | 476 | irq_set_noprobe(i); |
485 | #endif | 477 | #endif |
486 | } | 478 | } |
487 | 479 | ||
@@ -490,10 +482,10 @@ static int __devinit ezx_pcap_probe(struct spi_device *spi) | |||
490 | ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER); | 482 | ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER); |
491 | pcap->msr = PCAP_MASK_ALL_INTERRUPT; | 483 | pcap->msr = PCAP_MASK_ALL_INTERRUPT; |
492 | 484 | ||
493 | set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); | 485 | irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); |
494 | set_irq_data(spi->irq, pcap); | 486 | irq_set_handler_data(spi->irq, pcap); |
495 | set_irq_chained_handler(spi->irq, pcap_irq_handler); | 487 | irq_set_chained_handler(spi->irq, pcap_irq_handler); |
496 | set_irq_wake(spi->irq, 1); | 488 | irq_set_irq_wake(spi->irq, 1); |
497 | 489 | ||
498 | /* ADC */ | 490 | /* ADC */ |
499 | adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ? | 491 | adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ? |
@@ -522,7 +514,7 @@ remove_subdevs: | |||
522 | free_irq(adc_irq, pcap); | 514 | free_irq(adc_irq, pcap); |
523 | free_irqchip: | 515 | free_irqchip: |
524 | for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) | 516 | for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) |
525 | set_irq_chip_and_handler(i, NULL, NULL); | 517 | irq_set_chip_and_handler(i, NULL, NULL); |
526 | /* destroy_workqueue: */ | 518 | /* destroy_workqueue: */ |
527 | destroy_workqueue(pcap->workqueue); | 519 | destroy_workqueue(pcap->workqueue); |
528 | free_pcap: | 520 | free_pcap: |
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index d00b6d1a69e5..bbaec0ccba8f 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c | |||
@@ -100,7 +100,7 @@ static struct irq_chip egpio_muxed_chip = { | |||
100 | 100 | ||
101 | static void egpio_handler(unsigned int irq, struct irq_desc *desc) | 101 | static void egpio_handler(unsigned int irq, struct irq_desc *desc) |
102 | { | 102 | { |
103 | struct egpio_info *ei = get_irq_data(irq); | 103 | struct egpio_info *ei = irq_desc_get_handler_data(desc); |
104 | int irqpin; | 104 | int irqpin; |
105 | 105 | ||
106 | /* Read current pins. */ | 106 | /* Read current pins. */ |
@@ -113,9 +113,7 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc) | |||
113 | for_each_set_bit(irqpin, &readval, ei->nirqs) { | 113 | for_each_set_bit(irqpin, &readval, ei->nirqs) { |
114 | /* Run irq handler */ | 114 | /* Run irq handler */ |
115 | pr_debug("got IRQ %d\n", irqpin); | 115 | pr_debug("got IRQ %d\n", irqpin); |
116 | irq = ei->irq_start + irqpin; | 116 | generic_handle_irq(ei->irq_start + irqpin); |
117 | desc = irq_to_desc(irq); | ||
118 | desc->handle_irq(irq, desc); | ||
119 | } | 117 | } |
120 | } | 118 | } |
121 | 119 | ||
@@ -346,14 +344,14 @@ static int __init egpio_probe(struct platform_device *pdev) | |||
346 | ei->ack_write = 0; | 344 | ei->ack_write = 0; |
347 | irq_end = ei->irq_start + ei->nirqs; | 345 | irq_end = ei->irq_start + ei->nirqs; |
348 | for (irq = ei->irq_start; irq < irq_end; irq++) { | 346 | for (irq = ei->irq_start; irq < irq_end; irq++) { |
349 | set_irq_chip(irq, &egpio_muxed_chip); | 347 | irq_set_chip_and_handler(irq, &egpio_muxed_chip, |
350 | set_irq_chip_data(irq, ei); | 348 | handle_simple_irq); |
351 | set_irq_handler(irq, handle_simple_irq); | 349 | irq_set_chip_data(irq, ei); |
352 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 350 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
353 | } | 351 | } |
354 | set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING); | 352 | irq_set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING); |
355 | set_irq_data(ei->chained_irq, ei); | 353 | irq_set_handler_data(ei->chained_irq, ei); |
356 | set_irq_chained_handler(ei->chained_irq, egpio_handler); | 354 | irq_set_chained_handler(ei->chained_irq, egpio_handler); |
357 | ack_irqs(ei); | 355 | ack_irqs(ei); |
358 | 356 | ||
359 | device_init_wakeup(&pdev->dev, 1); | 357 | device_init_wakeup(&pdev->dev, 1); |
@@ -375,11 +373,10 @@ static int __exit egpio_remove(struct platform_device *pdev) | |||
375 | if (ei->chained_irq) { | 373 | if (ei->chained_irq) { |
376 | irq_end = ei->irq_start + ei->nirqs; | 374 | irq_end = ei->irq_start + ei->nirqs; |
377 | for (irq = ei->irq_start; irq < irq_end; irq++) { | 375 | for (irq = ei->irq_start; irq < irq_end; irq++) { |
378 | set_irq_chip(irq, NULL); | 376 | irq_set_chip_and_handler(irq, NULL, NULL); |
379 | set_irq_handler(irq, NULL); | ||
380 | set_irq_flags(irq, 0); | 377 | set_irq_flags(irq, 0); |
381 | } | 378 | } |
382 | set_irq_chained_handler(ei->chained_irq, NULL); | 379 | irq_set_chained_handler(ei->chained_irq, NULL); |
383 | device_init_wakeup(&pdev->dev, 0); | 380 | device_init_wakeup(&pdev->dev, 0); |
384 | } | 381 | } |
385 | iounmap(ei->base_addr); | 382 | iounmap(ei->base_addr); |
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 296ad1562f69..d55065cc324c 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c | |||
@@ -58,6 +58,7 @@ struct htcpld_chip { | |||
58 | uint irq_start; | 58 | uint irq_start; |
59 | int nirqs; | 59 | int nirqs; |
60 | 60 | ||
61 | unsigned int flow_type; | ||
61 | /* | 62 | /* |
62 | * Work structure to allow for setting values outside of any | 63 | * Work structure to allow for setting values outside of any |
63 | * possible interrupt context | 64 | * possible interrupt context |
@@ -97,12 +98,7 @@ static void htcpld_unmask(struct irq_data *data) | |||
97 | 98 | ||
98 | static int htcpld_set_type(struct irq_data *data, unsigned int flags) | 99 | static int htcpld_set_type(struct irq_data *data, unsigned int flags) |
99 | { | 100 | { |
100 | struct irq_desc *d = irq_to_desc(data->irq); | 101 | struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); |
101 | |||
102 | if (!d) { | ||
103 | pr_err("HTCPLD invalid IRQ: %d\n", data->irq); | ||
104 | return -EINVAL; | ||
105 | } | ||
106 | 102 | ||
107 | if (flags & ~IRQ_TYPE_SENSE_MASK) | 103 | if (flags & ~IRQ_TYPE_SENSE_MASK) |
108 | return -EINVAL; | 104 | return -EINVAL; |
@@ -111,9 +107,7 @@ static int htcpld_set_type(struct irq_data *data, unsigned int flags) | |||
111 | if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)) | 107 | if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)) |
112 | return -EINVAL; | 108 | return -EINVAL; |
113 | 109 | ||
114 | d->status &= ~IRQ_TYPE_SENSE_MASK; | 110 | chip->flow_type = flags; |
115 | d->status |= flags; | ||
116 | |||
117 | return 0; | 111 | return 0; |
118 | } | 112 | } |
119 | 113 | ||
@@ -135,7 +129,6 @@ static irqreturn_t htcpld_handler(int irq, void *dev) | |||
135 | unsigned int i; | 129 | unsigned int i; |
136 | unsigned long flags; | 130 | unsigned long flags; |
137 | int irqpin; | 131 | int irqpin; |
138 | struct irq_desc *desc; | ||
139 | 132 | ||
140 | if (!htcpld) { | 133 | if (!htcpld) { |
141 | pr_debug("htcpld is null in ISR\n"); | 134 | pr_debug("htcpld is null in ISR\n"); |
@@ -195,23 +188,19 @@ static irqreturn_t htcpld_handler(int irq, void *dev) | |||
195 | * associated interrupts. | 188 | * associated interrupts. |
196 | */ | 189 | */ |
197 | for (irqpin = 0; irqpin < chip->nirqs; irqpin++) { | 190 | for (irqpin = 0; irqpin < chip->nirqs; irqpin++) { |
198 | unsigned oldb, newb; | 191 | unsigned oldb, newb, type = chip->flow_type; |
199 | int flags; | ||
200 | 192 | ||
201 | irq = chip->irq_start + irqpin; | 193 | irq = chip->irq_start + irqpin; |
202 | desc = irq_to_desc(irq); | ||
203 | flags = desc->status; | ||
204 | 194 | ||
205 | /* Run the IRQ handler, but only if the bit value | 195 | /* Run the IRQ handler, but only if the bit value |
206 | * changed, and the proper flags are set */ | 196 | * changed, and the proper flags are set */ |
207 | oldb = (old_val >> irqpin) & 1; | 197 | oldb = (old_val >> irqpin) & 1; |
208 | newb = (uval >> irqpin) & 1; | 198 | newb = (uval >> irqpin) & 1; |
209 | 199 | ||
210 | if ((!oldb && newb && (flags & IRQ_TYPE_EDGE_RISING)) || | 200 | if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) || |
211 | (oldb && !newb && | 201 | (oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) { |
212 | (flags & IRQ_TYPE_EDGE_FALLING))) { | ||
213 | pr_debug("fire IRQ %d\n", irqpin); | 202 | pr_debug("fire IRQ %d\n", irqpin); |
214 | desc->handle_irq(irq, desc); | 203 | generic_handle_irq(irq); |
215 | } | 204 | } |
216 | } | 205 | } |
217 | } | 206 | } |
@@ -359,13 +348,13 @@ static int __devinit htcpld_setup_chip_irq( | |||
359 | /* Setup irq handlers */ | 348 | /* Setup irq handlers */ |
360 | irq_end = chip->irq_start + chip->nirqs; | 349 | irq_end = chip->irq_start + chip->nirqs; |
361 | for (irq = chip->irq_start; irq < irq_end; irq++) { | 350 | for (irq = chip->irq_start; irq < irq_end; irq++) { |
362 | set_irq_chip(irq, &htcpld_muxed_chip); | 351 | irq_set_chip_and_handler(irq, &htcpld_muxed_chip, |
363 | set_irq_chip_data(irq, chip); | 352 | handle_simple_irq); |
364 | set_irq_handler(irq, handle_simple_irq); | 353 | irq_set_chip_data(irq, chip); |
365 | #ifdef CONFIG_ARM | 354 | #ifdef CONFIG_ARM |
366 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 355 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
367 | #else | 356 | #else |
368 | set_irq_probe(irq); | 357 | irq_set_probe(irq); |
369 | #endif | 358 | #endif |
370 | } | 359 | } |
371 | 360 | ||
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index aa518b9beaf5..a0bd0cf05af3 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c | |||
@@ -112,7 +112,7 @@ static struct irq_chip jz4740_adc_irq_chip = { | |||
112 | 112 | ||
113 | static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) | 113 | static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) |
114 | { | 114 | { |
115 | struct jz4740_adc *adc = get_irq_desc_data(desc); | 115 | struct jz4740_adc *adc = irq_desc_get_handler_data(desc); |
116 | uint8_t status; | 116 | uint8_t status; |
117 | unsigned int i; | 117 | unsigned int i; |
118 | 118 | ||
@@ -310,13 +310,13 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev) | |||
310 | platform_set_drvdata(pdev, adc); | 310 | platform_set_drvdata(pdev, adc); |
311 | 311 | ||
312 | for (irq = adc->irq_base; irq < adc->irq_base + 5; ++irq) { | 312 | for (irq = adc->irq_base; irq < adc->irq_base + 5; ++irq) { |
313 | set_irq_chip_data(irq, adc); | 313 | irq_set_chip_data(irq, adc); |
314 | set_irq_chip_and_handler(irq, &jz4740_adc_irq_chip, | 314 | irq_set_chip_and_handler(irq, &jz4740_adc_irq_chip, |
315 | handle_level_irq); | 315 | handle_level_irq); |
316 | } | 316 | } |
317 | 317 | ||
318 | set_irq_data(adc->irq, adc); | 318 | irq_set_handler_data(adc->irq, adc); |
319 | set_irq_chained_handler(adc->irq, jz4740_adc_irq_demux); | 319 | irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux); |
320 | 320 | ||
321 | writeb(0x00, adc->base + JZ_REG_ADC_ENABLE); | 321 | writeb(0x00, adc->base + JZ_REG_ADC_ENABLE); |
322 | writeb(0xff, adc->base + JZ_REG_ADC_CTRL); | 322 | writeb(0xff, adc->base + JZ_REG_ADC_CTRL); |
@@ -347,8 +347,8 @@ static int __devexit jz4740_adc_remove(struct platform_device *pdev) | |||
347 | 347 | ||
348 | mfd_remove_devices(&pdev->dev); | 348 | mfd_remove_devices(&pdev->dev); |
349 | 349 | ||
350 | set_irq_data(adc->irq, NULL); | 350 | irq_set_handler_data(adc->irq, NULL); |
351 | set_irq_chained_handler(adc->irq, NULL); | 351 | irq_set_chained_handler(adc->irq, NULL); |
352 | 352 | ||
353 | iounmap(adc->base); | 353 | iounmap(adc->base); |
354 | release_mem_region(adc->mem->start, resource_size(adc->mem)); | 354 | release_mem_region(adc->mem->start, resource_size(adc->mem)); |
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 0e998dc4e7d8..58cc5fdde016 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -517,7 +517,6 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, | |||
517 | struct max8925_platform_data *pdata) | 517 | struct max8925_platform_data *pdata) |
518 | { | 518 | { |
519 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; | 519 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; |
520 | struct irq_desc *desc; | ||
521 | int i, ret; | 520 | int i, ret; |
522 | int __irq; | 521 | int __irq; |
523 | 522 | ||
@@ -544,19 +543,18 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, | |||
544 | mutex_init(&chip->irq_lock); | 543 | mutex_init(&chip->irq_lock); |
545 | chip->core_irq = irq; | 544 | chip->core_irq = irq; |
546 | chip->irq_base = pdata->irq_base; | 545 | chip->irq_base = pdata->irq_base; |
547 | desc = irq_to_desc(chip->core_irq); | ||
548 | 546 | ||
549 | /* register with genirq */ | 547 | /* register with genirq */ |
550 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { | 548 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { |
551 | __irq = i + chip->irq_base; | 549 | __irq = i + chip->irq_base; |
552 | set_irq_chip_data(__irq, chip); | 550 | irq_set_chip_data(__irq, chip); |
553 | set_irq_chip_and_handler(__irq, &max8925_irq_chip, | 551 | irq_set_chip_and_handler(__irq, &max8925_irq_chip, |
554 | handle_edge_irq); | 552 | handle_edge_irq); |
555 | set_irq_nested_thread(__irq, 1); | 553 | irq_set_nested_thread(__irq, 1); |
556 | #ifdef CONFIG_ARM | 554 | #ifdef CONFIG_ARM |
557 | set_irq_flags(__irq, IRQF_VALID); | 555 | set_irq_flags(__irq, IRQF_VALID); |
558 | #else | 556 | #else |
559 | set_irq_noprobe(__irq); | 557 | irq_set_noprobe(__irq); |
560 | #endif | 558 | #endif |
561 | } | 559 | } |
562 | if (!irq) { | 560 | if (!irq) { |
diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c new file mode 100644 index 000000000000..638bf7e4d3b3 --- /dev/null +++ b/drivers/mfd/max8997-irq.c | |||
@@ -0,0 +1,377 @@ | |||
1 | /* | ||
2 | * max8997-irq.c - Interrupt controller support for MAX8997 | ||
3 | * | ||
4 | * Copyright (C) 2011 Samsung Electronics Co.Ltd | ||
5 | * MyungJoo Ham <myungjoo.ham@samsung.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 as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | * This driver is based on max8998-irq.c | ||
22 | */ | ||
23 | |||
24 | #include <linux/err.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/mfd/max8997.h> | ||
28 | #include <linux/mfd/max8997-private.h> | ||
29 | |||
30 | static const u8 max8997_mask_reg[] = { | ||
31 | [PMIC_INT1] = MAX8997_REG_INT1MSK, | ||
32 | [PMIC_INT2] = MAX8997_REG_INT2MSK, | ||
33 | [PMIC_INT3] = MAX8997_REG_INT3MSK, | ||
34 | [PMIC_INT4] = MAX8997_REG_INT4MSK, | ||
35 | [FUEL_GAUGE] = MAX8997_REG_INVALID, | ||
36 | [MUIC_INT1] = MAX8997_MUIC_REG_INTMASK1, | ||
37 | [MUIC_INT2] = MAX8997_MUIC_REG_INTMASK2, | ||
38 | [MUIC_INT3] = MAX8997_MUIC_REG_INTMASK3, | ||
39 | [GPIO_LOW] = MAX8997_REG_INVALID, | ||
40 | [GPIO_HI] = MAX8997_REG_INVALID, | ||
41 | [FLASH_STATUS] = MAX8997_REG_INVALID, | ||
42 | }; | ||
43 | |||
44 | static struct i2c_client *get_i2c(struct max8997_dev *max8997, | ||
45 | enum max8997_irq_source src) | ||
46 | { | ||
47 | switch (src) { | ||
48 | case PMIC_INT1 ... PMIC_INT4: | ||
49 | return max8997->i2c; | ||
50 | case FUEL_GAUGE: | ||
51 | return NULL; | ||
52 | case MUIC_INT1 ... MUIC_INT3: | ||
53 | return max8997->muic; | ||
54 | case GPIO_LOW ... GPIO_HI: | ||
55 | return max8997->i2c; | ||
56 | case FLASH_STATUS: | ||
57 | return max8997->i2c; | ||
58 | default: | ||
59 | return ERR_PTR(-EINVAL); | ||
60 | } | ||
61 | |||
62 | return ERR_PTR(-EINVAL); | ||
63 | } | ||
64 | |||
65 | struct max8997_irq_data { | ||
66 | int mask; | ||
67 | enum max8997_irq_source group; | ||
68 | }; | ||
69 | |||
70 | #define DECLARE_IRQ(idx, _group, _mask) \ | ||
71 | [(idx)] = { .group = (_group), .mask = (_mask) } | ||
72 | static const struct max8997_irq_data max8997_irqs[] = { | ||
73 | DECLARE_IRQ(MAX8997_PMICIRQ_PWRONR, PMIC_INT1, 1 << 0), | ||
74 | DECLARE_IRQ(MAX8997_PMICIRQ_PWRONF, PMIC_INT1, 1 << 1), | ||
75 | DECLARE_IRQ(MAX8997_PMICIRQ_PWRON1SEC, PMIC_INT1, 1 << 3), | ||
76 | DECLARE_IRQ(MAX8997_PMICIRQ_JIGONR, PMIC_INT1, 1 << 4), | ||
77 | DECLARE_IRQ(MAX8997_PMICIRQ_JIGONF, PMIC_INT1, 1 << 5), | ||
78 | DECLARE_IRQ(MAX8997_PMICIRQ_LOWBAT2, PMIC_INT1, 1 << 6), | ||
79 | DECLARE_IRQ(MAX8997_PMICIRQ_LOWBAT1, PMIC_INT1, 1 << 7), | ||
80 | |||
81 | DECLARE_IRQ(MAX8997_PMICIRQ_JIGR, PMIC_INT2, 1 << 0), | ||
82 | DECLARE_IRQ(MAX8997_PMICIRQ_JIGF, PMIC_INT2, 1 << 1), | ||
83 | DECLARE_IRQ(MAX8997_PMICIRQ_MR, PMIC_INT2, 1 << 2), | ||
84 | DECLARE_IRQ(MAX8997_PMICIRQ_DVS1OK, PMIC_INT2, 1 << 3), | ||
85 | DECLARE_IRQ(MAX8997_PMICIRQ_DVS2OK, PMIC_INT2, 1 << 4), | ||
86 | DECLARE_IRQ(MAX8997_PMICIRQ_DVS3OK, PMIC_INT2, 1 << 5), | ||
87 | DECLARE_IRQ(MAX8997_PMICIRQ_DVS4OK, PMIC_INT2, 1 << 6), | ||
88 | |||
89 | DECLARE_IRQ(MAX8997_PMICIRQ_CHGINS, PMIC_INT3, 1 << 0), | ||
90 | DECLARE_IRQ(MAX8997_PMICIRQ_CHGRM, PMIC_INT3, 1 << 1), | ||
91 | DECLARE_IRQ(MAX8997_PMICIRQ_DCINOVP, PMIC_INT3, 1 << 2), | ||
92 | DECLARE_IRQ(MAX8997_PMICIRQ_TOPOFFR, PMIC_INT3, 1 << 3), | ||
93 | DECLARE_IRQ(MAX8997_PMICIRQ_CHGRSTF, PMIC_INT3, 1 << 5), | ||
94 | DECLARE_IRQ(MAX8997_PMICIRQ_MBCHGTMEXPD, PMIC_INT3, 1 << 7), | ||
95 | |||
96 | DECLARE_IRQ(MAX8997_PMICIRQ_RTC60S, PMIC_INT4, 1 << 0), | ||
97 | DECLARE_IRQ(MAX8997_PMICIRQ_RTCA1, PMIC_INT4, 1 << 1), | ||
98 | DECLARE_IRQ(MAX8997_PMICIRQ_RTCA2, PMIC_INT4, 1 << 2), | ||
99 | DECLARE_IRQ(MAX8997_PMICIRQ_SMPL_INT, PMIC_INT4, 1 << 3), | ||
100 | DECLARE_IRQ(MAX8997_PMICIRQ_RTC1S, PMIC_INT4, 1 << 4), | ||
101 | DECLARE_IRQ(MAX8997_PMICIRQ_WTSR, PMIC_INT4, 1 << 5), | ||
102 | |||
103 | DECLARE_IRQ(MAX8997_MUICIRQ_ADCError, MUIC_INT1, 1 << 2), | ||
104 | DECLARE_IRQ(MAX8997_MUICIRQ_ADCLow, MUIC_INT1, 1 << 1), | ||
105 | DECLARE_IRQ(MAX8997_MUICIRQ_ADC, MUIC_INT1, 1 << 0), | ||
106 | |||
107 | DECLARE_IRQ(MAX8997_MUICIRQ_VBVolt, MUIC_INT2, 1 << 4), | ||
108 | DECLARE_IRQ(MAX8997_MUICIRQ_DBChg, MUIC_INT2, 1 << 3), | ||
109 | DECLARE_IRQ(MAX8997_MUICIRQ_DCDTmr, MUIC_INT2, 1 << 2), | ||
110 | DECLARE_IRQ(MAX8997_MUICIRQ_ChgDetRun, MUIC_INT2, 1 << 1), | ||
111 | DECLARE_IRQ(MAX8997_MUICIRQ_ChgTyp, MUIC_INT2, 1 << 0), | ||
112 | |||
113 | DECLARE_IRQ(MAX8997_MUICIRQ_OVP, MUIC_INT3, 1 << 2), | ||
114 | }; | ||
115 | |||
116 | static void max8997_irq_lock(struct irq_data *data) | ||
117 | { | ||
118 | struct max8997_dev *max8997 = irq_get_chip_data(data->irq); | ||
119 | |||
120 | mutex_lock(&max8997->irqlock); | ||
121 | } | ||
122 | |||
123 | static void max8997_irq_sync_unlock(struct irq_data *data) | ||
124 | { | ||
125 | struct max8997_dev *max8997 = irq_get_chip_data(data->irq); | ||
126 | int i; | ||
127 | |||
128 | for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) { | ||
129 | u8 mask_reg = max8997_mask_reg[i]; | ||
130 | struct i2c_client *i2c = get_i2c(max8997, i); | ||
131 | |||
132 | if (mask_reg == MAX8997_REG_INVALID || | ||
133 | IS_ERR_OR_NULL(i2c)) | ||
134 | continue; | ||
135 | max8997->irq_masks_cache[i] = max8997->irq_masks_cur[i]; | ||
136 | |||
137 | max8997_write_reg(i2c, max8997_mask_reg[i], | ||
138 | max8997->irq_masks_cur[i]); | ||
139 | } | ||
140 | |||
141 | mutex_unlock(&max8997->irqlock); | ||
142 | } | ||
143 | |||
144 | static const inline struct max8997_irq_data * | ||
145 | irq_to_max8997_irq(struct max8997_dev *max8997, int irq) | ||
146 | { | ||
147 | return &max8997_irqs[irq - max8997->irq_base]; | ||
148 | } | ||
149 | |||
150 | static void max8997_irq_mask(struct irq_data *data) | ||
151 | { | ||
152 | struct max8997_dev *max8997 = irq_get_chip_data(data->irq); | ||
153 | const struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997, | ||
154 | data->irq); | ||
155 | |||
156 | max8997->irq_masks_cur[irq_data->group] |= irq_data->mask; | ||
157 | } | ||
158 | |||
159 | static void max8997_irq_unmask(struct irq_data *data) | ||
160 | { | ||
161 | struct max8997_dev *max8997 = irq_get_chip_data(data->irq); | ||
162 | const struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997, | ||
163 | data->irq); | ||
164 | |||
165 | max8997->irq_masks_cur[irq_data->group] &= ~irq_data->mask; | ||
166 | } | ||
167 | |||
168 | static struct irq_chip max8997_irq_chip = { | ||
169 | .name = "max8997", | ||
170 | .irq_bus_lock = max8997_irq_lock, | ||
171 | .irq_bus_sync_unlock = max8997_irq_sync_unlock, | ||
172 | .irq_mask = max8997_irq_mask, | ||
173 | .irq_unmask = max8997_irq_unmask, | ||
174 | }; | ||
175 | |||
176 | #define MAX8997_IRQSRC_PMIC (1 << 1) | ||
177 | #define MAX8997_IRQSRC_FUELGAUGE (1 << 2) | ||
178 | #define MAX8997_IRQSRC_MUIC (1 << 3) | ||
179 | #define MAX8997_IRQSRC_GPIO (1 << 4) | ||
180 | #define MAX8997_IRQSRC_FLASH (1 << 5) | ||
181 | static irqreturn_t max8997_irq_thread(int irq, void *data) | ||
182 | { | ||
183 | struct max8997_dev *max8997 = data; | ||
184 | u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {}; | ||
185 | u8 irq_src; | ||
186 | int ret; | ||
187 | int i; | ||
188 | |||
189 | ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src); | ||
190 | if (ret < 0) { | ||
191 | dev_err(max8997->dev, "Failed to read interrupt source: %d\n", | ||
192 | ret); | ||
193 | return IRQ_NONE; | ||
194 | } | ||
195 | |||
196 | if (irq_src & MAX8997_IRQSRC_PMIC) { | ||
197 | /* PMIC INT1 ~ INT4 */ | ||
198 | max8997_bulk_read(max8997->i2c, MAX8997_REG_INT1, 4, | ||
199 | &irq_reg[PMIC_INT1]); | ||
200 | } | ||
201 | if (irq_src & MAX8997_IRQSRC_FUELGAUGE) { | ||
202 | /* | ||
203 | * TODO: FUEL GAUGE | ||
204 | * | ||
205 | * This is to be supported by Max17042 driver. When | ||
206 | * an interrupt incurs here, it should be relayed to a | ||
207 | * Max17042 device that is connected (probably by | ||
208 | * platform-data). However, we do not have interrupt | ||
209 | * handling in Max17042 driver currently. The Max17042 IRQ | ||
210 | * driver should be ready to be used as a stand-alone device and | ||
211 | * a Max8997-dependent device. Because it is not ready in | ||
212 | * Max17042-side and it is not too critical in operating | ||
213 | * Max8997, we do not implement this in initial releases. | ||
214 | */ | ||
215 | irq_reg[FUEL_GAUGE] = 0; | ||
216 | } | ||
217 | if (irq_src & MAX8997_IRQSRC_MUIC) { | ||
218 | /* MUIC INT1 ~ INT3 */ | ||
219 | max8997_bulk_read(max8997->muic, MAX8997_MUIC_REG_INT1, 3, | ||
220 | &irq_reg[MUIC_INT1]); | ||
221 | } | ||
222 | if (irq_src & MAX8997_IRQSRC_GPIO) { | ||
223 | /* GPIO Interrupt */ | ||
224 | u8 gpio_info[MAX8997_NUM_GPIO]; | ||
225 | |||
226 | irq_reg[GPIO_LOW] = 0; | ||
227 | irq_reg[GPIO_HI] = 0; | ||
228 | |||
229 | max8997_bulk_read(max8997->i2c, MAX8997_REG_GPIOCNTL1, | ||
230 | MAX8997_NUM_GPIO, gpio_info); | ||
231 | for (i = 0; i < MAX8997_NUM_GPIO; i++) { | ||
232 | bool interrupt = false; | ||
233 | |||
234 | switch (gpio_info[i] & MAX8997_GPIO_INT_MASK) { | ||
235 | case MAX8997_GPIO_INT_BOTH: | ||
236 | if (max8997->gpio_status[i] != gpio_info[i]) | ||
237 | interrupt = true; | ||
238 | break; | ||
239 | case MAX8997_GPIO_INT_RISE: | ||
240 | if ((max8997->gpio_status[i] != gpio_info[i]) && | ||
241 | (gpio_info[i] & MAX8997_GPIO_DATA_MASK)) | ||
242 | interrupt = true; | ||
243 | break; | ||
244 | case MAX8997_GPIO_INT_FALL: | ||
245 | if ((max8997->gpio_status[i] != gpio_info[i]) && | ||
246 | !(gpio_info[i] & MAX8997_GPIO_DATA_MASK)) | ||
247 | interrupt = true; | ||
248 | break; | ||
249 | default: | ||
250 | break; | ||
251 | } | ||
252 | |||
253 | if (interrupt) { | ||
254 | if (i < 8) | ||
255 | irq_reg[GPIO_LOW] |= (1 << i); | ||
256 | else | ||
257 | irq_reg[GPIO_HI] |= (1 << (i - 8)); | ||
258 | } | ||
259 | |||
260 | } | ||
261 | } | ||
262 | if (irq_src & MAX8997_IRQSRC_FLASH) { | ||
263 | /* Flash Status Interrupt */ | ||
264 | ret = max8997_read_reg(max8997->i2c, MAX8997_REG_FLASHSTATUS, | ||
265 | &irq_reg[FLASH_STATUS]); | ||
266 | } | ||
267 | |||
268 | /* Apply masking */ | ||
269 | for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) | ||
270 | irq_reg[i] &= ~max8997->irq_masks_cur[i]; | ||
271 | |||
272 | /* Report */ | ||
273 | for (i = 0; i < MAX8997_IRQ_NR; i++) { | ||
274 | if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) | ||
275 | handle_nested_irq(max8997->irq_base + i); | ||
276 | } | ||
277 | |||
278 | return IRQ_HANDLED; | ||
279 | } | ||
280 | |||
281 | int max8997_irq_resume(struct max8997_dev *max8997) | ||
282 | { | ||
283 | if (max8997->irq && max8997->irq_base) | ||
284 | max8997_irq_thread(max8997->irq_base, max8997); | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | int max8997_irq_init(struct max8997_dev *max8997) | ||
289 | { | ||
290 | int i; | ||
291 | int cur_irq; | ||
292 | int ret; | ||
293 | u8 val; | ||
294 | |||
295 | if (!max8997->irq) { | ||
296 | dev_warn(max8997->dev, "No interrupt specified.\n"); | ||
297 | max8997->irq_base = 0; | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | if (!max8997->irq_base) { | ||
302 | dev_err(max8997->dev, "No interrupt base specified.\n"); | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | mutex_init(&max8997->irqlock); | ||
307 | |||
308 | /* Mask individual interrupt sources */ | ||
309 | for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) { | ||
310 | struct i2c_client *i2c; | ||
311 | |||
312 | max8997->irq_masks_cur[i] = 0xff; | ||
313 | max8997->irq_masks_cache[i] = 0xff; | ||
314 | i2c = get_i2c(max8997, i); | ||
315 | |||
316 | if (IS_ERR_OR_NULL(i2c)) | ||
317 | continue; | ||
318 | if (max8997_mask_reg[i] == MAX8997_REG_INVALID) | ||
319 | continue; | ||
320 | |||
321 | max8997_write_reg(i2c, max8997_mask_reg[i], 0xff); | ||
322 | } | ||
323 | |||
324 | for (i = 0; i < MAX8997_NUM_GPIO; i++) { | ||
325 | max8997->gpio_status[i] = (max8997_read_reg(max8997->i2c, | ||
326 | MAX8997_REG_GPIOCNTL1 + i, | ||
327 | &val) | ||
328 | & MAX8997_GPIO_DATA_MASK) ? | ||
329 | true : false; | ||
330 | } | ||
331 | |||
332 | /* Register with genirq */ | ||
333 | for (i = 0; i < MAX8997_IRQ_NR; i++) { | ||
334 | cur_irq = i + max8997->irq_base; | ||
335 | irq_set_chip_data(cur_irq, max8997); | ||
336 | irq_set_chip_and_handler(cur_irq, &max8997_irq_chip, | ||
337 | handle_edge_irq); | ||
338 | irq_set_nested_thread(cur_irq, 1); | ||
339 | #ifdef CONFIG_ARM | ||
340 | set_irq_flags(cur_irq, IRQF_VALID); | ||
341 | #else | ||
342 | irq_set_noprobe(cur_irq); | ||
343 | #endif | ||
344 | } | ||
345 | |||
346 | ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread, | ||
347 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
348 | "max8997-irq", max8997); | ||
349 | |||
350 | if (ret) { | ||
351 | dev_err(max8997->dev, "Failed to request IRQ %d: %d\n", | ||
352 | max8997->irq, ret); | ||
353 | return ret; | ||
354 | } | ||
355 | |||
356 | if (!max8997->ono) | ||
357 | return 0; | ||
358 | |||
359 | ret = request_threaded_irq(max8997->ono, NULL, max8997_irq_thread, | ||
360 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | | ||
361 | IRQF_ONESHOT, "max8997-ono", max8997); | ||
362 | |||
363 | if (ret) | ||
364 | dev_err(max8997->dev, "Failed to request ono-IRQ %d: %d\n", | ||
365 | max8997->ono, ret); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | void max8997_irq_exit(struct max8997_dev *max8997) | ||
371 | { | ||
372 | if (max8997->ono) | ||
373 | free_irq(max8997->ono, max8997); | ||
374 | |||
375 | if (max8997->irq) | ||
376 | free_irq(max8997->irq, max8997); | ||
377 | } | ||
diff --git a/drivers/mfd/max8998-irq.c b/drivers/mfd/max8998-irq.c index 3903e1fbb334..5919710dc9ed 100644 --- a/drivers/mfd/max8998-irq.c +++ b/drivers/mfd/max8998-irq.c | |||
@@ -224,14 +224,14 @@ int max8998_irq_init(struct max8998_dev *max8998) | |||
224 | /* register with genirq */ | 224 | /* register with genirq */ |
225 | for (i = 0; i < MAX8998_IRQ_NR; i++) { | 225 | for (i = 0; i < MAX8998_IRQ_NR; i++) { |
226 | cur_irq = i + max8998->irq_base; | 226 | cur_irq = i + max8998->irq_base; |
227 | set_irq_chip_data(cur_irq, max8998); | 227 | irq_set_chip_data(cur_irq, max8998); |
228 | set_irq_chip_and_handler(cur_irq, &max8998_irq_chip, | 228 | irq_set_chip_and_handler(cur_irq, &max8998_irq_chip, |
229 | handle_edge_irq); | 229 | handle_edge_irq); |
230 | set_irq_nested_thread(cur_irq, 1); | 230 | irq_set_nested_thread(cur_irq, 1); |
231 | #ifdef CONFIG_ARM | 231 | #ifdef CONFIG_ARM |
232 | set_irq_flags(cur_irq, IRQF_VALID); | 232 | set_irq_flags(cur_irq, IRQF_VALID); |
233 | #else | 233 | #else |
234 | set_irq_noprobe(cur_irq); | 234 | irq_set_noprobe(cur_irq); |
235 | #endif | 235 | #endif |
236 | } | 236 | } |
237 | 237 | ||
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index c00214257da2..9ec7570f5b81 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
@@ -209,7 +209,7 @@ static int max8998_suspend(struct device *dev) | |||
209 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | 209 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); |
210 | 210 | ||
211 | if (max8998->wakeup) | 211 | if (max8998->wakeup) |
212 | set_irq_wake(max8998->irq, 1); | 212 | irq_set_irq_wake(max8998->irq, 1); |
213 | return 0; | 213 | return 0; |
214 | } | 214 | } |
215 | 215 | ||
@@ -219,7 +219,7 @@ static int max8998_resume(struct device *dev) | |||
219 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | 219 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); |
220 | 220 | ||
221 | if (max8998->wakeup) | 221 | if (max8998->wakeup) |
222 | set_irq_wake(max8998->irq, 0); | 222 | irq_set_irq_wake(max8998->irq, 0); |
223 | /* | 223 | /* |
224 | * In LP3974, if IRQ registers are not "read & clear" | 224 | * In LP3974, if IRQ registers are not "read & clear" |
225 | * when it's set during sleep, the interrupt becomes | 225 | * when it's set during sleep, the interrupt becomes |
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 79eda0264fb2..d01574d98870 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -184,16 +184,12 @@ void mfd_remove_devices(struct device *parent) | |||
184 | } | 184 | } |
185 | EXPORT_SYMBOL(mfd_remove_devices); | 185 | EXPORT_SYMBOL(mfd_remove_devices); |
186 | 186 | ||
187 | static int add_shared_platform_device(const char *cell, const char *name) | 187 | int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) |
188 | { | 188 | { |
189 | struct mfd_cell cell_entry; | 189 | struct mfd_cell cell_entry; |
190 | struct device *dev; | 190 | struct device *dev; |
191 | struct platform_device *pdev; | 191 | struct platform_device *pdev; |
192 | int err; | 192 | int i; |
193 | |||
194 | /* check if we've already registered a device (don't fail if we have) */ | ||
195 | if (bus_find_device_by_name(&platform_bus_type, NULL, name)) | ||
196 | return 0; | ||
197 | 193 | ||
198 | /* fetch the parent cell's device (should already be registered!) */ | 194 | /* fetch the parent cell's device (should already be registered!) */ |
199 | dev = bus_find_device_by_name(&platform_bus_type, NULL, cell); | 195 | dev = bus_find_device_by_name(&platform_bus_type, NULL, cell); |
@@ -206,44 +202,17 @@ static int add_shared_platform_device(const char *cell, const char *name) | |||
206 | 202 | ||
207 | WARN_ON(!cell_entry.enable); | 203 | WARN_ON(!cell_entry.enable); |
208 | 204 | ||
209 | cell_entry.name = name; | 205 | for (i = 0; i < n_clones; i++) { |
210 | err = mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0); | 206 | cell_entry.name = clones[i]; |
211 | if (err) | 207 | /* don't give up if a single call fails; just report error */ |
212 | dev_err(dev, "MFD add devices failed: %d\n", err); | 208 | if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) |
213 | return err; | 209 | dev_err(dev, "failed to create platform device '%s'\n", |
214 | } | 210 | clones[i]); |
215 | 211 | } | |
216 | int mfd_shared_platform_driver_register(struct platform_driver *drv, | ||
217 | const char *cellname) | ||
218 | { | ||
219 | int err; | ||
220 | |||
221 | err = add_shared_platform_device(cellname, drv->driver.name); | ||
222 | if (err) | ||
223 | printk(KERN_ERR "failed to add platform device %s\n", | ||
224 | drv->driver.name); | ||
225 | |||
226 | err = platform_driver_register(drv); | ||
227 | if (err) | ||
228 | printk(KERN_ERR "failed to add platform driver %s\n", | ||
229 | drv->driver.name); | ||
230 | |||
231 | return err; | ||
232 | } | ||
233 | EXPORT_SYMBOL(mfd_shared_platform_driver_register); | ||
234 | |||
235 | void mfd_shared_platform_driver_unregister(struct platform_driver *drv) | ||
236 | { | ||
237 | struct device *dev; | ||
238 | |||
239 | dev = bus_find_device_by_name(&platform_bus_type, NULL, | ||
240 | drv->driver.name); | ||
241 | if (dev) | ||
242 | platform_device_unregister(to_platform_device(dev)); | ||
243 | 212 | ||
244 | platform_driver_unregister(drv); | 213 | return 0; |
245 | } | 214 | } |
246 | EXPORT_SYMBOL(mfd_shared_platform_driver_unregister); | 215 | EXPORT_SYMBOL(mfd_clone_cell); |
247 | 216 | ||
248 | MODULE_LICENSE("GPL"); | 217 | MODULE_LICENSE("GPL"); |
249 | MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); | 218 | MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); |
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index c1306ed43e3c..c7687f6a78a0 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c | |||
@@ -356,7 +356,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client) | |||
356 | return 0; | 356 | return 0; |
357 | } | 357 | } |
358 | 358 | ||
359 | static struct i2c_device_id pcf50633_id_table[] = { | 359 | static const struct i2c_device_id pcf50633_id_table[] = { |
360 | {"pcf50633", 0x73}, | 360 | {"pcf50633", 0x73}, |
361 | {/* end of list */} | 361 | {/* end of list */} |
362 | }; | 362 | }; |
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index 193c940225b5..10dbe6374a89 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c | |||
@@ -97,6 +97,7 @@ static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = { | |||
97 | { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) }, | 97 | { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) }, |
98 | {} | 98 | {} |
99 | }; | 99 | }; |
100 | MODULE_DEVICE_TABLE(pci, rdc321x_sb_table); | ||
100 | 101 | ||
101 | static struct pci_driver rdc321x_sb_driver = { | 102 | static struct pci_driver rdc321x_sb_driver = { |
102 | .name = "RDC321x Southbridge", | 103 | .name = "RDC321x Southbridge", |
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 3e5732b58c49..7ab7746631d4 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -762,14 +762,14 @@ static int __devinit stmpe_irq_init(struct stmpe *stmpe) | |||
762 | int irq; | 762 | int irq; |
763 | 763 | ||
764 | for (irq = base; irq < base + num_irqs; irq++) { | 764 | for (irq = base; irq < base + num_irqs; irq++) { |
765 | set_irq_chip_data(irq, stmpe); | 765 | irq_set_chip_data(irq, stmpe); |
766 | set_irq_chip_and_handler(irq, &stmpe_irq_chip, | 766 | irq_set_chip_and_handler(irq, &stmpe_irq_chip, |
767 | handle_edge_irq); | 767 | handle_edge_irq); |
768 | set_irq_nested_thread(irq, 1); | 768 | irq_set_nested_thread(irq, 1); |
769 | #ifdef CONFIG_ARM | 769 | #ifdef CONFIG_ARM |
770 | set_irq_flags(irq, IRQF_VALID); | 770 | set_irq_flags(irq, IRQF_VALID); |
771 | #else | 771 | #else |
772 | set_irq_noprobe(irq); | 772 | irq_set_noprobe(irq); |
773 | #endif | 773 | #endif |
774 | } | 774 | } |
775 | 775 | ||
@@ -786,8 +786,8 @@ static void stmpe_irq_remove(struct stmpe *stmpe) | |||
786 | #ifdef CONFIG_ARM | 786 | #ifdef CONFIG_ARM |
787 | set_irq_flags(irq, 0); | 787 | set_irq_flags(irq, 0); |
788 | #endif | 788 | #endif |
789 | set_irq_chip_and_handler(irq, NULL, NULL); | 789 | irq_set_chip_and_handler(irq, NULL, NULL); |
790 | set_irq_chip_data(irq, NULL); | 790 | irq_set_chip_data(irq, NULL); |
791 | } | 791 | } |
792 | } | 792 | } |
793 | 793 | ||
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index af57fc706a4c..42830e692964 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
@@ -186,7 +186,7 @@ static struct mfd_cell t7l66xb_cells[] = { | |||
186 | /* Handle the T7L66XB interrupt mux */ | 186 | /* Handle the T7L66XB interrupt mux */ |
187 | static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) | 187 | static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) |
188 | { | 188 | { |
189 | struct t7l66xb *t7l66xb = get_irq_data(irq); | 189 | struct t7l66xb *t7l66xb = irq_get_handler_data(irq); |
190 | unsigned int isr; | 190 | unsigned int isr; |
191 | unsigned int i, irq_base; | 191 | unsigned int i, irq_base; |
192 | 192 | ||
@@ -243,17 +243,16 @@ static void t7l66xb_attach_irq(struct platform_device *dev) | |||
243 | irq_base = t7l66xb->irq_base; | 243 | irq_base = t7l66xb->irq_base; |
244 | 244 | ||
245 | for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { | 245 | for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { |
246 | set_irq_chip(irq, &t7l66xb_chip); | 246 | irq_set_chip_and_handler(irq, &t7l66xb_chip, handle_level_irq); |
247 | set_irq_chip_data(irq, t7l66xb); | 247 | irq_set_chip_data(irq, t7l66xb); |
248 | set_irq_handler(irq, handle_level_irq); | ||
249 | #ifdef CONFIG_ARM | 248 | #ifdef CONFIG_ARM |
250 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 249 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
251 | #endif | 250 | #endif |
252 | } | 251 | } |
253 | 252 | ||
254 | set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING); | 253 | irq_set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING); |
255 | set_irq_data(t7l66xb->irq, t7l66xb); | 254 | irq_set_handler_data(t7l66xb->irq, t7l66xb); |
256 | set_irq_chained_handler(t7l66xb->irq, t7l66xb_irq); | 255 | irq_set_chained_handler(t7l66xb->irq, t7l66xb_irq); |
257 | } | 256 | } |
258 | 257 | ||
259 | static void t7l66xb_detach_irq(struct platform_device *dev) | 258 | static void t7l66xb_detach_irq(struct platform_device *dev) |
@@ -263,15 +262,15 @@ static void t7l66xb_detach_irq(struct platform_device *dev) | |||
263 | 262 | ||
264 | irq_base = t7l66xb->irq_base; | 263 | irq_base = t7l66xb->irq_base; |
265 | 264 | ||
266 | set_irq_chained_handler(t7l66xb->irq, NULL); | 265 | irq_set_chained_handler(t7l66xb->irq, NULL); |
267 | set_irq_data(t7l66xb->irq, NULL); | 266 | irq_set_handler_data(t7l66xb->irq, NULL); |
268 | 267 | ||
269 | for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { | 268 | for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { |
270 | #ifdef CONFIG_ARM | 269 | #ifdef CONFIG_ARM |
271 | set_irq_flags(irq, 0); | 270 | set_irq_flags(irq, 0); |
272 | #endif | 271 | #endif |
273 | set_irq_chip(irq, NULL); | 272 | irq_set_chip(irq, NULL); |
274 | set_irq_chip_data(irq, NULL); | 273 | irq_set_chip_data(irq, NULL); |
275 | } | 274 | } |
276 | } | 275 | } |
277 | 276 | ||
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 729dbeed2ce0..c27e515b0722 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c | |||
@@ -192,14 +192,14 @@ static int tc3589x_irq_init(struct tc3589x *tc3589x) | |||
192 | int irq; | 192 | int irq; |
193 | 193 | ||
194 | for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) { | 194 | for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) { |
195 | set_irq_chip_data(irq, tc3589x); | 195 | irq_set_chip_data(irq, tc3589x); |
196 | set_irq_chip_and_handler(irq, &dummy_irq_chip, | 196 | irq_set_chip_and_handler(irq, &dummy_irq_chip, |
197 | handle_edge_irq); | 197 | handle_edge_irq); |
198 | set_irq_nested_thread(irq, 1); | 198 | irq_set_nested_thread(irq, 1); |
199 | #ifdef CONFIG_ARM | 199 | #ifdef CONFIG_ARM |
200 | set_irq_flags(irq, IRQF_VALID); | 200 | set_irq_flags(irq, IRQF_VALID); |
201 | #else | 201 | #else |
202 | set_irq_noprobe(irq); | 202 | irq_set_noprobe(irq); |
203 | #endif | 203 | #endif |
204 | } | 204 | } |
205 | 205 | ||
@@ -215,8 +215,8 @@ static void tc3589x_irq_remove(struct tc3589x *tc3589x) | |||
215 | #ifdef CONFIG_ARM | 215 | #ifdef CONFIG_ARM |
216 | set_irq_flags(irq, 0); | 216 | set_irq_flags(irq, 0); |
217 | #endif | 217 | #endif |
218 | set_irq_chip_and_handler(irq, NULL, NULL); | 218 | irq_set_chip_and_handler(irq, NULL, NULL); |
219 | set_irq_chip_data(irq, NULL); | 219 | irq_set_chip_data(irq, NULL); |
220 | } | 220 | } |
221 | } | 221 | } |
222 | 222 | ||
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 3d62ded86a8f..fc53ce287601 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -513,7 +513,7 @@ static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base) | |||
513 | static void | 513 | static void |
514 | tc6393xb_irq(unsigned int irq, struct irq_desc *desc) | 514 | tc6393xb_irq(unsigned int irq, struct irq_desc *desc) |
515 | { | 515 | { |
516 | struct tc6393xb *tc6393xb = get_irq_data(irq); | 516 | struct tc6393xb *tc6393xb = irq_get_handler_data(irq); |
517 | unsigned int isr; | 517 | unsigned int isr; |
518 | unsigned int i, irq_base; | 518 | unsigned int i, irq_base; |
519 | 519 | ||
@@ -572,15 +572,14 @@ static void tc6393xb_attach_irq(struct platform_device *dev) | |||
572 | irq_base = tc6393xb->irq_base; | 572 | irq_base = tc6393xb->irq_base; |
573 | 573 | ||
574 | for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { | 574 | for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { |
575 | set_irq_chip(irq, &tc6393xb_chip); | 575 | irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq); |
576 | set_irq_chip_data(irq, tc6393xb); | 576 | irq_set_chip_data(irq, tc6393xb); |
577 | set_irq_handler(irq, handle_edge_irq); | ||
578 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 577 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
579 | } | 578 | } |
580 | 579 | ||
581 | set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); | 580 | irq_set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); |
582 | set_irq_data(tc6393xb->irq, tc6393xb); | 581 | irq_set_handler_data(tc6393xb->irq, tc6393xb); |
583 | set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq); | 582 | irq_set_chained_handler(tc6393xb->irq, tc6393xb_irq); |
584 | } | 583 | } |
585 | 584 | ||
586 | static void tc6393xb_detach_irq(struct platform_device *dev) | 585 | static void tc6393xb_detach_irq(struct platform_device *dev) |
@@ -588,15 +587,15 @@ static void tc6393xb_detach_irq(struct platform_device *dev) | |||
588 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | 587 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); |
589 | unsigned int irq, irq_base; | 588 | unsigned int irq, irq_base; |
590 | 589 | ||
591 | set_irq_chained_handler(tc6393xb->irq, NULL); | 590 | irq_set_chained_handler(tc6393xb->irq, NULL); |
592 | set_irq_data(tc6393xb->irq, NULL); | 591 | irq_set_handler_data(tc6393xb->irq, NULL); |
593 | 592 | ||
594 | irq_base = tc6393xb->irq_base; | 593 | irq_base = tc6393xb->irq_base; |
595 | 594 | ||
596 | for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { | 595 | for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { |
597 | set_irq_flags(irq, 0); | 596 | set_irq_flags(irq, 0); |
598 | set_irq_chip(irq, NULL); | 597 | irq_set_chip(irq, NULL); |
599 | set_irq_chip_data(irq, NULL); | 598 | irq_set_chip_data(irq, NULL); |
600 | } | 599 | } |
601 | } | 600 | } |
602 | 601 | ||
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 0aa9186aec19..b600808690c1 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
@@ -422,10 +422,10 @@ static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq, | |||
422 | 422 | ||
423 | for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { | 423 | for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { |
424 | int __irq = i + tps6586x->irq_base; | 424 | int __irq = i + tps6586x->irq_base; |
425 | set_irq_chip_data(__irq, tps6586x); | 425 | irq_set_chip_data(__irq, tps6586x); |
426 | set_irq_chip_and_handler(__irq, &tps6586x->irq_chip, | 426 | irq_set_chip_and_handler(__irq, &tps6586x->irq_chip, |
427 | handle_simple_irq); | 427 | handle_simple_irq); |
428 | set_irq_nested_thread(__irq, 1); | 428 | irq_set_nested_thread(__irq, 1); |
429 | #ifdef CONFIG_ARM | 429 | #ifdef CONFIG_ARM |
430 | set_irq_flags(__irq, IRQF_VALID); | 430 | set_irq_flags(__irq, IRQF_VALID); |
431 | #endif | 431 | #endif |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 63a30e88908f..8a7ee3139b86 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
@@ -320,24 +320,8 @@ static int twl4030_irq_thread(void *data) | |||
320 | for (module_irq = twl4030_irq_base; | 320 | for (module_irq = twl4030_irq_base; |
321 | pih_isr; | 321 | pih_isr; |
322 | pih_isr >>= 1, module_irq++) { | 322 | pih_isr >>= 1, module_irq++) { |
323 | if (pih_isr & 0x1) { | 323 | if (pih_isr & 0x1) |
324 | struct irq_desc *d = irq_to_desc(module_irq); | 324 | generic_handle_irq(module_irq); |
325 | |||
326 | if (!d) { | ||
327 | pr_err("twl4030: Invalid SIH IRQ: %d\n", | ||
328 | module_irq); | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | |||
332 | /* These can't be masked ... always warn | ||
333 | * if we get any surprises. | ||
334 | */ | ||
335 | if (d->status & IRQ_DISABLED) | ||
336 | note_interrupt(module_irq, d, | ||
337 | IRQ_NONE); | ||
338 | else | ||
339 | d->handle_irq(module_irq, d); | ||
340 | } | ||
341 | } | 325 | } |
342 | local_irq_enable(); | 326 | local_irq_enable(); |
343 | 327 | ||
@@ -470,7 +454,7 @@ static inline void activate_irq(int irq) | |||
470 | set_irq_flags(irq, IRQF_VALID); | 454 | set_irq_flags(irq, IRQF_VALID); |
471 | #else | 455 | #else |
472 | /* same effect on other architectures */ | 456 | /* same effect on other architectures */ |
473 | set_irq_noprobe(irq); | 457 | irq_set_noprobe(irq); |
474 | #endif | 458 | #endif |
475 | } | 459 | } |
476 | 460 | ||
@@ -560,24 +544,18 @@ static void twl4030_sih_do_edge(struct work_struct *work) | |||
560 | /* Modify only the bits we know must change */ | 544 | /* Modify only the bits we know must change */ |
561 | while (edge_change) { | 545 | while (edge_change) { |
562 | int i = fls(edge_change) - 1; | 546 | int i = fls(edge_change) - 1; |
563 | struct irq_desc *d = irq_to_desc(i + agent->irq_base); | 547 | struct irq_data *idata = irq_get_irq_data(i + agent->irq_base); |
564 | int byte = 1 + (i >> 2); | 548 | int byte = 1 + (i >> 2); |
565 | int off = (i & 0x3) * 2; | 549 | int off = (i & 0x3) * 2; |
566 | 550 | unsigned int type; | |
567 | if (!d) { | ||
568 | pr_err("twl4030: Invalid IRQ: %d\n", | ||
569 | i + agent->irq_base); | ||
570 | return; | ||
571 | } | ||
572 | 551 | ||
573 | bytes[byte] &= ~(0x03 << off); | 552 | bytes[byte] &= ~(0x03 << off); |
574 | 553 | ||
575 | raw_spin_lock_irq(&d->lock); | 554 | type = irqd_get_trigger_type(idata); |
576 | if (d->status & IRQ_TYPE_EDGE_RISING) | 555 | if (type & IRQ_TYPE_EDGE_RISING) |
577 | bytes[byte] |= BIT(off + 1); | 556 | bytes[byte] |= BIT(off + 1); |
578 | if (d->status & IRQ_TYPE_EDGE_FALLING) | 557 | if (type & IRQ_TYPE_EDGE_FALLING) |
579 | bytes[byte] |= BIT(off + 0); | 558 | bytes[byte] |= BIT(off + 0); |
580 | raw_spin_unlock_irq(&d->lock); | ||
581 | 559 | ||
582 | edge_change &= ~BIT(i); | 560 | edge_change &= ~BIT(i); |
583 | } | 561 | } |
@@ -626,21 +604,13 @@ static void twl4030_sih_unmask(struct irq_data *data) | |||
626 | static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) | 604 | static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) |
627 | { | 605 | { |
628 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); | 606 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); |
629 | struct irq_desc *desc = irq_to_desc(data->irq); | ||
630 | unsigned long flags; | 607 | unsigned long flags; |
631 | 608 | ||
632 | if (!desc) { | ||
633 | pr_err("twl4030: Invalid IRQ: %d\n", data->irq); | ||
634 | return -EINVAL; | ||
635 | } | ||
636 | |||
637 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 609 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
638 | return -EINVAL; | 610 | return -EINVAL; |
639 | 611 | ||
640 | spin_lock_irqsave(&sih_agent_lock, flags); | 612 | spin_lock_irqsave(&sih_agent_lock, flags); |
641 | if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { | 613 | if (irqd_get_trigger_type(data) != trigger) { |
642 | desc->status &= ~IRQ_TYPE_SENSE_MASK; | ||
643 | desc->status |= trigger; | ||
644 | sih->edge_change |= BIT(data->irq - sih->irq_base); | 614 | sih->edge_change |= BIT(data->irq - sih->irq_base); |
645 | queue_work(wq, &sih->edge_work); | 615 | queue_work(wq, &sih->edge_work); |
646 | } | 616 | } |
@@ -680,7 +650,7 @@ static inline int sih_read_isr(const struct sih *sih) | |||
680 | */ | 650 | */ |
681 | static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) | 651 | static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) |
682 | { | 652 | { |
683 | struct sih_agent *agent = get_irq_data(irq); | 653 | struct sih_agent *agent = irq_get_handler_data(irq); |
684 | const struct sih *sih = agent->sih; | 654 | const struct sih *sih = agent->sih; |
685 | int isr; | 655 | int isr; |
686 | 656 | ||
@@ -754,9 +724,9 @@ int twl4030_sih_setup(int module) | |||
754 | for (i = 0; i < sih->bits; i++) { | 724 | for (i = 0; i < sih->bits; i++) { |
755 | irq = irq_base + i; | 725 | irq = irq_base + i; |
756 | 726 | ||
757 | set_irq_chip_and_handler(irq, &twl4030_sih_irq_chip, | 727 | irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip, |
758 | handle_edge_irq); | 728 | handle_edge_irq); |
759 | set_irq_chip_data(irq, agent); | 729 | irq_set_chip_data(irq, agent); |
760 | activate_irq(irq); | 730 | activate_irq(irq); |
761 | } | 731 | } |
762 | 732 | ||
@@ -765,8 +735,8 @@ int twl4030_sih_setup(int module) | |||
765 | 735 | ||
766 | /* replace generic PIH handler (handle_simple_irq) */ | 736 | /* replace generic PIH handler (handle_simple_irq) */ |
767 | irq = sih_mod + twl4030_irq_base; | 737 | irq = sih_mod + twl4030_irq_base; |
768 | set_irq_data(irq, agent); | 738 | irq_set_handler_data(irq, agent); |
769 | set_irq_chained_handler(irq, handle_twl4030_sih); | 739 | irq_set_chained_handler(irq, handle_twl4030_sih); |
770 | 740 | ||
771 | pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name, | 741 | pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name, |
772 | irq, irq_base, twl4030_irq_next - 1); | 742 | irq, irq_base, twl4030_irq_next - 1); |
@@ -815,8 +785,8 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
815 | twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; | 785 | twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; |
816 | 786 | ||
817 | for (i = irq_base; i < irq_end; i++) { | 787 | for (i = irq_base; i < irq_end; i++) { |
818 | set_irq_chip_and_handler(i, &twl4030_irq_chip, | 788 | irq_set_chip_and_handler(i, &twl4030_irq_chip, |
819 | handle_simple_irq); | 789 | handle_simple_irq); |
820 | activate_irq(i); | 790 | activate_irq(i); |
821 | } | 791 | } |
822 | twl4030_irq_next = i; | 792 | twl4030_irq_next = i; |
@@ -856,7 +826,7 @@ fail_rqirq: | |||
856 | /* clean up twl4030_sih_setup */ | 826 | /* clean up twl4030_sih_setup */ |
857 | fail: | 827 | fail: |
858 | for (i = irq_base; i < irq_end; i++) | 828 | for (i = irq_base; i < irq_end; i++) |
859 | set_irq_chip_and_handler(i, NULL, NULL); | 829 | irq_set_chip_and_handler(i, NULL, NULL); |
860 | destroy_workqueue(wq); | 830 | destroy_workqueue(wq); |
861 | wq = NULL; | 831 | wq = NULL; |
862 | return status; | 832 | return status; |
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index 4082ed73613f..fa937052fbab 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
@@ -140,22 +140,7 @@ static int twl6030_irq_thread(void *data) | |||
140 | if (sts.int_sts & 0x1) { | 140 | if (sts.int_sts & 0x1) { |
141 | int module_irq = twl6030_irq_base + | 141 | int module_irq = twl6030_irq_base + |
142 | twl6030_interrupt_mapping[i]; | 142 | twl6030_interrupt_mapping[i]; |
143 | struct irq_desc *d = irq_to_desc(module_irq); | 143 | generic_handle_irq(module_irq); |
144 | |||
145 | if (!d) { | ||
146 | pr_err("twl6030: Invalid SIH IRQ: %d\n", | ||
147 | module_irq); | ||
148 | return -EINVAL; | ||
149 | } | ||
150 | |||
151 | /* These can't be masked ... always warn | ||
152 | * if we get any surprises. | ||
153 | */ | ||
154 | if (d->status & IRQ_DISABLED) | ||
155 | note_interrupt(module_irq, d, | ||
156 | IRQ_NONE); | ||
157 | else | ||
158 | d->handle_irq(module_irq, d); | ||
159 | 144 | ||
160 | } | 145 | } |
161 | local_irq_enable(); | 146 | local_irq_enable(); |
@@ -198,7 +183,7 @@ static inline void activate_irq(int irq) | |||
198 | set_irq_flags(irq, IRQF_VALID); | 183 | set_irq_flags(irq, IRQF_VALID); |
199 | #else | 184 | #else |
200 | /* same effect on other architectures */ | 185 | /* same effect on other architectures */ |
201 | set_irq_noprobe(irq); | 186 | irq_set_noprobe(irq); |
202 | #endif | 187 | #endif |
203 | } | 188 | } |
204 | 189 | ||
@@ -335,8 +320,8 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
335 | twl6030_irq_chip.irq_set_type = NULL; | 320 | twl6030_irq_chip.irq_set_type = NULL; |
336 | 321 | ||
337 | for (i = irq_base; i < irq_end; i++) { | 322 | for (i = irq_base; i < irq_end; i++) { |
338 | set_irq_chip_and_handler(i, &twl6030_irq_chip, | 323 | irq_set_chip_and_handler(i, &twl6030_irq_chip, |
339 | handle_simple_irq); | 324 | handle_simple_irq); |
340 | activate_irq(i); | 325 | activate_irq(i); |
341 | } | 326 | } |
342 | 327 | ||
@@ -365,7 +350,7 @@ fail_irq: | |||
365 | 350 | ||
366 | fail_kthread: | 351 | fail_kthread: |
367 | for (i = irq_base; i < irq_end; i++) | 352 | for (i = irq_base; i < irq_end; i++) |
368 | set_irq_chip_and_handler(i, NULL, NULL); | 353 | irq_set_chip_and_handler(i, NULL, NULL); |
369 | return status; | 354 | return status; |
370 | } | 355 | } |
371 | 356 | ||
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c index f76f6c798046..04914f2836c0 100644 --- a/drivers/mfd/wl1273-core.c +++ b/drivers/mfd/wl1273-core.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #define DRIVER_DESC "WL1273 FM Radio Core" | 26 | #define DRIVER_DESC "WL1273 FM Radio Core" |
27 | 27 | ||
28 | static struct i2c_device_id wl1273_driver_id_table[] = { | 28 | static const struct i2c_device_id wl1273_driver_id_table[] = { |
29 | { WL1273_FM_DRIVER_NAME, 0 }, | 29 | { WL1273_FM_DRIVER_NAME, 0 }, |
30 | { } | 30 | { } |
31 | }; | 31 | }; |
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index a5cd17e18d09..23e66af89dea 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
@@ -553,17 +553,17 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) | |||
553 | for (cur_irq = wm831x->irq_base; | 553 | for (cur_irq = wm831x->irq_base; |
554 | cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base; | 554 | cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base; |
555 | cur_irq++) { | 555 | cur_irq++) { |
556 | set_irq_chip_data(cur_irq, wm831x); | 556 | irq_set_chip_data(cur_irq, wm831x); |
557 | set_irq_chip_and_handler(cur_irq, &wm831x_irq_chip, | 557 | irq_set_chip_and_handler(cur_irq, &wm831x_irq_chip, |
558 | handle_edge_irq); | 558 | handle_edge_irq); |
559 | set_irq_nested_thread(cur_irq, 1); | 559 | irq_set_nested_thread(cur_irq, 1); |
560 | 560 | ||
561 | /* ARM needs us to explicitly flag the IRQ as valid | 561 | /* ARM needs us to explicitly flag the IRQ as valid |
562 | * and will set them noprobe when we do so. */ | 562 | * and will set them noprobe when we do so. */ |
563 | #ifdef CONFIG_ARM | 563 | #ifdef CONFIG_ARM |
564 | set_irq_flags(cur_irq, IRQF_VALID); | 564 | set_irq_flags(cur_irq, IRQF_VALID); |
565 | #else | 565 | #else |
566 | set_irq_noprobe(cur_irq); | 566 | irq_set_noprobe(cur_irq); |
567 | #endif | 567 | #endif |
568 | } | 568 | } |
569 | 569 | ||
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c index 5839966ebd85..ed4b22a167b3 100644 --- a/drivers/mfd/wm8350-irq.c +++ b/drivers/mfd/wm8350-irq.c | |||
@@ -518,17 +518,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq, | |||
518 | for (cur_irq = wm8350->irq_base; | 518 | for (cur_irq = wm8350->irq_base; |
519 | cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base; | 519 | cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base; |
520 | cur_irq++) { | 520 | cur_irq++) { |
521 | set_irq_chip_data(cur_irq, wm8350); | 521 | irq_set_chip_data(cur_irq, wm8350); |
522 | set_irq_chip_and_handler(cur_irq, &wm8350_irq_chip, | 522 | irq_set_chip_and_handler(cur_irq, &wm8350_irq_chip, |
523 | handle_edge_irq); | 523 | handle_edge_irq); |
524 | set_irq_nested_thread(cur_irq, 1); | 524 | irq_set_nested_thread(cur_irq, 1); |
525 | 525 | ||
526 | /* ARM needs us to explicitly flag the IRQ as valid | 526 | /* ARM needs us to explicitly flag the IRQ as valid |
527 | * and will set them noprobe when we do so. */ | 527 | * and will set them noprobe when we do so. */ |
528 | #ifdef CONFIG_ARM | 528 | #ifdef CONFIG_ARM |
529 | set_irq_flags(cur_irq, IRQF_VALID); | 529 | set_irq_flags(cur_irq, IRQF_VALID); |
530 | #else | 530 | #else |
531 | set_irq_noprobe(cur_irq); | 531 | irq_set_noprobe(cur_irq); |
532 | #endif | 532 | #endif |
533 | } | 533 | } |
534 | 534 | ||
diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c index 1e3bf4a2ff8e..71c6e8f9aedb 100644 --- a/drivers/mfd/wm8994-irq.c +++ b/drivers/mfd/wm8994-irq.c | |||
@@ -278,17 +278,17 @@ int wm8994_irq_init(struct wm8994 *wm8994) | |||
278 | for (cur_irq = wm8994->irq_base; | 278 | for (cur_irq = wm8994->irq_base; |
279 | cur_irq < ARRAY_SIZE(wm8994_irqs) + wm8994->irq_base; | 279 | cur_irq < ARRAY_SIZE(wm8994_irqs) + wm8994->irq_base; |
280 | cur_irq++) { | 280 | cur_irq++) { |
281 | set_irq_chip_data(cur_irq, wm8994); | 281 | irq_set_chip_data(cur_irq, wm8994); |
282 | set_irq_chip_and_handler(cur_irq, &wm8994_irq_chip, | 282 | irq_set_chip_and_handler(cur_irq, &wm8994_irq_chip, |
283 | handle_edge_irq); | 283 | handle_edge_irq); |
284 | set_irq_nested_thread(cur_irq, 1); | 284 | irq_set_nested_thread(cur_irq, 1); |
285 | 285 | ||
286 | /* ARM needs us to explicitly flag the IRQ as valid | 286 | /* ARM needs us to explicitly flag the IRQ as valid |
287 | * and will set them noprobe when we do so. */ | 287 | * and will set them noprobe when we do so. */ |
288 | #ifdef CONFIG_ARM | 288 | #ifdef CONFIG_ARM |
289 | set_irq_flags(cur_irq, IRQF_VALID); | 289 | set_irq_flags(cur_irq, IRQF_VALID); |
290 | #else | 290 | #else |
291 | set_irq_noprobe(cur_irq); | 291 | irq_set_noprobe(cur_irq); |
292 | #endif | 292 | #endif |
293 | } | 293 | } |
294 | 294 | ||
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index 1408bf8eed5f..ad1b19aa6508 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h | |||
@@ -63,6 +63,24 @@ extern int mfd_cell_enable(struct platform_device *pdev); | |||
63 | extern int mfd_cell_disable(struct platform_device *pdev); | 63 | extern int mfd_cell_disable(struct platform_device *pdev); |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * "Clone" multiple platform devices for a single cell. This is to be used | ||
67 | * for devices that have multiple users of a cell. For example, if an mfd | ||
68 | * driver wants the cell "foo" to be used by a GPIO driver, an MTD driver, | ||
69 | * and a platform driver, the following bit of code would be use after first | ||
70 | * calling mfd_add_devices(): | ||
71 | * | ||
72 | * const char *fclones[] = { "foo-gpio", "foo-mtd" }; | ||
73 | * err = mfd_clone_cells("foo", fclones, ARRAY_SIZE(fclones)); | ||
74 | * | ||
75 | * Each driver (MTD, GPIO, and platform driver) would then register | ||
76 | * platform_drivers for "foo-mtd", "foo-gpio", and "foo", respectively. | ||
77 | * The cell's .enable/.disable hooks should be used to deal with hardware | ||
78 | * resource contention. | ||
79 | */ | ||
80 | extern int mfd_clone_cell(const char *cell, const char **clones, | ||
81 | size_t n_clones); | ||
82 | |||
83 | /* | ||
66 | * Given a platform device that's been created by mfd_add_devices(), fetch | 84 | * Given a platform device that's been created by mfd_add_devices(), fetch |
67 | * the mfd_cell that created it. | 85 | * the mfd_cell that created it. |
68 | */ | 86 | */ |
@@ -87,13 +105,4 @@ extern int mfd_add_devices(struct device *parent, int id, | |||
87 | 105 | ||
88 | extern void mfd_remove_devices(struct device *parent); | 106 | extern void mfd_remove_devices(struct device *parent); |
89 | 107 | ||
90 | /* | ||
91 | * For MFD drivers with clients sharing access to resources, these create | ||
92 | * multiple platform devices per cell. Contention handling must still be | ||
93 | * handled via drivers (ie, with enable/disable hooks). | ||
94 | */ | ||
95 | extern int mfd_shared_platform_driver_register(struct platform_driver *drv, | ||
96 | const char *cellname); | ||
97 | extern void mfd_shared_platform_driver_unregister(struct platform_driver *drv); | ||
98 | |||
99 | #endif | 108 | #endif |
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index 93a9477e075f..69d1010e2e51 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h | |||
@@ -24,6 +24,8 @@ | |||
24 | 24 | ||
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | 26 | ||
27 | #define MAX8997_REG_INVALID (0xff) | ||
28 | |||
27 | enum max8997_pmic_reg { | 29 | enum max8997_pmic_reg { |
28 | MAX8997_REG_PMIC_ID0 = 0x00, | 30 | MAX8997_REG_PMIC_ID0 = 0x00, |
29 | MAX8997_REG_PMIC_ID1 = 0x01, | 31 | MAX8997_REG_PMIC_ID1 = 0x01, |
@@ -313,6 +315,7 @@ enum max8997_irq { | |||
313 | #define MAX8997_REG_BUCK2DVS(x) (MAX8997_REG_BUCK2DVS1 + (x) - 1) | 315 | #define MAX8997_REG_BUCK2DVS(x) (MAX8997_REG_BUCK2DVS1 + (x) - 1) |
314 | #define MAX8997_REG_BUCK5DVS(x) (MAX8997_REG_BUCK5DVS1 + (x) - 1) | 316 | #define MAX8997_REG_BUCK5DVS(x) (MAX8997_REG_BUCK5DVS1 + (x) - 1) |
315 | 317 | ||
318 | #define MAX8997_NUM_GPIO 12 | ||
316 | struct max8997_dev { | 319 | struct max8997_dev { |
317 | struct device *dev; | 320 | struct device *dev; |
318 | struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */ | 321 | struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */ |
@@ -324,11 +327,19 @@ struct max8997_dev { | |||
324 | int type; | 327 | int type; |
325 | struct platform_device *battery; /* battery control (not fuel gauge) */ | 328 | struct platform_device *battery; /* battery control (not fuel gauge) */ |
326 | 329 | ||
330 | int irq; | ||
331 | int ono; | ||
332 | int irq_base; | ||
327 | bool wakeup; | 333 | bool wakeup; |
334 | struct mutex irqlock; | ||
335 | int irq_masks_cur[MAX8997_IRQ_GROUP_NR]; | ||
336 | int irq_masks_cache[MAX8997_IRQ_GROUP_NR]; | ||
328 | 337 | ||
329 | /* For hibernation */ | 338 | /* For hibernation */ |
330 | u8 reg_dump[MAX8997_REG_PMIC_END + MAX8997_MUIC_REG_END + | 339 | u8 reg_dump[MAX8997_REG_PMIC_END + MAX8997_MUIC_REG_END + |
331 | MAX8997_HAPTIC_REG_END]; | 340 | MAX8997_HAPTIC_REG_END]; |
341 | |||
342 | bool gpio_status[MAX8997_NUM_GPIO]; | ||
332 | }; | 343 | }; |
333 | 344 | ||
334 | enum max8997_types { | 345 | enum max8997_types { |
@@ -336,6 +347,10 @@ enum max8997_types { | |||
336 | TYPE_MAX8966, | 347 | TYPE_MAX8966, |
337 | }; | 348 | }; |
338 | 349 | ||
350 | extern int max8997_irq_init(struct max8997_dev *max8997); | ||
351 | extern void max8997_irq_exit(struct max8997_dev *max8997); | ||
352 | extern int max8997_irq_resume(struct max8997_dev *max8997); | ||
353 | |||
339 | extern int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); | 354 | extern int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); |
340 | extern int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count, | 355 | extern int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count, |
341 | u8 *buf); | 356 | u8 *buf); |
@@ -344,4 +359,10 @@ extern int max8997_bulk_write(struct i2c_client *i2c, u8 reg, int count, | |||
344 | u8 *buf); | 359 | u8 *buf); |
345 | extern int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask); | 360 | extern int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask); |
346 | 361 | ||
362 | #define MAX8997_GPIO_INT_BOTH (0x3 << 4) | ||
363 | #define MAX8997_GPIO_INT_RISE (0x2 << 4) | ||
364 | #define MAX8997_GPIO_INT_FALL (0x1 << 4) | ||
365 | |||
366 | #define MAX8997_GPIO_INT_MASK (0x3 << 4) | ||
367 | #define MAX8997_GPIO_DATA_MASK (0x1 << 2) | ||
347 | #endif /* __LINUX_MFD_MAX8997_PRIV_H */ | 368 | #endif /* __LINUX_MFD_MAX8997_PRIV_H */ |
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index cb671b3451bf..60931d089422 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h | |||
@@ -78,8 +78,11 @@ struct max8997_regulator_data { | |||
78 | }; | 78 | }; |
79 | 79 | ||
80 | struct max8997_platform_data { | 80 | struct max8997_platform_data { |
81 | bool wakeup; | 81 | /* IRQ */ |
82 | /* IRQ: Not implemented */ | 82 | int irq_base; |
83 | int ono; | ||
84 | int wakeup; | ||
85 | |||
83 | /* ---- PMIC ---- */ | 86 | /* ---- PMIC ---- */ |
84 | struct max8997_regulator_data *regulators; | 87 | struct max8997_regulator_data *regulators; |
85 | int num_regulators; | 88 | int num_regulators; |