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

rtc: ds1685: use threaded interrupt

Handling of extended interrupts (kickstart, wake-up, ram-clear) was
moved off to a work queue, but the interrupts aren't acknowledged
in the interrupt handler. This leads to a deadlock, if driver
is used with interrupts. To fix this we use a threaded interrupt, get rid
of the work queue and do locking with just the rtc mutex lock.

Fixes: aaaf5fbf56f1 ("rtc: add driver for DS1685 family of real time clocks")
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

authored by

Thomas Bogendoerfer and committed by
Alexandre Belloni
3b6bddda e330c3d5

+104 -118
+104 -116
drivers/rtc/rtc-ds1685.c
··· 510 510 ds1685_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 511 511 { 512 512 struct ds1685_priv *rtc = dev_get_drvdata(dev); 513 - unsigned long flags = 0; 514 - 515 - /* Enable/disable the Alarm IRQ-Enable flag. */ 516 - spin_lock_irqsave(&rtc->lock, flags); 517 513 518 514 /* Flip the requisite interrupt-enable bit. */ 519 515 if (enabled) ··· 521 525 522 526 /* Read Control C to clear all the flag bits. */ 523 527 rtc->read(rtc, RTC_CTRL_C); 524 - spin_unlock_irqrestore(&rtc->lock, flags); 525 528 526 529 return 0; 527 530 } ··· 528 533 529 534 530 535 /* ----------------------------------------------------------------------- */ 531 - /* IRQ handler & workqueue. */ 536 + /* IRQ handler */ 532 537 533 538 /** 534 - * ds1685_rtc_irq_handler - IRQ handler. 535 - * @irq: IRQ number. 536 - * @dev_id: platform device pointer. 537 - */ 538 - static irqreturn_t 539 - ds1685_rtc_irq_handler(int irq, void *dev_id) 540 - { 541 - struct platform_device *pdev = dev_id; 542 - struct ds1685_priv *rtc = platform_get_drvdata(pdev); 543 - u8 ctrlb, ctrlc; 544 - unsigned long events = 0; 545 - u8 num_irqs = 0; 546 - 547 - /* Abort early if the device isn't ready yet (i.e., DEBUG_SHIRQ). */ 548 - if (unlikely(!rtc)) 549 - return IRQ_HANDLED; 550 - 551 - /* Ctrlb holds the interrupt-enable bits and ctrlc the flag bits. */ 552 - spin_lock(&rtc->lock); 553 - ctrlb = rtc->read(rtc, RTC_CTRL_B); 554 - ctrlc = rtc->read(rtc, RTC_CTRL_C); 555 - 556 - /* Is the IRQF bit set? */ 557 - if (likely(ctrlc & RTC_CTRL_C_IRQF)) { 558 - /* 559 - * We need to determine if it was one of the standard 560 - * events: PF, AF, or UF. If so, we handle them and 561 - * update the RTC core. 562 - */ 563 - if (likely(ctrlc & RTC_CTRL_B_PAU_MASK)) { 564 - events = RTC_IRQF; 565 - 566 - /* Check for a periodic interrupt. */ 567 - if ((ctrlb & RTC_CTRL_B_PIE) && 568 - (ctrlc & RTC_CTRL_C_PF)) { 569 - events |= RTC_PF; 570 - num_irqs++; 571 - } 572 - 573 - /* Check for an alarm interrupt. */ 574 - if ((ctrlb & RTC_CTRL_B_AIE) && 575 - (ctrlc & RTC_CTRL_C_AF)) { 576 - events |= RTC_AF; 577 - num_irqs++; 578 - } 579 - 580 - /* Check for an update interrupt. */ 581 - if ((ctrlb & RTC_CTRL_B_UIE) && 582 - (ctrlc & RTC_CTRL_C_UF)) { 583 - events |= RTC_UF; 584 - num_irqs++; 585 - } 586 - 587 - rtc_update_irq(rtc->dev, num_irqs, events); 588 - } else { 589 - /* 590 - * One of the "extended" interrupts was received that 591 - * is not recognized by the RTC core. These need to 592 - * be handled in task context as they can call other 593 - * functions and the time spent in irq context needs 594 - * to be minimized. Schedule them into a workqueue 595 - * and inform the RTC core that the IRQs were handled. 596 - */ 597 - spin_unlock(&rtc->lock); 598 - schedule_work(&rtc->work); 599 - rtc_update_irq(rtc->dev, 0, 0); 600 - return IRQ_HANDLED; 601 - } 602 - } 603 - spin_unlock(&rtc->lock); 604 - 605 - return events ? IRQ_HANDLED : IRQ_NONE; 606 - } 607 - 608 - /** 609 - * ds1685_rtc_work_queue - work queue handler. 610 - * @work: work_struct containing data to work on in task context. 539 + * ds1685_rtc_extended_irq - take care of extended interrupts 540 + * @rtc: pointer to the ds1685 rtc structure. 541 + * @pdev: platform device pointer. 611 542 */ 612 543 static void 613 - ds1685_rtc_work_queue(struct work_struct *work) 544 + ds1685_rtc_extended_irq(struct ds1685_priv *rtc, struct platform_device *pdev) 614 545 { 615 - struct ds1685_priv *rtc = container_of(work, 616 - struct ds1685_priv, work); 617 - struct platform_device *pdev = to_platform_device(&rtc->dev->dev); 618 - struct mutex *rtc_mutex = &rtc->dev->ops_lock; 619 546 u8 ctrl4a, ctrl4b; 620 - 621 - mutex_lock(rtc_mutex); 622 547 623 548 ds1685_rtc_switch_to_bank1(rtc); 624 549 ctrl4a = rtc->read(rtc, RTC_EXT_CTRL_4A); ··· 618 703 "RAM-Clear IRQ just occurred!\n"); 619 704 } 620 705 ds1685_rtc_switch_to_bank0(rtc); 706 + } 621 707 708 + /** 709 + * ds1685_rtc_irq_handler - IRQ handler. 710 + * @irq: IRQ number. 711 + * @dev_id: platform device pointer. 712 + */ 713 + static irqreturn_t 714 + ds1685_rtc_irq_handler(int irq, void *dev_id) 715 + { 716 + struct platform_device *pdev = dev_id; 717 + struct ds1685_priv *rtc = platform_get_drvdata(pdev); 718 + struct mutex *rtc_mutex; 719 + u8 ctrlb, ctrlc; 720 + unsigned long events = 0; 721 + u8 num_irqs = 0; 722 + 723 + /* Abort early if the device isn't ready yet (i.e., DEBUG_SHIRQ). */ 724 + if (unlikely(!rtc)) 725 + return IRQ_HANDLED; 726 + 727 + rtc_mutex = &rtc->dev->ops_lock; 728 + mutex_lock(rtc_mutex); 729 + 730 + /* Ctrlb holds the interrupt-enable bits and ctrlc the flag bits. */ 731 + ctrlb = rtc->read(rtc, RTC_CTRL_B); 732 + ctrlc = rtc->read(rtc, RTC_CTRL_C); 733 + 734 + /* Is the IRQF bit set? */ 735 + if (likely(ctrlc & RTC_CTRL_C_IRQF)) { 736 + /* 737 + * We need to determine if it was one of the standard 738 + * events: PF, AF, or UF. If so, we handle them and 739 + * update the RTC core. 740 + */ 741 + if (likely(ctrlc & RTC_CTRL_B_PAU_MASK)) { 742 + events = RTC_IRQF; 743 + 744 + /* Check for a periodic interrupt. */ 745 + if ((ctrlb & RTC_CTRL_B_PIE) && 746 + (ctrlc & RTC_CTRL_C_PF)) { 747 + events |= RTC_PF; 748 + num_irqs++; 749 + } 750 + 751 + /* Check for an alarm interrupt. */ 752 + if ((ctrlb & RTC_CTRL_B_AIE) && 753 + (ctrlc & RTC_CTRL_C_AF)) { 754 + events |= RTC_AF; 755 + num_irqs++; 756 + } 757 + 758 + /* Check for an update interrupt. */ 759 + if ((ctrlb & RTC_CTRL_B_UIE) && 760 + (ctrlc & RTC_CTRL_C_UF)) { 761 + events |= RTC_UF; 762 + num_irqs++; 763 + } 764 + } else { 765 + /* 766 + * One of the "extended" interrupts was received that 767 + * is not recognized by the RTC core. 768 + */ 769 + ds1685_rtc_extended_irq(rtc, pdev); 770 + } 771 + } 772 + rtc_update_irq(rtc->dev, num_irqs, events); 622 773 mutex_unlock(rtc_mutex); 774 + 775 + return events ? IRQ_HANDLED : IRQ_NONE; 623 776 } 624 777 /* ----------------------------------------------------------------------- */ 625 778 ··· 816 833 size_t size) 817 834 { 818 835 struct ds1685_priv *rtc = priv; 836 + struct mutex *rtc_mutex = &rtc->dev->ops_lock; 819 837 ssize_t count; 820 - unsigned long flags = 0; 821 838 u8 *buf = val; 839 + int err; 822 840 823 - spin_lock_irqsave(&rtc->lock, flags); 841 + err = mutex_lock_interruptible(rtc_mutex); 842 + if (err) 843 + return err; 844 + 824 845 ds1685_rtc_switch_to_bank0(rtc); 825 846 826 847 /* Read NVRAM in time and bank0 registers. */ ··· 874 887 ds1685_rtc_switch_to_bank0(rtc); 875 888 } 876 889 #endif /* !CONFIG_RTC_DRV_DS1689 */ 877 - spin_unlock_irqrestore(&rtc->lock, flags); 890 + mutex_unlock(rtc_mutex); 878 891 879 892 return 0; 880 893 } ··· 883 896 size_t size) 884 897 { 885 898 struct ds1685_priv *rtc = priv; 899 + struct mutex *rtc_mutex = &rtc->dev->ops_lock; 886 900 ssize_t count; 887 - unsigned long flags = 0; 888 901 u8 *buf = val; 902 + int err; 889 903 890 - spin_lock_irqsave(&rtc->lock, flags); 904 + err = mutex_lock_interruptible(rtc_mutex); 905 + if (err) 906 + return err; 907 + 891 908 ds1685_rtc_switch_to_bank0(rtc); 892 909 893 910 /* Write NVRAM in time and bank0 registers. */ ··· 941 950 ds1685_rtc_switch_to_bank0(rtc); 942 951 } 943 952 #endif /* !CONFIG_RTC_DRV_DS1689 */ 944 - spin_unlock_irqrestore(&rtc->lock, flags); 953 + mutex_unlock(rtc_mutex); 945 954 946 955 return 0; 947 956 } ··· 1132 1141 if (pdata->plat_post_ram_clear) 1133 1142 rtc->post_ram_clear = pdata->plat_post_ram_clear; 1134 1143 1135 - /* Init the spinlock, workqueue, & set the driver data. */ 1136 - spin_lock_init(&rtc->lock); 1137 - INIT_WORK(&rtc->work, ds1685_rtc_work_queue); 1144 + /* set the driver data. */ 1138 1145 platform_set_drvdata(pdev, rtc); 1139 1146 1140 1147 /* Turn the oscillator on if is not already on (DV1 = 1). */ ··· 1288 1299 */ 1289 1300 if (!pdata->no_irq) { 1290 1301 ret = platform_get_irq(pdev, 0); 1291 - if (ret > 0) { 1292 - rtc->irq_num = ret; 1293 - 1294 - /* Request an IRQ. */ 1295 - ret = devm_request_irq(&pdev->dev, rtc->irq_num, 1296 - ds1685_rtc_irq_handler, 1297 - IRQF_SHARED, pdev->name, pdev); 1298 - 1299 - /* Check to see if something came back. */ 1300 - if (unlikely(ret)) { 1301 - dev_warn(&pdev->dev, 1302 - "RTC interrupt not available\n"); 1303 - rtc->irq_num = 0; 1304 - } 1305 - } else 1302 + if (ret <= 0) 1306 1303 return ret; 1304 + 1305 + rtc->irq_num = ret; 1306 + 1307 + /* Request an IRQ. */ 1308 + ret = devm_request_threaded_irq(&pdev->dev, rtc->irq_num, 1309 + NULL, ds1685_rtc_irq_handler, 1310 + IRQF_SHARED | IRQF_ONESHOT, 1311 + pdev->name, pdev); 1312 + 1313 + /* Check to see if something came back. */ 1314 + if (unlikely(ret)) { 1315 + dev_warn(&pdev->dev, 1316 + "RTC interrupt not available\n"); 1317 + rtc->irq_num = 0; 1318 + } 1307 1319 } 1308 1320 rtc->no_irq = pdata->no_irq; 1309 1321 ··· 1350 1360 rtc->write(rtc, RTC_EXT_CTRL_4A, 1351 1361 (rtc->read(rtc, RTC_EXT_CTRL_4A) & 1352 1362 ~(RTC_CTRL_4A_RWK_MASK))); 1353 - 1354 - cancel_work_sync(&rtc->work); 1355 1363 1356 1364 return 0; 1357 1365 }
-2
include/linux/rtc/ds1685.h
··· 48 48 u32 regstep; 49 49 resource_size_t baseaddr; 50 50 size_t size; 51 - spinlock_t lock; 52 - struct work_struct work; 53 51 int irq_num; 54 52 bool bcd_mode; 55 53 bool no_irq;