gpio: pch9: Use proper flow type handlers

Jean-Francois Dagenais reported:

Configuring a gpio pin with the gpio-pch driver with
"IRQF_TRIGGER_LOW | IRQF_ONESHOT" generates an interrupt storm for
threaded ISR until the ISR thread actually gets to physically clear
the interrupt on the triggering chip!! The immediate observable
symptom is the high CPU usage for my ISR thread task and the
interrupt count in /proc/interrupts incrementing radically.

The driver is wrong in several ways:

1) Using handle_simple_irq() does not provide proper flow control
handling. In the case of oneshot threaded handlers for the
demultiplexed interrupts this results in an interrupt storm because
the simple handler does not deal with masking/unmasking. Even
without threaded oneshot handlers an interrupt storm for level type
interrupts can easily be triggered when the interrupt is disabled
and the interrupt line is activated from the device.

2) Acknowlegding the demultiplexed interrupt before calling the
handler is wrong for level type interrupts.

3) The set_type function unconditionally enables the interrupt. It's
supposed to set the type and nothing else. The unmasking is done by
the core code.

Move the acknowledge code into a separate function and add it to the
demux irqchip callbacks.

Remove the unconditional enabling from the set_type() callback and set
the proper flow handlers depending on the selected type (level/edge).

Reported-and-tested-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

authored by Thomas Gleixner and committed by Grant Likely df9541a6 6edd94db

Changed files
+28 -29
drivers
gpio
+28 -29
drivers/gpio/gpio-pch.c
··· 230 230 231 231 static int pch_irq_type(struct irq_data *d, unsigned int type) 232 232 { 233 - u32 im; 234 - u32 __iomem *im_reg; 235 - u32 ien; 236 - u32 im_pos; 237 - int ch; 238 - unsigned long flags; 239 - u32 val; 240 - int irq = d->irq; 241 233 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 242 234 struct pch_gpio *chip = gc->private; 235 + u32 im, im_pos, val; 236 + u32 __iomem *im_reg; 237 + unsigned long flags; 238 + int ch, irq = d->irq; 243 239 244 240 ch = irq - chip->irq_base; 245 241 if (irq <= chip->irq_base + 7) { ··· 266 270 case IRQ_TYPE_LEVEL_LOW: 267 271 val = PCH_LEVEL_L; 268 272 break; 269 - case IRQ_TYPE_PROBE: 270 - goto end; 271 273 default: 272 - dev_warn(chip->dev, "%s: unknown type(%dd)", 273 - __func__, type); 274 - goto end; 274 + goto unlock; 275 275 } 276 276 277 277 /* Set interrupt mode */ 278 278 im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); 279 279 iowrite32(im | (val << (im_pos * 4)), im_reg); 280 280 281 - /* iclr */ 282 - iowrite32(BIT(ch), &chip->reg->iclr); 281 + /* And the handler */ 282 + if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) 283 + __irq_set_handler_locked(d->irq, handle_level_irq); 284 + else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) 285 + __irq_set_handler_locked(d->irq, handle_edge_irq); 283 286 284 - /* IMASKCLR */ 285 - iowrite32(BIT(ch), &chip->reg->imaskclr); 286 - 287 - /* Enable interrupt */ 288 - ien = ioread32(&chip->reg->ien); 289 - iowrite32(ien | BIT(ch), &chip->reg->ien); 290 - end: 287 + unlock: 291 288 spin_unlock_irqrestore(&chip->spinlock, flags); 292 - 293 289 return 0; 294 290 } 295 291 ··· 301 313 iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); 302 314 } 303 315 316 + static void pch_irq_ack(struct irq_data *d) 317 + { 318 + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 319 + struct pch_gpio *chip = gc->private; 320 + 321 + iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->iclr); 322 + } 323 + 304 324 static irqreturn_t pch_gpio_handler(int irq, void *dev_id) 305 325 { 306 326 struct pch_gpio *chip = dev_id; 307 327 u32 reg_val = ioread32(&chip->reg->istatus); 308 - int i; 309 - int ret = IRQ_NONE; 328 + int i, ret = IRQ_NONE; 310 329 311 330 for (i = 0; i < gpio_pins[chip->ioh]; i++) { 312 331 if (reg_val & BIT(i)) { 313 332 dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", 314 333 __func__, i, irq, reg_val); 315 - iowrite32(BIT(i), &chip->reg->iclr); 316 334 generic_handle_irq(chip->irq_base + i); 317 335 ret = IRQ_HANDLED; 318 336 } ··· 337 343 gc->private = chip; 338 344 ct = gc->chip_types; 339 345 346 + ct->chip.irq_ack = pch_irq_ack; 340 347 ct->chip.irq_mask = pch_irq_mask; 341 348 ct->chip.irq_unmask = pch_irq_unmask; 342 349 ct->chip.irq_set_type = pch_irq_type; ··· 352 357 s32 ret; 353 358 struct pch_gpio *chip; 354 359 int irq_base; 360 + u32 msk; 355 361 356 362 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 357 363 if (chip == NULL) ··· 404 408 } 405 409 chip->irq_base = irq_base; 406 410 411 + /* Mask all interrupts, but enable them */ 412 + msk = (1 << gpio_pins[chip->ioh]) - 1; 413 + iowrite32(msk, &chip->reg->imask); 414 + iowrite32(msk, &chip->reg->ien); 415 + 407 416 ret = request_irq(pdev->irq, pch_gpio_handler, 408 - IRQF_SHARED, KBUILD_MODNAME, chip); 417 + IRQF_SHARED, KBUILD_MODNAME, chip); 409 418 if (ret != 0) { 410 419 dev_err(&pdev->dev, 411 420 "%s request_irq failed\n", __func__); ··· 419 418 420 419 pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); 421 420 422 - /* Initialize interrupt ien register */ 423 - iowrite32(0, &chip->reg->ien); 424 421 end: 425 422 return 0; 426 423