Commit 551b0bda46d4caf74755a018e2cdb1d093e000c9
Exists in
master
and in
4 other branches
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: mfd: Clean up max8997 IRQ namespace mfd: Fold irq_set_chip/irq_set_handler mfd: Cleanup irq namespace mfd: twl6030: Cleanup interrupt handling mfd: twl4030: Cleanup interrupt handling mfd: mx8925: Remove irq_desc leftovers mfd: htc-i2cpld: Cleanup interrupt handling mfd: htc-egpio: Cleanup interrupt handling mfd: ezx-pcap: Remvove open coded irq handling mfd: 88pm860x: Remove unused irq_desc leftovers mfd: asic3: Cleanup irq handling mfd: Select MFD_CORE if TPS6105X driver is configured mfd: Add MODULE_DEVICE_TABLE to rdc321x-southbridge mfd: Add MAX8997/8966 IRQ control mfd: Constify i2c_device_id tables mfd: OLPC: Clean up names to match what OLPC actually uses mfd: Add mfd_clone_cell(), convert cs5535-mfd/olpc-xo1 to it
Showing 33 changed files Side-by-side Diff
- arch/x86/platform/olpc/olpc-xo1.c
- drivers/mfd/88pm860x-core.c
- drivers/mfd/Kconfig
- drivers/mfd/Makefile
- drivers/mfd/ab3550-core.c
- drivers/mfd/ab8500-core.c
- drivers/mfd/asic3.c
- drivers/mfd/cs5535-mfd.c
- drivers/mfd/ezx-pcap.c
- drivers/mfd/htc-egpio.c
- drivers/mfd/htc-i2cpld.c
- drivers/mfd/jz4740-adc.c
- drivers/mfd/max8925-core.c
- drivers/mfd/max8997-irq.c
- drivers/mfd/max8998-irq.c
- drivers/mfd/max8998.c
- drivers/mfd/mfd-core.c
- drivers/mfd/pcf50633-core.c
- drivers/mfd/rdc321x-southbridge.c
- drivers/mfd/stmpe.c
- drivers/mfd/t7l66xb.c
- drivers/mfd/tc3589x.c
- drivers/mfd/tc6393xb.c
- drivers/mfd/tps6586x.c
- drivers/mfd/twl4030-irq.c
- drivers/mfd/twl6030-irq.c
- drivers/mfd/wl1273-core.c
- drivers/mfd/wm831x-irq.c
- drivers/mfd/wm8350-irq.c
- drivers/mfd/wm8994-irq.c
- include/linux/mfd/core.h
- include/linux/mfd/max8997-private.h
- include/linux/mfd/max8997.h
arch/x86/platform/olpc/olpc-xo1.c
... | ... | @@ -72,9 +72,9 @@ |
72 | 72 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
73 | 73 | return -EIO; |
74 | 74 | } |
75 | - if (strcmp(pdev->name, "olpc-xo1-pms") == 0) | |
75 | + if (strcmp(pdev->name, "cs5535-pms") == 0) | |
76 | 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 | 78 | acpi_base = res->start; |
79 | 79 | |
80 | 80 | /* If we have both addresses, we can override the poweroff hook */ |
81 | 81 | |
... | ... | @@ -90,9 +90,9 @@ |
90 | 90 | { |
91 | 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 | 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 | 96 | acpi_base = 0; |
97 | 97 | |
98 | 98 | pm_power_off = NULL; |
... | ... | @@ -101,7 +101,7 @@ |
101 | 101 | |
102 | 102 | static struct platform_driver cs5535_pms_drv = { |
103 | 103 | .driver = { |
104 | - .name = "olpc-xo1-pms", | |
104 | + .name = "cs5535-pms", | |
105 | 105 | .owner = THIS_MODULE, |
106 | 106 | }, |
107 | 107 | .probe = olpc_xo1_probe, |
... | ... | @@ -110,7 +110,7 @@ |
110 | 110 | |
111 | 111 | static struct platform_driver cs5535_acpi_drv = { |
112 | 112 | .driver = { |
113 | - .name = "olpc-xo1-acpi", | |
113 | + .name = "olpc-xo1-pm-acpi", | |
114 | 114 | .owner = THIS_MODULE, |
115 | 115 | }, |
116 | 116 | .probe = olpc_xo1_probe, |
117 | 117 | |
118 | 118 | |
119 | 119 | |
... | ... | @@ -121,22 +121,21 @@ |
121 | 121 | { |
122 | 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 | 125 | if (r) |
126 | 126 | return r; |
127 | 127 | |
128 | - r = mfd_shared_platform_driver_register(&cs5535_acpi_drv, | |
129 | - "cs5535-acpi"); | |
128 | + r = platform_driver_register(&cs5535_acpi_drv); | |
130 | 129 | if (r) |
131 | - mfd_shared_platform_driver_unregister(&cs5535_pms_drv); | |
130 | + platform_driver_unregister(&cs5535_pms_drv); | |
132 | 131 | |
133 | 132 | return r; |
134 | 133 | } |
135 | 134 | |
136 | 135 | static void __exit olpc_xo1_exit(void) |
137 | 136 | { |
138 | - mfd_shared_platform_driver_unregister(&cs5535_acpi_drv); | |
139 | - mfd_shared_platform_driver_unregister(&cs5535_pms_drv); | |
137 | + platform_driver_unregister(&cs5535_acpi_drv); | |
138 | + platform_driver_unregister(&cs5535_pms_drv); | |
140 | 139 | } |
141 | 140 | |
142 | 141 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); |
drivers/mfd/88pm860x-core.c
... | ... | @@ -416,7 +416,6 @@ |
416 | 416 | : chip->companion; |
417 | 417 | unsigned char status_buf[INT_STATUS_NUM]; |
418 | 418 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; |
419 | - struct irq_desc *desc; | |
420 | 419 | int i, data, mask, ret = -EINVAL; |
421 | 420 | int __irq; |
422 | 421 | |
423 | 422 | |
424 | 423 | |
425 | 424 | |
... | ... | @@ -468,19 +467,17 @@ |
468 | 467 | if (!chip->core_irq) |
469 | 468 | goto out; |
470 | 469 | |
471 | - desc = irq_to_desc(chip->core_irq); | |
472 | - | |
473 | 470 | /* register IRQ by genirq */ |
474 | 471 | for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { |
475 | 472 | __irq = i + chip->irq_base; |
476 | - set_irq_chip_data(__irq, chip); | |
477 | - set_irq_chip_and_handler(__irq, &pm860x_irq_chip, | |
473 | + irq_set_chip_data(__irq, chip); | |
474 | + irq_set_chip_and_handler(__irq, &pm860x_irq_chip, | |
478 | 475 | handle_edge_irq); |
479 | - set_irq_nested_thread(__irq, 1); | |
476 | + irq_set_nested_thread(__irq, 1); | |
480 | 477 | #ifdef CONFIG_ARM |
481 | 478 | set_irq_flags(__irq, IRQF_VALID); |
482 | 479 | #else |
483 | - set_irq_noprobe(__irq); | |
480 | + irq_set_noprobe(__irq); | |
484 | 481 | #endif |
485 | 482 | } |
486 | 483 |
drivers/mfd/Kconfig
drivers/mfd/Makefile
... | ... | @@ -63,7 +63,7 @@ |
63 | 63 | obj-$(CONFIG_PMIC_DA903X) += da903x.o |
64 | 64 | max8925-objs := max8925-core.o max8925-i2c.o |
65 | 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 | 67 | obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o |
68 | 68 | |
69 | 69 | pcf50633-objs := pcf50633-core.o pcf50633-irq.o |
drivers/mfd/ab3550-core.c
... | ... | @@ -668,7 +668,7 @@ |
668 | 668 | struct ab3550_platform_data *plf_data; |
669 | 669 | bool val; |
670 | 670 | |
671 | - ab = get_irq_chip_data(irq); | |
671 | + ab = irq_get_chip_data(irq); | |
672 | 672 | plf_data = ab->i2c_client[0]->dev.platform_data; |
673 | 673 | irq -= plf_data->irq.base; |
674 | 674 | val = ((ab->startup_events[irq / 8] & BIT(irq % 8)) != 0); |
675 | 675 | |
... | ... | @@ -1296,14 +1296,14 @@ |
1296 | 1296 | unsigned int irq; |
1297 | 1297 | |
1298 | 1298 | irq = ab3550_plf_data->irq.base + i; |
1299 | - set_irq_chip_data(irq, ab); | |
1300 | - set_irq_chip_and_handler(irq, &ab3550_irq_chip, | |
1301 | - handle_simple_irq); | |
1302 | - set_irq_nested_thread(irq, 1); | |
1299 | + irq_set_chip_data(irq, ab); | |
1300 | + irq_set_chip_and_handler(irq, &ab3550_irq_chip, | |
1301 | + handle_simple_irq); | |
1302 | + irq_set_nested_thread(irq, 1); | |
1303 | 1303 | #ifdef CONFIG_ARM |
1304 | 1304 | set_irq_flags(irq, IRQF_VALID); |
1305 | 1305 | #else |
1306 | - set_irq_noprobe(irq); | |
1306 | + irq_set_noprobe(irq); | |
1307 | 1307 | #endif |
1308 | 1308 | } |
1309 | 1309 |
drivers/mfd/ab8500-core.c
... | ... | @@ -334,14 +334,14 @@ |
334 | 334 | int irq; |
335 | 335 | |
336 | 336 | for (irq = base; irq < base + AB8500_NR_IRQS; irq++) { |
337 | - set_irq_chip_data(irq, ab8500); | |
338 | - set_irq_chip_and_handler(irq, &ab8500_irq_chip, | |
337 | + irq_set_chip_data(irq, ab8500); | |
338 | + irq_set_chip_and_handler(irq, &ab8500_irq_chip, | |
339 | 339 | handle_simple_irq); |
340 | - set_irq_nested_thread(irq, 1); | |
340 | + irq_set_nested_thread(irq, 1); | |
341 | 341 | #ifdef CONFIG_ARM |
342 | 342 | set_irq_flags(irq, IRQF_VALID); |
343 | 343 | #else |
344 | - set_irq_noprobe(irq); | |
344 | + irq_set_noprobe(irq); | |
345 | 345 | #endif |
346 | 346 | } |
347 | 347 | |
... | ... | @@ -357,8 +357,8 @@ |
357 | 357 | #ifdef CONFIG_ARM |
358 | 358 | set_irq_flags(irq, 0); |
359 | 359 | #endif |
360 | - set_irq_chip_and_handler(irq, NULL, NULL); | |
361 | - set_irq_chip_data(irq, NULL); | |
360 | + irq_set_chip_and_handler(irq, NULL, NULL); | |
361 | + irq_set_chip_data(irq, NULL); | |
362 | 362 | } |
363 | 363 | } |
364 | 364 |
drivers/mfd/asic3.c
... | ... | @@ -139,14 +139,13 @@ |
139 | 139 | |
140 | 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 | 144 | int iter, i; |
143 | 145 | unsigned long flags; |
144 | - struct asic3 *asic; | |
145 | 146 | |
146 | - desc->irq_data.chip->irq_ack(&desc->irq_data); | |
147 | + data->chip->irq_ack(irq_data); | |
147 | 148 | |
148 | - asic = get_irq_data(irq); | |
149 | - | |
150 | 149 | for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) { |
151 | 150 | u32 status; |
152 | 151 | int bank; |
... | ... | @@ -188,8 +187,7 @@ |
188 | 187 | irqnr = asic->irq_base + |
189 | 188 | (ASIC3_GPIOS_PER_BANK * bank) |
190 | 189 | + i; |
191 | - desc = irq_to_desc(irqnr); | |
192 | - desc->handle_irq(irqnr, desc); | |
190 | + generic_handle_irq(irqnr); | |
193 | 191 | if (asic->irq_bothedge[bank] & bit) |
194 | 192 | asic3_irq_flip_edge(asic, base, |
195 | 193 | bit); |
... | ... | @@ -200,11 +198,8 @@ |
200 | 198 | /* Handle remaining IRQs in the status register */ |
201 | 199 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { |
202 | 200 | /* They start at bit 4 and go up */ |
203 | - if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { | |
204 | - desc = irq_to_desc(asic->irq_base + i); | |
205 | - desc->handle_irq(asic->irq_base + i, | |
206 | - desc); | |
207 | - } | |
201 | + if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) | |
202 | + generic_handle_irq(asic->irq_base + i); | |
208 | 203 | } |
209 | 204 | } |
210 | 205 | |
211 | 206 | |
212 | 207 | |
213 | 208 | |
... | ... | @@ -393,21 +388,21 @@ |
393 | 388 | |
394 | 389 | for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { |
395 | 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 | 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); | |
401 | - set_irq_handler(irq, handle_level_irq); | |
395 | + irq_set_chip_data(irq, asic); | |
396 | + irq_set_handler(irq, handle_level_irq); | |
402 | 397 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
403 | 398 | } |
404 | 399 | |
405 | 400 | asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK), |
406 | 401 | ASIC3_INTMASK_GINTMASK); |
407 | 402 | |
408 | - set_irq_chained_handler(asic->irq_nr, asic3_irq_demux); | |
409 | - set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); | |
410 | - set_irq_data(asic->irq_nr, asic); | |
403 | + irq_set_chained_handler(asic->irq_nr, asic3_irq_demux); | |
404 | + irq_set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); | |
405 | + irq_set_handler_data(asic->irq_nr, asic); | |
411 | 406 | |
412 | 407 | return 0; |
413 | 408 | } |
414 | 409 | |
... | ... | @@ -421,11 +416,10 @@ |
421 | 416 | |
422 | 417 | for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) { |
423 | 418 | set_irq_flags(irq, 0); |
424 | - set_irq_handler(irq, NULL); | |
425 | - set_irq_chip(irq, NULL); | |
426 | - set_irq_chip_data(irq, NULL); | |
419 | + irq_set_chip_and_handler(irq, NULL, NULL); | |
420 | + irq_set_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 | 425 | /* GPIOs */ |
drivers/mfd/cs5535-mfd.c
... | ... | @@ -27,6 +27,7 @@ |
27 | 27 | #include <linux/mfd/core.h> |
28 | 28 | #include <linux/module.h> |
29 | 29 | #include <linux/pci.h> |
30 | +#include <asm/olpc.h> | |
30 | 31 | |
31 | 32 | #define DRV_NAME "cs5535-mfd" |
32 | 33 | |
... | ... | @@ -111,6 +112,20 @@ |
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 | 129 | static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, |
115 | 130 | const struct pci_device_id *id) |
116 | 131 | { |
... | ... | @@ -139,6 +154,7 @@ |
139 | 154 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); |
140 | 155 | goto err_disable; |
141 | 156 | } |
157 | + cs5535_clone_olpc_cells(); | |
142 | 158 | |
143 | 159 | dev_info(&pdev->dev, "%zu devices registered.\n", |
144 | 160 | ARRAY_SIZE(cs5535_mfd_cells)); |
drivers/mfd/ezx-pcap.c
... | ... | @@ -162,6 +162,7 @@ |
162 | 162 | |
163 | 163 | static struct irq_chip pcap_irq_chip = { |
164 | 164 | .name = "pcap", |
165 | + .irq_disable = pcap_mask_irq, | |
165 | 166 | .irq_mask = pcap_mask_irq, |
166 | 167 | .irq_unmask = pcap_unmask_irq, |
167 | 168 | }; |
... | ... | @@ -196,17 +197,8 @@ |
196 | 197 | local_irq_disable(); |
197 | 198 | service = isr & ~msr; |
198 | 199 | for (irq = pcap->irq_base; service; service >>= 1, irq++) { |
199 | - if (service & 1) { | |
200 | - struct irq_desc *desc = irq_to_desc(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 | - } | |
200 | + if (service & 1) | |
201 | + generic_handle_irq(irq); | |
210 | 202 | } |
211 | 203 | local_irq_enable(); |
212 | 204 | ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); |
... | ... | @@ -215,7 +207,7 @@ |
215 | 207 | |
216 | 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 | 212 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
221 | 213 | queue_work(pcap->workqueue, &pcap->isr_work); |
... | ... | @@ -419,7 +411,7 @@ |
419 | 411 | |
420 | 412 | /* cleanup irqchip */ |
421 | 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 | 416 | destroy_workqueue(pcap->workqueue); |
425 | 417 | |
426 | 418 | |
... | ... | @@ -476,12 +468,12 @@ |
476 | 468 | |
477 | 469 | /* setup irq chip */ |
478 | 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); | |
480 | - set_irq_chip_data(i, pcap); | |
471 | + irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq); | |
472 | + irq_set_chip_data(i, pcap); | |
481 | 473 | #ifdef CONFIG_ARM |
482 | 474 | set_irq_flags(i, IRQF_VALID); |
483 | 475 | #else |
484 | - set_irq_noprobe(i); | |
476 | + irq_set_noprobe(i); | |
485 | 477 | #endif |
486 | 478 | } |
487 | 479 | |
... | ... | @@ -490,10 +482,10 @@ |
490 | 482 | ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER); |
491 | 483 | pcap->msr = PCAP_MASK_ALL_INTERRUPT; |
492 | 484 | |
493 | - set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); | |
494 | - set_irq_data(spi->irq, pcap); | |
495 | - set_irq_chained_handler(spi->irq, pcap_irq_handler); | |
496 | - set_irq_wake(spi->irq, 1); | |
485 | + irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); | |
486 | + irq_set_handler_data(spi->irq, pcap); | |
487 | + irq_set_chained_handler(spi->irq, pcap_irq_handler); | |
488 | + irq_set_irq_wake(spi->irq, 1); | |
497 | 489 | |
498 | 490 | /* ADC */ |
499 | 491 | adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ? |
... | ... | @@ -522,7 +514,7 @@ |
522 | 514 | free_irq(adc_irq, pcap); |
523 | 515 | free_irqchip: |
524 | 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 | 518 | /* destroy_workqueue: */ |
527 | 519 | destroy_workqueue(pcap->workqueue); |
528 | 520 | free_pcap: |
drivers/mfd/htc-egpio.c
... | ... | @@ -100,7 +100,7 @@ |
100 | 100 | |
101 | 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 | 104 | int irqpin; |
105 | 105 | |
106 | 106 | /* Read current pins. */ |
... | ... | @@ -113,9 +113,7 @@ |
113 | 113 | for_each_set_bit(irqpin, &readval, ei->nirqs) { |
114 | 114 | /* Run irq handler */ |
115 | 115 | pr_debug("got IRQ %d\n", irqpin); |
116 | - irq = ei->irq_start + irqpin; | |
117 | - desc = irq_to_desc(irq); | |
118 | - desc->handle_irq(irq, desc); | |
116 | + generic_handle_irq(ei->irq_start + irqpin); | |
119 | 117 | } |
120 | 118 | } |
121 | 119 | |
122 | 120 | |
... | ... | @@ -346,14 +344,14 @@ |
346 | 344 | ei->ack_write = 0; |
347 | 345 | irq_end = ei->irq_start + ei->nirqs; |
348 | 346 | for (irq = ei->irq_start; irq < irq_end; irq++) { |
349 | - set_irq_chip(irq, &egpio_muxed_chip); | |
350 | - set_irq_chip_data(irq, ei); | |
351 | - set_irq_handler(irq, handle_simple_irq); | |
347 | + irq_set_chip_and_handler(irq, &egpio_muxed_chip, | |
348 | + handle_simple_irq); | |
349 | + irq_set_chip_data(irq, ei); | |
352 | 350 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
353 | 351 | } |
354 | - set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING); | |
355 | - set_irq_data(ei->chained_irq, ei); | |
356 | - set_irq_chained_handler(ei->chained_irq, egpio_handler); | |
352 | + irq_set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING); | |
353 | + irq_set_handler_data(ei->chained_irq, ei); | |
354 | + irq_set_chained_handler(ei->chained_irq, egpio_handler); | |
357 | 355 | ack_irqs(ei); |
358 | 356 | |
359 | 357 | device_init_wakeup(&pdev->dev, 1); |
360 | 358 | |
... | ... | @@ -375,11 +373,10 @@ |
375 | 373 | if (ei->chained_irq) { |
376 | 374 | irq_end = ei->irq_start + ei->nirqs; |
377 | 375 | for (irq = ei->irq_start; irq < irq_end; irq++) { |
378 | - set_irq_chip(irq, NULL); | |
379 | - set_irq_handler(irq, NULL); | |
376 | + irq_set_chip_and_handler(irq, NULL, NULL); | |
380 | 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 | 380 | device_init_wakeup(&pdev->dev, 0); |
384 | 381 | } |
385 | 382 | iounmap(ei->base_addr); |
drivers/mfd/htc-i2cpld.c
... | ... | @@ -58,6 +58,7 @@ |
58 | 58 | uint irq_start; |
59 | 59 | int nirqs; |
60 | 60 | |
61 | + unsigned int flow_type; | |
61 | 62 | /* |
62 | 63 | * Work structure to allow for setting values outside of any |
63 | 64 | * possible interrupt context |
64 | 65 | |
... | ... | @@ -97,13 +98,8 @@ |
97 | 98 | |
98 | 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 | |
102 | - if (!d) { | |
103 | - pr_err("HTCPLD invalid IRQ: %d\n", data->irq); | |
104 | - return -EINVAL; | |
105 | - } | |
106 | - | |
107 | 103 | if (flags & ~IRQ_TYPE_SENSE_MASK) |
108 | 104 | return -EINVAL; |
109 | 105 | |
... | ... | @@ -111,9 +107,7 @@ |
111 | 107 | if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)) |
112 | 108 | return -EINVAL; |
113 | 109 | |
114 | - d->status &= ~IRQ_TYPE_SENSE_MASK; | |
115 | - d->status |= flags; | |
116 | - | |
110 | + chip->flow_type = flags; | |
117 | 111 | return 0; |
118 | 112 | } |
119 | 113 | |
... | ... | @@ -135,7 +129,6 @@ |
135 | 129 | unsigned int i; |
136 | 130 | unsigned long flags; |
137 | 131 | int irqpin; |
138 | - struct irq_desc *desc; | |
139 | 132 | |
140 | 133 | if (!htcpld) { |
141 | 134 | pr_debug("htcpld is null in ISR\n"); |
142 | 135 | |
143 | 136 | |
144 | 137 | |
... | ... | @@ -195,23 +188,19 @@ |
195 | 188 | * associated interrupts. |
196 | 189 | */ |
197 | 190 | for (irqpin = 0; irqpin < chip->nirqs; irqpin++) { |
198 | - unsigned oldb, newb; | |
199 | - int flags; | |
191 | + unsigned oldb, newb, type = chip->flow_type; | |
200 | 192 | |
201 | 193 | irq = chip->irq_start + irqpin; |
202 | - desc = irq_to_desc(irq); | |
203 | - flags = desc->status; | |
204 | 194 | |
205 | 195 | /* Run the IRQ handler, but only if the bit value |
206 | 196 | * changed, and the proper flags are set */ |
207 | 197 | oldb = (old_val >> irqpin) & 1; |
208 | 198 | newb = (uval >> irqpin) & 1; |
209 | 199 | |
210 | - if ((!oldb && newb && (flags & IRQ_TYPE_EDGE_RISING)) || | |
211 | - (oldb && !newb && | |
212 | - (flags & IRQ_TYPE_EDGE_FALLING))) { | |
200 | + if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) || | |
201 | + (oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) { | |
213 | 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 | } |
218 | 207 | |
... | ... | @@ -359,13 +348,13 @@ |
359 | 348 | /* Setup irq handlers */ |
360 | 349 | irq_end = chip->irq_start + chip->nirqs; |
361 | 350 | for (irq = chip->irq_start; irq < irq_end; irq++) { |
362 | - set_irq_chip(irq, &htcpld_muxed_chip); | |
363 | - set_irq_chip_data(irq, chip); | |
364 | - set_irq_handler(irq, handle_simple_irq); | |
351 | + irq_set_chip_and_handler(irq, &htcpld_muxed_chip, | |
352 | + handle_simple_irq); | |
353 | + irq_set_chip_data(irq, chip); | |
365 | 354 | #ifdef CONFIG_ARM |
366 | 355 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
367 | 356 | #else |
368 | - set_irq_probe(irq); | |
357 | + irq_set_probe(irq); | |
369 | 358 | #endif |
370 | 359 | } |
371 | 360 |
drivers/mfd/jz4740-adc.c
... | ... | @@ -112,7 +112,7 @@ |
112 | 112 | |
113 | 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 | 116 | uint8_t status; |
117 | 117 | unsigned int i; |
118 | 118 | |
119 | 119 | |
... | ... | @@ -310,13 +310,13 @@ |
310 | 310 | platform_set_drvdata(pdev, adc); |
311 | 311 | |
312 | 312 | for (irq = adc->irq_base; irq < adc->irq_base + 5; ++irq) { |
313 | - set_irq_chip_data(irq, adc); | |
314 | - set_irq_chip_and_handler(irq, &jz4740_adc_irq_chip, | |
315 | - handle_level_irq); | |
313 | + irq_set_chip_data(irq, adc); | |
314 | + irq_set_chip_and_handler(irq, &jz4740_adc_irq_chip, | |
315 | + handle_level_irq); | |
316 | 316 | } |
317 | 317 | |
318 | - set_irq_data(adc->irq, adc); | |
319 | - set_irq_chained_handler(adc->irq, jz4740_adc_irq_demux); | |
318 | + irq_set_handler_data(adc->irq, adc); | |
319 | + irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux); | |
320 | 320 | |
321 | 321 | writeb(0x00, adc->base + JZ_REG_ADC_ENABLE); |
322 | 322 | writeb(0xff, adc->base + JZ_REG_ADC_CTRL); |
... | ... | @@ -347,8 +347,8 @@ |
347 | 347 | |
348 | 348 | mfd_remove_devices(&pdev->dev); |
349 | 349 | |
350 | - set_irq_data(adc->irq, NULL); | |
351 | - set_irq_chained_handler(adc->irq, NULL); | |
350 | + irq_set_handler_data(adc->irq, NULL); | |
351 | + irq_set_chained_handler(adc->irq, NULL); | |
352 | 352 | |
353 | 353 | iounmap(adc->base); |
354 | 354 | release_mem_region(adc->mem->start, resource_size(adc->mem)); |
drivers/mfd/max8925-core.c
... | ... | @@ -517,7 +517,6 @@ |
517 | 517 | struct max8925_platform_data *pdata) |
518 | 518 | { |
519 | 519 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; |
520 | - struct irq_desc *desc; | |
521 | 520 | int i, ret; |
522 | 521 | int __irq; |
523 | 522 | |
524 | 523 | |
525 | 524 | |
526 | 525 | |
... | ... | @@ -544,19 +543,18 @@ |
544 | 543 | mutex_init(&chip->irq_lock); |
545 | 544 | chip->core_irq = irq; |
546 | 545 | chip->irq_base = pdata->irq_base; |
547 | - desc = irq_to_desc(chip->core_irq); | |
548 | 546 | |
549 | 547 | /* register with genirq */ |
550 | 548 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { |
551 | 549 | __irq = i + chip->irq_base; |
552 | - set_irq_chip_data(__irq, chip); | |
553 | - set_irq_chip_and_handler(__irq, &max8925_irq_chip, | |
550 | + irq_set_chip_data(__irq, chip); | |
551 | + irq_set_chip_and_handler(__irq, &max8925_irq_chip, | |
554 | 552 | handle_edge_irq); |
555 | - set_irq_nested_thread(__irq, 1); | |
553 | + irq_set_nested_thread(__irq, 1); | |
556 | 554 | #ifdef CONFIG_ARM |
557 | 555 | set_irq_flags(__irq, IRQF_VALID); |
558 | 556 | #else |
559 | - set_irq_noprobe(__irq); | |
557 | + irq_set_noprobe(__irq); | |
560 | 558 | #endif |
561 | 559 | } |
562 | 560 | if (!irq) { |
drivers/mfd/max8997-irq.c
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 | +} |
drivers/mfd/max8998-irq.c
... | ... | @@ -224,14 +224,14 @@ |
224 | 224 | /* register with genirq */ |
225 | 225 | for (i = 0; i < MAX8998_IRQ_NR; i++) { |
226 | 226 | cur_irq = i + max8998->irq_base; |
227 | - set_irq_chip_data(cur_irq, max8998); | |
228 | - set_irq_chip_and_handler(cur_irq, &max8998_irq_chip, | |
227 | + irq_set_chip_data(cur_irq, max8998); | |
228 | + irq_set_chip_and_handler(cur_irq, &max8998_irq_chip, | |
229 | 229 | handle_edge_irq); |
230 | - set_irq_nested_thread(cur_irq, 1); | |
230 | + irq_set_nested_thread(cur_irq, 1); | |
231 | 231 | #ifdef CONFIG_ARM |
232 | 232 | set_irq_flags(cur_irq, IRQF_VALID); |
233 | 233 | #else |
234 | - set_irq_noprobe(cur_irq); | |
234 | + irq_set_noprobe(cur_irq); | |
235 | 235 | #endif |
236 | 236 | } |
237 | 237 |
drivers/mfd/max8998.c
... | ... | @@ -209,7 +209,7 @@ |
209 | 209 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); |
210 | 210 | |
211 | 211 | if (max8998->wakeup) |
212 | - set_irq_wake(max8998->irq, 1); | |
212 | + irq_set_irq_wake(max8998->irq, 1); | |
213 | 213 | return 0; |
214 | 214 | } |
215 | 215 | |
... | ... | @@ -219,7 +219,7 @@ |
219 | 219 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); |
220 | 220 | |
221 | 221 | if (max8998->wakeup) |
222 | - set_irq_wake(max8998->irq, 0); | |
222 | + irq_set_irq_wake(max8998->irq, 0); | |
223 | 223 | /* |
224 | 224 | * In LP3974, if IRQ registers are not "read & clear" |
225 | 225 | * when it's set during sleep, the interrupt becomes |
drivers/mfd/mfd-core.c
... | ... | @@ -184,17 +184,13 @@ |
184 | 184 | } |
185 | 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 | 189 | struct mfd_cell cell_entry; |
190 | 190 | struct device *dev; |
191 | 191 | struct platform_device *pdev; |
192 | - int err; | |
192 | + int i; | |
193 | 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 | - | |
198 | 194 | /* fetch the parent cell's device (should already be registered!) */ |
199 | 195 | dev = bus_find_device_by_name(&platform_bus_type, NULL, cell); |
200 | 196 | if (!dev) { |
201 | 197 | |
202 | 198 | |
... | ... | @@ -206,44 +202,17 @@ |
206 | 202 | |
207 | 203 | WARN_ON(!cell_entry.enable); |
208 | 204 | |
209 | - cell_entry.name = name; | |
210 | - err = mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0); | |
211 | - if (err) | |
212 | - dev_err(dev, "MFD add devices failed: %d\n", err); | |
213 | - return err; | |
214 | -} | |
205 | + for (i = 0; i < n_clones; i++) { | |
206 | + cell_entry.name = clones[i]; | |
207 | + /* don't give up if a single call fails; just report error */ | |
208 | + if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) | |
209 | + dev_err(dev, "failed to create platform device '%s'\n", | |
210 | + clones[i]); | |
211 | + } | |
215 | 212 | |
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; | |
213 | + return 0; | |
232 | 214 | } |
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 | - | |
244 | - platform_driver_unregister(drv); | |
245 | -} | |
246 | -EXPORT_SYMBOL(mfd_shared_platform_driver_unregister); | |
215 | +EXPORT_SYMBOL(mfd_clone_cell); | |
247 | 216 | |
248 | 217 | MODULE_LICENSE("GPL"); |
249 | 218 | MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); |
drivers/mfd/pcf50633-core.c
drivers/mfd/rdc321x-southbridge.c
drivers/mfd/stmpe.c
... | ... | @@ -762,14 +762,14 @@ |
762 | 762 | int irq; |
763 | 763 | |
764 | 764 | for (irq = base; irq < base + num_irqs; irq++) { |
765 | - set_irq_chip_data(irq, stmpe); | |
766 | - set_irq_chip_and_handler(irq, &stmpe_irq_chip, | |
765 | + irq_set_chip_data(irq, stmpe); | |
766 | + irq_set_chip_and_handler(irq, &stmpe_irq_chip, | |
767 | 767 | handle_edge_irq); |
768 | - set_irq_nested_thread(irq, 1); | |
768 | + irq_set_nested_thread(irq, 1); | |
769 | 769 | #ifdef CONFIG_ARM |
770 | 770 | set_irq_flags(irq, IRQF_VALID); |
771 | 771 | #else |
772 | - set_irq_noprobe(irq); | |
772 | + irq_set_noprobe(irq); | |
773 | 773 | #endif |
774 | 774 | } |
775 | 775 | |
... | ... | @@ -786,8 +786,8 @@ |
786 | 786 | #ifdef CONFIG_ARM |
787 | 787 | set_irq_flags(irq, 0); |
788 | 788 | #endif |
789 | - set_irq_chip_and_handler(irq, NULL, NULL); | |
790 | - set_irq_chip_data(irq, NULL); | |
789 | + irq_set_chip_and_handler(irq, NULL, NULL); | |
790 | + irq_set_chip_data(irq, NULL); | |
791 | 791 | } |
792 | 792 | } |
793 | 793 |
drivers/mfd/t7l66xb.c
... | ... | @@ -186,7 +186,7 @@ |
186 | 186 | /* Handle the T7L66XB interrupt mux */ |
187 | 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 | 190 | unsigned int isr; |
191 | 191 | unsigned int i, irq_base; |
192 | 192 | |
193 | 193 | |
... | ... | @@ -243,17 +243,16 @@ |
243 | 243 | irq_base = t7l66xb->irq_base; |
244 | 244 | |
245 | 245 | for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { |
246 | - set_irq_chip(irq, &t7l66xb_chip); | |
247 | - set_irq_chip_data(irq, t7l66xb); | |
248 | - set_irq_handler(irq, handle_level_irq); | |
246 | + irq_set_chip_and_handler(irq, &t7l66xb_chip, handle_level_irq); | |
247 | + irq_set_chip_data(irq, t7l66xb); | |
249 | 248 | #ifdef CONFIG_ARM |
250 | 249 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
251 | 250 | #endif |
252 | 251 | } |
253 | 252 | |
254 | - set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING); | |
255 | - set_irq_data(t7l66xb->irq, t7l66xb); | |
256 | - set_irq_chained_handler(t7l66xb->irq, t7l66xb_irq); | |
253 | + irq_set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING); | |
254 | + irq_set_handler_data(t7l66xb->irq, t7l66xb); | |
255 | + irq_set_chained_handler(t7l66xb->irq, t7l66xb_irq); | |
257 | 256 | } |
258 | 257 | |
259 | 258 | static void t7l66xb_detach_irq(struct platform_device *dev) |
260 | 259 | |
... | ... | @@ -263,15 +262,15 @@ |
263 | 262 | |
264 | 263 | irq_base = t7l66xb->irq_base; |
265 | 264 | |
266 | - set_irq_chained_handler(t7l66xb->irq, NULL); | |
267 | - set_irq_data(t7l66xb->irq, NULL); | |
265 | + irq_set_chained_handler(t7l66xb->irq, NULL); | |
266 | + irq_set_handler_data(t7l66xb->irq, NULL); | |
268 | 267 | |
269 | 268 | for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) { |
270 | 269 | #ifdef CONFIG_ARM |
271 | 270 | set_irq_flags(irq, 0); |
272 | 271 | #endif |
273 | - set_irq_chip(irq, NULL); | |
274 | - set_irq_chip_data(irq, NULL); | |
272 | + irq_set_chip(irq, NULL); | |
273 | + irq_set_chip_data(irq, NULL); | |
275 | 274 | } |
276 | 275 | } |
277 | 276 |
drivers/mfd/tc3589x.c
... | ... | @@ -192,14 +192,14 @@ |
192 | 192 | int irq; |
193 | 193 | |
194 | 194 | for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) { |
195 | - set_irq_chip_data(irq, tc3589x); | |
196 | - set_irq_chip_and_handler(irq, &dummy_irq_chip, | |
195 | + irq_set_chip_data(irq, tc3589x); | |
196 | + irq_set_chip_and_handler(irq, &dummy_irq_chip, | |
197 | 197 | handle_edge_irq); |
198 | - set_irq_nested_thread(irq, 1); | |
198 | + irq_set_nested_thread(irq, 1); | |
199 | 199 | #ifdef CONFIG_ARM |
200 | 200 | set_irq_flags(irq, IRQF_VALID); |
201 | 201 | #else |
202 | - set_irq_noprobe(irq); | |
202 | + irq_set_noprobe(irq); | |
203 | 203 | #endif |
204 | 204 | } |
205 | 205 | |
... | ... | @@ -215,8 +215,8 @@ |
215 | 215 | #ifdef CONFIG_ARM |
216 | 216 | set_irq_flags(irq, 0); |
217 | 217 | #endif |
218 | - set_irq_chip_and_handler(irq, NULL, NULL); | |
219 | - set_irq_chip_data(irq, NULL); | |
218 | + irq_set_chip_and_handler(irq, NULL, NULL); | |
219 | + irq_set_chip_data(irq, NULL); | |
220 | 220 | } |
221 | 221 | } |
222 | 222 |
drivers/mfd/tc6393xb.c
... | ... | @@ -513,7 +513,7 @@ |
513 | 513 | static void |
514 | 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 | 517 | unsigned int isr; |
518 | 518 | unsigned int i, irq_base; |
519 | 519 | |
520 | 520 | |
... | ... | @@ -572,15 +572,14 @@ |
572 | 572 | irq_base = tc6393xb->irq_base; |
573 | 573 | |
574 | 574 | for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { |
575 | - set_irq_chip(irq, &tc6393xb_chip); | |
576 | - set_irq_chip_data(irq, tc6393xb); | |
577 | - set_irq_handler(irq, handle_edge_irq); | |
575 | + irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq); | |
576 | + irq_set_chip_data(irq, tc6393xb); | |
578 | 577 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
579 | 578 | } |
580 | 579 | |
581 | - set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); | |
582 | - set_irq_data(tc6393xb->irq, tc6393xb); | |
583 | - set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq); | |
580 | + irq_set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); | |
581 | + irq_set_handler_data(tc6393xb->irq, tc6393xb); | |
582 | + irq_set_chained_handler(tc6393xb->irq, tc6393xb_irq); | |
584 | 583 | } |
585 | 584 | |
586 | 585 | static void tc6393xb_detach_irq(struct platform_device *dev) |
587 | 586 | |
... | ... | @@ -588,15 +587,15 @@ |
588 | 587 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); |
589 | 588 | unsigned int irq, irq_base; |
590 | 589 | |
591 | - set_irq_chained_handler(tc6393xb->irq, NULL); | |
592 | - set_irq_data(tc6393xb->irq, NULL); | |
590 | + irq_set_chained_handler(tc6393xb->irq, NULL); | |
591 | + irq_set_handler_data(tc6393xb->irq, NULL); | |
593 | 592 | |
594 | 593 | irq_base = tc6393xb->irq_base; |
595 | 594 | |
596 | 595 | for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { |
597 | 596 | set_irq_flags(irq, 0); |
598 | - set_irq_chip(irq, NULL); | |
599 | - set_irq_chip_data(irq, NULL); | |
597 | + irq_set_chip(irq, NULL); | |
598 | + irq_set_chip_data(irq, NULL); | |
600 | 599 | } |
601 | 600 | } |
602 | 601 |
drivers/mfd/tps6586x.c
... | ... | @@ -422,10 +422,10 @@ |
422 | 422 | |
423 | 423 | for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { |
424 | 424 | int __irq = i + tps6586x->irq_base; |
425 | - set_irq_chip_data(__irq, tps6586x); | |
426 | - set_irq_chip_and_handler(__irq, &tps6586x->irq_chip, | |
425 | + irq_set_chip_data(__irq, tps6586x); | |
426 | + irq_set_chip_and_handler(__irq, &tps6586x->irq_chip, | |
427 | 427 | handle_simple_irq); |
428 | - set_irq_nested_thread(__irq, 1); | |
428 | + irq_set_nested_thread(__irq, 1); | |
429 | 429 | #ifdef CONFIG_ARM |
430 | 430 | set_irq_flags(__irq, IRQF_VALID); |
431 | 431 | #endif |
drivers/mfd/twl4030-irq.c
... | ... | @@ -320,24 +320,8 @@ |
320 | 320 | for (module_irq = twl4030_irq_base; |
321 | 321 | pih_isr; |
322 | 322 | pih_isr >>= 1, module_irq++) { |
323 | - if (pih_isr & 0x1) { | |
324 | - struct irq_desc *d = irq_to_desc(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 | - } | |
323 | + if (pih_isr & 0x1) | |
324 | + generic_handle_irq(module_irq); | |
341 | 325 | } |
342 | 326 | local_irq_enable(); |
343 | 327 | |
... | ... | @@ -470,7 +454,7 @@ |
470 | 454 | set_irq_flags(irq, IRQF_VALID); |
471 | 455 | #else |
472 | 456 | /* same effect on other architectures */ |
473 | - set_irq_noprobe(irq); | |
457 | + irq_set_noprobe(irq); | |
474 | 458 | #endif |
475 | 459 | } |
476 | 460 | |
477 | 461 | |
478 | 462 | |
479 | 463 | |
480 | 464 | |
481 | 465 | |
... | ... | @@ -560,24 +544,18 @@ |
560 | 544 | /* Modify only the bits we know must change */ |
561 | 545 | while (edge_change) { |
562 | 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 | 548 | int byte = 1 + (i >> 2); |
565 | 549 | int off = (i & 0x3) * 2; |
550 | + unsigned int type; | |
566 | 551 | |
567 | - if (!d) { | |
568 | - pr_err("twl4030: Invalid IRQ: %d\n", | |
569 | - i + agent->irq_base); | |
570 | - return; | |
571 | - } | |
572 | - | |
573 | 552 | bytes[byte] &= ~(0x03 << off); |
574 | 553 | |
575 | - raw_spin_lock_irq(&d->lock); | |
576 | - if (d->status & IRQ_TYPE_EDGE_RISING) | |
554 | + type = irqd_get_trigger_type(idata); | |
555 | + if (type & IRQ_TYPE_EDGE_RISING) | |
577 | 556 | bytes[byte] |= BIT(off + 1); |
578 | - if (d->status & IRQ_TYPE_EDGE_FALLING) | |
557 | + if (type & IRQ_TYPE_EDGE_FALLING) | |
579 | 558 | bytes[byte] |= BIT(off + 0); |
580 | - raw_spin_unlock_irq(&d->lock); | |
581 | 559 | |
582 | 560 | edge_change &= ~BIT(i); |
583 | 561 | } |
584 | 562 | |
585 | 563 | |
... | ... | @@ -626,21 +604,13 @@ |
626 | 604 | static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) |
627 | 605 | { |
628 | 606 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); |
629 | - struct irq_desc *desc = irq_to_desc(data->irq); | |
630 | 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 | 609 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
638 | 610 | return -EINVAL; |
639 | 611 | |
640 | 612 | spin_lock_irqsave(&sih_agent_lock, flags); |
641 | - if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { | |
642 | - desc->status &= ~IRQ_TYPE_SENSE_MASK; | |
643 | - desc->status |= trigger; | |
613 | + if (irqd_get_trigger_type(data) != trigger) { | |
644 | 614 | sih->edge_change |= BIT(data->irq - sih->irq_base); |
645 | 615 | queue_work(wq, &sih->edge_work); |
646 | 616 | } |
... | ... | @@ -680,7 +650,7 @@ |
680 | 650 | */ |
681 | 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 | 654 | const struct sih *sih = agent->sih; |
685 | 655 | int isr; |
686 | 656 | |
... | ... | @@ -754,9 +724,9 @@ |
754 | 724 | for (i = 0; i < sih->bits; i++) { |
755 | 725 | irq = irq_base + i; |
756 | 726 | |
757 | - set_irq_chip_and_handler(irq, &twl4030_sih_irq_chip, | |
758 | - handle_edge_irq); | |
759 | - set_irq_chip_data(irq, agent); | |
727 | + irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip, | |
728 | + handle_edge_irq); | |
729 | + irq_set_chip_data(irq, agent); | |
760 | 730 | activate_irq(irq); |
761 | 731 | } |
762 | 732 | |
... | ... | @@ -765,8 +735,8 @@ |
765 | 735 | |
766 | 736 | /* replace generic PIH handler (handle_simple_irq) */ |
767 | 737 | irq = sih_mod + twl4030_irq_base; |
768 | - set_irq_data(irq, agent); | |
769 | - set_irq_chained_handler(irq, handle_twl4030_sih); | |
738 | + irq_set_handler_data(irq, agent); | |
739 | + irq_set_chained_handler(irq, handle_twl4030_sih); | |
770 | 740 | |
771 | 741 | pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name, |
772 | 742 | irq, irq_base, twl4030_irq_next - 1); |
... | ... | @@ -815,8 +785,8 @@ |
815 | 785 | twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; |
816 | 786 | |
817 | 787 | for (i = irq_base; i < irq_end; i++) { |
818 | - set_irq_chip_and_handler(i, &twl4030_irq_chip, | |
819 | - handle_simple_irq); | |
788 | + irq_set_chip_and_handler(i, &twl4030_irq_chip, | |
789 | + handle_simple_irq); | |
820 | 790 | activate_irq(i); |
821 | 791 | } |
822 | 792 | twl4030_irq_next = i; |
... | ... | @@ -856,7 +826,7 @@ |
856 | 826 | /* clean up twl4030_sih_setup */ |
857 | 827 | fail: |
858 | 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 | 830 | destroy_workqueue(wq); |
861 | 831 | wq = NULL; |
862 | 832 | return status; |
drivers/mfd/twl6030-irq.c
... | ... | @@ -140,23 +140,8 @@ |
140 | 140 | if (sts.int_sts & 0x1) { |
141 | 141 | int module_irq = twl6030_irq_base + |
142 | 142 | twl6030_interrupt_mapping[i]; |
143 | - struct irq_desc *d = irq_to_desc(module_irq); | |
143 | + generic_handle_irq(module_irq); | |
144 | 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 | - | |
160 | 145 | } |
161 | 146 | local_irq_enable(); |
162 | 147 | } |
... | ... | @@ -198,7 +183,7 @@ |
198 | 183 | set_irq_flags(irq, IRQF_VALID); |
199 | 184 | #else |
200 | 185 | /* same effect on other architectures */ |
201 | - set_irq_noprobe(irq); | |
186 | + irq_set_noprobe(irq); | |
202 | 187 | #endif |
203 | 188 | } |
204 | 189 | |
... | ... | @@ -335,8 +320,8 @@ |
335 | 320 | twl6030_irq_chip.irq_set_type = NULL; |
336 | 321 | |
337 | 322 | for (i = irq_base; i < irq_end; i++) { |
338 | - set_irq_chip_and_handler(i, &twl6030_irq_chip, | |
339 | - handle_simple_irq); | |
323 | + irq_set_chip_and_handler(i, &twl6030_irq_chip, | |
324 | + handle_simple_irq); | |
340 | 325 | activate_irq(i); |
341 | 326 | } |
342 | 327 | |
... | ... | @@ -365,7 +350,7 @@ |
365 | 350 | |
366 | 351 | fail_kthread: |
367 | 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 | 354 | return status; |
370 | 355 | } |
371 | 356 |
drivers/mfd/wl1273-core.c
drivers/mfd/wm831x-irq.c
... | ... | @@ -553,17 +553,17 @@ |
553 | 553 | for (cur_irq = wm831x->irq_base; |
554 | 554 | cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base; |
555 | 555 | cur_irq++) { |
556 | - set_irq_chip_data(cur_irq, wm831x); | |
557 | - set_irq_chip_and_handler(cur_irq, &wm831x_irq_chip, | |
556 | + irq_set_chip_data(cur_irq, wm831x); | |
557 | + irq_set_chip_and_handler(cur_irq, &wm831x_irq_chip, | |
558 | 558 | handle_edge_irq); |
559 | - set_irq_nested_thread(cur_irq, 1); | |
559 | + irq_set_nested_thread(cur_irq, 1); | |
560 | 560 | |
561 | 561 | /* ARM needs us to explicitly flag the IRQ as valid |
562 | 562 | * and will set them noprobe when we do so. */ |
563 | 563 | #ifdef CONFIG_ARM |
564 | 564 | set_irq_flags(cur_irq, IRQF_VALID); |
565 | 565 | #else |
566 | - set_irq_noprobe(cur_irq); | |
566 | + irq_set_noprobe(cur_irq); | |
567 | 567 | #endif |
568 | 568 | } |
569 | 569 |
drivers/mfd/wm8350-irq.c
... | ... | @@ -518,17 +518,17 @@ |
518 | 518 | for (cur_irq = wm8350->irq_base; |
519 | 519 | cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base; |
520 | 520 | cur_irq++) { |
521 | - set_irq_chip_data(cur_irq, wm8350); | |
522 | - set_irq_chip_and_handler(cur_irq, &wm8350_irq_chip, | |
521 | + irq_set_chip_data(cur_irq, wm8350); | |
522 | + irq_set_chip_and_handler(cur_irq, &wm8350_irq_chip, | |
523 | 523 | handle_edge_irq); |
524 | - set_irq_nested_thread(cur_irq, 1); | |
524 | + irq_set_nested_thread(cur_irq, 1); | |
525 | 525 | |
526 | 526 | /* ARM needs us to explicitly flag the IRQ as valid |
527 | 527 | * and will set them noprobe when we do so. */ |
528 | 528 | #ifdef CONFIG_ARM |
529 | 529 | set_irq_flags(cur_irq, IRQF_VALID); |
530 | 530 | #else |
531 | - set_irq_noprobe(cur_irq); | |
531 | + irq_set_noprobe(cur_irq); | |
532 | 532 | #endif |
533 | 533 | } |
534 | 534 |
drivers/mfd/wm8994-irq.c
... | ... | @@ -278,17 +278,17 @@ |
278 | 278 | for (cur_irq = wm8994->irq_base; |
279 | 279 | cur_irq < ARRAY_SIZE(wm8994_irqs) + wm8994->irq_base; |
280 | 280 | cur_irq++) { |
281 | - set_irq_chip_data(cur_irq, wm8994); | |
282 | - set_irq_chip_and_handler(cur_irq, &wm8994_irq_chip, | |
281 | + irq_set_chip_data(cur_irq, wm8994); | |
282 | + irq_set_chip_and_handler(cur_irq, &wm8994_irq_chip, | |
283 | 283 | handle_edge_irq); |
284 | - set_irq_nested_thread(cur_irq, 1); | |
284 | + irq_set_nested_thread(cur_irq, 1); | |
285 | 285 | |
286 | 286 | /* ARM needs us to explicitly flag the IRQ as valid |
287 | 287 | * and will set them noprobe when we do so. */ |
288 | 288 | #ifdef CONFIG_ARM |
289 | 289 | set_irq_flags(cur_irq, IRQF_VALID); |
290 | 290 | #else |
291 | - set_irq_noprobe(cur_irq); | |
291 | + irq_set_noprobe(cur_irq); | |
292 | 292 | #endif |
293 | 293 | } |
294 | 294 |
include/linux/mfd/core.h
... | ... | @@ -63,6 +63,24 @@ |
63 | 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 | 84 | * Given a platform device that's been created by mfd_add_devices(), fetch |
67 | 85 | * the mfd_cell that created it. |
68 | 86 | */ |
... | ... | @@ -86,15 +104,6 @@ |
86 | 104 | int irq_base); |
87 | 105 | |
88 | 106 | extern void mfd_remove_devices(struct device *parent); |
89 | - | |
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 | 107 | |
99 | 108 | #endif |
include/linux/mfd/max8997-private.h
... | ... | @@ -24,6 +24,8 @@ |
24 | 24 | |
25 | 25 | #include <linux/i2c.h> |
26 | 26 | |
27 | +#define MAX8997_REG_INVALID (0xff) | |
28 | + | |
27 | 29 | enum max8997_pmic_reg { |
28 | 30 | MAX8997_REG_PMIC_ID0 = 0x00, |
29 | 31 | MAX8997_REG_PMIC_ID1 = 0x01, |
... | ... | @@ -313,6 +315,7 @@ |
313 | 315 | #define MAX8997_REG_BUCK2DVS(x) (MAX8997_REG_BUCK2DVS1 + (x) - 1) |
314 | 316 | #define MAX8997_REG_BUCK5DVS(x) (MAX8997_REG_BUCK5DVS1 + (x) - 1) |
315 | 317 | |
318 | +#define MAX8997_NUM_GPIO 12 | |
316 | 319 | struct max8997_dev { |
317 | 320 | struct device *dev; |
318 | 321 | struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */ |
319 | 322 | |
320 | 323 | |
... | ... | @@ -324,11 +327,19 @@ |
324 | 327 | int type; |
325 | 328 | struct platform_device *battery; /* battery control (not fuel gauge) */ |
326 | 329 | |
330 | + int irq; | |
331 | + int ono; | |
332 | + int irq_base; | |
327 | 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 | 338 | /* For hibernation */ |
330 | 339 | u8 reg_dump[MAX8997_REG_PMIC_END + MAX8997_MUIC_REG_END + |
331 | 340 | MAX8997_HAPTIC_REG_END]; |
341 | + | |
342 | + bool gpio_status[MAX8997_NUM_GPIO]; | |
332 | 343 | }; |
333 | 344 | |
334 | 345 | enum max8997_types { |
... | ... | @@ -336,6 +347,10 @@ |
336 | 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 | 354 | extern int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); |
340 | 355 | extern int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count, |
341 | 356 | u8 *buf); |
... | ... | @@ -344,5 +359,11 @@ |
344 | 359 | u8 *buf); |
345 | 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 | 368 | #endif /* __LINUX_MFD_MAX8997_PRIV_H */ |
include/linux/mfd/max8997.h
... | ... | @@ -78,8 +78,11 @@ |
78 | 78 | }; |
79 | 79 | |
80 | 80 | struct max8997_platform_data { |
81 | - bool wakeup; | |
82 | - /* IRQ: Not implemented */ | |
81 | + /* IRQ */ | |
82 | + int irq_base; | |
83 | + int ono; | |
84 | + int wakeup; | |
85 | + | |
83 | 86 | /* ---- PMIC ---- */ |
84 | 87 | struct max8997_regulator_data *regulators; |
85 | 88 | int num_regulators; |