Skip to content

Commit 3837f9a

Browse files
committed
Merge tag 'tty-5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty / serial driver fixes from Greg KH: "Here are some small fixes for reported problems for tty and serial drivers for 5.13-rc4. They consist of: - 8250 bugfixes and new device support - lockdown security mode fixup - syzbot found problems fixed - 8250_omap fix for interrupt storm - revert of 8250_omap driver fix as it caused worse problem than the original issue All but the last patch have been in linux-next for a while, the last one is a revert of a problem found in linux-next with the 8250_omap driver change" * tag 'tty-5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: Revert "serial: 8250: 8250_omap: Fix possible interrupt storm" serial: 8250_pci: handle FL_NOIRQ board flag serial: rp2: use 'request_firmware' instead of 'request_firmware_nowait' serial: 8250_pci: Add support for new HPE serial device serial: 8250: 8250_omap: Fix possible interrupt storm serial: 8250: Use BIT(x) for UART_{CAP,BUG}_* serial: 8250: Add UART_BUG_TXRACE workaround for Aspeed VUART serial: 8250_dw: Add device HID for new AMD UART controller serial: sh-sci: Fix off-by-one error in FIFO threshold register setting serial: core: fix suspicious security_locked_down() call serial: tegra: Fix a mask operation that is always true
2 parents 523d0b1 + 56dde68 commit 3837f9a

File tree

10 files changed

+92
-68
lines changed

10 files changed

+92
-68
lines changed

drivers/acpi/acpi_apd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
226226
{ "AMDI0010", APD_ADDR(wt_i2c_desc) },
227227
{ "AMD0020", APD_ADDR(cz_uart_desc) },
228228
{ "AMDI0020", APD_ADDR(cz_uart_desc) },
229+
{ "AMDI0022", APD_ADDR(cz_uart_desc) },
229230
{ "AMD0030", },
230231
{ "AMD0040", APD_ADDR(fch_misc_desc)},
231232
{ "HYGO0010", APD_ADDR(wt_i2c_desc) },

drivers/tty/serial/8250/8250.h

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Copyright (C) 2001 Russell King.
88
*/
99

10+
#include <linux/bits.h>
1011
#include <linux/serial_8250.h>
1112
#include <linux/serial_reg.h>
1213
#include <linux/dmaengine.h>
@@ -70,24 +71,25 @@ struct serial8250_config {
7071
unsigned int flags;
7172
};
7273

73-
#define UART_CAP_FIFO (1 << 8) /* UART has FIFO */
74-
#define UART_CAP_EFR (1 << 9) /* UART has EFR */
75-
#define UART_CAP_SLEEP (1 << 10) /* UART has IER sleep */
76-
#define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */
77-
#define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */
78-
#define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */
79-
#define UART_CAP_HFIFO (1 << 14) /* UART has a "hidden" FIFO */
80-
#define UART_CAP_RPM (1 << 15) /* Runtime PM is active while idle */
81-
#define UART_CAP_IRDA (1 << 16) /* UART supports IrDA line discipline */
82-
#define UART_CAP_MINI (1 << 17) /* Mini UART on BCM283X family lacks:
74+
#define UART_CAP_FIFO BIT(8) /* UART has FIFO */
75+
#define UART_CAP_EFR BIT(9) /* UART has EFR */
76+
#define UART_CAP_SLEEP BIT(10) /* UART has IER sleep */
77+
#define UART_CAP_AFE BIT(11) /* MCR-based hw flow control */
78+
#define UART_CAP_UUE BIT(12) /* UART needs IER bit 6 set (Xscale) */
79+
#define UART_CAP_RTOIE BIT(13) /* UART needs IER bit 4 set (Xscale, Tegra) */
80+
#define UART_CAP_HFIFO BIT(14) /* UART has a "hidden" FIFO */
81+
#define UART_CAP_RPM BIT(15) /* Runtime PM is active while idle */
82+
#define UART_CAP_IRDA BIT(16) /* UART supports IrDA line discipline */
83+
#define UART_CAP_MINI BIT(17) /* Mini UART on BCM283X family lacks:
8384
* STOP PARITY EPAR SPAR WLEN5 WLEN6
8485
*/
8586

