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 74 u32 trigger_type; 75 75 }; 76 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 77 static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 91 78 { 92 79 if (offset > 8) { ··· 166 179 return pg->irq_base + offset; 167 180 } 168 181 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 182 /* the gpiointr register is read-clear, so just do nothing. */ 190 183 static void pmic_irq_unmask(struct irq_data *data) { } 191 184 ··· 178 211 .irq_set_type = pmic_irq_type, 179 212 }; 180 213 181 - static void pmic_irq_handler(unsigned irq, struct irq_desc *desc) 214 + static irqreturn_t pmic_irq_handler(int irq, void *data) 182 215 { 183 - struct pmic_gpio *pg = (struct pmic_gpio *)get_irq_data(irq); 216 + struct pmic_gpio *pg = data; 184 217 u8 intsts = *((u8 *)pg->gpiointr + 4); 185 218 int gpio; 219 + irqreturn_t ret = IRQ_NONE; 186 220 187 221 for (gpio = 0; gpio < 8; gpio++) { 188 222 if (intsts & (1 << gpio)) { 189 223 pr_debug("pmic pin %d triggered\n", gpio); 190 224 generic_handle_irq(pg->irq_base + gpio); 225 + ret = IRQ_HANDLED; 191 226 } 192 227 } 193 - desc->chip->irq_eoi(get_irq_desc_chip_data(desc)); 228 + return ret; 194 229 } 195 230 196 231 static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) ··· 249 280 printk(KERN_ERR "%s: Can not add pmic gpio chip.\n", __func__); 250 281 goto err; 251 282 } 252 - set_irq_data(pg->irq, pg); 253 - set_irq_chained_handler(pg->irq, pmic_irq_handler); 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 + 254 290 for (i = 0; i < 8; i++) { 255 291 set_irq_chip_and_handler_name(i + pg->irq_base, &pmic_irqchip, 256 292 handle_simple_irq, "demux");