summaryrefslogtreecommitdiff
path: root/drivers/staging/cg2900/mfd
diff options
context:
space:
mode:
authornitin.dhingra <nitin.dhingra@stericsson.com>2011-11-16 16:22:19 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:05:57 +0200
commitba58062a85795460be0658d5c4930b103eb15de2 (patch)
treec7e5dd7ee0ad4e0975287a3a01d4066a53b5c692 /drivers/staging/cg2900/mfd
parent07694d213b343410cd3c7461f54ab29d2027fd88 (diff)
cg2900: Code optimizations for CG2900 init time
Some general code optimizations during intialization done. Also we are releasing clock user like WLAN earlier as READ SELF TEST is not required for WLAN functionality. All these optimizations are done to reduce CG2900 init time which will also impact WLAN start-up time. Also ESD Clamp workaround has been removed from the code completely. This is not required anymore. ST-Ericsson Linux next: NA ST-Ericsson ID: 370603 ST-Ericsson FOSS-OUT ID: trivial Change-Id: I7895e21193d20d24ff65a51ff3591108d575399c Signed-off-by: Nitin Dhingra <nitin.dhingra@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/37998 Reviewed-by: QATOOLS
Diffstat (limited to 'drivers/staging/cg2900/mfd')
-rw-r--r--drivers/staging/cg2900/mfd/cg2900_chip.c67
-rw-r--r--drivers/staging/cg2900/mfd/cg2900_core.c3
2 files changed, 53 insertions, 17 deletions
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;