Skip to content

Commit acc902d

Browse files
andy-shevgregkh
authored andcommitted
serial: 8250: Move CE4100 quirks to a module under 8250 driver
There is inconvenient for maintainers and maintainership to have some quirks under architectural code. Move it to the specific quirk file like other 8250-compatible drivers do. Signed-off-by: Andy Shevchenko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5e40169 commit acc902d

File tree

4 files changed

+105
-98
lines changed

4 files changed

+105
-98
lines changed

arch/x86/include/asm/ce4100.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@
44

55
int ce4100_pci_init(void);
66

7+
#ifdef CONFIG_SERIAL_8250
8+
void __init sdv_serial_fixup(void);
9+
#else
10+
static inline void sdv_serial_fixup(void) {};
11+
#endif
12+
713
#endif

arch/x86/platform/ce4100/ce4100.c

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,12 @@
55
* (C) Copyright 2010 Intel Corporation
66
*/
77
#include <linux/init.h>
8-
#include <linux/kernel.h>
9-
#include <linux/irq.h>
108
#include <linux/reboot.h>
11-
#include <linux/serial_reg.h>
12-
#include <linux/serial_8250.h>
139

1410
#include <asm/ce4100.h>
1511
#include <asm/prom.h>
1612
#include <asm/setup.h>
17-
#include <asm/i8259.h>
1813
#include <asm/io.h>
19-
#include <asm/io_apic.h>
20-
#include <asm/emergency-restart.h>
2114

