From 58b0e564d0ec0055d48d8666526b93643774d8e8 Mon Sep 17 00:00:00 2001 From: Arun Murthy Date: Mon, 10 Oct 2011 14:55:06 +0530 Subject: 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 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33416 Reviewed-by: Bibek BASU Reviewed-by: QABUILD Reviewed-by: Magnus TEMPLING Reviewed-by: Rickard EVERTSSON Reviewed-by: Srinidhi KASAGAR --- drivers/modem/shrm/shrm_fifo.c | 14 +++++++++++--- drivers/modem/shrm/shrm_protocol.c | 29 ++++++++++++++++++++++------- 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 #include #include +#include #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<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<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<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; }; /** -- cgit v1.2.3