From 9f1688080050e0757bf2eecc0117f1f723ce95dc Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 9 Mar 2011 14:11:38 +0530 Subject: cg2900: enable UART pins after initialization Enable the UART pins only after it is initialized, to ensure that the pins remain in the sleep configuration until the UART startup sequence is complete. ST-Ericsson Linux next: - ST-Ericsson ID: ER327467 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Iebb88c0c91b2063727e8e2446369a9056872d192 Signed-off-by: Rabin Vincent Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/17959 Reviewed-by: Par-Gunnar HJALMDAHL Reviewed-by: Srinidhi KASAGAR --- drivers/bluetooth/cg2900_uart.c | 68 ++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/drivers/bluetooth/cg2900_uart.c b/drivers/bluetooth/cg2900_uart.c index ff901534270..1d59884125b 100644 --- a/drivers/bluetooth/cg2900_uart.c +++ b/drivers/bluetooth/cg2900_uart.c @@ -458,20 +458,8 @@ static irqreturn_t cts_interrupt(int irq, void *dev_id) static int set_cts_irq(struct uart_info *uart_info) { int err; - struct cg2900_platform_data *pf_data; int cts_val = 0; - pf_data = dev_get_platdata(uart_info->dev); - - /* First disable the UART so we can use IRQ on the GPIOs */ - if (pf_data->uart.disable_uart) { - err = pf_data->uart.disable_uart(&uart_info->chip_dev); - if (err) { - dev_err(MAIN_DEV, "Could not disable UART (%d)\n", err); - return err; - } - } - /* Set IRQ on CTS. */ err = request_irq(uart_info->cts_irq, cts_interrupt, @@ -480,7 +468,7 @@ static int set_cts_irq(struct uart_info *uart_info) uart_info->dev); if (err) { dev_err(MAIN_DEV, "Could not request CTS IRQ (%d)\n", err); - goto error; + return err; } /* @@ -493,43 +481,61 @@ static int set_cts_irq(struct uart_info *uart_info) dev_dbg(MAIN_DEV, "Missed interrupt, going back to " "awake state\n"); free_irq(uart_info->cts_irq, uart_info->dev); - err = -ECANCELED; - goto error; + return -ECANCELED; } #ifdef CONFIG_PM enable_irq_wake(uart_info->cts_irq); #endif return 0; - -error: - if (pf_data->uart.enable_uart) - (void)pf_data->uart.enable_uart(&uart_info->chip_dev); - return err; } /** - * unset_cts_irq() - Disable interrupt on CTS. + * disable_uart_pins() - Disable the UART pins. * @uart_info: Main Uart structure. */ -static void unset_cts_irq(struct uart_info *uart_info) +static void disable_uart_pins(struct uart_info *uart_info) { - int err = 0; struct cg2900_platform_data *pf_data; pf_data = dev_get_platdata(uart_info->dev); - /* Free CTS interrupt and restore UART settings. */ - free_irq(uart_info->cts_irq, uart_info->dev); + if (pf_data->uart.disable_uart) { + int err = pf_data->uart.disable_uart(&uart_info->chip_dev); + if (err) + dev_err(MAIN_DEV, + "Unable to disable UART Hardware (%d)\n", err); + } +} + +/** + * enable_uart_pins() - Enable the UART pins. + * @uart_info: Main Uart structure. + */ +static void enable_uart_pins(struct uart_info *uart_info) +{ + struct cg2900_platform_data *pf_data; + + pf_data = dev_get_platdata(uart_info->dev); if (pf_data->uart.enable_uart) { - err = pf_data->uart.enable_uart(&uart_info->chip_dev); + int err = pf_data->uart.enable_uart(&uart_info->chip_dev); if (err) dev_err(MAIN_DEV, "Unable to enable UART Hardware (%d)\n", err); } } +/** + * unset_cts_irq() - Disable interrupt on CTS. + * @uart_info: Main Uart structure. + */ +static void unset_cts_irq(struct uart_info *uart_info) +{ + /* Free CTS interrupt */ + free_irq(uart_info->cts_irq, uart_info->dev); +} + /** * get_sleep_timeout() - Get sleep timeout. * @uart_info: Main Uart structure. @@ -611,6 +617,8 @@ static void wake_up_chip(struct uart_info *uart_info) (void)hci_uart_set_baudrate(uart_info->hu, uart_info->baud_rate); + enable_uart_pins(uart_info); + /* * Wait before flowing on. Otherwise UART might not be ready in * time @@ -673,6 +681,8 @@ static void set_chip_sleep_mode(struct work_struct *work) /* Flow OFF. */ hci_uart_flow_ctrl(uart_info->hu, FLOW_OFF); + disable_uart_pins(uart_info); + /* * Set baud zero. * This cause shut off UART clock as well. @@ -681,6 +691,7 @@ static void set_chip_sleep_mode(struct work_struct *work) ZERO_BAUD_RATE); err = set_cts_irq(uart_info); if (err < 0) { + enable_uart_pins(uart_info); (void)hci_uart_set_baudrate(uart_info->hu, uart_info->baud_rate); hci_uart_flow_ctrl(uart_info->hu, FLOW_ON); @@ -1354,6 +1365,8 @@ static void uart_set_chip_power(struct cg2900_chip_dev *dev, bool chip_on) (void)hci_uart_set_baudrate(uart_info->hu, uart_baudrate); + hci_uart_flow_ctrl(uart_info->hu, FLOW_ON); + hci_uart_set_break(uart_info->hu, BREAK_OFF); } else { /* Turn off the chip.*/ switch (uart_info->sleep_state) { @@ -1365,8 +1378,7 @@ static void uart_set_chip_power(struct cg2900_chip_dev *dev, bool chip_on) case CHIP_SUSPENDED: case CHIP_ASLEEP: unset_cts_irq(uart_info); - hci_uart_flow_ctrl(uart_info->hu, FLOW_ON); - hci_uart_set_break(uart_info->hu, BREAK_OFF); + enable_uart_pins(uart_info); break; default: break; -- cgit v1.2.3