diff options
Diffstat (limited to 'drivers/tty/serial/sa1100.c')
-rw-r--r-- | drivers/tty/serial/sa1100.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index a399772be3fc..8e618129e65c 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -28,6 +28,8 @@ #include <mach/hardware.h> #include <mach/irqs.h> +#include "serial_mctrl_gpio.h" + /* We've been assigned a range on the "Low-density serial ports" major */ #define SERIAL_SA1100_MAJOR 204 #define MINOR_START 5 @@ -77,6 +79,7 @@ struct sa1100_port { struct uart_port port; struct timer_list timer; unsigned int old_status; + struct mctrl_gpios *gpios; }; /* @@ -174,6 +177,8 @@ static void sa1100_enable_ms(struct uart_port *port) container_of(port, struct sa1100_port, port); mod_timer(&sport->timer, jiffies); + + mctrl_gpio_enable_ms(sport->gpios); } static void @@ -322,11 +327,21 @@ static unsigned int sa1100_tx_empty(struct uart_port *port) static unsigned int sa1100_get_mctrl(struct uart_port *port) { - return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; + struct sa1100_port *sport = + container_of(port, struct sa1100_port, port); + int ret = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; + + mctrl_gpio_get(sport->gpios, &ret); + + return ret; } static void sa1100_set_mctrl(struct uart_port *port, unsigned int mctrl) { + struct sa1100_port *sport = + container_of(port, struct sa1100_port, port); + + mctrl_gpio_set(sport->gpios, mctrl); } /* @@ -842,6 +857,31 @@ static int sa1100_serial_resume(struct platform_device *dev) return 0; } +static int sa1100_serial_add_one_port(struct sa1100_port *sport, struct platform_device *dev) +{ + sport->port.dev = &dev->dev; + + // mctrl_gpio_init() requires that the GPIO driver supports interrupts, + // but we need to support GPIO drivers for hardware that has no such + // interrupts. Use mctrl_gpio_init_noauto() instead. + sport->gpios = mctrl_gpio_init_noauto(sport->port.dev, 0); + if (IS_ERR(sport->gpios)) { + int err = PTR_ERR(sport->gpios); + + dev_err(sport->port.dev, "failed to get mctrl gpios: %d\n", + err); + + if (err == -EPROBE_DEFER) + return err; + + sport->gpios = NULL; + } + + platform_set_drvdata(dev, sport); + + return uart_add_one_port(&sa1100_reg, &sport->port); +} + static int sa1100_serial_probe(struct platform_device *dev) { struct resource *res = dev->resource; @@ -856,9 +896,7 @@ static int sa1100_serial_probe(struct platform_device *dev) if (sa1100_ports[i].port.mapbase != res->start) continue; - sa1100_ports[i].port.dev = &dev->dev; - uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port); - platform_set_drvdata(dev, &sa1100_ports[i]); + sa1100_serial_add_one_port(&sa1100_ports[i], dev); break; } } |