aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/xilinx_uartps.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/xilinx_uartps.c')
-rw-r--r--drivers/tty/serial/xilinx_uartps.c50
1 files changed, 23 insertions, 27 deletions
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 9ab910370c56..ba451c7209fc 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -17,6 +17,7 @@
17#include <linux/tty.h> 17#include <linux/tty.h>
18#include <linux/tty_flip.h> 18#include <linux/tty_flip.h>
19#include <linux/console.h> 19#include <linux/console.h>
20#include <linux/clk.h>
20#include <linux/irq.h> 21#include <linux/irq.h>
21#include <linux/io.h> 22#include <linux/io.h>
22#include <linux/of.h> 23#include <linux/of.h>
@@ -147,15 +148,11 @@
147static irqreturn_t xuartps_isr(int irq, void *dev_id) 148static irqreturn_t xuartps_isr(int irq, void *dev_id)
148{ 149{
149 struct uart_port *port = (struct uart_port *)dev_id; 150 struct uart_port *port = (struct uart_port *)dev_id;
150 struct tty_struct *tty;
151 unsigned long flags; 151 unsigned long flags;
152 unsigned int isrstatus, numbytes; 152 unsigned int isrstatus, numbytes;
153 unsigned int data; 153 unsigned int data;
154 char status = TTY_NORMAL; 154 char status = TTY_NORMAL;
155 155
156 /* Get the tty which could be NULL so don't assume it's valid */
157 tty = tty_port_tty_get(&port->state->port);
158
159 spin_lock_irqsave(&port->lock, flags); 156 spin_lock_irqsave(&port->lock, flags);
160 157
161 /* Read the interrupt status register to determine which 158 /* Read the interrupt status register to determine which
@@ -187,14 +184,11 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
187 } else if (isrstatus & XUARTPS_IXR_OVERRUN) 184 } else if (isrstatus & XUARTPS_IXR_OVERRUN)
188 port->icount.overrun++; 185 port->icount.overrun++;
189 186
190 if (tty) 187 uart_insert_char(port, isrstatus, XUARTPS_IXR_OVERRUN,
191 uart_insert_char(port, isrstatus, 188 data, status);
192 XUARTPS_IXR_OVERRUN, data,
193 status);
194 } 189 }
195 spin_unlock(&port->lock); 190 spin_unlock(&port->lock);
196 if (tty) 191 tty_flip_buffer_push(&port->state->port);
197 tty_flip_buffer_push(tty);
198 spin_lock(&port->lock); 192 spin_lock(&port->lock);
199 } 193 }
200 194
@@ -237,7 +231,6 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
237 231
238 /* be sure to release the lock and tty before leaving */ 232 /* be sure to release the lock and tty before leaving */
239 spin_unlock_irqrestore(&port->lock, flags); 233 spin_unlock_irqrestore(&port->lock, flags);
240 tty_kref_put(tty);
241 234
242 return IRQ_HANDLED; 235 return IRQ_HANDLED;
243} 236}
@@ -944,16 +937,18 @@ static int xuartps_probe(struct platform_device *pdev)
944 int rc; 937 int rc;
945 struct uart_port *port; 938 struct uart_port *port;
946 struct resource *res, *res2; 939 struct resource *res, *res2;
947 int clk = 0; 940 struct clk *clk;
948
949 const unsigned int *prop;
950 941
951 prop = of_get_property(pdev->dev.of_node, "clock", NULL); 942 clk = of_clk_get(pdev->dev.of_node, 0);
952 if (prop) 943 if (IS_ERR(clk)) {
953 clk = be32_to_cpup(prop);
954 if (!clk) {
955 dev_err(&pdev->dev, "no clock specified\n"); 944 dev_err(&pdev->dev, "no clock specified\n");
956 return -ENODEV; 945 return PTR_ERR(clk);
946 }
947
948 rc = clk_prepare_enable(clk);
949 if (rc) {
950 dev_err(&pdev->dev, "could not enable clock\n");
951 return -EBUSY;
957 } 952 }
958 953
959 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 954 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -978,7 +973,8 @@ static int xuartps_probe(struct platform_device *pdev)
978 port->mapbase = res->start; 973 port->mapbase = res->start;
979 port->irq = res2->start; 974 port->irq = res2->start;
980 port->dev = &pdev->dev; 975 port->dev = &pdev->dev;
981 port->uartclk = clk; 976 port->uartclk = clk_get_rate(clk);
977 port->private_data = clk;
982 dev_set_drvdata(&pdev->dev, port); 978 dev_set_drvdata(&pdev->dev, port);
983 rc = uart_add_one_port(&xuartps_uart_driver, port); 979 rc = uart_add_one_port(&xuartps_uart_driver, port);
984 if (rc) { 980 if (rc) {
@@ -1000,14 +996,14 @@ static int xuartps_probe(struct platform_device *pdev)
1000static int xuartps_remove(struct platform_device *pdev) 996static int xuartps_remove(struct platform_device *pdev)
1001{ 997{
1002 struct uart_port *port = dev_get_drvdata(&pdev->dev); 998 struct uart_port *port = dev_get_drvdata(&pdev->dev);
1003 int rc = 0; 999 struct clk *clk = port->private_data;
1000 int rc;
1004 1001
1005 /* Remove the xuartps port from the serial core */ 1002 /* Remove the xuartps port from the serial core */
1006 if (port) { 1003 rc = uart_remove_one_port(&xuartps_uart_driver, port);
1007 rc = uart_remove_one_port(&xuartps_uart_driver, port); 1004 dev_set_drvdata(&pdev->dev, NULL);
1008 dev_set_drvdata(&pdev->dev, NULL); 1005 port->mapbase = 0;
1009 port->mapbase = 0; 1006 clk_disable_unprepare(clk);
1010 }
1011 return rc; 1007 return rc;
1012} 1008}
1013 1009
@@ -1048,7 +1044,7 @@ MODULE_DEVICE_TABLE(of, xuartps_of_match);
1048 1044
1049static struct platform_driver xuartps_platform_driver = { 1045static struct platform_driver xuartps_platform_driver = {
1050 .probe = xuartps_probe, /* Probe method */ 1046 .probe = xuartps_probe, /* Probe method */
1051 .remove = __exit_p(xuartps_remove), /* Detach method */ 1047 .remove = xuartps_remove, /* Detach method */
1052 .suspend = xuartps_suspend, /* Suspend */ 1048 .suspend = xuartps_suspend, /* Suspend */
1053 .resume = xuartps_resume, /* Resume after a suspend */ 1049 .resume = xuartps_resume, /* Resume after a suspend */
1054 .driver = { 1050 .driver = {