From 7c8ab967e3cd1513cd79fd5edc404fb43c7f3a96 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Thu, 16 Oct 2014 16:54:20 -0400 Subject: serial: Fix locking for uart driver set_termios() method The low-level uart driver may modify termios settings to override settings that are not compatible with the uart, such as CRTSCTS. Thus, callers of the low-level uart driver's set_termios() method must hold termios_rwsem write lock to prevent concurrent access to termios, in case such override occurs. The termios_rwsem lock requirement does not extend to console setup (ie., uart_set_options), as console setup cannot race with tty operations. Nor does this lock requirement extend to functions which cannot be concurrent with tty ioctls (ie., uart_port_startup() and uart_resume_port()). Further, always claim the port mutex to protect hardware re-reprogramming in the set_termios() uart driver method. Note this is unnecessary for console initialization in uart_set_options() which cannot be concurrent with other uart operations. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- Documentation/serial/driver | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/serial/driver b/Documentation/serial/driver index ba64e4b892e9..c415b0ef4493 100644 --- a/Documentation/serial/driver +++ b/Documentation/serial/driver @@ -59,7 +59,9 @@ The core driver uses the info->tmpbuf_sem lock to prevent multi-threaded access to the info->tmpbuf bouncebuffer used for port writes. The port_sem semaphore is used to protect against ports being added/ -removed or reconfigured at inappropriate times. +removed or reconfigured at inappropriate times. Since v2.6.27, this +semaphore has been the 'mutex' member of the tty_port struct, and +commonly referred to as the port mutex (or port->mutex). uart_ops @@ -248,7 +250,7 @@ hardware. Other flags may be used (eg, xon/xoff characters) if your hardware supports hardware "soft" flow control. - Locking: none. + Locking: caller holds port->mutex Interrupts: caller dependent. This call must not sleep -- cgit v1.2.3 From a7ae7f8243b15cd65b5811de031eb4f8413b3e6f Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 16 Oct 2014 22:43:27 +0200 Subject: serial: of_serial: add "ralink,rt2880-uart" to the binding documentation Signed-off-by: John Crispin Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/of-serial.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/of-serial.txt index 8c4fd0332028..b52b98234b9b 100644 --- a/Documentation/devicetree/bindings/serial/of-serial.txt +++ b/Documentation/devicetree/bindings/serial/of-serial.txt @@ -10,6 +10,7 @@ Required properties: - "ns16850" - "nvidia,tegra20-uart" - "nxp,lpc3220-uart" + - "ralink,rt2880-uart" - "ibm,qpace-nwp-serial" - "altr,16550-FIFO32" - "altr,16550-FIFO64" -- cgit v1.2.3 From 7c573d7ea6c5a866cf89b7bf45fc5ab82d289cf1 Mon Sep 17 00:00:00 2001 From: Janusz Uzycki Date: Fri, 10 Oct 2014 18:53:25 +0200 Subject: serial: mxs-auart: use mctrl_gpio helpers for handling modem signals Dedicated CTS and RTS pins are unusable together with a lot of other peripherals because they share the same line. Pinctrl is limited. Moreover, the AUART controller doesn't handle DTR/DSR/DCD/RI signals, so we have to control them via GPIO. This patch permits to use GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI signals. Signed-off-by: Janusz Uzycki Reviewed-by: Richard Genoud Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/fsl-mxs-auart.txt | 10 ++++- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/mxs-auart.c | 50 +++++++++++++++++++--- 3 files changed, 55 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt index 59a40f18d551..7c408c87e613 100644 --- a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +++ b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt @@ -11,8 +11,13 @@ Required properties: - dma-names: "rx" for RX channel, "tx" for TX channel. Optional properties: -- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines, +- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines + for hardware flow control, it also means you enable the DMA support for this UART. +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD + line respectively. It will use specified PIO instead of the peripheral + function pin for the USART feature. + If unsure, don't specify this property. Example: auart0: serial@8006a000 { @@ -21,6 +26,9 @@ auart0: serial@8006a000 { interrupts = <112>; dmas = <&dma_apbx 8>, <&dma_apbx 9>; dma-names = "rx", "tx"; + cts-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + dsr-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + dcd-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; Note: Each auart port should have an alias correctly numbered in "aliases" diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 649b784081c7..4e6a0babf6b9 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1408,6 +1408,7 @@ config SERIAL_MXS_AUART depends on ARCH_MXS tristate "MXS AUART support" select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB help This driver supports the MXS Application UART (AUART) port. diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 907c3e521906..5922cb435a87 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -42,6 +42,9 @@ #include +#include +#include "serial_mctrl_gpio.h" + #define MXS_AUART_PORTS 5 #define MXS_AUART_FIFO_SIZE 16 @@ -158,6 +161,8 @@ struct mxs_auart_port { struct scatterlist rx_sgl; struct dma_chan *rx_dma_chan; void *rx_dma_buf; + + struct mctrl_gpios *gpios; }; static struct platform_device_id mxs_auart_devtype[] = { @@ -405,6 +410,8 @@ static void mxs_auart_release_port(struct uart_port *u) static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) { + struct mxs_auart_port *s = to_auart_port(u); + u32 ctrl = readl(u->membase + AUART_CTRL2); ctrl &= ~(AUART_CTRL2_RTSEN | AUART_CTRL2_RTS); @@ -416,17 +423,20 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) } writel(ctrl, u->membase + AUART_CTRL2); + + mctrl_gpio_set(s->gpios, mctrl); } static u32 mxs_auart_get_mctrl(struct uart_port *u) { + struct mxs_auart_port *s = to_auart_port(u); u32 stat = readl(u->membase + AUART_STAT); u32 mctrl = 0; if (stat & AUART_STAT_CTS) mctrl |= TIOCM_CTS; - return mctrl; + return mctrl_gpio_get(s->gpios, &mctrl); } static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); @@ -554,6 +564,10 @@ err_out: } +#define RTS_AT_AUART() IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_RTS)) +#define CTS_AT_AUART() IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_CTS)) static void mxs_auart_settermios(struct uart_port *u, struct ktermios *termios, struct ktermios *old) @@ -630,6 +644,7 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl |= AUART_LINECTRL_STP2; /* figure out the hardware flow control settings */ + ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); if (cflag & CRTSCTS) { /* * The DMA has a bug(see errata:2836) in mx23. @@ -644,9 +659,11 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl2 |= AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR; } - ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; - } else { - ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); + /* Even if RTS is GPIO line RTSEN can be enabled because + * the pinctrl configuration decides about RTS pin function */ + ctrl2 |= AUART_CTRL2_RTSEN; + if (CTS_AT_AUART()) + ctrl2 |= AUART_CTRL2_CTSEN; } /* set baud rate */ @@ -690,7 +707,9 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) s->port.membase + AUART_INTR_CLR); if (istat & AUART_INTR_CTSMIS) { - uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); + if (CTS_AT_AUART()) + uart_handle_cts_change(&s->port, + stat & AUART_STAT_CTS); writel(AUART_INTR_CTSMIS, s->port.membase + AUART_INTR_CLR); istat &= ~AUART_INTR_CTSMIS; @@ -1014,6 +1033,23 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, return 0; } +static bool mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev) +{ + s->gpios = mctrl_gpio_init(dev, 0); + if (IS_ERR_OR_NULL(s->gpios)) + return false; + + /* Block (enabled before) DMA option if RTS or CTS is GPIO line */ + if (!RTS_AT_AUART() || !CTS_AT_AUART()) { + if (test_bit(MXS_AUART_RTSCTS, &s->flags)) + dev_warn(dev, + "DMA and flow control via gpio may cause some problems. DMA disabled!\n"); + clear_bit(MXS_AUART_RTSCTS, &s->flags); + } + + return true; +} + static int mxs_auart_probe(struct platform_device *pdev) { const struct of_device_id *of_id = @@ -1069,6 +1105,10 @@ static int mxs_auart_probe(struct platform_device *pdev) platform_set_drvdata(pdev, s); + if (!mxs_auart_init_gpios(s, &pdev->dev)) + dev_err(&pdev->dev, + "Failed to initialize GPIOs. The serial port may not work as expected\n"); + auart_port[s->port.line] = s; mxs_auart_reset(&s->port); -- cgit v1.2.3 From e1a184eea9bcab00faa5943292d049bc30f8cd09 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 21 Oct 2014 15:23:01 -0700 Subject: Documentation: DT: Add entries for bcm63xx UART This squashes a checkpatch warning on my new bcm3384 dts submission. Signed-off-by: Kevin Cernekee Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/bcm63xx-uart.txt | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/bcm63xx-uart.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/bcm63xx-uart.txt b/Documentation/devicetree/bindings/serial/bcm63xx-uart.txt new file mode 100644 index 000000000000..5c52e5eef16d --- /dev/null +++ b/Documentation/devicetree/bindings/serial/bcm63xx-uart.txt @@ -0,0 +1,30 @@ +* BCM63xx UART + +Required properties: + +- compatible: "brcm,bcm6345-uart" + +- reg: The base address of the UART register bank. + +- interrupts: A single interrupt specifier. + +- clocks: Clock driving the hardware; used to figure out the baud rate + divisor. + +Example: + + uart0: serial@14e00520 { + compatible = "brcm,bcm6345-uart"; + reg = <0x14e00520 0x18>; + interrupt-parent = <&periph_intc>; + interrupts = <2>; + clocks = <&periph_clk>; + }; + + clocks { + periph_clk: periph_clk@0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <54000000>; + }; + }; -- cgit v1.2.3 From 98267d33e2da8cd386212856a22f4a64b32834ab Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Fri, 7 Nov 2014 14:14:23 +0000 Subject: serial: pl011: Add device tree support for RX DMA polling Add equivalent attributes to those provided in the platform data for use when RX DMA is enabled. Signed-off-by: Andrew Jackson Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/pl011.txt | 19 ++++++++++++------- drivers/tty/serial/amba-pl011.c | 22 +++++++++++++++++++--- 2 files changed, 31 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/pl011.txt b/Documentation/devicetree/bindings/serial/pl011.txt index 5d2e840ae65c..0e05340055e1 100644 --- a/Documentation/devicetree/bindings/serial/pl011.txt +++ b/Documentation/devicetree/bindings/serial/pl011.txt @@ -6,12 +6,17 @@ Required properties: - interrupts: exactly one interrupt specifier Optional properties: -- pinctrl: When present, must have one state named "sleep" - and one state named "default" -- clocks: When present, must refer to exactly one clock named - "apb_pclk" -- dmas: When present, may have one or two dma channels. - The first one must be named "rx", the second one - must be named "tx". +- pinctrl: When present, must have one state named "sleep" + and one state named "default" +- clocks: When present, must refer to exactly one clock named + "apb_pclk" +- dmas: When present, may have one or two dma channels. + The first one must be named "rx", the second one + must be named "tx". +- auto-poll: Enables polling when using RX DMA. +- poll-rate-ms: Rate at which poll occurs when auto-poll is set, + default 100ms. +- poll-timeout-ms: Poll timeout when auto-poll is set, default + 3000ms. See also bindings/arm/primecell.txt diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d984a97043b3..8d94c194f090 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -341,6 +341,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * dmaengine_slave_config(chan, &rx_conf); uap->dmarx.chan = chan; + uap->dmarx.auto_poll_rate = false; if (plat && plat->dma_rx_poll_enable) { /* Set poll rate if specified. */ if (plat->dma_rx_poll_rate) { @@ -361,9 +362,24 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * plat->dma_rx_poll_timeout; else uap->dmarx.poll_timeout = 3000; - } else - uap->dmarx.auto_poll_rate = false; - + } else if (!plat && dev->of_node) { + uap->dmarx.auto_poll_rate = of_property_read_bool( + dev->of_node, "auto-poll"); + if (uap->dmarx.auto_poll_rate) { + u32 x; + + if (0 == of_property_read_u32(dev->of_node, + "poll-rate-ms", &x)) + uap->dmarx.poll_rate = x; + else + uap->dmarx.poll_rate = 100; + if (0 == of_property_read_u32(dev->of_node, + "poll-timeout-ms", &x)) + uap->dmarx.poll_timeout = x; + else + uap->dmarx.poll_timeout = 3000; + } + } dev_info(uap->port.dev, "DMA channel RX %s\n", dma_chan_name(uap->dmarx.chan)); } -- cgit v1.2.3 From bbac3297c6712f061853e3e11d5e21aa4164968f Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 14 Nov 2014 14:07:15 -0800 Subject: tty: serial: msm_serial: document DT alias Update devicetree binding for msm_serial to reflect msm_serial_probe() getting line id (port number) from the serialN alias. Signed-off-by: Frank Rowand Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/qcom,msm-uartdm.txt | 69 +++++++++++++++------- 1 file changed, 47 insertions(+), 22 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt index ffa5b784c66e..a2114c217376 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt @@ -27,27 +27,52 @@ Optional properties: - dmas: Should contain dma specifiers for transmit and receive channels - dma-names: Should contain "tx" for transmit and "rx" for receive channels +Note: Aliases may be defined to ensure the correct ordering of the UARTs. +The alias serialN will result in the UART being assigned port N. If any +serialN alias exists, then an alias must exist for each enabled UART. The +serialN aliases should be in a .dts file instead of in a .dtsi file. + Examples: -A uartdm v1.4 device with dma capabilities. - -serial@f991e000 { - compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; - reg = <0xf991e000 0x1000>; - interrupts = <0 108 0x0>; - clocks = <&blsp1_uart2_apps_cxc>, <&blsp1_ahb_cxc>; - clock-names = "core", "iface"; - dmas = <&dma0 0>, <&dma0 1>; - dma-names = "tx", "rx"; -}; - -A uartdm v1.3 device without dma capabilities and part of a GSBI complex. - -serial@19c40000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x19c40000 0x1000>, - <0x19c00000 0x1000>; - interrupts = <0 195 0x0>; - clocks = <&gsbi5_uart_cxc>, <&gsbi5_ahb_cxc>; - clock-names = "core", "iface"; -}; +- A uartdm v1.4 device with dma capabilities. + + serial@f991e000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0xf991e000 0x1000>; + interrupts = <0 108 0x0>; + clocks = <&blsp1_uart2_apps_cxc>, <&blsp1_ahb_cxc>; + clock-names = "core", "iface"; + dmas = <&dma0 0>, <&dma0 1>; + dma-names = "tx", "rx"; + }; + +- A uartdm v1.3 device without dma capabilities and part of a GSBI complex. + + serial@19c40000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x19c40000 0x1000>, + <0x19c00000 0x1000>; + interrupts = <0 195 0x0>; + clocks = <&gsbi5_uart_cxc>, <&gsbi5_ahb_cxc>; + clock-names = "core", "iface"; + }; + +- serialN alias. + + aliases { + serial0 = &uarta; + serial1 = &uartc; + serial2 = &uartb; + }; + + uarta: serial@12490000 { + status = "ok"; + }; + + uartb: serial@16340000 { + status = "ok"; + }; + + uartc: serial@1a240000 { + status = "ok"; + }; -- cgit v1.2.3 From c556522e89fb00ee1e1efd2e1d29ed092243cf66 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Fri, 14 Nov 2014 16:59:31 +0100 Subject: serial: sh-sci: Add device tree support for r8a7794 Simply document the new compat string. There appears to be no need for a driver update. Signed-off-by: Ulrich Hecht [geert: Reworded to match previous commits] Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index b3556609a06f..7b87eb2c66be 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -20,6 +20,10 @@ Required properties: - "renesas,scifa-r8a7791" for R8A7791 (R-Car M2) SCIFA compatible UART. - "renesas,scifb-r8a7791" for R8A7791 (R-Car M2) SCIFB compatible UART. - "renesas,hscif-r8a7791" for R8A7791 (R-Car M2) HSCIF compatible UART. + - "renesas,scif-r8a7794" for R8A7794 (R-Car E2) SCIF compatible UART. + - "renesas,scifa-r8a7794" for R8A7794 (R-Car E2) SCIFA compatible UART. + - "renesas,scifb-r8a7794" for R8A7794 (R-Car E2) SCIFB compatible UART. + - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART. - "renesas,scif" for generic SCIF compatible UART. - "renesas,scifa" for generic SCIFA compatible UART. - "renesas,scifb" for generic SCIFB compatible UART. -- cgit v1.2.3 From 681b05f58f0cd13ea21ee46600a9ad679199214c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 14 Nov 2014 16:59:32 +0100 Subject: serial: sh-sci: Add device tree support for r7s72100 Simply document the new compat string (and keep the list sorted by SoC). There appears to be no need for a driver update. Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 7b87eb2c66be..ae73bb0e9ad9 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -4,8 +4,7 @@ Required properties: - compatible: Must contain one of the following: - - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. - - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. + - "renesas,scif-r7s72100" for R7S72100 (RZ/A1H) SCIF compatible UART. - "renesas,scifa-r8a73a4" for R8A73A4 (R-Mobile APE6) SCIFA compatible UART. - "renesas,scifb-r8a73a4" for R8A73A4 (R-Mobile APE6) SCIFB compatible UART. - "renesas,scifa-r8a7740" for R8A7740 (R-Mobile A1) SCIFA compatible UART. @@ -24,6 +23,8 @@ Required properties: - "renesas,scifa-r8a7794" for R8A7794 (R-Car E2) SCIFA compatible UART. - "renesas,scifb-r8a7794" for R8A7794 (R-Car E2) SCIFB compatible UART. - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART. + - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. + - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. - "renesas,scif" for generic SCIF compatible UART. - "renesas,scifa" for generic SCIFA compatible UART. - "renesas,scifb" for generic SCIFB compatible UART. -- cgit v1.2.3 From 52bec4ed4ef83f1a14dbcfd1a97e35f77c6e261e Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Tue, 11 Nov 2014 20:44:58 +0800 Subject: serial: sirf: add a new uart type support in CSR A7DA SoC, uart6 located at BT module and it need multiple clock sources, so for "sirf,marco-bt-uart" compatible uarts, drivers take 3 clock sources and enable them. this patch also replaces clk_get by devm_clk_get function and fix DT binding document in which we missed to fix when we added marco platform in commit 909102db44f "serial: sirf: add support for Marco chip". Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/sirf-uart.txt | 16 +++++++++- drivers/tty/serial/sirfsoc_uart.c | 34 +++++++++++++++++----- drivers/tty/serial/sirfsoc_uart.h | 4 +++ 3 files changed, 46 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/sirf-uart.txt b/Documentation/devicetree/bindings/serial/sirf-uart.txt index a2dfc6522a91..3acdd969edf1 100644 --- a/Documentation/devicetree/bindings/serial/sirf-uart.txt +++ b/Documentation/devicetree/bindings/serial/sirf-uart.txt @@ -1,7 +1,9 @@ * CSR SiRFprimaII/atlasVI Universal Synchronous Asynchronous Receiver/Transmitter * Required properties: -- compatible : Should be "sirf,prima2-uart" or "sirf, prima2-usp-uart" +- compatible : Should be "sirf,prima2-uart", "sirf, prima2-usp-uart", + "sirf,marco-uart" or "sirf,marco-bt-uart" which means + uart located in BT module and used for BT. - reg : Offset and length of the register set for the device - interrupts : Should contain uart interrupt - fifosize : Should define hardware rx/tx fifo size @@ -31,3 +33,15 @@ usp@b0090000 { rts-gpios = <&gpio 15 0>; cts-gpios = <&gpio 46 0>; }; + +for uart use in BT module, +uart6: uart@11000000 { + cell-index = <6>; + compatible = "sirf,marco-bt-uart", "sirf,marco-uart"; + reg = <0x11000000 0x1000>; + interrupts = <0 100 0>; + clocks = <&clks 138>, <&clks 140>, <&clks 141>; + clock-names = "uart", "general", "noc"; + fifosize = <128>; + status = "disabled"; +} diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 4102192687ee..2f6c6b04cc8d 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -1032,10 +1032,19 @@ static void sirfsoc_uart_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { struct sirfsoc_uart_port *sirfport = to_sirfport(port); - if (!state) + if (!state) { + if (sirfport->is_bt_uart) { + clk_prepare_enable(sirfport->clk_noc); + clk_prepare_enable(sirfport->clk_general); + } clk_prepare_enable(sirfport->clk); - else + } else { clk_disable_unprepare(sirfport->clk); + if (sirfport->is_bt_uart) { + clk_disable_unprepare(sirfport->clk_general); + clk_disable_unprepare(sirfport->clk_noc); + } + } } static int sirfsoc_uart_startup(struct uart_port *port) @@ -1378,12 +1387,26 @@ usp_no_flow_control: } port->irq = res->start; - sirfport->clk = clk_get(&pdev->dev, NULL); + sirfport->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(sirfport->clk)) { ret = PTR_ERR(sirfport->clk); goto err; } port->uartclk = clk_get_rate(sirfport->clk); + if (of_device_is_compatible(pdev->dev.of_node, "sirf,marco-bt-uart")) { + sirfport->clk_general = devm_clk_get(&pdev->dev, "general"); + if (IS_ERR(sirfport->clk_general)) { + ret = PTR_ERR(sirfport->clk_general); + goto err; + } + sirfport->clk_noc = devm_clk_get(&pdev->dev, "noc"); + if (IS_ERR(sirfport->clk_noc)) { + ret = PTR_ERR(sirfport->clk_noc); + goto err; + } + sirfport->is_bt_uart = true; + } else + sirfport->is_bt_uart = false; port->ops = &sirfsoc_uart_ops; spin_lock_init(&port->lock); @@ -1392,7 +1415,7 @@ usp_no_flow_control: ret = uart_add_one_port(&sirfsoc_uart_drv, port); if (ret != 0) { dev_err(&pdev->dev, "Cannot add UART port(%d).\n", pdev->id); - goto port_err; + goto err; } sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx"); @@ -1421,8 +1444,6 @@ alloc_coherent_err: sirfport->rx_dma_items[j].xmit.buf, sirfport->rx_dma_items[j].dma_addr); dma_release_channel(sirfport->rx_dma_chan); -port_err: - clk_put(sirfport->clk); err: return ret; } @@ -1431,7 +1452,6 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) { struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); struct uart_port *port = &sirfport->port; - clk_put(sirfport->clk); uart_remove_one_port(&sirfsoc_uart_drv, port); if (sirfport->rx_dma_chan) { int i; diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index 6a7ebf7ef130..275d03893990 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h @@ -417,6 +417,10 @@ struct sirfsoc_uart_port { struct uart_port port; struct clk *clk; + /* UART6 for BT usage in A7DA platform need multi-clock source */ + bool is_bt_uart; + struct clk *clk_general; + struct clk *clk_noc; /* for SiRFmarco, there are SET/CLR for UART_INT_EN */ bool is_marco; struct sirfsoc_uart_register *uart_reg; -- cgit v1.2.3