Skip to content

Commit

Permalink
serial/efm32: parse location property
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Uwe Kleine-König authored and Greg Kroah-Hartman committed Jan 21, 2013
1 parent 2326669 commit c098020
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
6 changes: 6 additions & 0 deletions Documentation/devicetree/bindings/tty/serial/efm32-uart.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ Required properties:
- reg : Address and length of the register set
- interrupts : Should contain uart interrupt

Optional properties:
- location : Decides the location of the USART I/O pins.
Allowed range : [0 .. 5]
Default: 0

Example:

uart@0x4000c400 {
compatible = "efm32,uart";
reg = <0x4000c400 0x400>;
interrupts = <15>;
location = <0>;
};
31 changes: 24 additions & 7 deletions drivers/tty/serial/efm32-uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct efm32_uart_port {
struct uart_port port;
unsigned int txirq;
struct clk *clk;
struct efm32_uart_pdata pdata;
};
#define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port)
#define efm_debug(efm_port, format, arg...) \
Expand Down Expand Up @@ -293,13 +294,8 @@ static irqreturn_t efm32_uart_txirq(int irq, void *data)
static int efm32_uart_startup(struct uart_port *port)
{
struct efm32_uart_port *efm_port = to_efm_port(port);
u32 location = 0;
struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev);
int ret;

if (pdata)
location = UARTn_ROUTE_LOCATION(pdata->location);

ret = clk_enable(efm_port->clk);
if (ret) {
efm_debug(efm_port, "failed to enable clk\n");
Expand All @@ -308,7 +304,9 @@ static int efm32_uart_startup(struct uart_port *port)
port->uartclk = clk_get_rate(efm_port->clk);

/* Enable pins at configured location */
efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN,
efm32_uart_write32(efm_port,
UARTn_ROUTE_LOCATION(efm_port->pdata.location) |
UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN,
UARTn_ROUTE);

ret = request_irq(port->irq, efm32_uart_rxirq, 0,
Expand Down Expand Up @@ -667,11 +665,24 @@ static int efm32_uart_probe_dt(struct platform_device *pdev,
struct efm32_uart_port *efm_port)
{
struct device_node *np = pdev->dev.of_node;
u32 location;
int ret;

if (!np)
return 1;

ret = of_property_read_u32(np, "location", &location);
if (!ret) {
if (location > 5) {
dev_err(&pdev->dev, "invalid location\n");
return -EINVAL;
}
efm_debug(efm_port, "using location %u\n", location);
efm_port->pdata.location = location;
} else {
efm_debug(efm_port, "fall back to location 0\n");
}

ret = of_alias_get_id(np, "serial");
if (ret < 0) {
dev_err(&pdev->dev, "failed to get alias id: %d\n", ret);
Expand Down Expand Up @@ -731,10 +742,16 @@ static int efm32_uart_probe(struct platform_device *pdev)
efm_port->port.flags = UPF_BOOT_AUTOCONF;

ret = efm32_uart_probe_dt(pdev, efm_port);
if (ret > 0)
if (ret > 0) {
/* not created by device tree */
const struct efm32_uart_pdata *pdata = dev_get_platdata(&pdev->dev);

efm_port->port.line = pdev->id;

if (pdata)
efm_port->pdata = *pdata;
}

if (efm_port->port.line >= 0 &&
efm_port->port.line < ARRAY_SIZE(efm32_uart_ports))
efm32_uart_ports[efm_port->port.line] = efm_port;
Expand Down

0 comments on commit c098020

Please sign in to comment.