staging: ozwpan: Make oz_pd_stop atomic
Spencer Sutterlin [Tue, 17 Nov 2015 02:50:02 +0000 (18:50 -0800)]
Change responsibility of holding g_polling_lock to caller of
oz_services_stop()

Bug 200151967

Change-Id: I3a1d5d12d1c03153a62555c3ccd4121e90671afa
Signed-off-by: Spencer Sutterlin <ssutterlin@nvidia.com>
Reviewed-on: http://git-master/r/833613
GVS: Gerrit_Virtual_Submit
Reviewed-by: Vinayak Pane <vpane@nvidia.com>
(cherry picked from commit 7d3b6be98e84526eef2d731e544d58f1d6f309dd)
Reviewed-on: http://git-master/r/837862
Reviewed-by: Dhiren Parmar <dparmar@nvidia.com>
Tested-by: Dhiren Parmar <dparmar@nvidia.com>

drivers/staging/ozwpan/ozpd.c
drivers/staging/ozwpan/ozproto.c

index 37e0f8f..86b00bf 100644 (file)
@@ -354,6 +354,7 @@ int oz_services_start(struct oz_pd *pd, u16 apps, int resume)
 }
 /*------------------------------------------------------------------------------
  * Context: softirq or process
+ * Caller responsible for holding g_polling_lock
  */
 void oz_services_stop(struct oz_pd *pd, u16 apps, int pause)
 {
@@ -363,14 +364,12 @@ void oz_services_stop(struct oz_pd *pd, u16 apps, int pause)
                apps |= 1<<OZ_APPID_SERIAL;
        for (ai = g_app_if; ai < &g_app_if[OZ_APPID_MAX]; ai++) {
                if (apps & (1<<ai->app_id)) {
-                       oz_polling_lock_bh();
                        if (pause) {
                                pd->paused_apps |= (1<<ai->app_id);
                        } else {
                                pd->total_apps &= ~(1<<ai->app_id);
                                pd->paused_apps &= ~(1<<ai->app_id);
                        }
-                       oz_polling_unlock_bh();
                        if (ai->stop)
                                ai->stop(pd, pause);
                }
@@ -403,21 +402,23 @@ void oz_pd_heartbeat(struct oz_pd *pd, u16 apps)
 void oz_pd_stop(struct oz_pd *pd)
 {
        u16 stop_apps = 0;
-       oz_trace_msg(M, "oz_pd_stop() State = 0x%x\n", pd->state);
        oz_polling_lock_bh();
+       if (pd == NULL) {
+               oz_polling_unlock_bh();
+               return;
+       }
+       oz_trace_msg(M, "oz_pd_stop() State = 0x%x\n", pd->state);
        if (pd->state == OZ_PD_S_STOPPED) {
                pr_info("%s: pd already stopped, return\n", __func__);
                oz_polling_unlock_bh();
                return;
        }
        oz_pd_indicate_farewells(pd);
+       oz_pd_set_state(pd, OZ_PD_S_STOPPED);
        stop_apps = pd->total_apps;
        pd->total_apps = 0;
        pd->paused_apps = 0;
-       oz_polling_unlock_bh();
        oz_services_stop(pd, stop_apps, 0);
-       oz_polling_lock_bh();
-       oz_pd_set_state(pd, OZ_PD_S_STOPPED);
 
        if (hrtimer_active(&pd->timeout)) {
                oz_trace_msg(M, "hrtimer timeout active\n");
@@ -459,12 +460,13 @@ int oz_pd_sleep(struct oz_pd *pd)
                do_stop = 1;
        }
        stop_apps = pd->total_apps;
-       oz_polling_unlock_bh();
        if (do_stop) {
+               oz_polling_unlock_bh();
                pr_info("%s: disconnect requested from device\n", __func__);
                oz_pd_stop(pd);
        } else {
                oz_services_stop(pd, stop_apps, 1);
+               oz_polling_unlock_bh();
                oz_timer_add(pd, OZ_TIMER_STOP, pd->keep_alive);
        }
        return do_stop;
index 173bca6..cd2cd4f 100644 (file)
@@ -272,8 +272,11 @@ done:
                if (resume_apps)
                        if (oz_services_start(pd, resume_apps, 1))
                                rsp_status = OZ_STATUS_TOO_MANY_PDS;
-               if (stop_apps)
+               if (stop_apps) {
+                       spin_lock_bh(&g_polling_lock);
                        oz_services_stop(pd, stop_apps, 0);
+                       spin_unlock_bh(&g_polling_lock);
+               }
                oz_pd_request_heartbeat(pd);
        } else {
                spin_unlock_bh(&g_polling_lock);