3b942801793c7753d2637053efd182cc2663f278
[oweals/openwrt.git] / target / linux / ixp4xx / patches-4.9 / 160-delayed_uart_io.patch
1 --- a/drivers/tty/serial/8250/8250_core.c
2 +++ b/drivers/tty/serial/8250/8250_core.c
3 @@ -833,6 +833,7 @@ static int serial8250_probe(struct platf
4                 uart.port.get_mctrl     = p->get_mctrl;
5                 uart.port.pm            = p->pm;
6                 uart.port.dev           = &dev->dev;
7 +               uart.port.rw_delay      = p->rw_delay;
8                 uart.port.irqflags      |= irqflag;
9                 ret = serial8250_register_8250_port(&uart);
10                 if (ret < 0) {
11 @@ -989,6 +990,7 @@ int serial8250_register_8250_port(struct
12                 uart->bugs              = up->bugs;
13                 uart->port.mapbase      = up->port.mapbase;
14                 uart->port.mapsize      = up->port.mapsize;
15 +               uart->port.rw_delay     = up->port.rw_delay;
16                 uart->port.private_data = up->port.private_data;
17                 uart->tx_loadsz         = up->tx_loadsz;
18                 uart->capabilities      = up->capabilities;
19 --- a/drivers/tty/serial/serial_core.c
20 +++ b/drivers/tty/serial/serial_core.c
21 @@ -2259,6 +2259,7 @@ uart_report_port(struct uart_driver *drv
22                 snprintf(address, sizeof(address),
23                          "I/O 0x%lx offset 0x%x", port->iobase, port->hub6);
24                 break;
25 +       case UPIO_MEM_DELAY:
26         case UPIO_MEM:
27         case UPIO_MEM16:
28         case UPIO_MEM32:
29 @@ -2931,6 +2932,7 @@ int uart_match_port(struct uart_port *po
30         case UPIO_HUB6:
31                 return (port1->iobase == port2->iobase) &&
32                        (port1->hub6   == port2->hub6);
33 +       case UPIO_MEM_DELAY:
34         case UPIO_MEM:
35         case UPIO_MEM16:
36         case UPIO_MEM32:
37 --- a/include/linux/serial_8250.h
38 +++ b/include/linux/serial_8250.h
39 @@ -28,6 +28,7 @@ struct plat_serial8250_port {
40         void            *private_data;
41         unsigned char   regshift;       /* register shift */
42         unsigned char   iotype;         /* UPIO_* */
43 +       unsigned int rw_delay;  /* udelay for slower busses IXP4XX Expansion Bus */
44         unsigned char   hub6;
45         upf_t           flags;          /* UPF_* flags */
46         unsigned int    type;           /* If UPF_FIXED_TYPE */
47 --- a/include/linux/serial_core.h
48 +++ b/include/linux/serial_core.h
49 @@ -152,6 +152,7 @@ struct uart_port {
50  #define UPIO_TSI               (SERIAL_IO_TSI)         /* Tsi108/109 type IO */
51  #define UPIO_MEM32BE           (SERIAL_IO_MEM32BE)     /* 32b big endian */
52  #define UPIO_MEM16             (SERIAL_IO_MEM16)       /* 16b little endian */
53 +#define UPIO_MEM_DELAY         (SERIAL_IO_MEM_DELAY)
54  
55         unsigned int            read_status_mask;       /* driver specific */
56         unsigned int            ignore_status_mask;     /* driver specific */
57 @@ -233,6 +234,7 @@ struct uart_port {
58         int                     hw_stopped;             /* sw-assisted CTS flow state */
59         unsigned int            mctrl;                  /* current modem ctrl settings */
60         unsigned int            timeout;                /* character-based timeout */
61 +       unsigned int            rw_delay;               /* udelay for slow busses, IXP4XX Expansion Bus */
62         unsigned int            type;                   /* port type */
63         const struct uart_ops   *ops;
64         unsigned int            custom_divisor;
65 --- a/drivers/tty/serial/8250/8250_port.c
66 +++ b/drivers/tty/serial/8250/8250_port.c
67 @@ -383,6 +383,20 @@ static unsigned int mem16_serial_in(stru
68         return readw(p->membase + offset);
69  }
70  
71 +static unsigned int memdelay_serial_in(struct uart_port *p, int offset)
72 +{
73 +       struct uart_8250_port *up = (struct uart_8250_port *)p;
74 +       udelay(up->port.rw_delay);
75 +       return mem_serial_in(p, offset);
76 +}
77 +
78 +static void memdelay_serial_out(struct uart_port *p, int offset, int value)
79 +{
80 +       struct uart_8250_port *up = (struct uart_8250_port *)p;
81 +       udelay(up->port.rw_delay);
82 +       mem_serial_out(p, offset, value);
83 +}
84 +
85  static void mem32_serial_out(struct uart_port *p, int offset, int value)
86  {
87         offset = offset << p->regshift;
88 @@ -455,6 +469,11 @@ static void set_io_from_upio(struct uart
89                 p->serial_out = mem32be_serial_out;
90                 break;
91  
92 +       case UPIO_MEM_DELAY:
93 +               p->serial_in = memdelay_serial_in;
94 +               p->serial_out = memdelay_serial_out;
95 +               break;
96 +
97  #ifdef CONFIG_SERIAL_8250_RT288X
98         case UPIO_AU:
99                 p->serial_in = au_serial_in;
100 @@ -482,6 +501,7 @@ serial_port_out_sync(struct uart_port *p
101         case UPIO_MEM16:
102         case UPIO_MEM32:
103         case UPIO_MEM32BE:
104 +       case UPIO_MEM_DELAY:
105         case UPIO_AU:
106                 p->serial_out(p, offset, value);
107                 p->serial_in(p, UART_LCR);      /* safe, no side-effects */
108 @@ -2759,6 +2779,7 @@ static int serial8250_request_std_resour
109         case UPIO_MEM32BE:
110         case UPIO_MEM16:
111         case UPIO_MEM:
112 +       case UPIO_MEM_DELAY:
113                 if (!port->mapbase)
114                         break;
115  
116 @@ -2797,6 +2818,7 @@ static void serial8250_release_std_resou
117         case UPIO_MEM32BE:
118         case UPIO_MEM16:
119         case UPIO_MEM:
120 +       case UPIO_MEM_DELAY:
121                 if (!port->mapbase)
122                         break;
123  
124 --- a/include/uapi/linux/serial.h
125 +++ b/include/uapi/linux/serial.h
126 @@ -70,6 +70,7 @@ struct serial_struct {
127  #define SERIAL_IO_TSI    5
128  #define SERIAL_IO_MEM32BE 6
129  #define SERIAL_IO_MEM16        7
130 +#define SERIAL_IO_MEM_DELAY 10
131  
132  #define UART_CLEAR_FIFO                0x01
133  #define UART_USE_FIFO          0x02