summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArun Murthy <arun.murthy@stericsson.com>2011-10-10 14:55:06 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:07:17 +0200
commit74d2fc32aa4b51a735764414e04eaaef56746a1a (patch)
tree059437da7dfd0739fc6c9728001925e300adbceb
parent34d303fe6838a2dc710c99a2d5f07f06e8dedf03 (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.c14
-rw-r--r--drivers/modem/shrm/shrm_protocol.c29
-rw-r--r--include/linux/modem/shrm/shrm_driver.h2
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;
};
/**