diff options
Diffstat (limited to 'drivers/cpufreq/qcom-cpufreq-hw.c')
| -rw-r--r-- | drivers/cpufreq/qcom-cpufreq-hw.c | 39 | 
1 files changed, 19 insertions, 20 deletions
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index a2be0df7e174..05f3d7876e44 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -46,6 +46,7 @@ struct qcom_cpufreq_data {  	 */  	struct mutex throttle_lock;  	int throttle_irq; +	char irq_name[15];  	bool cancel_throttle;  	struct delayed_work throttle_work;  	struct cpufreq_policy *policy; @@ -275,10 +276,10 @@ static unsigned int qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data)  static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)  { -	unsigned long max_capacity, capacity, freq_hz, throttled_freq;  	struct cpufreq_policy *policy = data->policy;  	int cpu = cpumask_first(policy->cpus);  	struct device *dev = get_cpu_device(cpu); +	unsigned long freq_hz, throttled_freq;  	struct dev_pm_opp *opp;  	unsigned int freq; @@ -295,16 +296,8 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)  	throttled_freq = freq_hz / HZ_PER_KHZ; -	/* Update thermal pressure */ - -	max_capacity = arch_scale_cpu_capacity(cpu); -	capacity = mult_frac(max_capacity, throttled_freq, policy->cpuinfo.max_freq); - -	/* Don't pass boost capacity to scheduler */ -	if (capacity > max_capacity) -		capacity = max_capacity; - -	arch_set_thermal_pressure(policy->cpus, max_capacity - capacity); +	/* Update thermal pressure (the boost frequencies are accepted) */ +	arch_update_thermal_pressure(policy->related_cpus, throttled_freq);  	/*  	 * In the unlikely case policy is unregistered do not enable @@ -342,9 +335,9 @@ static irqreturn_t qcom_lmh_dcvs_handle_irq(int irq, void *data)  	/* Disable interrupt and enable polling */  	disable_irq_nosync(c_data->throttle_irq); -	qcom_lmh_dcvs_notify(c_data); +	schedule_delayed_work(&c_data->throttle_work, 0); -	return 0; +	return IRQ_HANDLED;  }  static const struct qcom_cpufreq_soc_data qcom_soc_data = { @@ -375,16 +368,17 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)  {  	struct qcom_cpufreq_data *data = policy->driver_data;  	struct platform_device *pdev = cpufreq_get_driver_data(); -	char irq_name[15];  	int ret;  	/*  	 * Look for LMh interrupt. If no interrupt line is specified /  	 * if there is an error, allow cpufreq to be enabled as usual.  	 */ -	data->throttle_irq = platform_get_irq(pdev, index); -	if (data->throttle_irq <= 0) -		return data->throttle_irq == -EPROBE_DEFER ? -EPROBE_DEFER : 0; +	data->throttle_irq = platform_get_irq_optional(pdev, index); +	if (data->throttle_irq == -ENXIO) +		return 0; +	if (data->throttle_irq < 0) +		return data->throttle_irq;  	data->cancel_throttle = false;  	data->policy = policy; @@ -392,14 +386,19 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)  	mutex_init(&data->throttle_lock);  	INIT_DEFERRABLE_WORK(&data->throttle_work, qcom_lmh_dcvs_poll); -	snprintf(irq_name, sizeof(irq_name), "dcvsh-irq-%u", policy->cpu); +	snprintf(data->irq_name, sizeof(data->irq_name), "dcvsh-irq-%u", policy->cpu);  	ret = request_threaded_irq(data->throttle_irq, NULL, qcom_lmh_dcvs_handle_irq, -				   IRQF_ONESHOT, irq_name, data); +				   IRQF_ONESHOT, data->irq_name, data);  	if (ret) { -		dev_err(&pdev->dev, "Error registering %s: %d\n", irq_name, ret); +		dev_err(&pdev->dev, "Error registering %s: %d\n", data->irq_name, ret);  		return 0;  	} +	ret = irq_set_affinity_hint(data->throttle_irq, policy->cpus); +	if (ret) +		dev_err(&pdev->dev, "Failed to set CPU affinity of %s[%d]\n", +			data->irq_name, data->throttle_irq); +  	return 0;  }  |