diff options
-rw-r--r-- | drivers/staging/cg2900/bluetooth/cg2900_uart.c | 4 | ||||
-rw-r--r-- | drivers/staging/cg2900/clock-cg2900.c | 5 | ||||
-rw-r--r-- | drivers/staging/cg2900/devices-cg2900-ux500.c | 18 | ||||
-rw-r--r-- | drivers/staging/cg2900/devices-cg2900.h | 1 | ||||
-rw-r--r-- | drivers/staging/cg2900/include/cg2900.h | 3 | ||||
-rw-r--r-- | drivers/staging/cg2900/mfd/cg2900_chip.c | 67 | ||||
-rw-r--r-- | drivers/staging/cg2900/mfd/cg2900_core.c | 3 |
7 files changed, 64 insertions, 37 deletions
diff --git a/drivers/staging/cg2900/bluetooth/cg2900_uart.c b/drivers/staging/cg2900/bluetooth/cg2900_uart.c index 6cde9d75c21..79b4efa189c 100644 --- a/drivers/staging/cg2900/bluetooth/cg2900_uart.c +++ b/drivers/staging/cg2900/bluetooth/cg2900_uart.c @@ -55,8 +55,8 @@ #define HCI_BT_CMD_COMPLETE_LEN (sizeof(struct hci_ev_cmd_complete) + 1) /* Timers used in milliseconds */ -#define UART_TX_TIMEOUT 100 -#define UART_RX_TIMEOUT 20 +#define UART_TX_TIMEOUT 10 +#define UART_RX_TIMEOUT 10 #define UART_RESP_TIMEOUT 1000 #define UART_RESUME_TIMEOUT 20 diff --git a/drivers/staging/cg2900/clock-cg2900.c b/drivers/staging/cg2900/clock-cg2900.c index 6e3c738e49d..54900c185fb 100644 --- a/drivers/staging/cg2900/clock-cg2900.c +++ b/drivers/staging/cg2900/clock-cg2900.c @@ -41,9 +41,10 @@ static struct clk_lookup *cg2900_clk_lookup; static int cg2900_clk_enable(struct clk *clk) { int err = -EINVAL; - if (pf_data) + if (pf_data) { + pf_data->is_clk_user = true; err = pf_data->open(pf_data); - + } return err; } diff --git a/drivers/staging/cg2900/devices-cg2900-ux500.c b/drivers/staging/cg2900/devices-cg2900-ux500.c index 7e7c12ce4a0..5a5734671cb 100644 --- a/drivers/staging/cg2900/devices-cg2900-ux500.c +++ b/drivers/staging/cg2900/devices-cg2900-ux500.c @@ -37,16 +37,10 @@ void dcg2900_u8500_enable_chip(struct cg2900_chip_dev *dev) return; /* - * Due to a bug in CG2900 we cannot just set GPIO high to enable - * the chip. We must wait more than 100 msecs before enabling the - * chip. - * - Set PDB to low. - * - Wait for 100 msecs + * - SET PMU_EN to high + * - Wait for 300usec * - Set PDB to high. */ - gpio_set_value(info->gbf_gpio, 0); - schedule_timeout_uninterruptible(msecs_to_jiffies( - CHIP_ENABLE_PDB_LOW_TIMEOUT)); if (info->pmuen_gpio != -1) { /* @@ -186,16 +180,8 @@ void dcg2900_u5500_enable_chip(struct cg2900_chip_dev *dev) clk_enable(info->lpoclk); /* - * Due to a bug in CG2900 we cannot just set GPIO high to enable - * the chip. We must wait more than 100 msecs before enbling the - * chip. - * - Set PDB to low. - * - Wait for 100 msecs * - Set PDB to high. */ - prcmu_resetout(1, 0); - schedule_timeout_uninterruptible(msecs_to_jiffies( - CHIP_ENABLE_PDB_LOW_TIMEOUT)); prcmu_resetout(1, 1); } diff --git a/drivers/staging/cg2900/devices-cg2900.h b/drivers/staging/cg2900/devices-cg2900.h index 5ca95e1e0a1..0a1db162279 100644 --- a/drivers/staging/cg2900/devices-cg2900.h +++ b/drivers/staging/cg2900/devices-cg2900.h @@ -9,6 +9,7 @@ #define __DEVICES_CG2900_H #include "cg2900.h" +#include "mfd/cg2900_chip.h" #include <linux/clk.h> #define CHIP_ENABLE_PDB_LOW_TIMEOUT 100 /* ms */ diff --git a/drivers/staging/cg2900/include/cg2900.h b/drivers/staging/cg2900/include/cg2900.h index bd165c0048b..eddfb71c8e4 100644 --- a/drivers/staging/cg2900/include/cg2900.h +++ b/drivers/staging/cg2900/include/cg2900.h @@ -196,6 +196,8 @@ struct cg2900_platform_data { * @h4_channel: H4 channel. Set by CG2900 driver. * @is_audio: True if this channel is an audio channel. Set by CG2900 * driver. + * @is_clk_user: whether enabling CG29XX was started external entity + * for eg. WLAN. * @chip_independent: True if this channel does not require chip to be * powered. Set by CG2900 driver. * @bt_bus: Transport used, see @include/net/bluetooth/hci.h. @@ -224,6 +226,7 @@ struct cg2900_user_data { int h4_channel; bool is_audio; + bool is_clk_user; bool chip_independent; union { diff --git a/drivers/staging/cg2900/mfd/cg2900_chip.c b/drivers/staging/cg2900/mfd/cg2900_chip.c index 020f7c906ad..3ff07714508 100644 --- a/drivers/staging/cg2900/mfd/cg2900_chip.c +++ b/drivers/staging/cg2900/mfd/cg2900_chip.c @@ -180,6 +180,8 @@ * @CG2900_CLOSING: CG2900 closing after last user has deregistered. * @CG2900_RESETING: CG2900 reset requested. * @CG2900_ACTIVE: CG2900 up and running with at least one user. + * @CG2900_ACTIVE_BEFORE_SELFTEST: CG2900 up and running before + * BT self test is run. */ enum main_state { CG2900_INIT, @@ -187,7 +189,8 @@ enum main_state { CG2900_BOOTING, CG2900_CLOSING, CG2900_RESETING, - CG2900_ACTIVE + CG2900_ACTIVE, + CG2900_ACTIVE_BEFORE_SELFTEST }; /** @@ -404,6 +407,13 @@ static struct main_info *main_info; * main_wait_queue - Main Wait Queue in CG2900 driver. */ static DECLARE_WAIT_QUEUE_HEAD(main_wait_queue); +/* + * Clock enabler should be released earlier + * before running read self test + * as that is not required for clock enabler + * as is the case for WLAN + */ +static DECLARE_WAIT_QUEUE_HEAD(clk_user_wait_queue); static struct mfd_cell cg2900_devs[]; static struct mfd_cell cg2900_char_devs[]; @@ -1814,10 +1824,20 @@ static bool handle_rx_data_bt_evt(struct cg2900_chip_dev *dev, pkt_handled = handle_vs_power_switch_off_cmd_complete(dev, data); - else if (op_code == CG2900_BT_OP_VS_SYSTEM_RESET) - pkt_handled = handle_vs_system_reset_cmd_complete(dev, - data); - else if (op_code == CG2900_BT_OP_VS_BT_ENABLE) + else if (op_code == CG2900_BT_OP_VS_SYSTEM_RESET) { + struct cg2900_chip_info *info = dev->c_data; + /* + * Don't wait till READ_SELFTESTS_RESULT is complete + * for clock users + */ + dev_dbg(dev->dev, + "New main_state: CG2900_ACTIVE_BEFORE_SELFTEST\n"); + info->main_state = CG2900_ACTIVE_BEFORE_SELFTEST; + wake_up_all(&clk_user_wait_queue); + + pkt_handled = + handle_vs_system_reset_cmd_complete(dev, data); + } else if (op_code == CG2900_BT_OP_VS_BT_ENABLE) pkt_handled = handle_vs_bt_enable_cmd_complete(dev, data); else if (op_code == CG2900_BT_OP_VS_READ_SELTESTS_RESULT) @@ -2296,8 +2316,14 @@ static void chip_startup_finished(struct cg2900_chip_info *info, int err) wake_up_all(&main_wait_queue); - if (err) + if (err) { + /* + * This will wakeup clock user too + * if it started the initialization process + */ + wake_up_all(&clk_user_wait_queue); return; + } if (!info->chip_dev->t_cb.chip_startup_finished) dev_dbg(BOOT_DEV, "chip_startup_finished callback not found\n"); @@ -2328,6 +2354,7 @@ static int cg2900_open(struct cg2900_user_data *user) struct cg2900_chip_info *info; struct list_head *cursor; struct cg2900_channel_item *tmp; + enum main_state state_to_check = CG2900_ACTIVE; BUG_ON(!main_info); @@ -2427,18 +2454,30 @@ static int cg2900_open(struct cg2900_user_data *user) cg2900_create_work_item(info->wq, work_load_patch_and_settings, dev); - dev_dbg(user->dev, "Wait up to 15 seconds for chip to start\n"); - wait_event_timeout(main_wait_queue, - (CG2900_ACTIVE == info->main_state || - CG2900_IDLE == info->main_state), - msecs_to_jiffies(CHIP_STARTUP_TIMEOUT)); - if (CG2900_ACTIVE != info->main_state) { - dev_err(user->dev, "CG2900 driver failed to start\n"); + dev_dbg(user->dev, "Wait 15sec for chip to start\n"); + if (user->is_clk_user) { + dev_dbg(user->dev, "Clock user is Waiting here\n"); + wait_event_timeout(clk_user_wait_queue, + CG2900_ACTIVE_BEFORE_SELFTEST + == info->main_state, + msecs_to_jiffies(CHIP_STARTUP_TIMEOUT)); + + state_to_check = CG2900_ACTIVE_BEFORE_SELFTEST; + } else { + dev_dbg(user->dev, "Not a Clock user\n"); + wait_event_timeout(main_wait_queue, + (CG2900_ACTIVE == info->main_state || + CG2900_IDLE == info->main_state), + msecs_to_jiffies(CHIP_STARTUP_TIMEOUT)); + } + + if (state_to_check != info->main_state) { + dev_err(user->dev, "CG2900 init failed\n"); if (dev->t_cb.close) dev->t_cb.close(dev); - dev_dbg(user->dev, "New main_state: CG2900_IDLE\n"); + dev_dbg(user->dev, "main_state: CG2900_IDLE\n"); info->main_state = CG2900_IDLE; err = -EIO; goto err_free_list_item; diff --git a/drivers/staging/cg2900/mfd/cg2900_core.c b/drivers/staging/cg2900/mfd/cg2900_core.c index 6ac27748e44..b1f34d71eec 100644 --- a/drivers/staging/cg2900/mfd/cg2900_core.c +++ b/drivers/staging/cg2900/mfd/cg2900_core.c @@ -354,9 +354,6 @@ static void work_hw_registered(struct work_struct *work) if (dev->t_cb.set_chip_power) dev->t_cb.set_chip_power(dev, true); - /* Wait 100ms before continuing to be sure that the chip is ready */ - schedule_timeout_killable(msecs_to_jiffies(CHIP_READY_TIMEOUT)); - /* Set our function to receive data from chip */ dev->c_cb.data_from_chip = cg2900_data_from_chip; |