[1/7] pinctrl: sunxi: add support for pin controllers without bus gate

Message ID 20180106042326.46519-1-icenowy@aosc.io
State New
Headers show
Series
  • Initial Allwinner H6 support
Related show

Commit Message

Icenowy Zheng Jan. 6, 2018, 4:23 a.m.
The Allwinner H6 pin controllers (both the main one and the CPUs one)
have no bus gate clocks.

Add support for this kind of pin controllers.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30 ++++++++++++++++++++----------
 drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
 2 files changed, 21 insertions(+), 10 deletions(-)

Comments

Andre Przywara Jan. 11, 2018, 10:08 a.m. | #1
Hi,

On 06/01/18 04:23, Icenowy Zheng wrote:
> The Allwinner H6 pin controllers (both the main one and the CPUs one)
> have no bus gate clocks.
> 
> Add support for this kind of pin controllers.
> 
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30 ++++++++++++++++++++----------
>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
>  2 files changed, 21 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> index 4b6cb25bc796..68cd505679d9 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
>  	unsigned int hosc_div, losc_div;
>  	struct clk *hosc, *losc;
>  	u8 div, src;
> -	int i, ret;
> +	int i, ret, clk_count;
> +
> +	if (pctl->desc->without_bus_gate)
> +		clk_count = 2;
> +	else
> +		clk_count = 3;
>  
>  	/* Deal with old DTs that didn't have the oscillators */
>  	if (of_count_phandle_with_args(node, "clocks", "#clock-cells") != 3)
> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
>  			goto gpiochip_error;
>  	}
>  
> -	clk = devm_clk_get(&pdev->dev, NULL);
> -	if (IS_ERR(clk)) {
> -		ret = PTR_ERR(clk);
> -		goto gpiochip_error;
> -	}
> +	if (!desc->without_bus_gate) {

Do we really need explicit support for that case?
Can't we have something that works automatically?

if (node has clock-names property)		(A)
	use clocks as enumerated and named there
else if (node has one clock reference)		(B)
	use this as gate clock, no debounce support
else if (node has no clock property at all)	(C)
	no gate clock needed, no debounce support

On top of that we should add the clock-names property to all DTs, even
for those with only a "apb" clock. Shouldn't hurt existing kernels.
Possibly even add debounce support for those on the way, if applicable.

So we would just support case (B) and (C) for legacy reasons.

Does that make sense?

Cheers,
Andre.

> +		clk = devm_clk_get(&pdev->dev, NULL);
> +		if (IS_ERR(clk)) {
> +			ret = PTR_ERR(clk);
> +			goto gpiochip_error;
> +		}
>  
> -	ret = clk_prepare_enable(clk);
> -	if (ret)
> -		goto gpiochip_error;
> +		ret = clk_prepare_enable(clk);
> +		if (ret)
> +			goto gpiochip_error;
> +	} else {
> +		clk = NULL;
> +	}
>  
>  	pctl->irq = devm_kcalloc(&pdev->dev,
>  				 pctl->desc->irq_banks,
> @@ -1425,7 +1434,8 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
>  	return 0;
>  
>  clk_error:
> -	clk_disable_unprepare(clk);
> +	if (clk)
> +		clk_disable_unprepare(clk);
>  gpiochip_error:
>  	gpiochip_remove(pctl->chip);
>  	return ret;
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> index 11b128f54ed2..ccb6230f0bb5 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> @@ -113,6 +113,7 @@ struct sunxi_pinctrl_desc {
>  	unsigned			irq_bank_base;
>  	bool				irq_read_needs_mux;
>  	bool				disable_strict_mode;
> +	bool				without_bus_gate;
>  };
>  
>  struct sunxi_pinctrl_function {
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Chen-Yu Tsai Jan. 11, 2018, 10:14 a.m. | #2
On Thu, Jan 11, 2018 at 6:08 PM, Andre Przywara <andre.przywara@arm.com> wrote:
> Hi,
>
> On 06/01/18 04:23, Icenowy Zheng wrote:
>> The Allwinner H6 pin controllers (both the main one and the CPUs one)
>> have no bus gate clocks.
>>
>> Add support for this kind of pin controllers.
>>
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>> ---
>>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30 ++++++++++++++++++++----------
>>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
>>  2 files changed, 21 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> index 4b6cb25bc796..68cd505679d9 100644
>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
>>       unsigned int hosc_div, losc_div;
>>       struct clk *hosc, *losc;
>>       u8 div, src;
>> -     int i, ret;
>> +     int i, ret, clk_count;
>> +
>> +     if (pctl->desc->without_bus_gate)
>> +             clk_count = 2;
>> +     else
>> +             clk_count = 3;
>>
>>       /* Deal with old DTs that didn't have the oscillators */
>>       if (of_count_phandle_with_args(node, "clocks", "#clock-cells") != 3)
>> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
>>                       goto gpiochip_error;
>>       }
>>
>> -     clk = devm_clk_get(&pdev->dev, NULL);
>> -     if (IS_ERR(clk)) {
>> -             ret = PTR_ERR(clk);
>> -             goto gpiochip_error;
>> -     }
>> +     if (!desc->without_bus_gate) {
>
> Do we really need explicit support for that case?
> Can't we have something that works automatically?
>
> if (node has clock-names property)              (A)
>         use clocks as enumerated and named there

You still need to know if the hardware has a bus gate or not.
If it's missing, and it's disabled, you end up with unusable
hardware.

Unless you are fully trusting the device tree to be correct.
IMHO that makes for hard to find bugs during SoC bringup.

ChenYu

> else if (node has one clock reference)          (B)
>         use this as gate clock, no debounce support
> else if (node has no clock property at all)     (C)
>         no gate clock needed, no debounce support
>
> On top of that we should add the clock-names property to all DTs, even
> for those with only a "apb" clock. Shouldn't hurt existing kernels.
> Possibly even add debounce support for those on the way, if applicable.
>
> So we would just support case (B) and (C) for legacy reasons.
>
> Does that make sense?
>
> Cheers,
> Andre.
>
>> +             clk = devm_clk_get(&pdev->dev, NULL);
>> +             if (IS_ERR(clk)) {
>> +                     ret = PTR_ERR(clk);
>> +                     goto gpiochip_error;
>> +             }
>>
>> -     ret = clk_prepare_enable(clk);
>> -     if (ret)
>> -             goto gpiochip_error;
>> +             ret = clk_prepare_enable(clk);
>> +             if (ret)
>> +                     goto gpiochip_error;
>> +     } else {
>> +             clk = NULL;
>> +     }
>>
>>       pctl->irq = devm_kcalloc(&pdev->dev,
>>                                pctl->desc->irq_banks,
>> @@ -1425,7 +1434,8 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
>>       return 0;
>>
>>  clk_error:
>> -     clk_disable_unprepare(clk);
>> +     if (clk)
>> +             clk_disable_unprepare(clk);
>>  gpiochip_error:
>>       gpiochip_remove(pctl->chip);
>>       return ret;
>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> index 11b128f54ed2..ccb6230f0bb5 100644
>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> @@ -113,6 +113,7 @@ struct sunxi_pinctrl_desc {
>>       unsigned                        irq_bank_base;
>>       bool                            irq_read_needs_mux;
>>       bool                            disable_strict_mode;
>> +     bool                            without_bus_gate;
>>  };
>>
>>  struct sunxi_pinctrl_function {
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Icenowy Zheng Jan. 11, 2018, 10:15 a.m. | #3
于 2018年1月11日 GMT+08:00 下午6:08:19, Andre Przywara <andre.przywara@arm.com> 写到:
>Hi,
>
>On 06/01/18 04:23, Icenowy Zheng wrote:
>> The Allwinner H6 pin controllers (both the main one and the CPUs one)
>> have no bus gate clocks.
>> 
>> Add support for this kind of pin controllers.
>> 
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>> ---
>>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30
>++++++++++++++++++++----------
>>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
>>  2 files changed, 21 insertions(+), 10 deletions(-)
>> 
>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> index 4b6cb25bc796..68cd505679d9 100644
>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct
>sunxi_pinctrl *pctl,
>>  	unsigned int hosc_div, losc_div;
>>  	struct clk *hosc, *losc;
>>  	u8 div, src;
>> -	int i, ret;
>> +	int i, ret, clk_count;
>> +
>> +	if (pctl->desc->without_bus_gate)
>> +		clk_count = 2;
>> +	else
>> +		clk_count = 3;
>>  
>>  	/* Deal with old DTs that didn't have the oscillators */
>>  	if (of_count_phandle_with_args(node, "clocks", "#clock-cells") !=
>3)
>> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct
>platform_device *pdev,
>>  			goto gpiochip_error;
>>  	}
>>  
>> -	clk = devm_clk_get(&pdev->dev, NULL);
>> -	if (IS_ERR(clk)) {
>> -		ret = PTR_ERR(clk);
>> -		goto gpiochip_error;
>> -	}
>> +	if (!desc->without_bus_gate) {
>
>Do we really need explicit support for that case?
>Can't we have something that works automatically?

It can be a sanity check. When a SoC comes with bus gate
support but no apb is provided, there's something wrong.

>
>if (node has clock-names property)		(A)
>	use clocks as enumerated and named there
>else if (node has one clock reference)		(B)
>	use this as gate clock, no debounce support
>else if (node has no clock property at all)	(C)
>	no gate clock needed, no debounce support

This should not happen in practice, as no gate clock is implemented
after debounce.

>
>On top of that we should add the clock-names property to all DTs, even
>for those with only a "apb" clock. Shouldn't hurt existing kernels.
>Possibly even add debounce support for those on the way, if applicable.
>
>So we would just support case (B) and (C) for legacy reasons.
>
>Does that make sense?
>
>Cheers,
>Andre.
>
>> +		clk = devm_clk_get(&pdev->dev, NULL);
>> +		if (IS_ERR(clk)) {
>> +			ret = PTR_ERR(clk);
>> +			goto gpiochip_error;
>> +		}
>>  
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret)
>> -		goto gpiochip_error;
>> +		ret = clk_prepare_enable(clk);
>> +		if (ret)
>> +			goto gpiochip_error;
>> +	} else {
>> +		clk = NULL;
>> +	}
>>  
>>  	pctl->irq = devm_kcalloc(&pdev->dev,
>>  				 pctl->desc->irq_banks,
>> @@ -1425,7 +1434,8 @@ int sunxi_pinctrl_init_with_variant(struct
>platform_device *pdev,
>>  	return 0;
>>  
>>  clk_error:
>> -	clk_disable_unprepare(clk);
>> +	if (clk)
>> +		clk_disable_unprepare(clk);
>>  gpiochip_error:
>>  	gpiochip_remove(pctl->chip);
>>  	return ret;
>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> index 11b128f54ed2..ccb6230f0bb5 100644
>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> @@ -113,6 +113,7 @@ struct sunxi_pinctrl_desc {
>>  	unsigned			irq_bank_base;
>>  	bool				irq_read_needs_mux;
>>  	bool				disable_strict_mode;
>> +	bool				without_bus_gate;
>>  };
>>  
>>  struct sunxi_pinctrl_function {
>> 
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andre Przywara Jan. 11, 2018, 10:23 a.m. | #4
Hi,

On 11/01/18 10:14, Chen-Yu Tsai wrote:
> On Thu, Jan 11, 2018 at 6:08 PM, Andre Przywara <andre.przywara@arm.com> wrote:
>> Hi,
>>
>> On 06/01/18 04:23, Icenowy Zheng wrote:
>>> The Allwinner H6 pin controllers (both the main one and the CPUs one)
>>> have no bus gate clocks.
>>>
>>> Add support for this kind of pin controllers.
>>>
>>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>>> ---
>>>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30 ++++++++++++++++++++----------
>>>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
>>>  2 files changed, 21 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>>> index 4b6cb25bc796..68cd505679d9 100644
>>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>>> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
>>>       unsigned int hosc_div, losc_div;
>>>       struct clk *hosc, *losc;
>>>       u8 div, src;
>>> -     int i, ret;
>>> +     int i, ret, clk_count;
>>> +
>>> +     if (pctl->desc->without_bus_gate)
>>> +             clk_count = 2;
>>> +     else
>>> +             clk_count = 3;
>>>
>>>       /* Deal with old DTs that didn't have the oscillators */
>>>       if (of_count_phandle_with_args(node, "clocks", "#clock-cells") != 3)
>>> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
>>>                       goto gpiochip_error;
>>>       }
>>>
>>> -     clk = devm_clk_get(&pdev->dev, NULL);
>>> -     if (IS_ERR(clk)) {
>>> -             ret = PTR_ERR(clk);
>>> -             goto gpiochip_error;
>>> -     }
>>> +     if (!desc->without_bus_gate) {
>>
>> Do we really need explicit support for that case?
>> Can't we have something that works automatically?
>>
>> if (node has clock-names property)              (A)
>>         use clocks as enumerated and named there
> 
> You still need to know if the hardware has a bus gate or not.
> If it's missing, and it's disabled, you end up with unusable
> hardware.

Yes. So what? If you have a broken DT, it will not work. Just don't do
it. I don't understand why we want to defend against this case.

> Unless you are fully trusting the device tree to be correct.

Sorry, but what else do we trust?

> IMHO that makes for hard to find bugs during SoC bringup.

I am not sure if that is really an issue. I would expect people doing
SoC bringup to be able to cope with those kinds of problems.

Cheers,
Andre.


> 
> ChenYu
> 
>> else if (node has one clock reference)          (B)
>>         use this as gate clock, no debounce support
>> else if (node has no clock property at all)     (C)
>>         no gate clock needed, no debounce support
>>
>> On top of that we should add the clock-names property to all DTs, even
>> for those with only a "apb" clock. Shouldn't hurt existing kernels.
>> Possibly even add debounce support for those on the way, if applicable.
>>
>> So we would just support case (B) and (C) for legacy reasons.
>>
>> Does that make sense?
>>
>> Cheers,
>> Andre.
>>
>>> +             clk = devm_clk_get(&pdev->dev, NULL);
>>> +             if (IS_ERR(clk)) {
>>> +                     ret = PTR_ERR(clk);
>>> +                     goto gpiochip_error;
>>> +             }
>>>
>>> -     ret = clk_prepare_enable(clk);
>>> -     if (ret)
>>> -             goto gpiochip_error;
>>> +             ret = clk_prepare_enable(clk);
>>> +             if (ret)
>>> +                     goto gpiochip_error;
>>> +     } else {
>>> +             clk = NULL;
>>> +     }
>>>
>>>       pctl->irq = devm_kcalloc(&pdev->dev,
>>>                                pctl->desc->irq_banks,
>>> @@ -1425,7 +1434,8 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
>>>       return 0;
>>>
>>>  clk_error:
>>> -     clk_disable_unprepare(clk);
>>> +     if (clk)
>>> +             clk_disable_unprepare(clk);
>>>  gpiochip_error:
>>>       gpiochip_remove(pctl->chip);
>>>       return ret;
>>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>>> index 11b128f54ed2..ccb6230f0bb5 100644
>>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>>> @@ -113,6 +113,7 @@ struct sunxi_pinctrl_desc {
>>>       unsigned                        irq_bank_base;
>>>       bool                            irq_read_needs_mux;
>>>       bool                            disable_strict_mode;
>>> +     bool                            without_bus_gate;
>>>  };
>>>
>>>  struct sunxi_pinctrl_function {
>>>
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Maxime Ripard Jan. 11, 2018, 10:41 a.m. | #5
On Thu, Jan 11, 2018 at 10:23:52AM +0000, Andre Przywara wrote:
> Hi,
> 
> On 11/01/18 10:14, Chen-Yu Tsai wrote:
> > On Thu, Jan 11, 2018 at 6:08 PM, Andre Przywara <andre.przywara@arm.com> wrote:
> >> Hi,
> >>
> >> On 06/01/18 04:23, Icenowy Zheng wrote:
> >>> The Allwinner H6 pin controllers (both the main one and the CPUs one)
> >>> have no bus gate clocks.
> >>>
> >>> Add support for this kind of pin controllers.
> >>>
> >>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> >>> ---
> >>>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30 ++++++++++++++++++++----------
> >>>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
> >>>  2 files changed, 21 insertions(+), 10 deletions(-)
> >>>
> >>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> >>> index 4b6cb25bc796..68cd505679d9 100644
> >>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> >>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> >>> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
> >>>       unsigned int hosc_div, losc_div;
> >>>       struct clk *hosc, *losc;
> >>>       u8 div, src;
> >>> -     int i, ret;
> >>> +     int i, ret, clk_count;
> >>> +
> >>> +     if (pctl->desc->without_bus_gate)
> >>> +             clk_count = 2;
> >>> +     else
> >>> +             clk_count = 3;
> >>>
> >>>       /* Deal with old DTs that didn't have the oscillators */
> >>>       if (of_count_phandle_with_args(node, "clocks", "#clock-cells") != 3)
> >>> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
> >>>                       goto gpiochip_error;
> >>>       }
> >>>
> >>> -     clk = devm_clk_get(&pdev->dev, NULL);
> >>> -     if (IS_ERR(clk)) {
> >>> -             ret = PTR_ERR(clk);
> >>> -             goto gpiochip_error;
> >>> -     }
> >>> +     if (!desc->without_bus_gate) {
> >>
> >> Do we really need explicit support for that case?
> >> Can't we have something that works automatically?
> >>
> >> if (node has clock-names property)              (A)
> >>         use clocks as enumerated and named there
> > 
> > You still need to know if the hardware has a bus gate or not.
> > If it's missing, and it's disabled, you end up with unusable
> > hardware.
> 
> Yes. So what? If you have a broken DT, it will not work. Just don't do
> it. I don't understand why we want to defend against this case.

This is not the point, but rather: if we have a way to detect easily
that the device tree is missing a property that is missing in our
binding, why shouldn't we do it?

We're already doing it for reg and interrupts for example, why not for
the clocks?

> > Unless you are fully trusting the device tree to be correct.
> 
> Sorry, but what else do we trust?
> 
> > IMHO that makes for hard to find bugs during SoC bringup.
> 
> I am not sure if that is really an issue. I would expect people
> doing SoC bringup to be able to cope with those kinds of problems.

Riiiight, because it worked so well in the past. We definitely didn't
overlooked some clocks used for debouncing in this particular driver,
or some to get the timekeeping right in the RTC.

The argument that "anyone who codes in the kernel should just know
better" doesn't work, on multiple levels. Because anyone that actually
knows better can make a mistake or overlook some feature (because you
didn't have your morning coffee yet, or because it was undocumented)
and because you just make someone that doesn't feel bad.

So, yes, we cannot not trust the device tree. But if we have a way to
detect simple mistakes in the binding, we should also do it.

Maxime
Andre Przywara Jan. 11, 2018, 10:41 a.m. | #6
Hi,

On 11/01/18 10:15, Icenowy Zheng wrote:
> 
> 
> 于 2018年1月11日 GMT+08:00 下午6:08:19, Andre Przywara <andre.przywara@arm.com> 写到:
>> Hi,
>>
>> On 06/01/18 04:23, Icenowy Zheng wrote:
>>> The Allwinner H6 pin controllers (both the main one and the CPUs one)
>>> have no bus gate clocks.
>>>
>>> Add support for this kind of pin controllers.
>>>
>>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>>> ---
>>>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30
>> ++++++++++++++++++++----------
>>>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
>>>  2 files changed, 21 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>>> index 4b6cb25bc796..68cd505679d9 100644
>>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>>> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct
>> sunxi_pinctrl *pctl,
>>>  	unsigned int hosc_div, losc_div;
>>>  	struct clk *hosc, *losc;
>>>  	u8 div, src;
>>> -	int i, ret;
>>> +	int i, ret, clk_count;
>>> +
>>> +	if (pctl->desc->without_bus_gate)
>>> +		clk_count = 2;
>>> +	else
>>> +		clk_count = 3;
>>>  
>>>  	/* Deal with old DTs that didn't have the oscillators */
>>>  	if (of_count_phandle_with_args(node, "clocks", "#clock-cells") !=
>> 3)

Just spotted: I guess you wanted to compare against that computed value
here?
But I wonder if we can get rid of this check at all? Don't we rely on
clock-names and input-debounce anyway? So we will bail out later anyway
if the DT does not have those?
Why do we need this check then?

>>> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct
>> platform_device *pdev,
>>>  			goto gpiochip_error;
>>>  	}
>>>  
>>> -	clk = devm_clk_get(&pdev->dev, NULL);
>>> -	if (IS_ERR(clk)) {
>>> -		ret = PTR_ERR(clk);
>>> -		goto gpiochip_error;
>>> -	}
>>> +	if (!desc->without_bus_gate) {
>>
>> Do we really need explicit support for that case?
>> Can't we have something that works automatically?
> 
> It can be a sanity check. When a SoC comes with bus gate
> support but no apb is provided, there's something wrong.
> 
>>
>> if (node has clock-names property)		(A)
>> 	use clocks as enumerated and named there
>> else if (node has one clock reference)		(B)
>> 	use this as gate clock, no debounce support
>> else if (node has no clock property at all)	(C)
>> 	no gate clock needed, no debounce support
> 
> This should not happen in practice, as no gate clock is implemented
> after debounce.

But still you seem to somewhat support it with your changes above - by
bailing out if there aren't two clocks.
This kind of explicitly checking for a certain number of clocks sounds
not very robust and future proof to me, hence the suggestion to get rid
of it.

Cheers,
Andre.

>>
>> On top of that we should add the clock-names property to all DTs, even
>> for those with only a "apb" clock. Shouldn't hurt existing kernels.
>> Possibly even add debounce support for those on the way, if applicable.
>>
>> So we would just support case (B) and (C) for legacy reasons.
>>
>> Does that make sense?
>>
>> Cheers,
>> Andre.
>>
>>> +		clk = devm_clk_get(&pdev->dev, NULL);
>>> +		if (IS_ERR(clk)) {
>>> +			ret = PTR_ERR(clk);
>>> +			goto gpiochip_error;
>>> +		}
>>>  
>>> -	ret = clk_prepare_enable(clk);
>>> -	if (ret)
>>> -		goto gpiochip_error;
>>> +		ret = clk_prepare_enable(clk);
>>> +		if (ret)
>>> +			goto gpiochip_error;
>>> +	} else {
>>> +		clk = NULL;
>>> +	}
>>>  
>>>  	pctl->irq = devm_kcalloc(&pdev->dev,
>>>  				 pctl->desc->irq_banks,
>>> @@ -1425,7 +1434,8 @@ int sunxi_pinctrl_init_with_variant(struct
>> platform_device *pdev,
>>>  	return 0;
>>>  
>>>  clk_error:
>>> -	clk_disable_unprepare(clk);
>>> +	if (clk)
>>> +		clk_disable_unprepare(clk);
>>>  gpiochip_error:
>>>  	gpiochip_remove(pctl->chip);
>>>  	return ret;
>>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>>> index 11b128f54ed2..ccb6230f0bb5 100644
>>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>>> @@ -113,6 +113,7 @@ struct sunxi_pinctrl_desc {
>>>  	unsigned			irq_bank_base;
>>>  	bool				irq_read_needs_mux;
>>>  	bool				disable_strict_mode;
>>> +	bool				without_bus_gate;
>>>  };
>>>  
>>>  struct sunxi_pinctrl_function {
>>>
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Icenowy Zheng Jan. 11, 2018, 10:43 a.m. | #7
在 2018年1月11日星期四 CST 下午6:41:00,Maxime Ripard 写道:
> On Thu, Jan 11, 2018 at 10:23:52AM +0000, Andre Przywara wrote:
> > Hi,
> > 
> > On 11/01/18 10:14, Chen-Yu Tsai wrote:
> > > On Thu, Jan 11, 2018 at 6:08 PM, Andre Przywara <andre.przywara@arm.com> 
wrote:
> > >> Hi,
> > >> 
> > >> On 06/01/18 04:23, Icenowy Zheng wrote:
> > >>> The Allwinner H6 pin controllers (both the main one and the CPUs one)
> > >>> have no bus gate clocks.
> > >>> 
> > >>> Add support for this kind of pin controllers.
> > >>> 
> > >>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> > >>> ---
> > >>> 
> > >>>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30
> > >>>  ++++++++++++++++++++----------
> > >>>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
> > >>>  2 files changed, 21 insertions(+), 10 deletions(-)
> > >>> 
> > >>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> > >>> b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index
> > >>> 4b6cb25bc796..68cd505679d9 100644
> > >>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> > >>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> > >>> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct
> > >>> sunxi_pinctrl *pctl,> >>> 
> > >>>       unsigned int hosc_div, losc_div;
> > >>>       struct clk *hosc, *losc;
> > >>>       u8 div, src;
> > >>> 
> > >>> -     int i, ret;
> > >>> +     int i, ret, clk_count;
> > >>> +
> > >>> +     if (pctl->desc->without_bus_gate)
> > >>> +             clk_count = 2;
> > >>> +     else
> > >>> +             clk_count = 3;
> > >>> 
> > >>>       /* Deal with old DTs that didn't have the oscillators */
> > >>>       if (of_count_phandle_with_args(node, "clocks", "#clock-cells")
> > >>>       != 3)
> > >>> 
> > >>> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct
> > >>> platform_device *pdev,> >>> 
> > >>>                       goto gpiochip_error;
> > >>>       
> > >>>       }
> > >>> 
> > >>> -     clk = devm_clk_get(&pdev->dev, NULL);
> > >>> -     if (IS_ERR(clk)) {
> > >>> -             ret = PTR_ERR(clk);
> > >>> -             goto gpiochip_error;
> > >>> -     }
> > >>> +     if (!desc->without_bus_gate) {
> > >> 
> > >> Do we really need explicit support for that case?
> > >> Can't we have something that works automatically?
> > >> 
> > >> if (node has clock-names property)              (A)
> > >> 
> > >>         use clocks as enumerated and named there
> > > 
> > > You still need to know if the hardware has a bus gate or not.
> > > If it's missing, and it's disabled, you end up with unusable
> > > hardware.
> > 
> > Yes. So what? If you have a broken DT, it will not work. Just don't do
> > it. I don't understand why we want to defend against this case.
> 
> This is not the point, but rather: if we have a way to detect easily
> that the device tree is missing a property that is missing in our
> binding, why shouldn't we do it?
> 
> We're already doing it for reg and interrupts for example, why not for
> the clocks?
> 
> > > Unless you are fully trusting the device tree to be correct.
> > 
> > Sorry, but what else do we trust?
> > 
> > > IMHO that makes for hard to find bugs during SoC bringup.
> > 
> > I am not sure if that is really an issue. I would expect people
> > doing SoC bringup to be able to cope with those kinds of problems.
> 
> Riiiight, because it worked so well in the past. We definitely didn't
> overlooked some clocks used for debouncing in this particular driver,
> or some to get the timekeeping right in the RTC.
> 
> The argument that "anyone who codes in the kernel should just know
> better" doesn't work, on multiple levels. Because anyone that actually
> knows better can make a mistake or overlook some feature (because you
> didn't have your morning coffee yet, or because it was undocumented)
> and because you just make someone that doesn't feel bad.

I agree it here -- when I'm doing initial trial on H6 I didn't found that apb 
gate is missing ;-)

> 
> So, yes, we cannot not trust the device tree. But if we have a way to
> detect simple mistakes in the binding, we should also do it.
> 
> Maxime


--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andre Przywara Jan. 11, 2018, 11:48 a.m. | #8
Hi,

On 11/01/18 10:41, Maxime Ripard wrote:
> On Thu, Jan 11, 2018 at 10:23:52AM +0000, Andre Przywara wrote:
>> Hi,
>>
>> On 11/01/18 10:14, Chen-Yu Tsai wrote:
>>> On Thu, Jan 11, 2018 at 6:08 PM, Andre Przywara <andre.przywara@arm.com> wrote:
>>>> Hi,
>>>>
>>>> On 06/01/18 04:23, Icenowy Zheng wrote:
>>>>> The Allwinner H6 pin controllers (both the main one and the CPUs one)
>>>>> have no bus gate clocks.
>>>>>
>>>>> Add support for this kind of pin controllers.
>>>>>
>>>>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>>>>> ---
>>>>>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30 ++++++++++++++++++++----------
>>>>>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
>>>>>  2 files changed, 21 insertions(+), 10 deletions(-)
>>>>>
>>>>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>>>>> index 4b6cb25bc796..68cd505679d9 100644
>>>>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>>>>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>>>>> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
>>>>>       unsigned int hosc_div, losc_div;
>>>>>       struct clk *hosc, *losc;
>>>>>       u8 div, src;
>>>>> -     int i, ret;
>>>>> +     int i, ret, clk_count;
>>>>> +
>>>>> +     if (pctl->desc->without_bus_gate)
>>>>> +             clk_count = 2;
>>>>> +     else
>>>>> +             clk_count = 3;
>>>>>
>>>>>       /* Deal with old DTs that didn't have the oscillators */
>>>>>       if (of_count_phandle_with_args(node, "clocks", "#clock-cells") != 3)
>>>>> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
>>>>>                       goto gpiochip_error;
>>>>>       }
>>>>>
>>>>> -     clk = devm_clk_get(&pdev->dev, NULL);
>>>>> -     if (IS_ERR(clk)) {
>>>>> -             ret = PTR_ERR(clk);
>>>>> -             goto gpiochip_error;
>>>>> -     }
>>>>> +     if (!desc->without_bus_gate) {
>>>>
>>>> Do we really need explicit support for that case?
>>>> Can't we have something that works automatically?
>>>>
>>>> if (node has clock-names property)              (A)
>>>>         use clocks as enumerated and named there
>>>
>>> You still need to know if the hardware has a bus gate or not.
>>> If it's missing, and it's disabled, you end up with unusable
>>> hardware.
>>
>> Yes. So what? If you have a broken DT, it will not work. Just don't do
>> it. I don't understand why we want to defend against this case.
> 
> This is not the point, but rather: if we have a way to detect easily
> that the device tree is missing a property that is missing in our
> binding, why shouldn't we do it?
> 
> We're already doing it for reg and interrupts for example, why not for
> the clocks?
> 
>>> Unless you are fully trusting the device tree to be correct.
>>
>> Sorry, but what else do we trust?
>>
>>> IMHO that makes for hard to find bugs during SoC bringup.
>>
>> I am not sure if that is really an issue. I would expect people
>> doing SoC bringup to be able to cope with those kinds of problems.
> 
> Riiiight, because it worked so well in the past. We definitely didn't
> overlooked some clocks used for debouncing in this particular driver,
> or some to get the timekeeping right in the RTC.

I think that's a different issue, because debouncing is an optional
feature. How would those kind of explicit molly guards here have
prevented this omission in the past, when we only discovered that later?

> The argument that "anyone who codes in the kernel should just know
> better" doesn't work, on multiple levels. Because anyone that actually
> knows better can make a mistake or overlook some feature (because you
> didn't have your morning coffee yet, or because it was undocumented)
> and because you just make someone that doesn't feel bad.

I agree to that. But: If something doesn't work, checking clocks and
reset would be my first impulse. And Icenowy did exactly that and
quickly found it.
Plus this only protects against known pitfalls.

> So, yes, we cannot not trust the device tree. But if we have a way to
> detect simple mistakes in the binding, we should also do it.

I totally honour that, I am just wondering what price we pay for that.
This kind of: "We need three clocks here, or wait, two clock in this
particular case" sounds a bit dodgy and little future proof to me.
Which is somewhat confirmed by the fact that we need to adjust this
check now. So I suggest we remove it, as we have more, actual checks
afterwards anyway. That should cover future extensions without further ado:
The clock-names property should cater nicely for those cases, hence my
suggestion to rely on it. Plus we need to support the legacy DTs with
just a single clock and no clock-names. Done.
So I think we should change the devm_get_clk(..., NULL) to
devm_get_clk(..., "apb"), and then check for just a single unnamed clock
if that fails (older DTs), or no clock at all, if we need to support
future SoCs without debouncing.

Looking deeper I actually think we are not binding compliant at the
moment, as we rely on the "apb" clock to be the first one, however
clock-names = "hosc", "losc", "apb" would be perfectly legal as well, as
we don't document a certain order of the clock - which is not necessary
with clock-names.

I can make a patch if we agree on that.

Cheers,
Andre.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andre Przywara Jan. 11, 2018, 11:48 a.m. | #9
Hi,

another take to avoid this patch at all, I just remembered this from an
IRC discussion before:

On 06/01/18 04:23, Icenowy Zheng wrote:
> The Allwinner H6 pin controllers (both the main one and the CPUs one)
> have no bus gate clocks.

I don't think this is true. The pin controller *needs* an APB clock,
it's just not gate-able or not exposed or documented.
The "system bus tree" on page 90 in the manual shows that the "GPIO"
block is located on the APB1 bus.
So can't we just reference this apb clock directly? That would be much
cleaner, "more" correct and require less changes: "The best patch is no
patch":

	clocks = <&ccu APB1>, <&osc24M>, <&osc32k>;
	/* or whatever this APB clock is actually called. */
	clock-names = "apb", "hosc", "losc";

Cheers,
Andre.

> 
> Add support for this kind of pin controllers.
> 
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30 ++++++++++++++++++++----------
>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
>  2 files changed, 21 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> index 4b6cb25bc796..68cd505679d9 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
>  	unsigned int hosc_div, losc_div;
>  	struct clk *hosc, *losc;
>  	u8 div, src;
> -	int i, ret;
> +	int i, ret, clk_count;
> +
> +	if (pctl->desc->without_bus_gate)
> +		clk_count = 2;
> +	else
> +		clk_count = 3;
>  
>  	/* Deal with old DTs that didn't have the oscillators */
>  	if (of_count_phandle_with_args(node, "clocks", "#clock-cells") != 3)
> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
>  			goto gpiochip_error;
>  	}
>  
> -	clk = devm_clk_get(&pdev->dev, NULL);
> -	if (IS_ERR(clk)) {
> -		ret = PTR_ERR(clk);
> -		goto gpiochip_error;
> -	}
> +	if (!desc->without_bus_gate) {
> +		clk = devm_clk_get(&pdev->dev, NULL);
> +		if (IS_ERR(clk)) {
> +			ret = PTR_ERR(clk);
> +			goto gpiochip_error;
> +		}
>  
> -	ret = clk_prepare_enable(clk);
> -	if (ret)
> -		goto gpiochip_error;
> +		ret = clk_prepare_enable(clk);
> +		if (ret)
> +			goto gpiochip_error;
> +	} else {
> +		clk = NULL;
> +	}
>  
>  	pctl->irq = devm_kcalloc(&pdev->dev,
>  				 pctl->desc->irq_banks,
> @@ -1425,7 +1434,8 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
>  	return 0;
>  
>  clk_error:
> -	clk_disable_unprepare(clk);
> +	if (clk)
> +		clk_disable_unprepare(clk);
>  gpiochip_error:
>  	gpiochip_remove(pctl->chip);
>  	return ret;
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> index 11b128f54ed2..ccb6230f0bb5 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> @@ -113,6 +113,7 @@ struct sunxi_pinctrl_desc {
>  	unsigned			irq_bank_base;
>  	bool				irq_read_needs_mux;
>  	bool				disable_strict_mode;
> +	bool				without_bus_gate;
>  };
>  
>  struct sunxi_pinctrl_function {
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Icenowy Zheng Jan. 11, 2018, 1:21 p.m. | #10
于 2018年1月11日 GMT+08:00 下午7:48:40, Andre Przywara <andre.przywara@arm.com> 写到:
>Hi,
>
>another take to avoid this patch at all, I just remembered this from an
>IRC discussion before:
>
>On 06/01/18 04:23, Icenowy Zheng wrote:
>> The Allwinner H6 pin controllers (both the main one and the CPUs one)
>> have no bus gate clocks.
>
>I don't think this is true. The pin controller *needs* an APB clock,
>it's just not gate-able or not exposed or documented.
>The "system bus tree" on page 90 in the manual shows that the "GPIO"
>block is located on the APB1 bus.
>So can't we just reference this apb clock directly? That would be much
>cleaner, "more" correct and require less changes: "The best patch is no
>patch":

I can accept this. (In fact I have considered this, but
I don't dare to directly use bus clock in a device, as it's not
exported before.

Maxime, Chen-Yu, can you agree the following code?

>
>	clocks = <&ccu APB1>, <&osc24M>, <&osc32k>;
>	/* or whatever this APB clock is actually called. */
>	clock-names = "apb", "hosc", "losc";
>
>Cheers,
>Andre.
>
>> 
>> Add support for this kind of pin controllers.
>> 
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>> ---
>>  drivers/pinctrl/sunxi/pinctrl-sunxi.c | 30
>++++++++++++++++++++----------
>>  drivers/pinctrl/sunxi/pinctrl-sunxi.h |  1 +
>>  2 files changed, 21 insertions(+), 10 deletions(-)
>> 
>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> index 4b6cb25bc796..68cd505679d9 100644
>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
>> @@ -1182,7 +1182,12 @@ static int sunxi_pinctrl_setup_debounce(struct
>sunxi_pinctrl *pctl,
>>  	unsigned int hosc_div, losc_div;
>>  	struct clk *hosc, *losc;
>>  	u8 div, src;
>> -	int i, ret;
>> +	int i, ret, clk_count;
>> +
>> +	if (pctl->desc->without_bus_gate)
>> +		clk_count = 2;
>> +	else
>> +		clk_count = 3;
>>  
>>  	/* Deal with old DTs that didn't have the oscillators */
>>  	if (of_count_phandle_with_args(node, "clocks", "#clock-cells") !=
>3)
>> @@ -1360,15 +1365,19 @@ int sunxi_pinctrl_init_with_variant(struct
>platform_device *pdev,
>>  			goto gpiochip_error;
>>  	}
>>  
>> -	clk = devm_clk_get(&pdev->dev, NULL);
>> -	if (IS_ERR(clk)) {
>> -		ret = PTR_ERR(clk);
>> -		goto gpiochip_error;
>> -	}
>> +	if (!desc->without_bus_gate) {
>> +		clk = devm_clk_get(&pdev->dev, NULL);
>> +		if (IS_ERR(clk)) {
>> +			ret = PTR_ERR(clk);
>> +			goto gpiochip_error;
>> +		}
>>  
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret)
>> -		goto gpiochip_error;
>> +		ret = clk_prepare_enable(clk);
>> +		if (ret)
>> +			goto gpiochip_error;
>> +	} else {
>> +		clk = NULL;
>> +	}
>>  
>>  	pctl->irq = devm_kcalloc(&pdev->dev,
>>  				 pctl->desc->irq_banks,
>> @@ -1425,7 +1434,8 @@ int sunxi_pinctrl_init_with_variant(struct
>platform_device *pdev,
>>  	return 0;
>>  
>>  clk_error:
>> -	clk_disable_unprepare(clk);
>> +	if (clk)
>> +		clk_disable_unprepare(clk);
>>  gpiochip_error:
>>  	gpiochip_remove(pctl->chip);
>>  	return ret;
>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> index 11b128f54ed2..ccb6230f0bb5 100644
>> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
>> @@ -113,6 +113,7 @@ struct sunxi_pinctrl_desc {
>>  	unsigned			irq_bank_base;
>>  	bool				irq_read_needs_mux;
>>  	bool				disable_strict_mode;
>> +	bool				without_bus_gate;
>>  };
>>  
>>  struct sunxi_pinctrl_function {
>> 
>
>_______________________________________________
>linux-arm-kernel mailing list
>linux-arm-kernel@lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Maxime Ripard Jan. 12, 2018, 8:51 a.m. | #11
1;5002;0c
On Thu, Jan 11, 2018 at 09:21:06PM +0800, Icenowy Zheng wrote:
> 
> 
> 于 2018年1月11日 GMT+08:00 下午7:48:40, Andre Przywara <andre.przywara@arm.com> 写到:
> >Hi,
> >
> >another take to avoid this patch at all, I just remembered this from an
> >IRC discussion before:
> >
> >On 06/01/18 04:23, Icenowy Zheng wrote:
> >> The Allwinner H6 pin controllers (both the main one and the CPUs one)
> >> have no bus gate clocks.
> >
> >I don't think this is true. The pin controller *needs* an APB clock,
> >it's just not gate-able or not exposed or documented.
> >The "system bus tree" on page 90 in the manual shows that the "GPIO"
> >block is located on the APB1 bus.
> >So can't we just reference this apb clock directly? That would be much
> >cleaner, "more" correct and require less changes: "The best patch is no
> >patch":
> 
> I can accept this. (In fact I have considered this, but
> I don't dare to directly use bus clock in a device, as it's not
> exported before.
> 
> Maxime, Chen-Yu, can you agree the following code?

Yes, that works for me.

Maxime

Patch

diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 4b6cb25bc796..68cd505679d9 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -1182,7 +1182,12 @@  static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
 	unsigned int hosc_div, losc_div;
 	struct clk *hosc, *losc;
 	u8 div, src;
-	int i, ret;
+	int i, ret, clk_count;
+
+	if (pctl->desc->without_bus_gate)
+		clk_count = 2;
+	else
+		clk_count = 3;
 
 	/* Deal with old DTs that didn't have the oscillators */
 	if (of_count_phandle_with_args(node, "clocks", "#clock-cells") != 3)
@@ -1360,15 +1365,19 @@  int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
 			goto gpiochip_error;
 	}
 
-	clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
-		goto gpiochip_error;
-	}
+	if (!desc->without_bus_gate) {
+		clk = devm_clk_get(&pdev->dev, NULL);
+		if (IS_ERR(clk)) {
+			ret = PTR_ERR(clk);
+			goto gpiochip_error;
+		}
 
-	ret = clk_prepare_enable(clk);
-	if (ret)
-		goto gpiochip_error;
+		ret = clk_prepare_enable(clk);
+		if (ret)
+			goto gpiochip_error;
+	} else {
+		clk = NULL;
+	}
 
 	pctl->irq = devm_kcalloc(&pdev->dev,
 				 pctl->desc->irq_banks,
@@ -1425,7 +1434,8 @@  int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
 	return 0;
 
 clk_error:
-	clk_disable_unprepare(clk);
+	if (clk)
+		clk_disable_unprepare(clk);
 gpiochip_error:
 	gpiochip_remove(pctl->chip);
 	return ret;
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index 11b128f54ed2..ccb6230f0bb5 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -113,6 +113,7 @@  struct sunxi_pinctrl_desc {
 	unsigned			irq_bank_base;
 	bool				irq_read_needs_mux;
 	bool				disable_strict_mode;
+	bool				without_bus_gate;
 };
 
 struct sunxi_pinctrl_function {