Skip to content

Commit d3a28a5

Browse files
haukegregkh
authored andcommitted
serial: lantiq: Do not swap register read/writes
The ltq_r32() and ltq_w32() macros use the __raw_readl() and __raw_writel() functions which do not swap the value to little endian. On the big endian vrx200 SoC the UART is operated in big endian IO mode, the readl() and write() functions convert the value to little endian first and then the driver does not work any more on this SoC. Currently the vrx200 SoC selects the CONFIG_SWAP_IO_SPACE option, without this option the serial driver would work, but PCI devices do not work any more. This patch makes the driver use the __raw_readl() and __raw_writel() functions which do not swap the endianness. On big endian system it is assumed that the device should be access in big endian IO mode and on a little endian system it would be access in little endian mode. Fixes: 89b8bd2 ("serial: lantiq: Use readl/writel instead of ltq_r32/ltq_w32") Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Acked-by: John Crispin <john@phrozen.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent bfeffd1 commit d3a28a5

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

drivers/tty/serial/lantiq.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ struct ltq_uart_port {
114114

115115
static inline void asc_update_bits(u32 clear, u32 set, void __iomem *reg)
116116
{
117-
u32 tmp = readl(reg);
117+
u32 tmp = __raw_readl(reg);
118118

119-
writel((tmp & ~clear) | set, reg);
119+
__raw_writel((tmp & ~clear) | set, reg);
120120
}
121121

122122
static inline struct
@@ -144,7 +144,7 @@ lqasc_start_tx(struct uart_port *port)
144144
static void
145145
lqasc_stop_rx(struct uart_port *port)
146146
{
147-
writel(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE);
147+
__raw_writel(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE);
148148
}
149149

150150
static int
@@ -153,11 +153,12 @@ lqasc_rx_chars(struct uart_port *port)
153153
struct tty_port *tport = &port->state->port;
154154
unsigned int ch = 0, rsr = 0, fifocnt;
155155

156-
fifocnt = readl(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
156+
fifocnt = __raw_readl(port->membase + LTQ_ASC_FSTAT) &
157+
ASCFSTAT_RXFFLMASK;
157158
while (fifocnt--) {
158159
u8 flag = TTY_NORMAL;
159160
ch = readb(port->membase + LTQ_ASC_RBUF);
160-
rsr = (readl(port->membase + LTQ_ASC_STATE)
161+
rsr = (__raw_readl(port->membase + LTQ_ASC_STATE)
161162
& ASCSTATE_ANY) | UART_DUMMY_UER_RX;
162163
tty_flip_buffer_push(tport);
163164
port->icount.rx++;
@@ -217,7 +218,7 @@ lqasc_tx_chars(struct uart_port *port)
217218
return;
218219
}
219220

220-
while (((readl(port->membase + LTQ_ASC_FSTAT) &
221+
while (((__raw_readl(port->membase + LTQ_ASC_FSTAT) &
221222
ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF) != 0) {
222223
if (port->x_char) {
223224
writeb(port->x_char, port->membase + LTQ_ASC_TBUF);
@@ -245,7 +246,7 @@ lqasc_tx_int(int irq, void *_port)
245246
unsigned long flags;
246247
struct uart_port *port = (struct uart_port *)_port;
247248
spin_lock_irqsave(&ltq_asc_lock, flags);
248-
writel(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
249+
__raw_writel(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
249250
spin_unlock_irqrestore(&ltq_asc_lock, flags);
250251
lqasc_start_tx(port);
251252
return IRQ_HANDLED;
@@ -270,7 +271,7 @@ lqasc_rx_int(int irq, void *_port)
270271
unsigned long flags;
271272
struct uart_port *port = (struct uart_port *)_port;
272273
spin_lock_irqsave(&ltq_asc_lock, flags);
273-
writel(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
274+
__raw_writel(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
274275
lqasc_rx_chars(port);
275276
spin_unlock_irqrestore(&ltq_asc_lock, flags);
276277
return IRQ_HANDLED;
@@ -280,7 +281,8 @@ static unsigned int
280281
lqasc_tx_empty(struct uart_port *port)
281282
{
282283
int status;
283-
status = readl(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_TXFFLMASK;
284+
status = __raw_readl(port->membase + LTQ_ASC_FSTAT) &
285+
ASCFSTAT_TXFFLMASK;
284286
return status ? 0 : TIOCSER_TEMT;
285287
}
286288

@@ -313,12 +315,12 @@ lqasc_startup(struct uart_port *port)
313315
asc_update_bits(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
314316
port->membase + LTQ_ASC_CLC);
315317

316-
writel(0, port->membase + LTQ_ASC_PISEL);
317-
writel(
318+
__raw_writel(0, port->membase + LTQ_ASC_PISEL);
319+
__raw_writel(
318320
((TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) |
319321
ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU,
320322
port->membase + LTQ_ASC_TXFCON);
321-
writel(
323+
__raw_writel(
322324
((RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK)
323325
| ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU,
324326
port->membase + LTQ_ASC_RXFCON);
@@ -350,7 +352,7 @@ lqasc_startup(struct uart_port *port)
350352
goto err2;
351353
}
352354

353-
writel(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
355+
__raw_writel(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
354356
port->membase + LTQ_ASC_IRNREN);
355357
return 0;
356358

@@ -369,7 +371,7 @@ lqasc_shutdown(struct uart_port *port)
369371
free_irq(ltq_port->rx_irq, port);
370372
free_irq(ltq_port->err_irq, port);
371373

372-
writel(0, port->membase + LTQ_ASC_CON);
374+
__raw_writel(0, port->membase + LTQ_ASC_CON);
373375
asc_update_bits(ASCRXFCON_RXFEN, ASCRXFCON_RXFFLU,
374376
port->membase + LTQ_ASC_RXFCON);
375377
asc_update_bits(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
@@ -461,13 +463,13 @@ lqasc_set_termios(struct uart_port *port,
461463
asc_update_bits(ASCCON_BRS, 0, port->membase + LTQ_ASC_CON);
462464

463465
/* now we can write the new baudrate into the register */
464-
writel(divisor, port->membase + LTQ_ASC_BG);
466+
__raw_writel(divisor, port->membase + LTQ_ASC_BG);
465467

466468
/* turn the baudrate generator back on */
467469
asc_update_bits(0, ASCCON_R, port->membase + LTQ_ASC_CON);
468470

469471
/* enable rx */
470-
writel(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
472+
__raw_writel(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
471473

472474
spin_unlock_irqrestore(&ltq_asc_lock, flags);
473475

@@ -578,7 +580,7 @@ lqasc_console_putchar(struct uart_port *port, int ch)
578580
return;
579581

580582
do {
581-
fifofree = (readl(port->membase + LTQ_ASC_FSTAT)
583+
fifofree = (__raw_readl(port->membase + LTQ_ASC_FSTAT)
582584
& ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF;
583585
} while (fifofree == 0);
584586
writeb(ch, port->membase + LTQ_ASC_TBUF);

0 commit comments

Comments
 (0)