diff mbox series

[v4,7/7] irqchip: qcom-pdc: Reset all pdc interrupts during init

Message ID 1597058460-16211-8-git-send-email-mkshah@codeaurora.org (mailing list archive)
State Superseded
Headers show
Series irqchip: qcom: pdc: Introduce irq_set_wake call | expand

Commit Message

Maulik Shah Aug. 10, 2020, 11:21 a.m. UTC
Clear previous kernel's configuration during init by resetting
interrupts in enable bank to zero.

Suggested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
---
 drivers/irqchip/qcom-pdc.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

Felipe Balbi Aug. 10, 2020, 12:09 p.m. UTC | #1
Maulik Shah <mkshah@codeaurora.org> writes:

> Clear previous kernel's configuration during init by resetting
> interrupts in enable bank to zero.
>
> Suggested-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
> ---
>  drivers/irqchip/qcom-pdc.c | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c
> index dfcdfc5..80e0dfb 100644
> --- a/drivers/irqchip/qcom-pdc.c
> +++ b/drivers/irqchip/qcom-pdc.c
> @@ -389,7 +389,8 @@ static const struct irq_domain_ops qcom_pdc_gpio_ops = {
>  
>  static int pdc_setup_pin_mapping(struct device_node *np)
>  {
> -	int ret, n;
> +	int ret, n, i;
> +	u32 irq_index, reg_index, val;
>  
>  	n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32));
>  	if (n <= 0 || n % 3)
> @@ -418,6 +419,15 @@ static int pdc_setup_pin_mapping(struct device_node *np)
>  						 &pdc_region[n].cnt);
>  		if (ret)
>  			return ret;
> +
> +		for (i = pdc_region[n].pin_base; i < pdc_region[n].pin_base +
> +						 pdc_region[n].cnt; i++) {

how about making the for loop slightly easier to read by moving pin_base
inside the loop?

	for (i = 0; i < pdc_region[n].cnt; i++) {
        	reg_index = (i + pdc_region[n].pin_base) >> 5;
        	irq_index = (i + pdc_region[n].pin_base) & 0x1f;

		[...]
        }
Stephen Boyd Aug. 11, 2020, 9:31 p.m. UTC | #2
Quoting Maulik Shah (2020-08-10 04:21:00)
> Clear previous kernel's configuration during init by resetting
> interrupts in enable bank to zero.

Can you please add some more information here about why we're not
clearing all the pdc irqs and only the ones that are listed in DT? Is
that because the pdc is shared between exception levels of the CPU and
so some irqs shouldn't be used? Does the DT binding need to change to
only list the hwirqs that are usable by the OS instead of the ones that
are usable for the entire system? The binding doesn't mention this at
all so I am just guessing here.

> 
> Suggested-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
Maulik Shah Aug. 13, 2020, 7:21 a.m. UTC | #3
Hi,

On 8/10/2020 5:39 PM, Felipe Balbi wrote:
> Maulik Shah <mkshah@codeaurora.org> writes:
>
>> Clear previous kernel's configuration during init by resetting
>> interrupts in enable bank to zero.
>>
>> Suggested-by: Stephen Boyd <swboyd@chromium.org>
>> Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
>> ---
>>   drivers/irqchip/qcom-pdc.c | 12 +++++++++++-
>>   1 file changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c
>> index dfcdfc5..80e0dfb 100644
>> --- a/drivers/irqchip/qcom-pdc.c
>> +++ b/drivers/irqchip/qcom-pdc.c
>> @@ -389,7 +389,8 @@ static const struct irq_domain_ops qcom_pdc_gpio_ops = {
>>   
>>   static int pdc_setup_pin_mapping(struct device_node *np)
>>   {
>> -	int ret, n;
>> +	int ret, n, i;
>> +	u32 irq_index, reg_index, val;
>>   
>>   	n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32));
>>   	if (n <= 0 || n % 3)
>> @@ -418,6 +419,15 @@ static int pdc_setup_pin_mapping(struct device_node *np)
>>   						 &pdc_region[n].cnt);
>>   		if (ret)
>>   			return ret;
>> +
>> +		for (i = pdc_region[n].pin_base; i < pdc_region[n].pin_base +
>> +						 pdc_region[n].cnt; i++) {
> how about making the for loop slightly easier to read by moving pin_base
> inside the loop?
>
> 	for (i = 0; i < pdc_region[n].cnt; i++) {
>          	reg_index = (i + pdc_region[n].pin_base) >> 5;
>          	irq_index = (i + pdc_region[n].pin_base) & 0x1f;
>
> 		[...]
>          }

Sure, i will move pin_base inside for loop in v5.

Thanks,
Maulik
Maulik Shah Aug. 13, 2020, 7:30 a.m. UTC | #4
Hi,

On 8/12/2020 3:01 AM, Stephen Boyd wrote:
> Quoting Maulik Shah (2020-08-10 04:21:00)
>> Clear previous kernel's configuration during init by resetting
>> interrupts in enable bank to zero.
> Can you please add some more information here about why we're not
> clearing all the pdc irqs and only the ones that are listed in DT?
sure.
>   Is
> that because the pdc is shared between exception levels of the CPU and
> so some irqs shouldn't be used? Does the DT binding need to change to
> only list the hwirqs that are usable by the OS instead of the ones that
> are usable for the entire system? The binding doesn't mention this at
> all so I am just guessing here.

The IRQs specified in qcom,pdc-ranges property in DT are the only ones 
that can be used in the current OS for the PDC.

So instead of setting entire register to zero (each reg supports 32 
interrupts enable bit) only clearing the ones that can be used.

Thanks,
Maulik

>
>> Suggested-by: Stephen Boyd <swboyd@chromium.org>
>> Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
Stephen Boyd Aug. 14, 2020, 8:24 p.m. UTC | #5
Quoting Maulik Shah (2020-08-13 00:30:44)
> Hi,
> 
> On 8/12/2020 3:01 AM, Stephen Boyd wrote:
> > Quoting Maulik Shah (2020-08-10 04:21:00)
> >> Clear previous kernel's configuration during init by resetting
> >> interrupts in enable bank to zero.
> > Can you please add some more information here about why we're not
> > clearing all the pdc irqs and only the ones that are listed in DT?
> sure.
> >   Is
> > that because the pdc is shared between exception levels of the CPU and
> > so some irqs shouldn't be used? Does the DT binding need to change to
> > only list the hwirqs that are usable by the OS instead of the ones that
> > are usable for the entire system? The binding doesn't mention this at
> > all so I am just guessing here.
> 
> The IRQs specified in qcom,pdc-ranges property in DT are the only ones 
> that can be used in the current OS for the PDC.
> 
> So instead of setting entire register to zero (each reg supports 32 
> interrupts enable bit) only clearing the ones that can be used.
> 

Ok. Is something wrong with setting all the register bits to 0? Is there
something else in those registers that shouldn't be touched? Please add
these details to the commit message.
diff mbox series

Patch

diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c
index dfcdfc5..80e0dfb 100644
--- a/drivers/irqchip/qcom-pdc.c
+++ b/drivers/irqchip/qcom-pdc.c
@@ -389,7 +389,8 @@  static const struct irq_domain_ops qcom_pdc_gpio_ops = {
 
 static int pdc_setup_pin_mapping(struct device_node *np)
 {
-	int ret, n;
+	int ret, n, i;
+	u32 irq_index, reg_index, val;
 
 	n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32));
 	if (n <= 0 || n % 3)
@@ -418,6 +419,15 @@  static int pdc_setup_pin_mapping(struct device_node *np)
 						 &pdc_region[n].cnt);
 		if (ret)
 			return ret;
+
+		for (i = pdc_region[n].pin_base; i < pdc_region[n].pin_base +
+						 pdc_region[n].cnt; i++) {
+			reg_index = i / 32;
+			irq_index = i % 32;
+			val = pdc_reg_read(IRQ_ENABLE_BANK, reg_index);
+			val &= ~BIT(irq_index);
+			pdc_reg_write(IRQ_ENABLE_BANK, reg_index, val);
+		}
 	}
 
 	return 0;