diff options
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r-- | drivers/tty/serial/8250/8250.h | 7 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_core.c | 18 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_dw.c | 33 |
3 files changed, 35 insertions, 23 deletions
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 34eb676916fe..1ebf8538b4fa 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -117,13 +117,6 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value) | |||
117 | * is cleared, the machine locks up with endless interrupts. | 117 | * is cleared, the machine locks up with endless interrupts. |
118 | */ | 118 | */ |
119 | #define ALPHA_KLUDGE_MCR (UART_MCR_OUT2 | UART_MCR_OUT1) | 119 | #define ALPHA_KLUDGE_MCR (UART_MCR_OUT2 | UART_MCR_OUT1) |
120 | #elif defined(CONFIG_SBC8560) | ||
121 | /* | ||
122 | * WindRiver did something similarly broken on their SBC8560 board. The | ||
123 | * UART tristates its IRQ output while OUT2 is clear, but they pulled | ||
124 | * the interrupt line _up_ instead of down, so if we register the IRQ | ||
125 | * while the UART is in that state, we die in an IRQ storm. */ | ||
126 | #define ALPHA_KLUDGE_MCR (UART_MCR_OUT2) | ||
127 | #else | 120 | #else |
128 | #define ALPHA_KLUDGE_MCR 0 | 121 | #define ALPHA_KLUDGE_MCR 0 |
129 | #endif | 122 | #endif |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 35f9c96aada9..46528d57be72 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -2755,7 +2755,7 @@ static void __init serial8250_isa_init_ports(void) | |||
2755 | if (nr_uarts > UART_NR) | 2755 | if (nr_uarts > UART_NR) |
2756 | nr_uarts = UART_NR; | 2756 | nr_uarts = UART_NR; |
2757 | 2757 | ||
2758 | for (i = 0; i < nr_uarts; i++) { | 2758 | for (i = 0; i < UART_NR; i++) { |
2759 | struct uart_8250_port *up = &serial8250_ports[i]; | 2759 | struct uart_8250_port *up = &serial8250_ports[i]; |
2760 | struct uart_port *port = &up->port; | 2760 | struct uart_port *port = &up->port; |
2761 | 2761 | ||
@@ -2916,7 +2916,7 @@ static int __init serial8250_console_setup(struct console *co, char *options) | |||
2916 | * if so, search for the first available port that does have | 2916 | * if so, search for the first available port that does have |
2917 | * console support. | 2917 | * console support. |
2918 | */ | 2918 | */ |
2919 | if (co->index >= nr_uarts) | 2919 | if (co->index >= UART_NR) |
2920 | co->index = 0; | 2920 | co->index = 0; |
2921 | port = &serial8250_ports[co->index].port; | 2921 | port = &serial8250_ports[co->index].port; |
2922 | if (!port->iobase && !port->membase) | 2922 | if (!port->iobase && !port->membase) |
@@ -2957,7 +2957,7 @@ int serial8250_find_port(struct uart_port *p) | |||
2957 | int line; | 2957 | int line; |
2958 | struct uart_port *port; | 2958 | struct uart_port *port; |
2959 | 2959 | ||
2960 | for (line = 0; line < nr_uarts; line++) { | 2960 | for (line = 0; line < UART_NR; line++) { |
2961 | port = &serial8250_ports[line].port; | 2961 | port = &serial8250_ports[line].port; |
2962 | if (uart_match_port(p, port)) | 2962 | if (uart_match_port(p, port)) |
2963 | return line; | 2963 | return line; |
@@ -3110,7 +3110,7 @@ static int serial8250_remove(struct platform_device *dev) | |||
3110 | { | 3110 | { |
3111 | int i; | 3111 | int i; |
3112 | 3112 | ||
3113 | for (i = 0; i < nr_uarts; i++) { | 3113 | for (i = 0; i < UART_NR; i++) { |
3114 | struct uart_8250_port *up = &serial8250_ports[i]; | 3114 | struct uart_8250_port *up = &serial8250_ports[i]; |
3115 | 3115 | ||
3116 | if (up->port.dev == &dev->dev) | 3116 | if (up->port.dev == &dev->dev) |
@@ -3178,7 +3178,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3178 | /* | 3178 | /* |
3179 | * First, find a port entry which matches. | 3179 | * First, find a port entry which matches. |
3180 | */ | 3180 | */ |
3181 | for (i = 0; i < nr_uarts; i++) | 3181 | for (i = 0; i < UART_NR; i++) |
3182 | if (uart_match_port(&serial8250_ports[i].port, port)) | 3182 | if (uart_match_port(&serial8250_ports[i].port, port)) |
3183 | return &serial8250_ports[i]; | 3183 | return &serial8250_ports[i]; |
3184 | 3184 | ||
@@ -3187,7 +3187,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3187 | * free entry. We look for one which hasn't been previously | 3187 | * free entry. We look for one which hasn't been previously |
3188 | * used (indicated by zero iobase). | 3188 | * used (indicated by zero iobase). |
3189 | */ | 3189 | */ |
3190 | for (i = 0; i < nr_uarts; i++) | 3190 | for (i = 0; i < UART_NR; i++) |
3191 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && | 3191 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && |
3192 | serial8250_ports[i].port.iobase == 0) | 3192 | serial8250_ports[i].port.iobase == 0) |
3193 | return &serial8250_ports[i]; | 3193 | return &serial8250_ports[i]; |
@@ -3196,7 +3196,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3196 | * That also failed. Last resort is to find any entry which | 3196 | * That also failed. Last resort is to find any entry which |
3197 | * doesn't have a real port associated with it. | 3197 | * doesn't have a real port associated with it. |
3198 | */ | 3198 | */ |
3199 | for (i = 0; i < nr_uarts; i++) | 3199 | for (i = 0; i < UART_NR; i++) |
3200 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) | 3200 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) |
3201 | return &serial8250_ports[i]; | 3201 | return &serial8250_ports[i]; |
3202 | 3202 | ||
@@ -3247,6 +3247,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3247 | uart->tx_loadsz = up->tx_loadsz; | 3247 | uart->tx_loadsz = up->tx_loadsz; |
3248 | uart->capabilities = up->capabilities; | 3248 | uart->capabilities = up->capabilities; |
3249 | 3249 | ||
3250 | /* Take tx_loadsz from fifosize if it wasn't set separately */ | ||
3251 | if (uart->port.fifosize && !uart->tx_loadsz) | ||
3252 | uart->tx_loadsz = uart->port.fifosize; | ||
3253 | |||
3250 | if (up->port.dev) | 3254 | if (up->port.dev) |
3251 | uart->port.dev = up->port.dev; | 3255 | uart->port.dev = up->port.dev; |
3252 | 3256 | ||
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index db0e66f6dd0e..3dedd2470db1 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/acpi.h> | 28 | #include <linux/acpi.h> |
29 | #include <linux/clk.h> | ||
29 | 30 | ||
30 | #include "8250.h" | 31 | #include "8250.h" |
31 | 32 | ||
@@ -55,8 +56,9 @@ | |||
55 | 56 | ||
56 | 57 | ||
57 | struct dw8250_data { | 58 | struct dw8250_data { |
58 | int last_lcr; | 59 | int last_lcr; |
59 | int line; | 60 | int line; |
61 | struct clk *clk; | ||
60 | }; | 62 | }; |
61 | 63 | ||
62 | static void dw8250_serial_out(struct uart_port *p, int offset, int value) | 64 | static void dw8250_serial_out(struct uart_port *p, int offset, int value) |
@@ -136,8 +138,13 @@ static int dw8250_probe_of(struct uart_port *p) | |||
136 | if (!of_property_read_u32(np, "reg-shift", &val)) | 138 | if (!of_property_read_u32(np, "reg-shift", &val)) |
137 | p->regshift = val; | 139 | p->regshift = val; |
138 | 140 | ||
141 | /* clock got configured through clk api, all done */ | ||
142 | if (p->uartclk) | ||
143 | return 0; | ||
144 | |||
145 | /* try to find out clock frequency from DT as fallback */ | ||
139 | if (of_property_read_u32(np, "clock-frequency", &val)) { | 146 | if (of_property_read_u32(np, "clock-frequency", &val)) { |
140 | dev_err(p->dev, "no clock-frequency property set\n"); | 147 | dev_err(p->dev, "clk or clock-frequency not defined\n"); |
141 | return -EINVAL; | 148 | return -EINVAL; |
142 | } | 149 | } |
143 | p->uartclk = val; | 150 | p->uartclk = val; |
@@ -294,9 +301,20 @@ static int dw8250_probe(struct platform_device *pdev) | |||
294 | if (!uart.port.membase) | 301 | if (!uart.port.membase) |
295 | return -ENOMEM; | 302 | return -ENOMEM; |
296 | 303 | ||
304 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
305 | if (!data) | ||
306 | return -ENOMEM; | ||
307 | |||
308 | data->clk = devm_clk_get(&pdev->dev, NULL); | ||
309 | if (!IS_ERR(data->clk)) { | ||
310 | clk_prepare_enable(data->clk); | ||
311 | uart.port.uartclk = clk_get_rate(data->clk); | ||
312 | } | ||
313 | |||
297 | uart.port.iotype = UPIO_MEM; | 314 | uart.port.iotype = UPIO_MEM; |
298 | uart.port.serial_in = dw8250_serial_in; | 315 | uart.port.serial_in = dw8250_serial_in; |
299 | uart.port.serial_out = dw8250_serial_out; | 316 | uart.port.serial_out = dw8250_serial_out; |
317 | uart.port.private_data = data; | ||
300 | 318 | ||
301 | dw8250_setup_port(&uart); | 319 | dw8250_setup_port(&uart); |
302 | 320 | ||
@@ -312,12 +330,6 @@ static int dw8250_probe(struct platform_device *pdev) | |||
312 | return -ENODEV; | 330 | return -ENODEV; |
313 | } | 331 | } |
314 | 332 | ||
315 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
316 | if (!data) | ||
317 | return -ENOMEM; | ||
318 | |||
319 | uart.port.private_data = data; | ||
320 | |||
321 | data->line = serial8250_register_8250_port(&uart); | 333 | data->line = serial8250_register_8250_port(&uart); |
322 | if (data->line < 0) | 334 | if (data->line < 0) |
323 | return data->line; | 335 | return data->line; |
@@ -333,6 +345,9 @@ static int dw8250_remove(struct platform_device *pdev) | |||
333 | 345 | ||
334 | serial8250_unregister_port(data->line); | 346 | serial8250_unregister_port(data->line); |
335 | 347 | ||
348 | if (!IS_ERR(data->clk)) | ||
349 | clk_disable_unprepare(data->clk); | ||
350 | |||
336 | return 0; | 351 | return 0; |
337 | } | 352 | } |
338 | 353 | ||