86-
#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
87-
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
88-
#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
89-
#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
90-
#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */
87+
#define UART_BUG_QUOT BIT(0) /* UART has buggy quot LSB */
88+
#define UART_BUG_TXEN BIT(1) /* UART has buggy TX IIR status */
89+
#define UART_BUG_NOMSR BIT(2) /* UART has buggy MSR status bits (Au1x00) */
90+
#define UART_BUG_THRE BIT(3) /* UART has buggy THRE reassertion */
91+
#define UART_BUG_PARITY BIT(4) /* UART mishandles parity if FIFO enabled */
92+
#define UART_BUG_TXRACE BIT(5) /* UART Tx fails to set remote DR */
9193

9294

9395
#ifdef CONFIG_SERIAL_8250_SHARE_IRQ

drivers/tty/serial/8250/8250_aspeed_vuart.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
437437
port.port.status = UPSTAT_SYNC_FIFO;
438438
port.port.dev = &pdev->dev;
439439
port.port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);
440+
port.bugs |= UART_BUG_TXRACE;
440441

441442
rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
442443
if (rc < 0)

drivers/tty/serial/8250/8250_dw.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = {
714714
{ "APMC0D08", 0},
715715
{ "AMD0020", 0 },
716716
{ "AMDI0020", 0 },
717+
{ "AMDI0022", 0 },
717718
{ "BRCM2032", 0 },
718719
{ "HISI0031", 0 },
719720
{ },

drivers/tty/serial/8250/8250_pci.c

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,17 @@ struct serial_private {
5656
int line[];
5757
};
5858

59+
#define PCI_DEVICE_ID_HPE_PCI_SERIAL 0x37e
60+
5961
static const struct pci_device_id pci_use_msi[] = {
6062
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
6163
0xA000, 0x1000) },
6264
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
6365
0xA000, 0x1000) },
6466
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922,
6567
0xA000, 0x1000) },
68+
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_HP_3PAR, PCI_DEVICE_ID_HPE_PCI_SERIAL,
69+
PCI_ANY_ID, PCI_ANY_ID) },
6670
{ }
6771
};
6872

@@ -1997,6 +2001,16 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
19972001
.init = pci_hp_diva_init,
19982002
.setup = pci_hp_diva_setup,
19992003
},
2004+
/*
2005+
* HPE PCI serial device
2006+
*/
2007+
{
2008+
.vendor = PCI_VENDOR_ID_HP_3PAR,
2009+
.device = PCI_DEVICE_ID_HPE_PCI_SERIAL,
2010+
.subvendor = PCI_ANY_ID,
2011+
.subdevice = PCI_ANY_ID,
2012+
.setup = pci_hp_diva_setup,
2013+
},
20002014
/*
20012015
* Intel
20022016
*/
@@ -3944,21 +3958,26 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
39443958
uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
39453959
uart.port.uartclk = board->base_baud * 16;
39463960

3947-
if (pci_match_id(pci_use_msi, dev)) {
3948-
dev_dbg(&dev->dev, "Using MSI(-X) interrupts\n");
3949-
pci_set_master(dev);
3950-
rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES);
3961+
if (board->flags & FL_NOIRQ) {
3962+
uart.port.irq = 0;
39513963
} else {
3952-
dev_dbg(&dev->dev, "Using legacy interrupts\n");
3953-
rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY);
3954-
}
3955-
if (rc < 0) {
3956-
kfree(priv);
3957-
priv = ERR_PTR(rc);
3958-
goto err_deinit;
3964+
if (pci_match_id(pci_use_msi, dev)) {
3965+
dev_dbg(&dev->dev, "Using MSI(-X) interrupts\n");
3966+
pci_set_master(dev);
3967+
rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES);
3968+
} else {
3969+
dev_dbg(&dev->dev, "Using legacy interrupts\n");
3970+
rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY);
3971+
}
3972+
if (rc < 0) {
3973+
kfree(priv);
3974+
priv = ERR_PTR(rc);
3975+
goto err_deinit;
3976+
}
3977+
3978+
uart.port.irq = pci_irq_vector(dev, 0);
39593979
}
39603980

