summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/omap-serial.c
diff options
context:
space:
mode:
authormattis fjallstrom <mattis@acm.org>2015-08-11 19:29:20 -0700
committermattis fjallstrom <mattis@acm.org>2015-08-11 19:29:20 -0700
commit9ccd6e0d99208ca9a7bb514cc956b1de6800940b (patch)
tree3e5550dd0998fafb61e1d871a8da4df987f04f5a /drivers/tty/serial/omap-serial.c
parentb66fe63ea9d50a1049d9142559121d16f86db9eb (diff)
downloadolio-linux-3.10-9ccd6e0d99208ca9a7bb514cc956b1de6800940b.tar.xz
olio-linux-3.10-9ccd6e0d99208ca9a7bb514cc956b1de6800940b.zip
Bluetooth working in sleep mode.
Change-Id: I20e42e204dbf73c5f8468fc7733fa29c6ea1c2f2
Diffstat (limited to 'drivers/tty/serial/omap-serial.c')
-rw-r--r--drivers/tty/serial/omap-serial.c91
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