aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/8250/8250_dw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/8250/8250_dw.c')
-rw-r--r--drivers/tty/serial/8250/8250_dw.c33
1 files changed, 24 insertions, 9 deletions
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
57struct dw8250_data { 58struct dw8250_data {
58 int last_lcr; 59 int last_lcr;
59 int line; 60 int line;
61 struct clk *clk;
60}; 62};
61 63
62static void dw8250_serial_out(struct uart_port *p, int offset, int value) 64static 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