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>
This commit is contained in:
parent
2326669ccb
commit
c098020d03
|
@ -5,10 +5,16 @@ Required properties:
|
||||||
- reg : Address and length of the register set
|
- reg : Address and length of the register set
|
||||||
- interrupts : Should contain uart interrupt
|
- interrupts : Should contain uart interrupt
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- location : Decides the location of the USART I/O pins.
|
||||||
|
Allowed range : [0 .. 5]
|
||||||
|
Default: 0
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
uart@0x4000c400 {
|
uart@0x4000c400 {
|
||||||
compatible = "efm32,uart";
|
compatible = "efm32,uart";
|
||||||
reg = <0x4000c400 0x400>;
|
reg = <0x4000c400 0x400>;
|
||||||
interrupts = <15>;
|
interrupts = <15>;
|
||||||
|
location = <0>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct efm32_uart_port {
|
||||||
struct uart_port port;
|
struct uart_port port;
|
||||||
unsigned int txirq;
|
unsigned int txirq;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
struct efm32_uart_pdata pdata;
|
||||||
};
|
};
|
||||||
#define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port)
|
#define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port)
|
||||||
#define efm_debug(efm_port, format, arg...) \
|
#define efm_debug(efm_port, format, arg...) \
|
||||||
|
@ -293,13 +294,8 @@ static irqreturn_t efm32_uart_txirq(int irq, void *data)
|
||||||
static int efm32_uart_startup(struct uart_port *port)
|
static int efm32_uart_startup(struct uart_port *port)
|
||||||
{
|
{
|
||||||
struct efm32_uart_port *efm_port = to_efm_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;
|
int ret;
|
||||||
|
|
||||||
if (pdata)
|
|
||||||
location = UARTn_ROUTE_LOCATION(pdata->location);
|
|
||||||
|
|
||||||
ret = clk_enable(efm_port->clk);
|
ret = clk_enable(efm_port->clk);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
efm_debug(efm_port, "failed to enable clk\n");
|
efm_debug(efm_port, "failed to enable clk\n");
|
||||||
|
@ -308,7 +304,9 @@ static int efm32_uart_startup(struct uart_port *port)
|
||||||
port->uartclk = clk_get_rate(efm_port->clk);
|
port->uartclk = clk_get_rate(efm_port->clk);
|
||||||
|
|
||||||
/* Enable pins at configured location */
|
/* 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);
|
UARTn_ROUTE);
|
||||||
|
|
||||||
ret = request_irq(port->irq, efm32_uart_rxirq, 0,
|
ret = request_irq(port->irq, efm32_uart_rxirq, 0,
|
||||||
|
@ -667,11 +665,24 @@ static int efm32_uart_probe_dt(struct platform_device *pdev,
|
||||||
struct efm32_uart_port *efm_port)
|
struct efm32_uart_port *efm_port)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
u32 location;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!np)
|
if (!np)
|
||||||
return 1;
|
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");
|
ret = of_alias_get_id(np, "serial");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&pdev->dev, "failed to get alias id: %d\n", ret);
|
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)
|
||||||
efm_port->port.flags = UPF_BOOT_AUTOCONF;
|
efm_port->port.flags = UPF_BOOT_AUTOCONF;
|
||||||
|
|
||||||
ret = efm32_uart_probe_dt(pdev, efm_port);
|
ret = efm32_uart_probe_dt(pdev, efm_port);
|
||||||
if (ret > 0)
|
if (ret > 0) {
|
||||||
/* not created by device tree */
|
/* not created by device tree */
|
||||||
|
const struct efm32_uart_pdata *pdata = dev_get_platdata(&pdev->dev);
|
||||||
|
|
||||||
efm_port->port.line = pdev->id;
|
efm_port->port.line = pdev->id;
|
||||||
|
|
||||||
|
if (pdata)
|
||||||
|
efm_port->pdata = *pdata;
|
||||||
|
}
|
||||||
|
|
||||||
if (efm_port->port.line >= 0 &&
|
if (efm_port->port.line >= 0 &&
|
||||||
efm_port->port.line < ARRAY_SIZE(efm32_uart_ports))
|
efm_port->port.line < ARRAY_SIZE(efm32_uart_ports))
|
||||||
efm32_uart_ports[efm_port->port.line] = efm_port;
|
efm32_uart_ports[efm_port->port.line] = efm_port;
|
||||||
|
|
Loading…
Reference in New Issue