Skip to content

Commit 438630e

Browse files
committed
Merge tag 'tty-4.13-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial fixes from Greg KH: "Here are two tty serial driver fixes for 4.13-rc5. One is a revert of a -rc1 patch that turned out to not be a good idea, and the other is a fix for the pl011 serial driver. Both have been in linux-next with no reported issues" * tag 'tty-4.13-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: Revert "serial: Delete dead code for CIR serial ports" tty: pl011: fix initialization order of QDF2400 E44
2 parents dd95f18 + 9527b82 commit 438630e

File tree

4 files changed

+71
-26
lines changed

4 files changed

+71
-26
lines changed

drivers/acpi/spcr.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@
1616
#include <linux/kernel.h>
1717
#include <linux/serial_core.h>
1818

19+
/*
20+
* Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
21+
* occasionally getting stuck as 1. To avoid the potential for a hang, check
22+
* TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
23+
* implementations, so only do so if an affected platform is detected in
24+
* parse_spcr().
25+
*/
26+
bool qdf2400_e44_present;
27+
EXPORT_SYMBOL(qdf2400_e44_present);
28+
1929
/*
2030
* Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
2131
* Detect them by examining the OEM fields in the SPCR header, similiar to PCI
@@ -147,8 +157,30 @@ int __init parse_spcr(bool earlycon)
147157
goto done;
148158
}
149159

150-
if (qdf2400_erratum_44_present(&table->header))
151-
uart = "qdf2400_e44";
160+
/*
161+
* If the E44 erratum is required, then we need to tell the pl011
162+
* driver to implement the work-around.
163+
*
164+
* The global variable is used by the probe function when it
165+
* creates the UARTs, whether or not they're used as a console.
166+
*
167+
* If the user specifies "traditional" earlycon, the qdf2400_e44
168+
* console name matches the EARLYCON_DECLARE() statement, and
169+
* SPCR is not used. Parameter "earlycon" is false.
170+
*
171+
* If the user specifies "SPCR" earlycon, then we need to update
172+
* the console name so that it also says "qdf2400_e44". Parameter
173+
* "earlycon" is true.
174+
*
175+
* For consistency, if we change the console name, then we do it
176+
* for everyone, not just earlycon.
177+
*/
178+
if (qdf2400_erratum_44_present(&table->header)) {
179+
qdf2400_e44_present = true;
180+
if (earlycon)
181+
uart = "qdf2400_e44";
182+
}
183+
152184
if (xgene_8250_erratum_present(table))
153185
iotype = "mmio32";
154186

drivers/tty/serial/8250/8250_core.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,13 +1043,24 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
10431043
if (up->dl_write)
10441044
uart->dl_write = up->dl_write;
10451045

1046-
if (serial8250_isa_config != NULL)
1047-
serial8250_isa_config(0, &uart->port,
1048-
&uart->capabilities);
1046+
if (uart->port.type != PORT_8250_CIR) {
1047+
if (serial8250_isa_config != NULL)
1048+
serial8250_isa_config(0, &uart->port,
1049+
&uart->capabilities);
1050+
1051+
ret = uart_add_one_port(&serial8250_reg,
1052+
&uart->port);
1053+
if (ret == 0)
1054+
ret = uart->port.line;
1055+
} else {
1056+
dev_info(uart->port.dev,
1057+
"skipping CIR port at 0x%lx / 0x%llx, IRQ %d\n",
1058+
uart->port.iobase,
1059+
(unsigned long long)uart->port.mapbase,
1060+
uart->port.irq);
10491061

1050-
ret = uart_add_one_port(&serial8250_reg, &uart->port);
1051-
if (ret == 0)
1052-
ret = uart->port.line;
1062+
ret = 0;
1063+
}
10531064
}
10541065
mutex_unlock(&serial_mutex);
10551066

drivers/tty/serial/amba-pl011.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,7 @@ static struct vendor_data vendor_sbsa = {
142142
.fixed_options = true,
143143
};
144144

145-
/*
146-
* Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
147-
* occasionally getting stuck as 1. To avoid the potential for a hang, check
148-
* TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
149-
* implementations, so only do so if an affected platform is detected in
150-
* parse_spcr().
151-
*/
152-
static bool qdf2400_e44_present = false;
153-
145+
#ifdef CONFIG_ACPI_SPCR_TABLE
154146
static struct vendor_data vendor_qdt_qdf2400_e44 = {
155147
.reg_offset = pl011_std_offsets,
156148
.fr_busy = UART011_FR_TXFE,
@@ -165,6 +157,7 @@ static struct vendor_data vendor_qdt_qdf2400_e44 = {
165157
.always_enabled = true,
166158
.fixed_options = true,
167159
};
160+
#endif
168161

169162
static u16 pl011_st_offsets[REG_ARRAY_SIZE] = {
170163
[REG_DR] = UART01x_DR,
@@ -2375,12 +2368,14 @@ static int __init pl011_console_match(struct console *co, char *name, int idx,
23752368
resource_size_t addr;
23762369
int i;
23772370

2378-
if (strcmp(name, "qdf2400_e44") == 0) {
2379-
pr_info_once("UART: Working around QDF2400 SoC erratum 44");
2380-
qdf2400_e44_present = true;
2381-
} else if (strcmp(name, "pl011") != 0) {
2371+
/*
2372+
* Systems affected by the Qualcomm Technologies QDF2400 E44 erratum
2373+
* have a distinct console name, so make sure we check for that.
2374+
* The actual implementation of the erratum occurs in the probe
2375+
* function.
2376+
*/
2377+
if ((strcmp(name, "qdf2400_e44") != 0) && (strcmp(name, "pl011") != 0))
23822378
return -ENODEV;
2383-
}
23842379

23852380
if (uart_parse_earlycon(options, &iotype, &addr, &options))
23862381
return -ENODEV;
@@ -2734,11 +2729,17 @@ static int sbsa_uart_probe(struct platform_device *pdev)
27342729
}
27352730
uap->port.irq = ret;
27362731

2737-
uap->reg_offset = vendor_sbsa.reg_offset;
2738-
uap->vendor = qdf2400_e44_present ?
2739-
&vendor_qdt_qdf2400_e44 : &vendor_sbsa;
2732+
#ifdef CONFIG_ACPI_SPCR_TABLE
2733+
if (qdf2400_e44_present) {
2734+
dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n");
2735+
uap->vendor = &vendor_qdt_qdf2400_e44;
2736+
} else
2737+
#endif
2738+
uap->vendor = &vendor_sbsa;
2739+
2740+
uap->reg_offset = uap->vendor->reg_offset;
27402741
uap->fifosize = 32;
2741-
uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM;
2742+
uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM;
27422743
uap->port.ops = &sbsa_uart_pops;
27432744
uap->fixed_baud = baudrate;
27442745

include/linux/acpi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,7 @@ static inline bool acpi_has_watchdog(void) { return false; }
12091209
#endif
12101210

12111211
#ifdef CONFIG_ACPI_SPCR_TABLE
1212+
extern bool qdf2400_e44_present;
12121213
int parse_spcr(bool earlycon);
12131214
#else
12141215
static inline int parse_spcr(bool earlycon) { return 0; }

0 commit comments

Comments
 (0)