diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/Kconfig | 2 | ||||
-rw-r--r-- | drivers/tty/serial/ar933x_uart.c | 35 |
2 files changed, 27 insertions, 10 deletions
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index f136248..3c598e3 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1402,7 +1402,7 @@ config SERIAL_XILINX_PS_UART_CONSOLE config SERIAL_AR933X bool "AR933X serial port support" - depends on SOC_AR933X + depends on HAVE_CLK && SOC_AR933X select SERIAL_CORE help If you have an Atheros AR933X SOC based board and want to use the diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 78be13a..1052ee0 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -24,11 +24,11 @@ #include <linux/slab.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/clk.h> #include <asm/div64.h> #include <asm/mach-ath79/ar933x_uart.h> -#include <asm/mach-ath79/ar933x_uart_platform.h> #define DRIVER_NAME "ar933x-uart" @@ -47,6 +47,7 @@ struct ar933x_uart_port { unsigned int ier; /* shadow Interrupt Enable Register */ unsigned int min_baud; unsigned int max_baud; + struct clk *clk; }; static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, @@ -622,7 +623,6 @@ static struct uart_driver ar933x_uart_driver = { static int ar933x_uart_probe(struct platform_device *pdev) { - struct ar933x_uart_platform_data *pdata; struct ar933x_uart_port *up; struct uart_port *port; struct resource *mem_res; @@ -631,10 +631,6 @@ static int ar933x_uart_probe(struct platform_device *pdev) int id; int ret; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) - return -EINVAL; - id = pdev->id; if (id == -1) id = 0; @@ -653,6 +649,12 @@ static int ar933x_uart_probe(struct platform_device *pdev) if (!up) return -ENOMEM; + up->clk = devm_clk_get(&pdev->dev, "uart"); + if (IS_ERR(up->clk)) { + dev_err(&pdev->dev, "unable to get UART clock\n"); + return PTR_ERR(up->clk); + } + port = &up->port; mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -660,13 +662,22 @@ static int ar933x_uart_probe(struct platform_device *pdev) if (IS_ERR(port->membase)) return PTR_ERR(port->membase); + ret = clk_prepare_enable(up->clk); + if (ret) + return ret; + + port->uartclk = clk_get_rate(up->clk); + if (!port->uartclk) { + ret = -EINVAL; + goto err_disable_clk; + } + port->mapbase = mem_res->start; port->line = id; port->irq = irq_res->start; port->dev = &pdev->dev; port->type = PORT_AR933X; port->iotype = UPIO_MEM32; - port->uartclk = pdata->uartclk; port->regshift = 2; port->fifosize = AR933X_UART_FIFO_SIZE; @@ -682,10 +693,14 @@ static int ar933x_uart_probe(struct platform_device *pdev) ret = uart_add_one_port(&ar933x_uart_driver, &up->port); if (ret) - return ret; + goto err_disable_clk; platform_set_drvdata(pdev, up); return 0; + +err_disable_clk: + clk_disable_unprepare(up->clk); + return ret; } static int ar933x_uart_remove(struct platform_device *pdev) @@ -694,8 +709,10 @@ static int ar933x_uart_remove(struct platform_device *pdev) up = platform_get_drvdata(pdev); - if (up) + if (up) { uart_remove_one_port(&ar933x_uart_driver, &up->port); + clk_disable_unprepare(up->clk); + } return 0; } |