Loading drivers/cpuidle/lpm-levels.c +24 −5 Original line number Diff line number Diff line Loading @@ -83,7 +83,7 @@ struct lpm_debug { }; static struct system_pm_ops *sys_pm_ops; static DEFINE_SPINLOCK(bc_timer_lock); struct lpm_cluster *lpm_root_node; Loading Loading @@ -1029,6 +1029,7 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, struct lpm_cluster_level *level = &cluster->levels[idx]; struct cpumask online_cpus, cpumask; unsigned int cpu; int ret = 0; cpumask_and(&online_cpus, &cluster->num_children_in_sync, cpu_online_mask); Loading Loading @@ -1067,10 +1068,14 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, clear_predict_history(); clear_cl_predict_history(); if (sys_pm_ops && sys_pm_ops->enter) if ((sys_pm_ops->enter(&cpumask))) if (sys_pm_ops && sys_pm_ops->enter) { spin_lock(&bc_timer_lock); ret = sys_pm_ops->enter(&cpumask); spin_unlock(&bc_timer_lock); if (ret) return -EBUSY; } } /* Notify cluster enter event after successfully config completion */ cluster_notify(cluster, level, true); Loading Loading @@ -1202,8 +1207,11 @@ static void cluster_unprepare(struct lpm_cluster *cluster, level = &cluster->levels[cluster->last_level]; if (level->notify_rpm) if (sys_pm_ops && sys_pm_ops->exit) if (sys_pm_ops && sys_pm_ops->exit) { spin_lock(&bc_timer_lock); sys_pm_ops->exit(); spin_unlock(&bc_timer_lock); } update_debug_pc_event(CLUSTER_EXIT, cluster->last_level, cluster->num_children_in_sync.bits[0], Loading Loading @@ -1298,6 +1306,7 @@ static bool psci_enter_sleep(struct lpm_cpu *cpu, int idx, bool from_idle) { int affinity_level = 0, state_id = 0, power_state = 0; bool success = false; int ret = 0; /* * idx = 0 is the default LPM state */ Loading @@ -1310,7 +1319,17 @@ static bool psci_enter_sleep(struct lpm_cpu *cpu, int idx, bool from_idle) } if (from_idle && cpu->levels[idx].use_bc_timer) { if (tick_broadcast_enter()) /* * tick_broadcast_enter can change the affinity of the * broadcast timer interrupt, during which interrupt will * be disabled and enabled back. To avoid system pm ops * doing any interrupt state save or restore in between * this window hold the lock. */ spin_lock(&bc_timer_lock); ret = tick_broadcast_enter(); spin_unlock(&bc_timer_lock); if (ret) return success; } Loading Loading
drivers/cpuidle/lpm-levels.c +24 −5 Original line number Diff line number Diff line Loading @@ -83,7 +83,7 @@ struct lpm_debug { }; static struct system_pm_ops *sys_pm_ops; static DEFINE_SPINLOCK(bc_timer_lock); struct lpm_cluster *lpm_root_node; Loading Loading @@ -1029,6 +1029,7 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, struct lpm_cluster_level *level = &cluster->levels[idx]; struct cpumask online_cpus, cpumask; unsigned int cpu; int ret = 0; cpumask_and(&online_cpus, &cluster->num_children_in_sync, cpu_online_mask); Loading Loading @@ -1067,10 +1068,14 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, clear_predict_history(); clear_cl_predict_history(); if (sys_pm_ops && sys_pm_ops->enter) if ((sys_pm_ops->enter(&cpumask))) if (sys_pm_ops && sys_pm_ops->enter) { spin_lock(&bc_timer_lock); ret = sys_pm_ops->enter(&cpumask); spin_unlock(&bc_timer_lock); if (ret) return -EBUSY; } } /* Notify cluster enter event after successfully config completion */ cluster_notify(cluster, level, true); Loading Loading @@ -1202,8 +1207,11 @@ static void cluster_unprepare(struct lpm_cluster *cluster, level = &cluster->levels[cluster->last_level]; if (level->notify_rpm) if (sys_pm_ops && sys_pm_ops->exit) if (sys_pm_ops && sys_pm_ops->exit) { spin_lock(&bc_timer_lock); sys_pm_ops->exit(); spin_unlock(&bc_timer_lock); } update_debug_pc_event(CLUSTER_EXIT, cluster->last_level, cluster->num_children_in_sync.bits[0], Loading Loading @@ -1298,6 +1306,7 @@ static bool psci_enter_sleep(struct lpm_cpu *cpu, int idx, bool from_idle) { int affinity_level = 0, state_id = 0, power_state = 0; bool success = false; int ret = 0; /* * idx = 0 is the default LPM state */ Loading @@ -1310,7 +1319,17 @@ static bool psci_enter_sleep(struct lpm_cpu *cpu, int idx, bool from_idle) } if (from_idle && cpu->levels[idx].use_bc_timer) { if (tick_broadcast_enter()) /* * tick_broadcast_enter can change the affinity of the * broadcast timer interrupt, during which interrupt will * be disabled and enabled back. To avoid system pm ops * doing any interrupt state save or restore in between * this window hold the lock. */ spin_lock(&bc_timer_lock); ret = tick_broadcast_enter(); spin_unlock(&bc_timer_lock); if (ret) return success; } Loading