Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: Use threaded irq for pcf50633

Use threaded oneshot irq handler instead of normal irq handler and a workqueue.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Lars-Peter Clausen and committed by
Samuel Ortiz
f7b2a77f 6438a694

+10 -49
+1 -1
drivers/mfd/Makefile
··· 57 57 max8925-objs := max8925-core.o max8925-i2c.o 58 58 obj-$(CONFIG_MFD_MAX8925) += max8925.o 59 59 60 - obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o 60 + obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o pcf50633-irq.o 61 61 obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o 62 62 obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o 63 63 obj-$(CONFIG_ABX500_CORE) += abx500-core.o
+9 -48
drivers/mfd/pcf50633-core.c
··· 325 325 /* Maximum amount of time ONKEY is held before emergency action is taken */ 326 326 #define PCF50633_ONKEY1S_TIMEOUT 8 327 327 328 - static void pcf50633_irq_worker(struct work_struct *work) 328 + static irqreturn_t pcf50633_irq(int irq, void *data) 329 329 { 330 - struct pcf50633 *pcf; 330 + struct pcf50633 *pcf = data; 331 331 int ret, i, j; 332 332 u8 pcf_int[5], chgstat; 333 - 334 - pcf = container_of(work, struct pcf50633, irq_work); 335 333 336 334 /* Read the 5 INT regs in one transaction */ 337 335 ret = pcf50633_read_block(pcf, PCF50633_REG_INT1, ··· 434 436 } 435 437 436 438 out: 437 - put_device(pcf->dev); 438 - enable_irq(pcf->irq); 439 - } 440 - 441 - static irqreturn_t pcf50633_irq(int irq, void *data) 442 - { 443 - struct pcf50633 *pcf = data; 444 - 445 - dev_dbg(pcf->dev, "pcf50633_irq\n"); 446 - 447 - get_device(pcf->dev); 448 - disable_irq_nosync(pcf->irq); 449 - queue_work(pcf->work_queue, &pcf->irq_work); 450 - 451 - return IRQ_HANDLED; 439 + return IRQ_HANDLED 452 440 } 453 441 454 442 static void ··· 471 487 /* Make sure our interrupt handlers are not called 472 488 * henceforth */ 473 489 disable_irq(pcf->irq); 474 - 475 - /* Make sure that any running IRQ worker has quit */ 476 - cancel_work_sync(&pcf->irq_work); 477 490 478 491 /* Save the masks */ 479 492 ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M, ··· 512 531 if (ret < 0) 513 532 dev_err(pcf->dev, "Error restoring saved suspend masks\n"); 514 533 515 - /* Restore regulators' state */ 516 - 517 - 518 - get_device(pcf->dev); 519 - 520 - /* 521 - * Clear any pending interrupts and set resume reason if any. 522 - * This will leave with enable_irq() 523 - */ 524 - pcf50633_irq_worker(&pcf->irq_work); 534 + enable_irq(pcf->irq); 525 535 526 536 return 0; 527 537 } ··· 546 574 pcf->dev = &client->dev; 547 575 pcf->i2c_client = client; 548 576 pcf->irq = client->irq; 549 - pcf->work_queue = create_singlethread_workqueue("pcf50633"); 550 - 551 - if (!pcf->work_queue) { 552 - dev_err(&client->dev, "Failed to alloc workqueue\n"); 553 - ret = -ENOMEM; 554 - goto err_free; 555 - } 556 - 557 - INIT_WORK(&pcf->irq_work, pcf50633_irq_worker); 558 577 559 578 version = pcf50633_reg_read(pcf, 0); 560 579 variant = pcf50633_reg_read(pcf, 1); 561 580 if (version < 0 || variant < 0) { 562 581 dev_err(pcf->dev, "Unable to probe pcf50633\n"); 563 582 ret = -ENODEV; 564 - goto err_destroy_workqueue; 583 + goto err_free; 565 584 } 566 585 567 586 dev_info(pcf->dev, "Probed device version %d variant %d\n", ··· 566 603 pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00); 567 604 pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00); 568 605 569 - ret = request_irq(client->irq, pcf50633_irq, 570 - IRQF_TRIGGER_LOW, "pcf50633", pcf); 606 + ret = request_threaded_irq(client->irq, NULL, pcf50633_irq, 607 + IRQF_TRIGGER_LOW | IRQF_ONESHOT, 608 + "pcf50633", pcf); 571 609 572 610 if (ret) { 573 611 dev_err(pcf->dev, "Failed to request IRQ %d\n", ret); 574 - goto err_destroy_workqueue; 612 + goto err_free; 575 613 } 576 614 577 615 /* Create sub devices */ ··· 618 654 619 655 return 0; 620 656 621 - err_destroy_workqueue: 622 - destroy_workqueue(pcf->work_queue); 623 657 err_free: 624 658 i2c_set_clientdata(client, NULL); 625 659 kfree(pcf); ··· 631 669 int i; 632 670 633 671 free_irq(pcf->irq, pcf); 634 - destroy_workqueue(pcf->work_queue); 635 672 636 673 platform_device_unregister(pcf->input_pdev); 637 674 platform_device_unregister(pcf->rtc_pdev);