diff options
Diffstat (limited to 'drivers/tty/serial/omap-serial.c')
| -rw-r--r-- | drivers/tty/serial/omap-serial.c | 91 | 
1 files changed, 81 insertions, 10 deletions
| diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 9b19ae172c3..a9c37ae9b2a 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -180,6 +180,8 @@ struct uart_omap_port {  	unsigned int		rx_trig;  	int			wakelock_timeout;  	int (*get_context_loss_count)(struct device *); + +    bool rts_wait;  };  #define to_uart_omap_port(p)	((container_of((p), struct uart_omap_port, port))) @@ -1115,8 +1117,41 @@ static void serial_omap_wake_peer(struct uart_port *port)         struct omap_uart_port_info *pdata = up->dev->platform_data;         if (pdata->wake_peer) -               pdata->wake_peer(port); +           pdata->wake_peer(port); +} + +static void serial_omap_rts_enable(struct uart_port *port) +{ +    struct uart_omap_port *up; +    struct omap_uart_port_info *pdata; + +    up = to_uart_omap_port(port); + +    if ((up != NULL) && (up->dev != NULL) && (up->dev->platform_data != NULL)) { +        pdata = up->dev->platform_data; + +        if (pdata->rts_enable_fn) { +            pdata->rts_enable_fn(); +        } +    } +} + +static void serial_omap_rts_disable(struct uart_port *port) +{ +    struct uart_omap_port *up; + +    up = to_uart_omap_port(port); + +    if ((up != NULL) && (up->dev != NULL) && (up->dev->platform_data != NULL)) { +        struct omap_uart_port_info *pdata = up->dev->platform_data; + +        if (pdata->rts_disable_fn) { +            pdata->rts_disable_fn(); +        } +    }  } + +  static void serial_omap_release_port(struct uart_port *port)  {  	dev_dbg(port->dev, "serial_omap_release_port+\n"); @@ -1348,12 +1383,14 @@ static struct uart_ops serial_omap_pops = {  	.shutdown	= serial_omap_shutdown,  	.set_termios	= serial_omap_set_termios,  	.pm		= serial_omap_pm, -	.wake_peer 	= serial_omap_wake_peer,  	.type		= serial_omap_type,  	.release_port	= serial_omap_release_port,  	.request_port	= serial_omap_request_port,  	.config_port	= serial_omap_config_port,  	.verify_port	= serial_omap_verify_port, +	.wake_peer 	    = serial_omap_wake_peer, +    .rts_enable     = serial_omap_rts_enable, +    .rts_disable    = serial_omap_rts_disable,  #ifdef CONFIG_CONSOLE_POLL  	.poll_put_char  = serial_omap_poll_put_char,  	.poll_get_char  = serial_omap_poll_get_char, @@ -1364,7 +1401,7 @@ static struct uart_driver serial_omap_reg = {  	.owner		= THIS_MODULE,  	.driver_name	= "OMAP-SERIAL",  	.dev_name	= OMAP_SERIAL_NAME, -	.nr		= OMAP_MAX_HSUART_PORTS, +	.nr	    	= OMAP_MAX_HSUART_PORTS,  	.cons		= OMAP_CONSOLE,  }; @@ -1372,9 +1409,17 @@ static struct uart_driver serial_omap_reg = {  static int serial_omap_prepare(struct device *dev)  {  	struct uart_omap_port *up = dev_get_drvdata(dev); +	unsigned long flags;  	up->is_suspending = true; +    if (up->rts_wait) { +        spin_lock_irqsave(&up->delayed_rts_lock, flags); +        up->port.ops->rts_disable(&(up->port)); +        up->need_delayed_rts = 1; +        spin_unlock_irqrestore(&up->delayed_rts_lock, flags); +    } +  	return 0;  } @@ -1389,6 +1434,12 @@ static void serial_omap_complete(struct device *dev)  		up->need_delayed_rts = 0;  	} +    /* OLIO: We're not using pinctrl, but we still need rts delayed */ +    else if (up->need_delayed_rts) { +        up->port.ops->rts_enable(&(up->port)); +		up->need_delayed_rts = 0; +    } +  	up->is_suspending = false;  	spin_unlock_irqrestore(&up->delayed_rts_lock, flags);  } @@ -1412,7 +1463,7 @@ static int serial_omap_resume(struct device *dev)  }  #else  #define serial_omap_prepare NULL -#define serial_omap_prepare NULL +#define serial_omap_complete NULL  #endif /* CONFIG_PM_SLEEP */  static void omap_serial_fill_features_erratas(struct uart_omap_port *up) @@ -1618,6 +1669,10 @@ static int serial_omap_probe(struct platform_device *pdev)  		goto err_ioremap;  	} +    /* OLIO */ +    if (omap_up_info->rts_wait) +      up->rts_wait = omap_up_info->rts_wait; +  	up->rx_trig = omap_up_info->rx_trig;  	up->port.flags = omap_up_info->flags;  	up->port.uartclk = omap_up_info->uartclk; @@ -1781,6 +1836,15 @@ static int serial_omap_runtime_suspend(struct device *dev)  		up->need_delayed_rts = 0;  		spin_unlock_irqrestore(&up->delayed_rts_lock, flags);  	} + +    /* OLIO */ +    else if (up->rts_wait) { +      spin_lock_irqsave(&up->delayed_rts_lock, flags); +      up->port.ops->rts_disable(&(up->port)); +      up->need_delayed_rts = 0; +      spin_unlock_irqrestore(&up->delayed_rts_lock, flags); +    } +  	up->context_loss_cnt = serial_omap_get_context_loss_count(up);  	if (device_may_wakeup(dev)) { @@ -1810,13 +1874,20 @@ static int serial_omap_runtime_resume(struct device *dev)  	}  	up->latency = up->calc_latency;  	serial_omap_uart_qos(up); -	if (up->pin_default && up->pin_idle) { -		if (up->is_suspending) -			up->need_delayed_rts = 1; -		else -			pinctrl_select_state(up->pins, up->pin_default); -	} +    if (up->pin_default && up->pin_idle) { +        if (up->is_suspending) +            up->need_delayed_rts = 1; +        else +            pinctrl_select_state(up->pins, up->pin_default); +    } +    else if (up->rts_wait) { +        if (up->is_suspending) +            up->need_delayed_rts = 1; +        else { +            up->port.ops->rts_enable(&(up->port)); +        } +    }  	return 0;  }  #endif |