diff options
Diffstat (limited to 'drivers/tty/serial/amba-pl011.c')
| -rw-r--r-- | drivers/tty/serial/amba-pl011.c | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 4ad721fb8405..c17923ec6e95 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
| @@ -133,6 +133,10 @@ struct pl011_dmatx_data { | |||
| 133 | struct uart_amba_port { | 133 | struct uart_amba_port { |
| 134 | struct uart_port port; | 134 | struct uart_port port; |
| 135 | struct clk *clk; | 135 | struct clk *clk; |
| 136 | /* Two optional pin states - default & sleep */ | ||
| 137 | struct pinctrl *pinctrl; | ||
| 138 | struct pinctrl_state *pins_default; | ||
| 139 | struct pinctrl_state *pins_sleep; | ||
| 136 | const struct vendor_data *vendor; | 140 | const struct vendor_data *vendor; |
| 137 | unsigned int dmacr; /* dma control reg */ | 141 | unsigned int dmacr; /* dma control reg */ |
| 138 | unsigned int im; /* interrupt mask */ | 142 | unsigned int im; /* interrupt mask */ |
| @@ -1312,6 +1316,14 @@ static int pl011_startup(struct uart_port *port) | |||
| 1312 | unsigned int cr; | 1316 | unsigned int cr; |
| 1313 | int retval; | 1317 | int retval; |
| 1314 | 1318 | ||
| 1319 | /* Optionaly enable pins to be muxed in and configured */ | ||
| 1320 | if (!IS_ERR(uap->pins_default)) { | ||
| 1321 | retval = pinctrl_select_state(uap->pinctrl, uap->pins_default); | ||
| 1322 | if (retval) | ||
| 1323 | dev_err(port->dev, | ||
| 1324 | "could not set default pins\n"); | ||
| 1325 | } | ||
| 1326 | |||
| 1315 | retval = clk_prepare(uap->clk); | 1327 | retval = clk_prepare(uap->clk); |
| 1316 | if (retval) | 1328 | if (retval) |
| 1317 | goto out; | 1329 | goto out; |
| @@ -1420,6 +1432,7 @@ static void pl011_shutdown(struct uart_port *port) | |||
| 1420 | { | 1432 | { |
| 1421 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1433 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| 1422 | unsigned int cr; | 1434 | unsigned int cr; |
| 1435 | int retval; | ||
| 1423 | 1436 | ||
| 1424 | /* | 1437 | /* |
| 1425 | * disable all interrupts | 1438 | * disable all interrupts |
| @@ -1462,6 +1475,14 @@ static void pl011_shutdown(struct uart_port *port) | |||
| 1462 | */ | 1475 | */ |
| 1463 | clk_disable(uap->clk); | 1476 | clk_disable(uap->clk); |
| 1464 | clk_unprepare(uap->clk); | 1477 | clk_unprepare(uap->clk); |
| 1478 | /* Optionally let pins go into sleep states */ | ||
| 1479 | if (!IS_ERR(uap->pins_sleep)) { | ||
| 1480 | retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); | ||
| 1481 | if (retval) | ||
| 1482 | dev_err(port->dev, | ||
| 1483 | "could not set pins to sleep state\n"); | ||
| 1484 | } | ||
| 1485 | |||
| 1465 | 1486 | ||
| 1466 | if (uap->port.dev->platform_data) { | 1487 | if (uap->port.dev->platform_data) { |
| 1467 | struct amba_pl011_data *plat; | 1488 | struct amba_pl011_data *plat; |
| @@ -1792,6 +1813,14 @@ static int __init pl011_console_setup(struct console *co, char *options) | |||
| 1792 | if (!uap) | 1813 | if (!uap) |
| 1793 | return -ENODEV; | 1814 | return -ENODEV; |
| 1794 | 1815 | ||
| 1816 | /* Allow pins to be muxed in and configured */ | ||
| 1817 | if (!IS_ERR(uap->pins_default)) { | ||
| 1818 | ret = pinctrl_select_state(uap->pinctrl, uap->pins_default); | ||
| 1819 | if (ret) | ||
| 1820 | dev_err(uap->port.dev, | ||
| 1821 | "could not set default pins\n"); | ||
| 1822 | } | ||
| 1823 | |||
| 1795 | ret = clk_prepare(uap->clk); | 1824 | ret = clk_prepare(uap->clk); |
| 1796 | if (ret) | 1825 | if (ret) |
| 1797 | return ret; | 1826 | return ret; |
| @@ -1844,7 +1873,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
| 1844 | { | 1873 | { |
| 1845 | struct uart_amba_port *uap; | 1874 | struct uart_amba_port *uap; |
| 1846 | struct vendor_data *vendor = id->data; | 1875 | struct vendor_data *vendor = id->data; |
| 1847 | struct pinctrl *pinctrl; | ||
| 1848 | void __iomem *base; | 1876 | void __iomem *base; |
| 1849 | int i, ret; | 1877 | int i, ret; |
| 1850 | 1878 | ||
| @@ -1869,11 +1897,20 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
| 1869 | goto free; | 1897 | goto free; |
| 1870 | } | 1898 | } |
| 1871 | 1899 | ||
| 1872 | pinctrl = devm_pinctrl_get_select_default(&dev->dev); | 1900 | uap->pinctrl = devm_pinctrl_get(&dev->dev); |
| 1873 | if (IS_ERR(pinctrl)) { | 1901 | if (IS_ERR(uap->pinctrl)) { |
| 1874 | ret = PTR_ERR(pinctrl); | 1902 | ret = PTR_ERR(uap->pinctrl); |
| 1875 | goto unmap; | 1903 | goto unmap; |
| 1876 | } | 1904 | } |
| 1905 | uap->pins_default = pinctrl_lookup_state(uap->pinctrl, | ||
| 1906 | PINCTRL_STATE_DEFAULT); | ||
| 1907 | if (IS_ERR(uap->pins_default)) | ||
| 1908 | dev_err(&dev->dev, "could not get default pinstate\n"); | ||
| 1909 | |||
| 1910 | uap->pins_sleep = pinctrl_lookup_state(uap->pinctrl, | ||
| 1911 | PINCTRL_STATE_SLEEP); | ||
| 1912 | if (IS_ERR(uap->pins_sleep)) | ||
| 1913 | dev_dbg(&dev->dev, "could not get sleep pinstate\n"); | ||
| 1877 | 1914 | ||
| 1878 | uap->clk = clk_get(&dev->dev, NULL); | 1915 | uap->clk = clk_get(&dev->dev, NULL); |
| 1879 | if (IS_ERR(uap->clk)) { | 1916 | if (IS_ERR(uap->clk)) { |
