platform-drivers: x86: pmic: Use request_irq instead of chained handler

There is no need to install a chained handler for this hardware. This
is a plain x86 IOAPIC interrupt which is handled by the core code
perfectly fine. There is nothing special about demultiplexing these
gpio interrupts which justifies a custom hack. Replace it by a plain
old interrupt handler installed with request_irq. That makes the code
agnostic about the underlying primary interrupt hardware. The overhead
for this is minimal, but it gives us the advantage of accounting,
balancing and to detect interrupt storms. gpio interrupts are not
really that performance critical.

Patch fixups from akpm

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by Thomas Gleixner and committed by Matthew Garrett 98401ae4 d4b7de61

+12 -38
+12 -38
drivers/platform/x86/intel_pmic_gpio.c
··· 74 u32 trigger_type; 75 }; 76 77 - static void pmic_program_irqtype(int gpio, int type) 78 - { 79 - if (type & IRQ_TYPE_EDGE_RISING) 80 - intel_scu_ipc_update_register(GPIO0 + gpio, 0x20, 0x20); 81 - else 82 - intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x20); 83 - 84 - if (type & IRQ_TYPE_EDGE_FALLING) 85 - intel_scu_ipc_update_register(GPIO0 + gpio, 0x10, 0x10); 86 - else 87 - intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x10); 88 - }; 89 - 90 static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 91 { 92 if (offset > 8) { ··· 166 return pg->irq_base + offset; 167 } 168 169 - static void pmic_bus_lock(struct irq_data *data) 170 - { 171 - struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); 172 - 173 - mutex_lock(&pg->buslock); 174 - } 175 - 176 - static void pmic_bus_sync_unlock(struct irq_data *data) 177 - { 178 - struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); 179 - 180 - if (pg->update_type) { 181 - unsigned int gpio = pg->update_type & ~GPIO_UPDATE_TYPE; 182 - 183 - pmic_program_irqtype(gpio, pg->trigger_type); 184 - pg->update_type = 0; 185 - } 186 - mutex_unlock(&pg->buslock); 187 - } 188 - 189 /* the gpiointr register is read-clear, so just do nothing. */ 190 static void pmic_irq_unmask(struct irq_data *data) { } 191 ··· 178 .irq_set_type = pmic_irq_type, 179 }; 180 181 - static void pmic_irq_handler(unsigned irq, struct irq_desc *desc) 182 { 183 - struct pmic_gpio *pg = (struct pmic_gpio *)get_irq_data(irq); 184 u8 intsts = *((u8 *)pg->gpiointr + 4); 185 int gpio; 186 187 for (gpio = 0; gpio < 8; gpio++) { 188 if (intsts & (1 << gpio)) { 189 pr_debug("pmic pin %d triggered\n", gpio); 190 generic_handle_irq(pg->irq_base + gpio); 191 } 192 } 193 - desc->chip->irq_eoi(get_irq_desc_chip_data(desc)); 194 } 195 196 static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) ··· 249 printk(KERN_ERR "%s: Can not add pmic gpio chip.\n", __func__); 250 goto err; 251 } 252 - set_irq_data(pg->irq, pg); 253 - set_irq_chained_handler(pg->irq, pmic_irq_handler); 254 for (i = 0; i < 8; i++) { 255 set_irq_chip_and_handler_name(i + pg->irq_base, &pmic_irqchip, 256 handle_simple_irq, "demux");
··· 74 u32 trigger_type; 75 }; 76 77 static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 78 { 79 if (offset > 8) { ··· 179 return pg->irq_base + offset; 180 } 181 182 /* the gpiointr register is read-clear, so just do nothing. */ 183 static void pmic_irq_unmask(struct irq_data *data) { } 184 ··· 211 .irq_set_type = pmic_irq_type, 212 }; 213 214 + static irqreturn_t pmic_irq_handler(int irq, void *data) 215 { 216 + struct pmic_gpio *pg = data; 217 u8 intsts = *((u8 *)pg->gpiointr + 4); 218 int gpio; 219 + irqreturn_t ret = IRQ_NONE; 220 221 for (gpio = 0; gpio < 8; gpio++) { 222 if (intsts & (1 << gpio)) { 223 pr_debug("pmic pin %d triggered\n", gpio); 224 generic_handle_irq(pg->irq_base + gpio); 225 + ret = IRQ_HANDLED; 226 } 227 } 228 + return ret; 229 } 230 231 static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) ··· 280 printk(KERN_ERR "%s: Can not add pmic gpio chip.\n", __func__); 281 goto err; 282 } 283 + 284 + retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg); 285 + if (retval) { 286 + printk(KERN_WARNING "pmic: Interrupt request failed\n"); 287 + goto err; 288 + } 289 + 290 for (i = 0; i < 8; i++) { 291 set_irq_chip_and_handler_name(i + pg->irq_base, &pmic_irqchip, 292 handle_simple_irq, "demux");