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

Configure Feed

Select the types of activity you want to include in your feed.

serial: sc16is7xx: change EFR lock to operate on each channels

Now that the driver has been converted to use one regmap per port, change
efr locking to operate on a channel basis instead of on the whole IC.

Fixes: 3837a0379533 ("serial: sc16is7xx: improve regmap debugfs by using one regmap per port")
Cc: <stable@vger.kernel.org> # 6.1.x: 3837a03 serial: sc16is7xx: improve regmap debugfs by using one regmap per port
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Link: https://lore.kernel.org/r/20231211171353.2901416-5-hugo@hugovil.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Hugo Villeneuve and committed by
Greg Kroah-Hartman
4409df58 41a308cb

+26 -23
+26 -23
drivers/tty/serial/sc16is7xx.c
··· 323 323 struct sc16is7xx_one { 324 324 struct uart_port port; 325 325 struct regmap *regmap; 326 + struct mutex efr_lock; /* EFR registers access */ 326 327 struct kthread_work tx_work; 327 328 struct kthread_work reg_work; 328 329 struct kthread_delayed_work ms_work; ··· 343 342 unsigned char buf[SC16IS7XX_FIFO_SIZE]; 344 343 struct kthread_worker kworker; 345 344 struct task_struct *kworker_task; 346 - struct mutex efr_lock; 347 345 struct sc16is7xx_one p[]; 348 346 }; 349 347 ··· 494 494 495 495 static int sc16is7xx_set_baud(struct uart_port *port, int baud) 496 496 { 497 - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); 498 497 struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); 499 498 u8 lcr; 500 499 u8 prescaler = 0; ··· 517 518 * because the bulk of the interrupt processing is run as a workqueue 518 519 * job in thread context. 519 520 */ 520 - mutex_lock(&s->efr_lock); 521 + mutex_lock(&one->efr_lock); 521 522 522 523 lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG); 523 524 ··· 536 537 /* Put LCR back to the normal mode */ 537 538 sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); 538 539 539 - mutex_unlock(&s->efr_lock); 540 + mutex_unlock(&one->efr_lock); 540 541 541 542 sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, 542 543 SC16IS7XX_MCR_CLKSEL_BIT, ··· 704 705 static void sc16is7xx_update_mlines(struct sc16is7xx_one *one) 705 706 { 706 707 struct uart_port *port = &one->port; 707 - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); 708 708 unsigned long flags; 709 709 unsigned int status, changed; 710 710 711 - lockdep_assert_held_once(&s->efr_lock); 711 + lockdep_assert_held_once(&one->efr_lock); 712 712 713 713 status = sc16is7xx_get_hwmctrl(port); 714 714 changed = status ^ one->old_mctrl; ··· 733 735 734 736 static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) 735 737 { 738 + bool rc = true; 736 739 struct uart_port *port = &s->p[portno].port; 740 + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); 741 + 742 + mutex_lock(&one->efr_lock); 737 743 738 744 do { 739 745 unsigned int iir, rxlen; 740 - struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); 741 746 742 747 iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG); 743 - if (iir & SC16IS7XX_IIR_NO_INT_BIT) 744 - return false; 748 + if (iir & SC16IS7XX_IIR_NO_INT_BIT) { 749 + rc = false; 750 + goto out_port_irq; 751 + } 745 752 746 753 iir &= SC16IS7XX_IIR_ID_MASK; 747 754 ··· 786 783 break; 787 784 } 788 785 } while (0); 789 - return true; 786 + 787 + out_port_irq: 788 + mutex_unlock(&one->efr_lock); 789 + 790 + return rc; 790 791 } 791 792 792 793 static irqreturn_t sc16is7xx_irq(int irq, void *dev_id) 793 794 { 794 795 struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; 795 - 796 - mutex_lock(&s->efr_lock); 797 796 798 797 while (1) { 799 798 bool keep_polling = false; ··· 807 802 break; 808 803 } 809 804 810 - mutex_unlock(&s->efr_lock); 811 - 812 805 return IRQ_HANDLED; 813 806 } 814 807 815 808 static void sc16is7xx_tx_proc(struct kthread_work *ws) 816 809 { 817 810 struct uart_port *port = &(to_sc16is7xx_one(ws, tx_work)->port); 818 - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); 811 + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); 819 812 unsigned long flags; 820 813 821 814 if ((port->rs485.flags & SER_RS485_ENABLED) && 822 815 (port->rs485.delay_rts_before_send > 0)) 823 816 msleep(port->rs485.delay_rts_before_send); 824 817 825 - mutex_lock(&s->efr_lock); 818 + mutex_lock(&one->efr_lock); 826 819 sc16is7xx_handle_tx(port); 827 - mutex_unlock(&s->efr_lock); 820 + mutex_unlock(&one->efr_lock); 828 821 829 822 uart_port_lock_irqsave(port, &flags); 830 823 sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT); ··· 929 926 struct sc16is7xx_port *s = dev_get_drvdata(one->port.dev); 930 927 931 928 if (one->port.state) { 932 - mutex_lock(&s->efr_lock); 929 + mutex_lock(&one->efr_lock); 933 930 sc16is7xx_update_mlines(one); 934 - mutex_unlock(&s->efr_lock); 931 + mutex_unlock(&one->efr_lock); 935 932 936 933 kthread_queue_delayed_work(&s->kworker, &one->ms_work, HZ); 937 934 } ··· 1015 1012 struct ktermios *termios, 1016 1013 const struct ktermios *old) 1017 1014 { 1018 - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); 1019 1015 struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); 1020 1016 unsigned int lcr, flow = 0; 1021 1017 int baud; ··· 1073 1071 port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK; 1074 1072 1075 1073 /* As above, claim the mutex while accessing the EFR. */ 1076 - mutex_lock(&s->efr_lock); 1074 + mutex_lock(&one->efr_lock); 1077 1075 1078 1076 sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, 1079 1077 SC16IS7XX_LCR_CONF_MODE_B); ··· 1103 1101 /* Update LCR register */ 1104 1102 sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); 1105 1103 1106 - mutex_unlock(&s->efr_lock); 1104 + mutex_unlock(&one->efr_lock); 1107 1105 1108 1106 /* Get baud rate generator configuration */ 1109 1107 baud = uart_get_baud_rate(port, termios, old, ··· 1537 1535 1538 1536 s->devtype = devtype; 1539 1537 dev_set_drvdata(dev, s); 1540 - mutex_init(&s->efr_lock); 1541 1538 1542 1539 kthread_init_worker(&s->kworker); 1543 1540 s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker, ··· 1578 1577 ret = -ENOMEM; 1579 1578 goto out_ports; 1580 1579 } 1580 + 1581 + mutex_init(&s->p[i].efr_lock); 1581 1582 1582 1583 ret = uart_get_rs485_mode(&s->p[i].port); 1583 1584 if (ret)