Skip to content

Commit 6d53c3b

Browse files
Michal Simekgregkh
authored andcommitted
tty: serial: uartlite: Support uartlite on big and little endian systems
Use big and little endian accessors function to reflect system configuration. Detection is done via control register in ulite_request_port. Tested on Microblaze LE, BE, PPC440 and Arm zynq. Signed-off-by: Michal Simek <[email protected]> Acked-by: Arnd Bergmann <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3240b48 commit 6d53c3b

File tree

1 file changed

+79
-22
lines changed

1 file changed

+79
-22
lines changed

drivers/tty/serial/uartlite.c

Lines changed: 79 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
* Register definitions
3535
*
3636
* For register details see datasheet:
37-
* http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf
37+
* http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf
3838
*/
3939

4040
#define ULITE_RX 0x00
@@ -57,6 +57,54 @@
5757
#define ULITE_CONTROL_RST_RX 0x02
5858
#define ULITE_CONTROL_IE 0x10
5959

60+
struct uartlite_reg_ops {
61+
u32 (*in)(void __iomem *addr);
62+
void (*out)(u32 val, void __iomem *addr);
63+
};
64+
65+
static u32 uartlite_inbe32(void __iomem *addr)
66+
{
67+
return ioread32be(addr);
68+
}
69+
70+
static void uartlite_outbe32(u32 val, void __iomem *addr)
71+
{
72+
iowrite32be(val, addr);
73+
}
74+
75+
static struct uartlite_reg_ops uartlite_be = {
76+
.in = uartlite_inbe32,
77+
.out = uartlite_outbe32,
78+
};
79+
80+
static u32 uartlite_inle32(void __iomem *addr)
81+
{
82+
return ioread32(addr);
83+
}
84+
85+
static void uartlite_outle32(u32 val, void __iomem *addr)
86+
{
87+
iowrite32(val, addr);
88+
}
89+
90+
static struct uartlite_reg_ops uartlite_le = {
91+
.in = uartlite_inle32,
92+
.out = uartlite_outle32,
93+
};
94+
95+
static inline u32 uart_in32(u32 offset, struct uart_port *port)
96+
{
97+
struct uartlite_reg_ops *reg_ops = port->private_data;
98+
99+
return reg_ops->in(port->membase + offset);
100+
}
101+
102+
static inline void uart_out32(u32 val, u32 offset, struct uart_port *port)
103+
{
104+
struct uartlite_reg_ops *reg_ops = port->private_data;
105+
106+
reg_ops->out(val, port->membase + offset);
107+
}
60108

61109
static struct uart_port ulite_ports[ULITE_NR_UARTS];
62110

@@ -77,7 +125,7 @@ static int ulite_receive(struct uart_port *port, int stat)
77125
/* stats */
78126
if (stat & ULITE_STATUS_RXVALID) {
79127
port->icount.rx++;
80-
ch = ioread32be(port->membase + ULITE_RX);
128+
ch = uart_in32(ULITE_RX, port);
81129

82130
if (stat & ULITE_STATUS_PARITY)
83131
port->icount.parity++;
@@ -122,7 +170,7 @@ static int ulite_transmit(struct uart_port *port, int stat)
122170
return 0;
123171

124172
if (port->x_char) {
125-
iowrite32be(port->x_char, port->membase + ULITE_TX);
173+
uart_out32(port->x_char, ULITE_TX, port);
126174
port->x_char = 0;
127175
port->icount.tx++;
128176
return 1;
@@ -131,7 +179,7 @@ static int ulite_transmit(struct uart_port *port, int stat)
131179
if (uart_circ_empty(xmit) || uart_tx_stopped(port))
132180
return 0;
133181

134-
iowrite32be(xmit->buf[xmit->tail], port->membase + ULITE_TX);
182+
uart_out32(xmit->buf[xmit->tail], ULITE_TX, port);
135183
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
136184
port->icount.tx++;
137185

@@ -148,7 +196,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id)
148196
int busy, n = 0;
149197

150198
do {
151-
int stat = ioread32be(port->membase + ULITE_STATUS);
199+
int stat = uart_in32(ULITE_STATUS, port);
152200
busy = ulite_receive(port, stat);
153201
busy |= ulite_transmit(port, stat);
154202
n++;
@@ -169,7 +217,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port)
169217
unsigned int ret;
170218

171219
spin_lock_irqsave(&port->lock, flags);
172-
ret = ioread32be(port->membase + ULITE_STATUS);
220+
ret = uart_in32(ULITE_STATUS, port);
173221
spin_unlock_irqrestore(&port->lock, flags);
174222

175223
return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0;
@@ -192,7 +240,7 @@ static void ulite_stop_tx(struct uart_port *port)
192240

193241
static void ulite_start_tx(struct uart_port *port)
194242
{
195-
ulite_transmit(port, ioread32be(port->membase + ULITE_STATUS));
243+
ulite_transmit(port, uart_in32(ULITE_STATUS, port));
196244
}
197245

198246
static void ulite_stop_rx(struct uart_port *port)
@@ -220,17 +268,17 @@ static int ulite_startup(struct uart_port *port)
220268
if (ret)
221269
return ret;
222270

223-
iowrite32be(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX,
224-
port->membase + ULITE_CONTROL);
225-
iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
271+
uart_out32(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX,
272+
ULITE_CONTROL, port);
273+
uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port);
226274

