Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Uwe Kleine-König and committed by
Greg Kroah-Hartman
c098020d 2326669c

+30 -7
+6
Documentation/devicetree/bindings/tty/serial/efm32-uart.txt
··· 5 5 - reg : Address and length of the register set 6 6 - interrupts : Should contain uart interrupt 7 7 8 + Optional properties: 9 + - location : Decides the location of the USART I/O pins. 10 + Allowed range : [0 .. 5] 11 + Default: 0 12 + 8 13 Example: 9 14 10 15 uart@0x4000c400 { 11 16 compatible = "efm32,uart"; 12 17 reg = <0x4000c400 0x400>; 13 18 interrupts = <15>; 19 + location = <0>; 14 20 };
+24 -7
drivers/tty/serial/efm32-uart.c
··· 81 81 struct uart_port port; 82 82 unsigned int txirq; 83 83 struct clk *clk; 84 + struct efm32_uart_pdata pdata; 84 85 }; 85 86 #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) 86 87 #define efm_debug(efm_port, format, arg...) \ ··· 294 293 static int efm32_uart_startup(struct uart_port *port) 295 294 { 296 295 struct efm32_uart_port *efm_port = to_efm_port(port); 297 - u32 location = 0; 298 - struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); 299 296 int ret; 300 - 301 - if (pdata) 302 - location = UARTn_ROUTE_LOCATION(pdata->location); 303 297 304 298 ret = clk_enable(efm_port->clk); 305 299 if (ret) { ··· 304 308 port->uartclk = clk_get_rate(efm_port->clk); 305 309 306 310 /* Enable pins at configured location */ 307 - efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, 311 + efm32_uart_write32(efm_port, 312 + UARTn_ROUTE_LOCATION(efm_port->pdata.location) | 313 + UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, 308 314 UARTn_ROUTE); 309 315 310 316 ret = request_irq(port->irq, efm32_uart_rxirq, 0, ··· 665 667 struct efm32_uart_port *efm_port) 666 668 { 667 669 struct device_node *np = pdev->dev.of_node; 670 + u32 location; 668 671 int ret; 669 672 670 673 if (!np) 671 674 return 1; 675 + 676 + ret = of_property_read_u32(np, "location", &location); 677 + if (!ret) { 678 + if (location > 5) { 679 + dev_err(&pdev->dev, "invalid location\n"); 680 + return -EINVAL; 681 + } 682 + efm_debug(efm_port, "using location %u\n", location); 683 + efm_port->pdata.location = location; 684 + } else { 685 + efm_debug(efm_port, "fall back to location 0\n"); 686 + } 672 687 673 688 ret = of_alias_get_id(np, "serial"); 674 689 if (ret < 0) { ··· 742 731 efm_port->port.flags = UPF_BOOT_AUTOCONF; 743 732 744 733 ret = efm32_uart_probe_dt(pdev, efm_port); 745 - if (ret > 0) 734 + if (ret > 0) { 746 735 /* not created by device tree */ 736 + const struct efm32_uart_pdata *pdata = dev_get_platdata(&pdev->dev); 737 + 747 738 efm_port->port.line = pdev->id; 739 + 740 + if (pdata) 741 + efm_port->pdata = *pdata; 742 + } 748 743 749 744 if (efm_port->port.line >= 0 && 750 745 efm_port->port.line < ARRAY_SIZE(efm32_uart_ports))