3961-
uart.port.irq = pci_irq_vector(dev, 0);
39623981
uart.port.dev = &dev->dev;
39633982

39643983
for (i = 0; i < nr_ports; i++) {
@@ -4973,6 +4992,10 @@ static const struct pci_device_id serial_pci_tbl[] = {
49734992
{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX,
49744993
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
49754994
pbn_b2_1_115200 },
4995+
/* HPE PCI serial device */
4996+
{ PCI_VENDOR_ID_HP_3PAR, PCI_DEVICE_ID_HPE_PCI_SERIAL,
4997+
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
4998+
pbn_b1_1_115200 },
49764999

49775000
{ PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM2,
49785001
PCI_ANY_ID, PCI_ANY_ID, 0, 0,

drivers/tty/serial/8250/8250_port.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,18 @@ void serial8250_tx_chars(struct uart_8250_port *up)
18091809
count = up->tx_loadsz;
18101810
do {
18111811
serial_out(up, UART_TX, xmit->buf[xmit->tail]);
1812+
if (up->bugs & UART_BUG_TXRACE) {
1813+
/*
1814+
* The Aspeed BMC virtual UARTs have a bug where data
1815+
* may get stuck in the BMC's Tx FIFO from bursts of
1816+
* writes on the APB interface.
1817+
*
1818+
* Delay back-to-back writes by a read cycle to avoid
1819+
* stalling the VUART. Read a register that won't have
1820+
* side-effects and discard the result.
1821+
*/
1822+
serial_in(up, UART_SCR);
1823+
}
18121824
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
18131825
port->icount.tx++;
18141826
if (uart_circ_empty(xmit))

drivers/tty/serial/rp2.c

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,6 @@ struct rp2_card {
195195
void __iomem *bar0;
196196
void __iomem *bar1;
197197
spinlock_t card_lock;
198-
struct completion fw_loaded;
199198
};
200199

201200
#define RP_ID(prod) PCI_VDEVICE(RP, (prod))
@@ -662,17 +661,10 @@ static void rp2_remove_ports(struct rp2_card *card)
662661
card->initialized_ports = 0;
663662
}
664663

665-
static void rp2_fw_cb(const struct firmware *fw, void *context)
664+
static int rp2_load_firmware(struct rp2_card *card, const struct firmware *fw)
666665
{
667-
struct rp2_card *card = context;
668666
resource_size_t phys_base;
669-
int i, rc = -ENOENT;
670-
671-
if (!fw) {
672-
dev_err(&card->pdev->dev, "cannot find '%s' firmware image\n",
673-
RP2_FW_NAME);
674-
goto no_fw;
675-
}
667+
int i, rc = 0;
676668

677669
phys_base = pci_resource_start(card->pdev, 1);
678670

@@ -718,23 +710,13 @@ static void rp2_fw_cb(const struct firmware *fw, void *context)
718710
card->initialized_ports++;
719711
}
720712

721-
release_firmware(fw);
722-
no_fw:
723-
/*
724-
* rp2_fw_cb() is called from a workqueue long after rp2_probe()
725-
* has already returned success. So if something failed here,
726-
* we'll just leave the now-dormant device in place until somebody
727-
* unbinds it.
728-
*/
729-
if (rc)
730-
dev_warn(&card->pdev->dev, "driver initialization failed\n");
731-
732-
complete(&card->fw_loaded);
713+
return rc;
733714
}
734715

735716
static int rp2_probe(struct pci_dev *pdev,
736717
const struct pci_device_id *id)
737718
{
719+
const struct firmware *fw;
738720
struct rp2_card *card;
739721
struct rp2_uart_port *ports;
740722
void __iomem * const *bars;
@@ -745,7 +727,6 @@ static int rp2_probe(struct pci_dev *pdev,
745727
return -ENOMEM;
746728
pci_set_drvdata(pdev, card);
747729
spin_lock_init(&card->card_lock);
748-
init_completion(&card->fw_loaded);
749730

750731
rc = pcim_enable_device(pdev);
751732
if (rc)
@@ -778,21 +759,23 @@ static int rp2_probe(struct pci_dev *pdev,
778759
return -ENOMEM;
779760
card->ports = ports;
780761

781-
rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt,
782-
IRQF_SHARED, DRV_NAME, card);
783-
if (rc)
762+
rc = request_firmware(&fw, RP2_FW_NAME, &pdev->dev);
763+
if (rc < 0) {
764+
dev_err(&pdev->dev, "cannot find '%s' firmware image\n",
765+
RP2_FW_NAME);
784766
return rc;
767+
}
785768

786-
/*
787-
* Only catastrophic errors (e.g. ENOMEM) are reported here.
788-
* If the FW image is missing, we'll find out in rp2_fw_cb()
789-
* and print an error message.
790-
*/
791-
rc = request_firmware_nowait(THIS_MODULE, 1, RP2_FW_NAME, &pdev->dev,
792-
GFP_KERNEL, card, rp2_fw_cb);
769+
rc = rp2_load_firmware(card, fw);
770+
771+
release_firmware(fw);
772+
if (rc < 0)
773+
return rc;
774+
775+
rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt,
776+
IRQF_SHARED, DRV_NAME, card);
793777
if (rc)
794778
return rc;
795-
dev_dbg(&pdev->dev, "waiting for firmware blob...\n");
796779

797780
return 0;
798781
}
@@ -801,7 +784,6 @@ static void rp2_remove(struct pci_dev *pdev)
801784
{
802785
struct rp2_card *card = pci_get_drvdata(pdev);
803786

804-
wait_for_completion(&card->fw_loaded);
805787
rp2_remove_ports(card);
806788
}
807789

drivers/tty/serial/serial-tegra.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits)
338338

339339
do {
340340
lsr = tegra_uart_read(tup, UART_LSR);
341-
if ((lsr | UART_LSR_TEMT) && !(lsr & UART_LSR_DR))
341+
if ((lsr & UART_LSR_TEMT) && !(lsr & UART_LSR_DR))
342342
break;
343343
udelay(1);
344344
} while (--tmout);

drivers/tty/serial/serial_core.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -863,9 +863,11 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
863863
goto check_and_exit;
864864
}
865865

866-
retval = security_locked_down(LOCKDOWN_TIOCSSERIAL);
867-
if (retval && (change_irq || change_port))
868-
goto exit;
866+
if (change_irq || change_port) {
867+
retval = security_locked_down(LOCKDOWN_TIOCSSERIAL);
868+
if (retval)
869+
goto exit;
870+
}
869871

870872
/*
871873
* Ask the low level driver to verify the settings.

drivers/tty/serial/sh-sci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,10 +1023,10 @@ static int scif_set_rtrg(struct uart_port *port, int rx_trig)
10231023
{
10241024
unsigned int bits;
10251025

1026+
if (rx_trig >= port->fifosize)
1027+
rx_trig = port->fifosize - 1;
10261028
if (rx_trig < 1)
10271029
rx_trig = 1;
1028-
if (rx_trig >= port->fifosize)
1029-
rx_trig = port->fifosize;
10301030

10311031
/* HSCIF can be set to an arbitrary level. */
10321032
if (sci_getreg(port, HSRTRGR)->size) {

0 commit comments

Comments
 (0)