2215
/*
2316
* The CE4100 platform has an internal 8051 Microcontroller which is
@@ -31,97 +24,6 @@ static void ce4100_power_off(void)
3124
outb(0x4, 0xcf9);
3225
}
3326

34-
#ifdef CONFIG_SERIAL_8250
35-
36-
static unsigned int mem_serial_in(struct uart_port *p, int offset)
37-
{
38-
offset = offset << p->regshift;
39-
return readl(p->membase + offset);
40-
}
41-
42-
/*
43-
* The UART Tx interrupts are not set under some conditions and therefore serial
44-
* transmission hangs. This is a silicon issue and has not been root caused. The
45-
* workaround for this silicon issue checks UART_LSR_THRE bit and UART_LSR_TEMT
46-
* bit of LSR register in interrupt handler to see whether at least one of these
47-
* two bits is set, if so then process the transmit request. If this workaround
48-
* is not applied, then the serial transmission may hang. This workaround is for
49-
* errata number 9 in Errata - B step.
50-
*/
51-
52-
static u32 ce4100_mem_serial_in(struct uart_port *p, unsigned int offset)
53-
{
54-
u32 ret, ier, lsr;
55-
56-
if (offset != UART_IIR)
57-
return mem_serial_in(p, offset);
58-
59-
offset <<= p->regshift;
60-
61-
ret = readl(p->membase + offset);
62-
if (!(ret & UART_IIR_NO_INT))
63-
return ret;
64-
65-
/* see if the TX interrupt should have really set */
66-
ier = mem_serial_in(p, UART_IER);
67-
/* see if the UART's XMIT interrupt is enabled */
68-
if (!(ier & UART_IER_THRI))
69-
return ret;
70-
71-
lsr = mem_serial_in(p, UART_LSR);
72-
/* now check to see if the UART should be generating an interrupt (but isn't) */
73-
if (lsr & (UART_LSR_THRE | UART_LSR_TEMT))
74-
ret &= ~UART_IIR_NO_INT;
75-
76-
return ret;
77-
}
78-
79-
static void ce4100_mem_serial_out(struct uart_port *p, unsigned int offset, u32 value)
80-
{
81-
offset <<= p->regshift;
82-
writel(value, p->membase + offset);
83-
}
84-
85-
static void ce4100_serial_fixup(int port, struct uart_port *up,
86-
u32 *capabilities)
87-
{
88-
#ifdef CONFIG_EARLY_PRINTK
89-
/*
90-
* Over ride the legacy port configuration that comes from
91-
* asm/serial.h. Using the ioport driver then switching to the
92-
* PCI memmaped driver hangs the IOAPIC
93-
*/
94-
if (up->iotype != UPIO_MEM32) {
95-
up->uartclk = 14745600;
96-
up->mapbase = 0xdffe0200;
97-
set_fixmap_nocache(FIX_EARLYCON_MEM_BASE,
98-
up->mapbase & PAGE_MASK);
99-
up->membase =
100-
(void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
101-
up->membase += up->mapbase & ~PAGE_MASK;
102-
up->mapbase += port * 0x100;
103-
up->membase += port * 0x100;
104-
up->iotype = UPIO_MEM32;
105-
up->regshift = 2;
106-
up->irq = 4;
107-
}
108-
#endif
109-
up->iobase = 0;
110-
up->serial_in = ce4100_mem_serial_in;
111-
up->serial_out = ce4100_mem_serial_out;
112-
113-
*capabilities |= (1 << 12);
114-
}
115-
116-
static __init void sdv_serial_fixup(void)
117-
{
118-
serial8250_set_isa_configurator(ce4100_serial_fixup);
119-
}
120-
121-
#else
122-
static inline void sdv_serial_fixup(void) {};
123-
#endif
124-
12527
static void __init sdv_arch_setup(void)
12628
{
12729
sdv_serial_fixup();
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Intel CE4100 platform specific setup code
4+
*
5+
* (C) Copyright 2010 Intel Corporation
6+
*/
7+
8+
#include <linux/init.h>
9+
#include <linux/io.h>
10+
#include <linux/types.h>
11+
12+
#include <asm/ce4100.h>
13+
#include <asm/fixmap.h>
14+
#include <asm/page.h>
15+
16+
#include <linux/serial_reg.h>
17+
#include <linux/serial_8250.h>
18+
19+
static unsigned int mem_serial_in(struct uart_port *p, int offset)
20+
{
21+
offset = offset << p->regshift;
22+
return readl(p->membase + offset);
23+
}
24+
25+
/*
26+
* The UART Tx interrupts are not set under some conditions and therefore serial
27+
* transmission hangs. This is a silicon issue and has not been root caused. The
28+
* workaround for this silicon issue checks UART_LSR_THRE bit and UART_LSR_TEMT
29+
* bit of LSR register in interrupt handler to see whether at least one of these
30+
* two bits is set, if so then process the transmit request. If this workaround
31+
* is not applied, then the serial transmission may hang. This workaround is for
32+
* errata number 9 in Errata - B step.
33+
*/
34+
static u32 ce4100_mem_serial_in(struct uart_port *p, unsigned int offset)
35+
{
36+
u32 ret, ier, lsr;
37+
38+
if (offset != UART_IIR)
39+
return mem_serial_in(p, offset);
40+
41+
offset <<= p->regshift;
42+
43+
ret = readl(p->membase + offset);
44+
if (!(ret & UART_IIR_NO_INT))
45+
return ret;
46+
47+
/* see if the TX interrupt should have really set */
48+
ier = mem_serial_in(p, UART_IER);
49+
/* see if the UART's XMIT interrupt is enabled */
50+
if (!(ier & UART_IER_THRI))
51+
return ret;
52+
53+
lsr = mem_serial_in(p, UART_LSR);
54+
/* now check to see if the UART should be generating an interrupt (but isn't) */
55+
if (lsr & (UART_LSR_THRE | UART_LSR_TEMT))
56+
ret &= ~UART_IIR_NO_INT;
57+
58+
return ret;
59+
}
60+
61+
static void ce4100_mem_serial_out(struct uart_port *p, unsigned int offset, u32 value)
62+
{
63+
offset <<= p->regshift;
64+
writel(value, p->membase + offset);
65+
}
66+
67+
static void ce4100_serial_fixup(int port, struct uart_port *up, u32 *capabilities)
68+
{
69+
#ifdef CONFIG_EARLY_PRINTK
70+
/*
71+
* Override the legacy port configuration that comes from
72+
* asm/serial.h. Using the ioport driver then switching to the
73+
* PCI memmaped driver hangs the IOAPIC.
74+
*/
75+
if (up->iotype != UPIO_MEM32) {
76+
up->uartclk = 14745600;
77+
up->mapbase = 0xdffe0200;
78+
set_fixmap_nocache(FIX_EARLYCON_MEM_BASE, up->mapbase & PAGE_MASK);
79+
up->membase = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
80+
up->membase += up->mapbase & ~PAGE_MASK;
81+
up->mapbase += port * 0x100;
82+
up->membase += port * 0x100;
83+
up->iotype = UPIO_MEM32;
84+
up->regshift = 2;
85+
up->irq = 4;
86+
}
87+
#endif
88+
up->iobase = 0;
89+
up->serial_in = ce4100_mem_serial_in;
90+
up->serial_out = ce4100_mem_serial_out;
91+
92+
*capabilities |= (1 << 12);
93+
}
94+
95+
void __init sdv_serial_fixup(void)
96+
{
97+
serial8250_set_isa_configurator(ce4100_serial_fixup);
98+
}

drivers/tty/serial/8250/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ obj-$(CONFIG_SERIAL_8250_ASPEED_VUART) += 8250_aspeed_vuart.o
2424
obj-$(CONFIG_SERIAL_8250_BCM2835AUX) += 8250_bcm2835aux.o
2525
obj-$(CONFIG_SERIAL_8250_BCM7271) += 8250_bcm7271.o
2626
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
27+
obj-$(CONFIG_X86_INTEL_CE) += 8250_ce4100.o
2728
obj-$(CONFIG_SERIAL_8250_DFL) += 8250_dfl.o
2829
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
2930
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o

0 commit comments

Comments
 (0)