msm: SSR: Consolidate loops during restart
The main restart function loops over the restart list many times
and repeats the same looping logic each time. Extract that loop
into a function and call it with a function reflecting what each
loop is doing: shutdown, ramdump, powerup, and all the notifiers
before and after.
Change-Id: Ic448367f708e9ddee151511df2be3773e9d4f63f
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 884586d..563313b 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -198,17 +198,6 @@
return order;
}
-static void _send_notification_to_order(struct subsys_device **restart_list,
- int count, enum subsys_notif_type type)
-{
- int i;
- struct subsys_device **dev;
-
- for (i = 0, dev = restart_list; i < count; i++, dev++)
- if (*dev)
- subsys_notif_queue_notification((*dev)->notify, type);
-}
-
static int max_restarts;
module_param(max_restarts, int, 0644);
@@ -273,11 +262,63 @@
mutex_unlock(&restart_log_mutex);
}
+static void for_each_subsys_device(struct subsys_device **list, unsigned count,
+ void *data, void (*fn)(struct subsys_device *, void *))
+{
+ while (count--) {
+ struct subsys_device *dev = *list++;
+ if (!dev)
+ continue;
+ fn(dev, data);
+ }
+}
+
+static void __send_notification_to_order(struct subsys_device *dev, void *data)
+{
+ enum subsys_notif_type type = (enum subsys_notif_type)data;
+
+ subsys_notif_queue_notification(dev->notify, type);
+}
+
+static void send_notification_to_order(struct subsys_device **l, unsigned n,
+ enum subsys_notif_type t)
+{
+ for_each_subsys_device(l, n, (void *)t, __send_notification_to_order);
+}
+
+static void subsystem_shutdown(struct subsys_device *dev, void *data)
+{
+ const char *name = dev->desc->name;
+
+ pr_info("[%p]: Shutting down %s\n", current, name);
+ if (dev->desc->shutdown(dev->desc) < 0)
+ panic("subsys-restart: [%p]: Failed to shutdown %s!",
+ current, name);
+}
+
+static void subsystem_ramdump(struct subsys_device *dev, void *data)
+{
+ const char *name = dev->desc->name;
+
+ if (dev->desc->ramdump)
+ if (dev->desc->ramdump(enable_ramdumps, dev->desc) < 0)
+ pr_warn("%s[%p]: Ramdump failed.\n", name, current);
+}
+
+static void subsystem_powerup(struct subsys_device *dev, void *data)
+{
+ const char *name = dev->desc->name;
+
+ pr_info("[%p]: Powering up %s\n", current, name);
+ if (dev->desc->powerup(dev->desc) < 0)
+ panic("[%p]: Failed to powerup %s!", current, name);
+}
+
static void subsystem_restart_wq_func(struct work_struct *work)
{
struct restart_wq_data *r_work = container_of(work,
struct restart_wq_data, work);
- struct subsys_device **restart_list;
+ struct subsys_device **list;
struct subsys_device *dev = r_work->dev;
struct subsys_desc *desc = dev->desc;
struct subsys_soc_restart_order *soc_restart_order = NULL;
@@ -285,8 +326,7 @@
struct mutex *powerup_lock;
struct mutex *shutdown_lock;
- int i;
- int restart_list_count = 0;
+ unsigned count;
if (r_work->use_restart_order)
soc_restart_order = dev->restart_order;
@@ -297,13 +337,13 @@
* restart order is not being traversed.
*/
if (!soc_restart_order) {
- restart_list = &dev;
- restart_list_count = 1;
+ list = &dev;
+ count = 1;
powerup_lock = &dev->powerup_lock;
shutdown_lock = &dev->shutdown_lock;
} else {
- restart_list = soc_restart_order->subsys_ptrs;
- restart_list_count = soc_restart_order->count;
+ list = soc_restart_order->subsys_ptrs;
+ count = soc_restart_order->count;
powerup_lock = &soc_restart_order->powerup_lock;
shutdown_lock = &soc_restart_order->shutdown_lock;
}
@@ -340,28 +380,9 @@
pr_debug("[%p]: Starting restart sequence for %s\n", current,
desc->name);
-
- _send_notification_to_order(restart_list,
- restart_list_count,
- SUBSYS_BEFORE_SHUTDOWN);
-
- for (i = 0; i < restart_list_count; i++) {
- const struct subsys_device *dev = restart_list[i];
- const char *name;
-
- if (!dev)
- continue;
- name = dev->desc->name;
-
- pr_info("[%p]: Shutting down %s\n", current, name);
-
- if (dev->desc->shutdown(dev->desc) < 0)
- panic("subsys-restart: %s[%p]: Failed to shutdown %s!",
- __func__, current, name);
- }
-
- _send_notification_to_order(restart_list, restart_list_count,
- SUBSYS_AFTER_SHUTDOWN);
+ send_notification_to_order(list, count, SUBSYS_BEFORE_SHUTDOWN);
+ for_each_subsys_device(list, count, NULL, subsystem_shutdown);
+ send_notification_to_order(list, count, SUBSYS_AFTER_SHUTDOWN);
/*
* Now that we've finished shutting down these subsystems, release the
@@ -372,42 +393,11 @@
mutex_unlock(shutdown_lock);
/* Collect ram dumps for all subsystems in order here */
- for (i = 0; i < restart_list_count; i++) {
- const struct subsys_device *dev = restart_list[i];
- const char *name;
+ for_each_subsys_device(list, count, NULL, subsystem_ramdump);
- if (!dev)
- continue;
- name = dev->desc->name;
-
- if (dev->desc->ramdump)
- if (dev->desc->ramdump(enable_ramdumps, dev->desc) < 0)
- pr_warn("%s[%p]: Ramdump failed.\n", name,
- current);
- }
-
- _send_notification_to_order(restart_list,
- restart_list_count,
- SUBSYS_BEFORE_POWERUP);
-
- for (i = restart_list_count - 1; i >= 0; i--) {
- const struct subsys_device *dev = restart_list[i];
- const char *name;
-
- if (!dev)
- continue;
- name = dev->desc->name;
-
- pr_info("[%p]: Powering up %s\n", current, name);
-
- if (dev->desc->powerup(dev->desc) < 0)
- panic("%s[%p]: Failed to powerup %s!", __func__,
- current, name);
- }
-
- _send_notification_to_order(restart_list,
- restart_list_count,
- SUBSYS_AFTER_POWERUP);
+ send_notification_to_order(list, count, SUBSYS_BEFORE_POWERUP);
+ for_each_subsys_device(list, count, NULL, subsystem_powerup);
+ send_notification_to_order(list, count, SUBSYS_AFTER_POWERUP);
pr_info("[%p]: Restart sequence for %s completed.\n",
current, desc->name);