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 :)