On 27-07-21, 11:25, Thara Gopinath wrote: > +static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) > +{ > + /* In the unlikely case cpufreq is de-registered do not enable polling or h/w interrupt */ > + > + spin_lock(&data->throttle_lock); > + if (data->cancel_throttle) { > + spin_unlock(&data->throttle_lock); > + return; > + } > + spin_unlock(&data->throttle_lock); > + > + /* > + * If h/w throttled frequency is higher than what cpufreq has requested for, stop > + * polling and switch back to interrupt mechanism > + */ > + > + if (throttled_freq >= qcom_cpufreq_hw_get(cpumask_first(policy->cpus))) > + /* Clear the existing interrupts and enable it back */ > + enable_irq(data->throttle_irq); > + else > + mod_delayed_work(system_highpri_wq, &data->throttle_work, > + msecs_to_jiffies(10)); > +} > +static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data) > +{ > + if (data->throttle_irq <= 0) > + return; > + > + spin_lock(&data->throttle_lock); > + data->cancel_throttle = true; > + spin_unlock(&data->throttle_lock); > + cancel_delayed_work_sync(&data->throttle_work); > + free_irq(data->throttle_irq, data); > +} Lets see if we can still make it break :) CPU0 CPU1 qcom_lmh_dcvs_notify() qcom_cpufreq_hw_lmh_exit() spin_unlock() spin_lock(), cancel_throttle = true spin_unlock() cancel_delayed_work_sync() mod_delayed_work() free_irq() kfree(data) qcom_lmh_dcvs_poll() Uses data. Sorry, locking is fun :) -- viresh