diff options
author | Arun Murthy <arun.murthy@stericsson.com> | 2011-10-10 14:55:06 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:07:17 +0200 |
commit | 74d2fc32aa4b51a735764414e04eaaef56746a1a (patch) | |
tree | 059437da7dfd0739fc6c9728001925e300adbceb | |
parent | 34d303fe6838a2dc710c99a2d5f07f06e8dedf03 (diff) |
u8500-shrm: Initiate MSR in case of serious bug
During APE-Modem communication, for some reasson if software or hardware
fails, instead of calling kernel function BUG() and halting the system
making it no more useful until reboot, initiate a MSR.
ST-Ericsson Linux next: NA
ST-Ericsson ID: 366150
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I59e93b338c3242b506be7775487be065421022b8
Signed-off-by: Arun Murthy <arun.murthy@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33416
Reviewed-by: Bibek BASU <bibek.basu@stericsson.com>
Reviewed-by: QABUILD
Reviewed-by: Magnus TEMPLING <magnus.templing@stericsson.com>
Reviewed-by: Rickard EVERTSSON <rickard.evertsson@stericsson.com>
Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r-- | drivers/modem/shrm/shrm_fifo.c | 14 | ||||
-rw-r--r-- | drivers/modem/shrm/shrm_protocol.c | 29 | ||||
-rw-r--r-- | include/linux/modem/shrm/shrm_driver.h | 2 |
3 files changed, 35 insertions, 10 deletions
diff --git a/drivers/modem/shrm/shrm_fifo.c b/drivers/modem/shrm/shrm_fifo.c index 1f0f9202e51..57da56f4905 100644 --- a/drivers/modem/shrm/shrm_fifo.c +++ b/drivers/modem/shrm/shrm_fifo.c @@ -11,6 +11,7 @@ #include <linux/modem/shrm/shrm_driver.h> #include <linux/modem/shrm/shrm_private.h> #include <linux/modem/shrm/shrm_net.h> +#include <linux/mfd/dbx500-prcmu.h> #define L1_BOOT_INFO_REQ 1 #define L1_BOOT_INFO_RESP 2 @@ -109,7 +110,10 @@ u8 read_boot_info_req(struct shrm_dev *shrm, if (msgtype != L1_BOOT_INFO_REQ) { dev_err(shrm->dev, "Read_Boot_Info_Req Fatal ERROR\n"); dev_err(shrm->dev, "Received msgtype is %d\n", msgtype); - BUG(); + dev_info(shrm->dev, "Initiating a modem reset\n"); + queue_work(shrm->shm_ac_wake_wq, + &shrm->shm_mod_reset_req); + return 0; } *config = (header >> CONFIG_OFFSET) & MASK_0_15_BIT; *version = header & MASK_0_15_BIT; @@ -416,7 +420,9 @@ u8 read_one_l2msg_common(struct shrm_dev *shrm, fifo->end_addr_fifo); /* Fatal ERROR - should never happens */ dev_crit(shrm->dev, "Fatal ERROR - should never happen\n"); - BUG(); + dev_info(shrm->dev, "Initiating a modem reset\n"); + queue_work(shrm->shm_ac_wake_wq, + &shrm->shm_mod_reset_req); } if (fifo->reader_local_rptr == (fifo->end_addr_fifo-1)) { l2_header = (*((u32 *)fifo->fifo_virtual_addr)); @@ -522,7 +528,9 @@ u8 read_one_l2msg_audio(struct shrm_dev *shrm, dev_info(shrm->dev, "Received msgtype is %d\n", msgtype); /* Fatal ERROR - should never happens */ dev_crit(shrm->dev, "Fatal ERROR - should never happen\n"); - BUG(); + dev_info(shrm->dev, "Initiating a modem reset\n"); + queue_work(shrm->shm_ac_wake_wq, + &shrm->shm_mod_reset_req); } if (fifo->reader_local_rptr == (fifo->end_addr_fifo-1)) { l2_header = (*((u32 *)fifo->fifo_virtual_addr)); diff --git a/drivers/modem/shrm/shrm_protocol.c b/drivers/modem/shrm/shrm_protocol.c index 50443e4803a..e34a88676be 100644 --- a/drivers/modem/shrm/shrm_protocol.c +++ b/drivers/modem/shrm/shrm_protocol.c @@ -70,6 +70,11 @@ enum shrm_nl { SHRM_NL_STATUS_MOD_OFFLINE, }; +void shm_mod_reset_req_work(struct work_struct *work) +{ + prcmu_modem_reset(); +} + static void shm_ac_sleep_req_work(struct work_struct *work) { mutex_lock(&ac_state_mutex); @@ -264,7 +269,7 @@ void shm_ca_msgpending_0_tasklet(unsigned long tasklet_data) if (!read_boot_info_req(shrm, &config, &version)) { dev_err(shrm->dev, "Unable to read boot state\n"); - BUG(); + return; } /* SendReadNotification */ ca_msg_read_notification_0(shrm); @@ -468,8 +473,11 @@ void shm_ca_wake_req_work(struct work_struct *work) mutex_unlock(&ac_state_mutex); /* send ca_wake_ack_interrupt to CMU */ - if (!get_host_accessport_val()) - BUG(); + if (!get_host_accessport_val()) { + dev_crit(shrm->dev, "get_host_accessport failed\n"); + dev_info(shrm->dev, "Initiating a modem reset\n"); + prcmu_modem_reset(); + } writel((1<<GOP_CA_WAKE_ACK_BIT), shm_dev->intr_base + GOP_SET_REGISTER_BASE); } @@ -611,8 +619,11 @@ static void send_ac_msg_pend_notify_0_work(struct work_struct *work) modem_request(shrm->modem); mutex_unlock(&ac_state_mutex); - if (!get_host_accessport_val()) - BUG(); + if (!get_host_accessport_val()) { + dev_crit(shrm->dev, "get_host_accessport failed\n"); + dev_info(shrm->dev, "Initiating a modem reset\n"); + prcmu_modem_reset(); + } /* Trigger AcMsgPendingNotification to CMU */ writel((1<<GOP_COMMON_AC_MSG_PENDING_NOTIFICATION_BIT), @@ -638,8 +649,11 @@ static void send_ac_msg_pend_notify_1_work(struct work_struct *work) modem_request(shrm->modem); mutex_unlock(&ac_state_mutex); - if (!get_host_accessport_val()) - BUG(); + if (!get_host_accessport_val()) { + dev_crit(shrm->dev, "get_host_accessport failed\n"); + dev_info(shrm->dev, "Initiating a modem reset\n"); + prcmu_modem_reset(); + } /* Trigger AcMsgPendingNotification to CMU */ writel((1<<GOP_AUDIO_AC_MSG_PENDING_NOTIFICATION_BIT), @@ -734,6 +748,7 @@ int shrm_protocol_init(struct shrm_dev *shrm, INIT_WORK(&shrm->shm_ca_sleep_req, shm_ca_sleep_req_work); INIT_WORK(&shrm->shm_ac_sleep_req, shm_ac_sleep_req_work); INIT_WORK(&shrm->shm_ac_wake_req, shm_ac_wake_req_work); + INIT_WORK(&shrm->shm_mod_reset_req, shm_mod_reset_req_work); /* set tasklet data */ shm_ca_0_tasklet.data = (unsigned long)shrm; diff --git a/include/linux/modem/shrm/shrm_driver.h b/include/linux/modem/shrm/shrm_driver.h index e7b87005565..8fa215571eb 100644 --- a/include/linux/modem/shrm/shrm_driver.h +++ b/include/linux/modem/shrm/shrm_driver.h @@ -77,6 +77,7 @@ * @shm_ca_wake_req: work to send cmt-ape wake request * @shm_ca_sleep_req: work to send cmt-ape sleep request * @shm_ac_sleep_req: work to send ape-cmt sleep request + * @shm_mod_reset_req: work to send a reset request to modem */ struct shrm_dev { u8 ca_wake_irq; @@ -127,6 +128,7 @@ struct shrm_dev { struct work_struct shm_ca_wake_req; struct work_struct shm_ca_sleep_req; struct work_struct shm_ac_sleep_req; + struct work_struct shm_mod_reset_req; }; /** |