summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-10-08 06:35:54 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-08 06:35:54 -0700
commit5f659ecb42b62048f181a3c37fa0eed49e755789 (patch)
tree5f7148a53d2c02edf2ec6f4793367d9919c95a06 /drivers/soc
parent062b309db9be77da33176c8534fa06ff2a10e8c9 (diff)
parent0da8e4a21cba123d3c864ae6035149977cbaadbc (diff)
Merge "icnss: Wait uninterruptible for unregister driver"
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/qcom/icnss.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 460c2d1f6824..25b522806c3e 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -260,7 +260,12 @@ void *icnss_ipc_log_context;
void *icnss_ipc_log_long_context;
#endif
-#define ICNSS_EVENT_PENDING 2989
+#define ICNSS_EVENT_PENDING 2989
+
+#define ICNSS_EVENT_SYNC BIT(0)
+#define ICNSS_EVENT_UNINTERRUPTIBLE BIT(1)
+#define ICNSS_EVENT_SYNC_UNINTERRUPTIBLE (ICNSS_EVENT_UNINTERRUPTIBLE | \
+ ICNSS_EVENT_SYNC)
enum icnss_driver_event_type {
ICNSS_DRIVER_EVENT_SERVER_ARRIVE,
@@ -565,16 +570,16 @@ static char *icnss_driver_event_to_str(enum icnss_driver_event_type type)
};
static int icnss_driver_event_post(enum icnss_driver_event_type type,
- bool sync, void *data)
+ u32 flags, void *data)
{
struct icnss_driver_event *event;
- unsigned long flags;
+ unsigned long irq_flags;
int gfp = GFP_KERNEL;
int ret = 0;
- icnss_pr_dbg("Posting event: %s: %s%s(%d), state: 0x%lx\n",
- current->comm, icnss_driver_event_to_str(type),
- sync ? "-sync" : "", type, penv->state);
+ icnss_pr_dbg("Posting event: %s(%d), %s, flags: 0x%x, state: 0x%lx\n",
+ icnss_driver_event_to_str(type), type, current->comm,
+ flags, penv->state);
if (type >= ICNSS_DRIVER_EVENT_MAX) {
icnss_pr_err("Invalid Event type: %d, can't post", type);
@@ -594,31 +599,35 @@ static int icnss_driver_event_post(enum icnss_driver_event_type type,
event->data = data;
init_completion(&event->complete);
event->ret = ICNSS_EVENT_PENDING;
- event->sync = sync;
+ event->sync = !!(flags & ICNSS_EVENT_SYNC);
- spin_lock_irqsave(&penv->event_lock, flags);
+ spin_lock_irqsave(&penv->event_lock, irq_flags);
list_add_tail(&event->list, &penv->event_list);
- spin_unlock_irqrestore(&penv->event_lock, flags);
+ spin_unlock_irqrestore(&penv->event_lock, irq_flags);
penv->stats.events[type].posted++;
queue_work(penv->event_wq, &penv->event_work);
- if (!sync)
+ if (!(flags & ICNSS_EVENT_SYNC))
goto out;
- ret = wait_for_completion_interruptible(&event->complete);
+ if (flags & ICNSS_EVENT_UNINTERRUPTIBLE)
+ wait_for_completion(&event->complete);
+ else
+ ret = wait_for_completion_interruptible(&event->complete);
icnss_pr_dbg("Completed event: %s(%d), state: 0x%lx, ret: %d/%d\n",
icnss_driver_event_to_str(type), type, penv->state, ret,
event->ret);
- spin_lock_irqsave(&penv->event_lock, flags);
+ spin_lock_irqsave(&penv->event_lock, irq_flags);
if (ret == -ERESTARTSYS && event->ret == ICNSS_EVENT_PENDING) {
event->sync = false;
- spin_unlock_irqrestore(&penv->event_lock, flags);
+ spin_unlock_irqrestore(&penv->event_lock, irq_flags);
+ ret = -EINTR;
goto out;
}
- spin_unlock_irqrestore(&penv->event_lock, flags);
+ spin_unlock_irqrestore(&penv->event_lock, irq_flags);
ret = event->ret;
kfree(event);
@@ -2228,7 +2237,7 @@ static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle,
switch (msg_id) {
case QMI_WLFW_FW_READY_IND_V01:
icnss_driver_event_post(ICNSS_DRIVER_EVENT_FW_READY_IND,
- false, NULL);
+ 0, NULL);
break;
case QMI_WLFW_MSA_READY_IND_V01:
icnss_pr_dbg("Received MSA Ready Indication msg_id 0x%x\n",
@@ -2650,12 +2659,12 @@ static int icnss_qmi_wlfw_clnt_svc_event_notify(struct notifier_block *this,
switch (code) {
case QMI_SERVER_ARRIVE:
ret = icnss_driver_event_post(ICNSS_DRIVER_EVENT_SERVER_ARRIVE,
- false, NULL);
+ 0, NULL);
break;
case QMI_SERVER_EXIT:
ret = icnss_driver_event_post(ICNSS_DRIVER_EVENT_SERVER_EXIT,
- false, NULL);
+ 0, NULL);
break;
default:
icnss_pr_dbg("Invalid code: %ld", code);
@@ -2692,7 +2701,7 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
event_data->crashed = notif->crashed;
icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
- true, event_data);
+ ICNSS_EVENT_SYNC, event_data);
return NOTIFY_OK;
}
@@ -2767,7 +2776,7 @@ static int icnss_service_notifier_notify(struct notifier_block *nb,
event_data->crashed = true;
icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
- true, event_data);
+ ICNSS_EVENT_SYNC, event_data);
break;
case SERVREG_NOTIF_SERVICE_STATE_UP_V01:
icnss_pr_dbg("Service up, state: 0x%lx\n", priv->state);
@@ -2939,7 +2948,7 @@ int icnss_register_driver(struct icnss_driver_ops *ops)
}
ret = icnss_driver_event_post(ICNSS_DRIVER_EVENT_REGISTER_DRIVER,
- true, ops);
+ ICNSS_EVENT_SYNC, ops);
if (ret == -ERESTARTSYS)
ret = 0;
@@ -2967,7 +2976,7 @@ int icnss_unregister_driver(struct icnss_driver_ops *ops)
}
ret = icnss_driver_event_post(ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
- true, NULL);
+ ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
out:
return ret;
}
@@ -3871,6 +3880,7 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
seq_puts(s, "MSA0 ASSIGNED");
continue;
case ICNSS_WLFW_EXISTS:
+ seq_puts(s, "WLAN FW EXISTS");
continue;
}