summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJaewon Kim <jaewon02.kim@samsung.com>2014-10-10 16:54:22 +0900
committerJaewon Kim <jaewon02.kim@samsung.com>2014-10-13 15:11:49 +0900
commit2c32e60fa5fda0df9bf2cdda1dcd2c2c4639a28e (patch)
tree9a153bc220ca136b9bf0a680fef41aedb0cc38ac /drivers
parent4f4be99ddfb041f99d9c6041b04c108e7deeac72 (diff)
downloadlinux-3.10-2c32e60fa5fda0df9bf2cdda1dcd2c2c4639a28e.tar.gz
linux-3.10-2c32e60fa5fda0df9bf2cdda1dcd2c2c4639a28e.tar.bz2
linux-3.10-2c32e60fa5fda0df9bf2cdda1dcd2c2c4639a28e.zip
sensorhub: Move MCU firmware check to workqueue
MCU firmware check process in ssp_probe() moves to workqueue to reduce booting time. And when driver try to check MCU revision, MCU is not ready to communicate. So, this patch uses delayed workqueue to wait MCU. Change-Id: I2a64d195fc4a7910884a6da03e9a0f8846c17ac3 Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/sensorhub/stm/ssp.h1
-rw-r--r--drivers/sensorhub/stm/ssp_dev.c67
2 files changed, 40 insertions, 28 deletions
diff --git a/drivers/sensorhub/stm/ssp.h b/drivers/sensorhub/stm/ssp.h
index 49cdc80cb92..f567cffc9d9 100644
--- a/drivers/sensorhub/stm/ssp.h
+++ b/drivers/sensorhub/stm/ssp.h
@@ -455,6 +455,7 @@ struct ssp_data {
#endif
struct delayed_work work_firmware;
struct delayed_work work_refresh;
+ struct delayed_work work_mcu_state;
struct miscdevice shtc1_device;
/*snamy.jeong@samsung.com temporary code for voice data sending to mcu*/
diff --git a/drivers/sensorhub/stm/ssp_dev.c b/drivers/sensorhub/stm/ssp_dev.c
index 616514939ad..249e7c346b0 100644
--- a/drivers/sensorhub/stm/ssp_dev.c
+++ b/drivers/sensorhub/stm/ssp_dev.c
@@ -214,6 +214,41 @@ static void work_function_firmware_update(struct work_struct *work)
ssp_info("firmware update done!\n");
}
+static void work_function_mcu_state(struct work_struct *work)
+{
+ struct ssp_data *data = container_of((struct delayed_work*)work,
+ struct ssp_data, work_mcu_state);
+ int iRet;
+
+ ssp_info("MCU state check!\n");
+
+ /* check boot loader binary */
+ data->fw_dl_state = check_fwbl(data);
+ switch (data->fw_dl_state) {
+ case FW_DL_STATE_FAIL:
+ data->bSspShutdown = true;
+ break;
+ case FW_DL_STATE_NONE:
+ iRet = initialize_mcu(data);
+ if (iRet < SUCCESS) {
+ ssp_err("initialize_mcu retry\n");
+ data->uResetCnt++;
+ toggle_mcu_reset(data);
+ msleep(SSP_SW_RESET_TIME);
+ initialize_mcu(data);
+ }
+ break;
+ case FW_DL_STATE_NEED_TO_SCHEDULE:
+ ssp_info("Firmware update is scheduled\n");
+ schedule_delayed_work(&data->work_firmware,
+ msecs_to_jiffies(1000));
+ data->fw_dl_state = FW_DL_STATE_SCHEDULED;
+ break;
+ default:
+ break;
+ }
+}
+
static int check_ap_rev(void)
{
return system_rev;
@@ -410,6 +445,7 @@ static int ssp_probe(struct spi_device *spi)
initialize_variable(data);
INIT_DELAYED_WORK(&data->work_firmware, work_function_firmware_update);
+ INIT_DELAYED_WORK(&data->work_mcu_state, work_function_mcu_state);
iRet = initialize_input_dev(data);
if (iRet < 0) {
@@ -455,42 +491,19 @@ static int ssp_probe(struct spi_device *spi)
ssp_sensorhub_remove(data);
}
#endif
-
ssp_enable(data, true);
- /* check boot loader binary */
- data->fw_dl_state = check_fwbl(data);
-
- if (data->fw_dl_state == FW_DL_STATE_NONE) {
- iRet = initialize_mcu(data);
- if (iRet == ERROR) {
- toggle_mcu_reset(data);
- } else if (iRet < ERROR) {
- ssp_err("initialize_mcu failed\n");
- goto err_read_reg;
- }
- }
+ schedule_delayed_work(&data->work_mcu_state,
+ msecs_to_jiffies(200));
#ifdef CONFIG_HAS_EARLYSUSPEND
data->early_suspend.suspend = ssp_early_suspend;
data->early_suspend.resume = ssp_late_resume;
register_early_suspend(&data->early_suspend);
#endif
-
ssp_info("probe success!\n");
enable_debug_timer(data);
-
- if (data->fw_dl_state == FW_DL_STATE_NEED_TO_SCHEDULE) {
- ssp_info("Firmware update is scheduled\n");
- schedule_delayed_work(&data->work_firmware,
- msecs_to_jiffies(1000));
- data->fw_dl_state = FW_DL_STATE_SCHEDULED;
- } else if (data->fw_dl_state == FW_DL_STATE_FAIL) {
- data->bSspShutdown = true;
- }
-
data->bProbeIsDone = true;
- iRet = 0;
if (data->check_lpmode() == true) {
ssp_charging_motion(data, 1);
@@ -501,9 +514,8 @@ static int ssp_probe(struct spi_device *spi)
ssp_dbg("Normal Booting OK\n");
}
- goto exit;
+ return 0;
-err_read_reg:
err_symlink_create:
remove_sysfs(data);
err_sysfs_create:
@@ -522,7 +534,6 @@ err_input_register_device:
err_setup:
ssp_err("probe failed!\n");
-exit:
return iRet;
}