This patch permits the usage for GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI signals. Changed by Stefan: Only call mctrl_gpio_init(), if the device has no ACPI companion device to not break existing ACPI based systems. Also only use the mctrl_gpio_ functions when "gpios" is available. Use MSR / MCR <-> TIOCM wrapper functions.
Unified · Split
| @@ -53,6 +53,9 @@ Optional properties: · 52 unmodified lines | |||
| 53 | programmable TX FIFO thresholds. | 53 | programmable TX FIFO thresholds. |
| 54 | - resets : phandle + reset specifier pairs | 54 | - resets : phandle + reset specifier pairs |
| 55 | - overrun-throttle-ms : how long to pause uart rx when input overrun is encountered. | 55 | - overrun-throttle-ms : how long to pause uart rx when input overrun is encountered. |
| 56 | - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD | ||
| 57 | line respectively. It will use specified GPIO instead of the peripheral | ||
| 58 | function pin for the UART feature. If unsure, don't specify this property. | ||
| 56 | 59 | ||
| 57 | Note: | 60 | Note: |
| 58 | * fsl,ns16550: | 61 | * fsl,ns16550: |
| @@ -74,3 +77,19 @@ Example: · 15 unmodified lines | |||
| 74 | interrupts = <10>; | 77 | interrupts = <10>; |
| 75 | reg-shift = <2>; | 78 | reg-shift = <2>; |
| 76 | }; | 79 | }; |
| 80 | |||
| 81 | Example for OMAP UART using GPIO-based modem control signals: | ||
| 82 | |||
| 83 | uart4: serial@49042000 { | ||
| 84 | compatible = "ti,omap3-uart"; | ||
| 85 | reg = <0x49042000 0x400>; | ||
| 86 | interrupts = <80>; | ||
| 87 | ti,hwmods = "uart4"; | ||
| 88 | clock-frequency = <48000000>; | ||
| 89 | cts-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; | ||
| 90 | rts-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; | ||
| 91 | dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; | ||
| 92 | dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; | ||
| 93 | dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; | ||
| 94 | rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; | ||
| 95 | }; | ||
| @@ -11,6 +11,8 @@ · 10 unmodified lines | |||
| 11 | #include <linux/serial_reg.h> | 11 | #include <linux/serial_reg.h> |
| 12 | #include <linux/dmaengine.h> | 12 | #include <linux/dmaengine.h> |
| 13 | 13 | ||
| 14 | #include "../serial_mctrl_gpio.h" | ||
| 15 | |||
| 14 | struct uart_8250_dma { | 16 | struct uart_8250_dma { |
| 15 | int (*tx_dma)(struct uart_8250_port *p); | 17 | int (*tx_dma)(struct uart_8250_port *p); |
| 16 | int (*rx_dma)(struct uart_8250_port *p); | 18 | int (*rx_dma)(struct uart_8250_port *p); |
| @@ -214,11 +216,25 @@ static inline int serial8250_MSR_to_TIOCM(int msr) · 197 unmodified lines | |||
| 214 | static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) | 216 | static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) |
| 215 | { | 217 | { |
| 216 | serial_out(up, UART_MCR, value); | 218 | serial_out(up, UART_MCR, value); |
| 219 | |||
| 220 | if (up->gpios) | ||
| 221 | mctrl_gpio_set(up->gpios, serial8250_MCR_to_TIOCM(value)); | ||
| 217 | } | 222 | } |
| 218 | 223 | ||
| 219 | static inline int serial8250_in_MCR(struct uart_8250_port *up) | 224 | static inline int serial8250_in_MCR(struct uart_8250_port *up) |
| 220 | { | 225 | { |
| 221 | return serial_in(up, UART_MCR); | 226 | int mctrl; |
| 227 | |||
| 228 | mctrl = serial_in(up, UART_MCR); | ||
| 229 | |||
| 230 | if (up->gpios) { | ||
| 231 | unsigned int mctrl_gpio = 0; | ||
| 232 | |||
| 233 | mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio); | ||
| 234 | mctrl |= serial8250_TIOCM_to_MCR(mctrl_gpio); | ||
| 235 | } | ||
| 236 | |||
| 237 | return mctrl; | ||
| 222 | } | 238 | } |
| 223 | 239 | ||
| 224 | #if defined(__alpha__) && !defined(CONFIG_PCI) | 240 | #if defined(__alpha__) && !defined(CONFIG_PCI) |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | * serial8250_register_8250_port() ports | 14 | * serial8250_register_8250_port() ports |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/acpi.h> | ||
| 17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 18 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
| 19 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
| @@ -982,6 +983,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) · 962 unmodified lines | |||
| 982 | 983 | ||
| 983 | uart = serial8250_find_match_or_unused(&up->port); | 984 | uart = serial8250_find_match_or_unused(&up->port); |
| 984 | if (uart && uart->port.type != PORT_8250_CIR) { | 985 | if (uart && uart->port.type != PORT_8250_CIR) { |
| 986 | struct mctrl_gpios *gpios; | ||
| 987 | |||
| 985 | if (uart->port.dev) | 988 | if (uart->port.dev) |
| 986 | uart_remove_one_port(&serial8250_reg, &uart->port); | 989 | uart_remove_one_port(&serial8250_reg, &uart->port); |
| 987 | 990 | ||
| @@ -1016,6 +1019,20 @@ int serial8250_register_8250_port(struct uart_8250_port *up) · 28 unmodified lines | |||
| 1016 | if (up->port.flags & UPF_FIXED_TYPE) | 1019 | if (up->port.flags & UPF_FIXED_TYPE) |
| 1017 | uart->port.type = up->port.type; | 1020 | uart->port.type = up->port.type; |
| 1018 | 1021 | ||
| 1022 | /* | ||
| 1023 | * Only call mctrl_gpio_init(), if the device has no ACPI | ||
| 1024 | * companion device | ||
| 1025 | */ | ||
| 1026 | if (!has_acpi_companion(uart->port.dev)) { | ||
| 1027 | gpios = mctrl_gpio_init(&uart->port, 0); | ||
| 1028 | if (IS_ERR(gpios)) { | ||
| 1029 | if (PTR_ERR(gpios) != -ENOSYS) | ||
| 1030 | return PTR_ERR(gpios); | ||
| 1031 | } else { | ||
| 1032 | uart->gpios = gpios; | ||
| 1033 | } | ||
| 1034 | } | ||
| 1035 | |||
| 1019 | serial8250_set_defaults(uart); | 1036 | serial8250_set_defaults(uart); |
| 1020 | 1037 | ||
| 1021 | /* Possibly override default I/O functions. */ | 1038 | /* Possibly override default I/O functions. */ |
| @@ -141,18 +141,20 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) · 140 unmodified lines | |||
| 141 | 141 | ||
| 142 | serial8250_do_set_mctrl(port, mctrl); | 142 | serial8250_do_set_mctrl(port, mctrl); |
| 143 | 143 | ||
| 144 | /* | 144 | if (!up->gpios) { |
| 145 | * Turn off autoRTS if RTS is lowered and restore autoRTS setting | 145 | /* |
| 146 | * if RTS is raised | 146 | * Turn off autoRTS if RTS is lowered and restore autoRTS |
| 147 | */ | 147 | * setting if RTS is raised |
| 148 | lcr = serial_in(up, UART_LCR); | 148 | */ |
| 149 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 149 | lcr = serial_in(up, UART_LCR); |
| 150 | if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) | 150 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 151 | priv->efr |= UART_EFR_RTS; | 151 | if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) |
| 152 | else | 152 | priv->efr |= UART_EFR_RTS; |
| 153 | priv->efr &= ~UART_EFR_RTS; | 153 | else |
| 154 | serial_out(up, UART_EFR, priv->efr); | 154 | priv->efr &= ~UART_EFR_RTS; |
| 155 | serial_out(up, UART_LCR, lcr); | 155 | serial_out(up, UART_EFR, priv->efr); |
| 156 | serial_out(up, UART_LCR, lcr); | ||
| 157 | } | ||
| 156 | } | 158 | } |
| 157 | 159 | ||
| 158 | /* | 160 | /* |
| @@ -453,7 +455,8 @@ static void omap_8250_set_termios(struct uart_port *port, · 294 unmodified lines | |||
| 453 | priv->efr = 0; | 455 | priv->efr = 0; |
| 454 | up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); | 456 | up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); |
| 455 | 457 | ||
| 456 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { | 458 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW && |
| 459 | !up->gpios) { | ||
| 457 | /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ | 460 | /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ |
| 458 | up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; | 461 | up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; |
| 459 | priv->efr |= UART_EFR_CTS; | 462 | priv->efr |= UART_EFR_CTS; |
| @@ -1656,6 +1656,8 @@ static void serial8250_disable_ms(struct uart_port *port) · 1655 unmodified lines | |||
| 1656 | if (up->bugs & UART_BUG_NOMSR) | 1656 | if (up->bugs & UART_BUG_NOMSR) |
| 1657 | return; | 1657 | return; |
| 1658 | 1658 | ||
| 1659 | mctrl_gpio_disable_ms(up->gpios); | ||
| 1660 | |||
| 1659 | up->ier &= ~UART_IER_MSI; | 1661 | up->ier &= ~UART_IER_MSI; |
| 1660 | serial_port_out(port, UART_IER, up->ier); | 1662 | serial_port_out(port, UART_IER, up->ier); |
| 1661 | } | 1663 | } |
| @@ -1668,6 +1670,8 @@ static void serial8250_enable_ms(struct uart_port *port) · 6 unmodified lines | |||
| 1668 | if (up->bugs & UART_BUG_NOMSR) | 1670 | if (up->bugs & UART_BUG_NOMSR) |
| 1669 | return; | 1671 | return; |
| 1670 | 1672 | ||
| 1673 | mctrl_gpio_enable_ms(up->gpios); | ||
| 1674 | |||
| 1671 | up->ier |= UART_IER_MSI; | 1675 | up->ier |= UART_IER_MSI; |
| 1672 | 1676 | ||
| 1673 | serial8250_rpm_get(up); | 1677 | serial8250_rpm_get(up); |
| @@ -1939,12 +1943,17 @@ unsigned int serial8250_do_get_mctrl(struct uart_port *port) · 265 unmodified lines | |||
| 1939 | { | 1943 | { |
| 1940 | struct uart_8250_port *up = up_to_u8250p(port); | 1944 | struct uart_8250_port *up = up_to_u8250p(port); |
| 1941 | unsigned int status; | 1945 | unsigned int status; |
| 1946 | unsigned int val; | ||
| 1942 | 1947 | ||
| 1943 | serial8250_rpm_get(up); | 1948 | serial8250_rpm_get(up); |
| 1944 | status = serial8250_modem_status(up); | 1949 | status = serial8250_modem_status(up); |
| 1945 | serial8250_rpm_put(up); | 1950 | serial8250_rpm_put(up); |
| 1946 | 1951 | ||
| 1947 | return serial8250_MSR_to_TIOCM(status); | 1952 | val = serial8250_MSR_to_TIOCM(status); |
| 1953 | if (up->gpios) | ||
| 1954 | return mctrl_gpio_get(up->gpios, &val); | ||
| 1955 | |||
| 1956 | return val; | ||
| 1948 | } | 1957 | } |
| 1949 | EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl); | 1958 | EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl); |
| 1950 | 1959 | ||
| @@ -8,6 +8,7 @@ config SERIAL_8250 · 7 unmodified lines | |||
| 8 | tristate "8250/16550 and compatible serial support" | 8 | tristate "8250/16550 and compatible serial support" |
| 9 | depends on !S390 | 9 | depends on !S390 |
| 10 | select SERIAL_CORE | 10 | select SERIAL_CORE |
| 11 | select SERIAL_MCTRL_GPIO if GPIOLIB | ||
| 11 | ---help--- | 12 | ---help--- |
| 12 | This selects whether you want to include the driver for the standard | 13 | This selects whether you want to include the driver for the standard |
| 13 | serial ports. The standard answer is Y. People who might say N | 14 | serial ports. The standard answer is Y. People who might say N |
| @@ -110,6 +110,7 @@ struct uart_8250_port { · 109 unmodified lines | |||
| 110 | * if no_console_suspend | 110 | * if no_console_suspend |
| 111 | */ | 111 | */ |
| 112 | unsigned char probe; | 112 | unsigned char probe; |
| 113 | struct mctrl_gpios *gpios; | ||
| 113 | #define UART_PROBE_RSA (1 << 0) | 114 | #define UART_PROBE_RSA (1 << 0) |
| 114 | 115 | ||
| 115 | /* | 116 | /* |