aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>2018-07-21 07:49:05 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-08-02 04:08:43 -0400
commit14288befeb572b4d2155f3435dca5cdec799152c (patch)
tree8b38b1d382573f3c69b7183f8a5c55b1acf1f69a
parentda7bf20e7758042eb3931ff68fc96bdfaf94d881 (diff)
tty: serial: uartlite: Add clock adaptation
Add support of Common Clock Framework for Uartlite driver. Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/uartlite.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c
index 0f798f7837ad..b3a12be45801 100644
--- a/drivers/tty/serial/uartlite.c
+++ b/drivers/tty/serial/uartlite.c
@@ -21,6 +21,7 @@
21#include <linux/of_address.h> 21#include <linux/of_address.h>
22#include <linux/of_device.h> 22#include <linux/of_device.h>
23#include <linux/of_platform.h> 23#include <linux/of_platform.h>
24#include <linux/clk.h>
24 25
25#define ULITE_NAME "ttyUL" 26#define ULITE_NAME "ttyUL"
26#define ULITE_MAJOR 204 27#define ULITE_MAJOR 204
@@ -56,6 +57,7 @@
56 57
57struct uartlite_data { 58struct uartlite_data {
58 const struct uartlite_reg_ops *reg_ops; 59 const struct uartlite_reg_ops *reg_ops;
60 struct clk *clk;
59}; 61};
60 62
61struct uartlite_reg_ops { 63struct uartlite_reg_ops {
@@ -261,8 +263,15 @@ static void ulite_break_ctl(struct uart_port *port, int ctl)
261 263
262static int ulite_startup(struct uart_port *port) 264static int ulite_startup(struct uart_port *port)
263{ 265{
266 struct uartlite_data *pdata = port->private_data;
264 int ret; 267 int ret;
265 268
269 ret = clk_enable(pdata->clk);
270 if (ret) {
271 dev_err(port->dev, "Failed to enable clock\n");
272 return ret;
273 }
274
266 ret = request_irq(port->irq, ulite_isr, IRQF_SHARED | IRQF_TRIGGER_RISING, 275 ret = request_irq(port->irq, ulite_isr, IRQF_SHARED | IRQF_TRIGGER_RISING,
267 "uartlite", port); 276 "uartlite", port);
268 if (ret) 277 if (ret)
@@ -277,9 +286,12 @@ static int ulite_startup(struct uart_port *port)
277 286
278static void ulite_shutdown(struct uart_port *port) 287static void ulite_shutdown(struct uart_port *port)
279{ 288{
289 struct uartlite_data *pdata = port->private_data;
290
280 uart_out32(0, ULITE_CONTROL, port); 291 uart_out32(0, ULITE_CONTROL, port);
281 uart_in32(ULITE_CONTROL, port); /* dummy */ 292 uart_in32(ULITE_CONTROL, port); /* dummy */
282 free_irq(port->irq, port); 293 free_irq(port->irq, port);
294 clk_disable(pdata->clk);
283} 295}
284 296
285static void ulite_set_termios(struct uart_port *port, struct ktermios *termios, 297static void ulite_set_termios(struct uart_port *port, struct ktermios *termios,
@@ -370,6 +382,17 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
370 return -EINVAL; 382 return -EINVAL;
371} 383}
372 384
385static void ulite_pm(struct uart_port *port, unsigned int state,
386 unsigned int oldstate)
387{
388 struct uartlite_data *pdata = port->private_data;
389
390 if (!state)
391 clk_enable(pdata->clk);
392 else
393 clk_disable(pdata->clk);
394}
395
373#ifdef CONFIG_CONSOLE_POLL 396#ifdef CONFIG_CONSOLE_POLL
374static int ulite_get_poll_char(struct uart_port *port) 397static int ulite_get_poll_char(struct uart_port *port)
375{ 398{
@@ -405,6 +428,7 @@ static const struct uart_ops ulite_ops = {
405 .request_port = ulite_request_port, 428 .request_port = ulite_request_port,
406 .config_port = ulite_config_port, 429 .config_port = ulite_config_port,
407 .verify_port = ulite_verify_port, 430 .verify_port = ulite_verify_port,
431 .pm = ulite_pm,
408#ifdef CONFIG_CONSOLE_POLL 432#ifdef CONFIG_CONSOLE_POLL
409 .poll_get_char = ulite_get_poll_char, 433 .poll_get_char = ulite_get_poll_char,
410 .poll_put_char = ulite_put_poll_char, 434 .poll_put_char = ulite_put_poll_char,
@@ -669,7 +693,6 @@ static int ulite_release(struct device *dev)
669/* --------------------------------------------------------------------- 693/* ---------------------------------------------------------------------
670 * Platform bus binding 694 * Platform bus binding
671 */ 695 */
672
673#if defined(CONFIG_OF) 696#if defined(CONFIG_OF)
674/* Match table for of_platform binding */ 697/* Match table for of_platform binding */
675static const struct of_device_id ulite_of_match[] = { 698static const struct of_device_id ulite_of_match[] = {
@@ -684,7 +707,7 @@ static int ulite_probe(struct platform_device *pdev)
684{ 707{
685 struct resource *res; 708 struct resource *res;
686 struct uartlite_data *pdata; 709 struct uartlite_data *pdata;
687 int irq; 710 int irq, ret;
688 int id = pdev->id; 711 int id = pdev->id;
689#ifdef CONFIG_OF 712#ifdef CONFIG_OF
690 const __be32 *prop; 713 const __be32 *prop;
@@ -706,11 +729,33 @@ static int ulite_probe(struct platform_device *pdev)
706 if (irq <= 0) 729 if (irq <= 0)
707 return -ENXIO; 730 return -ENXIO;
708 731
732 pdata->clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
733 if (IS_ERR(pdata->clk)) {
734 if (PTR_ERR(pdata->clk) != -ENOENT)
735 return PTR_ERR(pdata->clk);
736
737 /*
738 * Clock framework support is optional, continue on
739 * anyways if we don't find a matching clock.
740 */
741 pdata->clk = NULL;
742 }
743
744 ret = clk_prepare(pdata->clk);
745 if (ret) {
746 dev_err(&pdev->dev, "Failed to prepare clock\n");
747 return ret;
748 }
749
709 return ulite_assign(&pdev->dev, id, res->start, irq, pdata); 750 return ulite_assign(&pdev->dev, id, res->start, irq, pdata);
710} 751}
711 752
712static int ulite_remove(struct platform_device *pdev) 753static int ulite_remove(struct platform_device *pdev)
713{ 754{
755 struct uart_port *port = dev_get_drvdata(&pdev->dev);
756 struct uartlite_data *pdata = port->private_data;
757
758 clk_disable_unprepare(pdata->clk);
714 return ulite_release(&pdev->dev); 759 return ulite_release(&pdev->dev);
715} 760}
716 761