227275
return 0;
228276
}
229277

230278
static void ulite_shutdown(struct uart_port *port)
231279
{
232-
iowrite32be(0, port->membase + ULITE_CONTROL);
233-
ioread32be(port->membase + ULITE_CONTROL); /* dummy */
280+
uart_out32(0, ULITE_CONTROL, port);
281+
uart_in32(ULITE_CONTROL, port); /* dummy */
234282
free_irq(port->irq, port);
235283
}
236284

@@ -281,6 +329,8 @@ static void ulite_release_port(struct uart_port *port)
281329

282330
static int ulite_request_port(struct uart_port *port)
283331
{
332+
int ret;
333+
284334
pr_debug("ulite console: port=%p; port->mapbase=%llx\n",
285335
port, (unsigned long long) port->mapbase);
286336

@@ -296,6 +346,14 @@ static int ulite_request_port(struct uart_port *port)
296346
return -EBUSY;
297347
}
298348

349+
port->private_data = &uartlite_be;
350+
ret = uart_in32(ULITE_CONTROL, port);
351+
uart_out32(ULITE_CONTROL_RST_TX, ULITE_CONTROL, port);
352+
ret = uart_in32(ULITE_STATUS, port);
353+
/* Endianess detection */
354+
if ((ret & ULITE_STATUS_TXEMPTY) != ULITE_STATUS_TXEMPTY)
355+
port->private_data = &uartlite_le;
356+
299357
return 0;
300358
}
301359

@@ -314,20 +372,19 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
314372
#ifdef CONFIG_CONSOLE_POLL
315373
static int ulite_get_poll_char(struct uart_port *port)
316374
{
317-
if (!(ioread32be(port->membase + ULITE_STATUS)
318-
& ULITE_STATUS_RXVALID))
375+
if (!(uart_in32(ULITE_STATUS, port) & ULITE_STATUS_RXVALID))
319376
return NO_POLL_CHAR;
320377

321-
return ioread32be(port->membase + ULITE_RX);
378+
return uart_in32(ULITE_RX, port);
322379
}
323380

324381
static void ulite_put_poll_char(struct uart_port *port, unsigned char ch)
325382
{
326-
while (ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_TXFULL)
383+
while (uart_in32(ULITE_STATUS, port) & ULITE_STATUS_TXFULL)
327384
cpu_relax();
328385

329386
/* write char to device */
330-
iowrite32be(ch, port->membase + ULITE_TX);
387+
uart_out32(ch, ULITE_TX, port);
331388
}
332389
#endif
333390

@@ -366,7 +423,7 @@ static void ulite_console_wait_tx(struct uart_port *port)
366423

367424
/* Spin waiting for TX fifo to have space available */
368425
for (i = 0; i < 100000; i++) {
369-
val = ioread32be(port->membase + ULITE_STATUS);
426+
val = uart_in32(ULITE_STATUS, port);
370427
if ((val & ULITE_STATUS_TXFULL) == 0)
371428
break;
372429
cpu_relax();
@@ -376,7 +433,7 @@ static void ulite_console_wait_tx(struct uart_port *port)
376433
static void ulite_console_putchar(struct uart_port *port, int ch)
377434
{
378435
ulite_console_wait_tx(port);
379-
iowrite32be(ch, port->membase + ULITE_TX);
436+
uart_out32(ch, ULITE_TX, port);
380437
}
381438

382439
static void ulite_console_write(struct console *co, const char *s,
@@ -393,16 +450,16 @@ static void ulite_console_write(struct console *co, const char *s,
393450
spin_lock_irqsave(&port->lock, flags);
394451

395452
/* save and disable interrupt */
396-
ier = ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_IE;
397-
iowrite32be(0, port->membase + ULITE_CONTROL);
453+
ier = uart_in32(ULITE_STATUS, port) & ULITE_STATUS_IE;
454+
uart_out32(0, ULITE_CONTROL, port);
398455

399456
uart_console_write(port, s, count, ulite_console_putchar);
400457

401458
ulite_console_wait_tx(port);
402459

403460
/* restore interrupt state */
404461
if (ier)
405-
iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
462+
uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port);
406463

407464
if (locked)
408465
spin_unlock_irqrestore(&port->lock, flags);

0 commit comments

Comments
 (0)