diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2013-01-21 08:22:56 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-21 16:56:46 -0500 |
commit | c098020d0368ded1c6ba8d7b612feffe067509a6 (patch) | |
tree | 0e7c3ee24e378feb4eaccb955aa7e8f66f76a048 /drivers/tty/serial | |
parent | 2326669ccbd901dffeefb66ed742c294b2e8041b (diff) |
serial/efm32: parse location property
The non-dt probing allowed passing the location via platform data from
the beginning. So make up leeway for device tree probing.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/efm32-uart.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index de14bd7dce10..7d199c8e1a75 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c | |||
@@ -81,6 +81,7 @@ struct efm32_uart_port { | |||
81 | struct uart_port port; | 81 | struct uart_port port; |
82 | unsigned int txirq; | 82 | unsigned int txirq; |
83 | struct clk *clk; | 83 | struct clk *clk; |
84 | struct efm32_uart_pdata pdata; | ||
84 | }; | 85 | }; |
85 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) | 86 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) |
86 | #define efm_debug(efm_port, format, arg...) \ | 87 | #define efm_debug(efm_port, format, arg...) \ |
@@ -293,13 +294,8 @@ static irqreturn_t efm32_uart_txirq(int irq, void *data) | |||
293 | static int efm32_uart_startup(struct uart_port *port) | 294 | static int efm32_uart_startup(struct uart_port *port) |
294 | { | 295 | { |
295 | struct efm32_uart_port *efm_port = to_efm_port(port); | 296 | struct efm32_uart_port *efm_port = to_efm_port(port); |
296 | u32 location = 0; | ||
297 | struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); | ||
298 | int ret; | 297 | int ret; |
299 | 298 | ||
300 | if (pdata) | ||
301 | location = UARTn_ROUTE_LOCATION(pdata->location); | ||
302 | |||
303 | ret = clk_enable(efm_port->clk); | 299 | ret = clk_enable(efm_port->clk); |
304 | if (ret) { | 300 | if (ret) { |
305 | efm_debug(efm_port, "failed to enable clk\n"); | 301 | efm_debug(efm_port, "failed to enable clk\n"); |
@@ -308,7 +304,9 @@ static int efm32_uart_startup(struct uart_port *port) | |||
308 | port->uartclk = clk_get_rate(efm_port->clk); | 304 | port->uartclk = clk_get_rate(efm_port->clk); |
309 | 305 | ||
310 | /* Enable pins at configured location */ | 306 | /* Enable pins at configured location */ |
311 | efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | 307 | efm32_uart_write32(efm_port, |
308 | UARTn_ROUTE_LOCATION(efm_port->pdata.location) | | ||
309 | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | ||
312 | UARTn_ROUTE); | 310 | UARTn_ROUTE); |
313 | 311 | ||
314 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, | 312 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, |
@@ -667,11 +665,24 @@ static int efm32_uart_probe_dt(struct platform_device *pdev, | |||
667 | struct efm32_uart_port *efm_port) | 665 | struct efm32_uart_port *efm_port) |
668 | { | 666 | { |
669 | struct device_node *np = pdev->dev.of_node; | 667 | struct device_node *np = pdev->dev.of_node; |
668 | u32 location; | ||
670 | int ret; | 669 | int ret; |
671 | 670 | ||
672 | if (!np) | 671 | if (!np) |
673 | return 1; | 672 | return 1; |
674 | 673 | ||
674 | ret = of_property_read_u32(np, "location", &location); | ||
675 | if (!ret) { | ||
676 | if (location > 5) { | ||
677 | dev_err(&pdev->dev, "invalid location\n"); | ||
678 | return -EINVAL; | ||
679 | } | ||
680 | efm_debug(efm_port, "using location %u\n", location); | ||
681 | efm_port->pdata.location = location; | ||
682 | } else { | ||
683 | efm_debug(efm_port, "fall back to location 0\n"); | ||
684 | } | ||
685 | |||
675 | ret = of_alias_get_id(np, "serial"); | 686 | ret = of_alias_get_id(np, "serial"); |
676 | if (ret < 0) { | 687 | if (ret < 0) { |
677 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); | 688 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); |
@@ -731,10 +742,16 @@ static int efm32_uart_probe(struct platform_device *pdev) | |||
731 | efm_port->port.flags = UPF_BOOT_AUTOCONF; | 742 | efm_port->port.flags = UPF_BOOT_AUTOCONF; |
732 | 743 | ||
733 | ret = efm32_uart_probe_dt(pdev, efm_port); | 744 | ret = efm32_uart_probe_dt(pdev, efm_port); |
734 | if (ret > 0) | 745 | if (ret > 0) { |
735 | /* not created by device tree */ | 746 | /* not created by device tree */ |
747 | const struct efm32_uart_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
748 | |||
736 | efm_port->port.line = pdev->id; | 749 | efm_port->port.line = pdev->id; |
737 | 750 | ||
751 | if (pdata) | ||
752 | efm_port->pdata = *pdata; | ||
753 | } | ||
754 | |||
738 | if (efm_port->port.line >= 0 && | 755 | if (efm_port->port.line >= 0 && |
739 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) | 756 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) |
740 | efm32_uart_ports[efm_port->port.line] = efm_port; | 757 | efm32_uart_ports[efm_port->port.line] = efm_port; |