diff mbox

[RFC,1/2] libahci_platform: add ahci_platform_get_of_property

Message ID 1403067249-8021-2-git-send-email-zhangfei.gao@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Zhangfei Gao June 18, 2014, 4:54 a.m. UTC
Instead of setting hflags in different files,
ahci_platform_get_of_property set hpriv->flags when ahci_platform_init_host
according to property in dts.

Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
---
 .../devicetree/bindings/ata/ahci-platform.txt      |    9 +++++
 drivers/ata/libahci_platform.c                     |   39 ++++++++++++++++++++
 2 files changed, 48 insertions(+)

Comments

Lothar Waßmann June 18, 2014, 7:37 a.m. UTC | #1
Hi,

Zhangfei Gao wrote:
> Instead of setting hflags in different files,
> ahci_platform_get_of_property set hpriv->flags when ahci_platform_init_host
> according to property in dts.
> 
> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
> ---
>  .../devicetree/bindings/ata/ahci-platform.txt      |    9 +++++
>  drivers/ata/libahci_platform.c                     |   39 ++++++++++++++++++++
>  2 files changed, 48 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
> index c96d8dcf98fd..c0b9f6e76ba4 100644
> --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
> +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
> @@ -26,6 +26,15 @@ Optional properties:
>  - clocks            : must contain the sata, sata_ref and ahb clocks
>  - clock-names       : must contain "ahb" for the ahb clock
>  
> +- no-ncq: when present, controller can't do NCQ, turning off CAP_NCQ
> +- 32bit-only: when present, controller can't do 64bit DMA, forcing 32bit
> +- no-msi: when present, no PCI MSI
> +- no-pmp: when present, controller can't do PMP, turning off CAP_PMP
> +- yes-ncq: when present,controller can do NCQ, turning on CAP_NCQ
> +- no-suspend: when present, controller can't do suspend
> +- yes-fbs: when present, controller can do FBS, turning on CAP_FBS
> +- no-fbs: when present, controller can't do FBS, turning off CAP_FBS
> +
'yes-...' sounds a bit silly to me.
What about 'force-...'?
That's also what the comment to the flag definitions in
drivers/ata/ahci.h says:
|AHCI_HFLAG_YES_NCQ              = (1 << 9), /* force NCQ cap on */
|AHCI_HFLAG_YES_FBS              = (1 << 14), /* force FBS cap on */


Lothar Waßmann
Mark Rutland June 18, 2014, 2:03 p.m. UTC | #2
On Wed, Jun 18, 2014 at 05:54:08AM +0100, Zhangfei Gao wrote:
> Instead of setting hflags in different files,
> ahci_platform_get_of_property set hpriv->flags when ahci_platform_init_host
> according to property in dts.

The AHCI_HFLAGS are a Linux implementation detail, so it would be nice
to have a good justification for each of these being turned into DT
properties.

> 
> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
> ---
>  .../devicetree/bindings/ata/ahci-platform.txt      |    9 +++++
>  drivers/ata/libahci_platform.c                     |   39 ++++++++++++++++++++
>  2 files changed, 48 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
> index c96d8dcf98fd..c0b9f6e76ba4 100644
> --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
> +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
> @@ -26,6 +26,15 @@ Optional properties:
>  - clocks            : must contain the sata, sata_ref and ahb clocks
>  - clock-names       : must contain "ahb" for the ahb clock
>  
> +- no-ncq: when present, controller can't do NCQ, turning off CAP_NCQ
> +- 32bit-only: when present, controller can't do 64bit DMA, forcing 32bit
> +- no-msi: when present, no PCI MSI
> +- no-pmp: when present, controller can't do PMP, turning off CAP_PMP
> +- yes-ncq: when present,controller can do NCQ, turning on CAP_NCQ
> +- no-suspend: when present, controller can't do suspend
> +- yes-fbs: when present, controller can do FBS, turning on CAP_FBS
> +- no-fbs: when present, controller can't do FBS, turning off CAP_FBS

There is absolutely no reason to mention CAP_* here; the DT should
describe the HW, not Linux internals.

Do these all make sense to be placed in DT?

I worry that for other quirks we may need more flags in future. For that
reason I'd rather figure this out in the driver based on the compatible
string.

> +
>  Examples:
>          sata@ffe08000 {
>  		compatible = "snps,spear-ahci";
> diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
> index 3a5b4ed25a4f..880b9f360056 100644
> --- a/drivers/ata/libahci_platform.c
> +++ b/drivers/ata/libahci_platform.c
> @@ -278,6 +278,44 @@ err_out:
>  }
>  EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
>  
> +#ifdef CONFIG_OF
> +static void ahci_platform_get_of_property(struct platform_device *pdev,
> +					  struct ahci_host_priv *hpriv)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +
> +	if (of_device_is_available(np)) {
> +		if (of_get_property(np, "no-ncq", NULL))
> +			hpriv->flags |= AHCI_HFLAG_NO_NCQ;

For boolean flags please use of_property_read_bool.

Mark.
Zhangfei Gao June 19, 2014, 2:22 a.m. UTC | #3
Hi Mark,

On 06/18/2014 10:03 PM, Mark Rutland wrote:
> On Wed, Jun 18, 2014 at 05:54:08AM +0100, Zhangfei Gao wrote:
>> Instead of setting hflags in different files,
>> ahci_platform_get_of_property set hpriv->flags when ahci_platform_init_host
>> according to property in dts.
>
> The AHCI_HFLAGS are a Linux implementation detail, so it would be nice
> to have a good justification for each of these being turned into DT
> properties.

Do you mean only add required property now?

Add ahci_platform_get_of_property is considering sharing 
drivers/ata/ahci_platform.c, refering sdhci_get_of_property in 
drivers/mmc/host/sdhci-pltfm.c.

The problem we met is different AHCI_HFLAGS required even in one soc 
series, for example, current version of "hisilicon,hisi-ahci" requires 
AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ, while next version solve the 
limitation, and no HFLAG required.
We may need different compatible, or it may simplier just state in dts.
What's more,  one common compatible can be used instead of adding 
specific compatible string.

>
>>
>> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
>> ---
>>   .../devicetree/bindings/ata/ahci-platform.txt      |    9 +++++
>>   drivers/ata/libahci_platform.c                     |   39 ++++++++++++++++++++
>>   2 files changed, 48 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
>> index c96d8dcf98fd..c0b9f6e76ba4 100644
>> --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
>> +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
>> @@ -26,6 +26,15 @@ Optional properties:
>>   - clocks            : must contain the sata, sata_ref and ahb clocks
>>   - clock-names       : must contain "ahb" for the ahb clock
>>
>> +- no-ncq: when present, controller can't do NCQ, turning off CAP_NCQ
>> +- 32bit-only: when present, controller can't do 64bit DMA, forcing 32bit
>> +- no-msi: when present, no PCI MSI
>> +- no-pmp: when present, controller can't do PMP, turning off CAP_PMP
>> +- yes-ncq: when present,controller can do NCQ, turning on CAP_NCQ
>> +- no-suspend: when present, controller can't do suspend
>> +- yes-fbs: when present, controller can do FBS, turning on CAP_FBS
>> +- no-fbs: when present, controller can't do FBS, turning off CAP_FBS
>
> There is absolutely no reason to mention CAP_* here; the DT should
> describe the HW, not Linux internals.
Yes, got it, will remove CAP*.

>
> Do these all make sense to be placed in DT?
Currently, "hisilicon,hisi-ahci" only need AHCI_HFLAG_NO_FBS | 
AHCI_HFLAG_NO_NCQ.
Just grep AHCI_HFLAG under ata.

>
> I worry that for other quirks we may need more flags in future. For that
> reason I'd rather figure this out in the driver based on the compatible
> string.
So do we just add no-ncq & no-fbs now?
>
>> +
>>   Examples:
>>           sata@ffe08000 {
>>   		compatible = "snps,spear-ahci";
>> diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
>> index 3a5b4ed25a4f..880b9f360056 100644
>> --- a/drivers/ata/libahci_platform.c
>> +++ b/drivers/ata/libahci_platform.c
>> @@ -278,6 +278,44 @@ err_out:
>>   }
>>   EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
>>
>> +#ifdef CONFIG_OF
>> +static void ahci_platform_get_of_property(struct platform_device *pdev,
>> +					  struct ahci_host_priv *hpriv)
>> +{
>> +	struct device_node *np = pdev->dev.of_node;
>> +
>> +	if (of_device_is_available(np)) {
>> +		if (of_get_property(np, "no-ncq", NULL))
>> +			hpriv->flags |= AHCI_HFLAG_NO_NCQ;
>
> For boolean flags please use of_property_read_bool.
Yes, it's more accurate.

Thanks for advices.
>
> Mark.
>
Zhangfei Gao June 19, 2014, 2:23 a.m. UTC | #4
On 06/18/2014 03:37 PM, Lothar Waßmann wrote:
> Hi,
>
> Zhangfei Gao wrote:
>> Instead of setting hflags in different files,
>> ahci_platform_get_of_property set hpriv->flags when ahci_platform_init_host
>> according to property in dts.
>>
>> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
>> ---
>>   .../devicetree/bindings/ata/ahci-platform.txt      |    9 +++++
>>   drivers/ata/libahci_platform.c                     |   39 ++++++++++++++++++++
>>   2 files changed, 48 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
>> index c96d8dcf98fd..c0b9f6e76ba4 100644
>> --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
>> +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
>> @@ -26,6 +26,15 @@ Optional properties:
>>   - clocks            : must contain the sata, sata_ref and ahb clocks
>>   - clock-names       : must contain "ahb" for the ahb clock
>>
>> +- no-ncq: when present, controller can't do NCQ, turning off CAP_NCQ
>> +- 32bit-only: when present, controller can't do 64bit DMA, forcing 32bit
>> +- no-msi: when present, no PCI MSI
>> +- no-pmp: when present, controller can't do PMP, turning off CAP_PMP
>> +- yes-ncq: when present,controller can do NCQ, turning on CAP_NCQ
>> +- no-suspend: when present, controller can't do suspend
>> +- yes-fbs: when present, controller can do FBS, turning on CAP_FBS
>> +- no-fbs: when present, controller can't do FBS, turning off CAP_FBS
>> +
> 'yes-...' sounds a bit silly to me.
> What about 'force-...'?

Yes, good idea, thanks for the suggestion.

> That's also what the comment to the flag definitions in
> drivers/ata/ahci.h says:
> |AHCI_HFLAG_YES_NCQ              = (1 << 9), /* force NCQ cap on */
> |AHCI_HFLAG_YES_FBS              = (1 << 14), /* force FBS cap on */
>
>
> Lothar Waßmann
>
Hans de Goede June 19, 2014, 7:39 a.m. UTC | #5
Hi,

On 06/19/2014 04:22 AM, zhangfei wrote:
> Hi Mark,
> 
> On 06/18/2014 10:03 PM, Mark Rutland wrote:
>> On Wed, Jun 18, 2014 at 05:54:08AM +0100, Zhangfei Gao wrote:
>>> Instead of setting hflags in different files,
>>> ahci_platform_get_of_property set hpriv->flags when ahci_platform_init_host
>>> according to property in dts.
>>
>> The AHCI_HFLAGS are a Linux implementation detail, so it would be nice
>> to have a good justification for each of these being turned into DT
>> properties.
> 
> Do you mean only add required property now?

No you should not add any properties at all using properties to set SoC specific quirks
is just wrong, if a device is not 100% ahci compatible you should use a SoC specific
compatible string for it, and set quirks in the kernel driver based on that.

Devicetree is supposed to describe hardware, in this case the quirks are a property
of the specific model of the hardware, so this should be expressed through the
compatible string. Extra properties in devicetree are meant to be used for board
specific things, like having a gpio to enable power to the sata target device.
Extra properties should not be used in the way you are proposing to use them now.

Regards,

Hans
Zhangfei Gao June 20, 2014, 5:56 a.m. UTC | #6
On 06/19/2014 03:39 PM, Hans de Goede wrote:
> Hi,
>
> On 06/19/2014 04:22 AM, zhangfei wrote:
>> Hi Mark,
>>
>> On 06/18/2014 10:03 PM, Mark Rutland wrote:
>>> On Wed, Jun 18, 2014 at 05:54:08AM +0100, Zhangfei Gao wrote:
>>>> Instead of setting hflags in different files,
>>>> ahci_platform_get_of_property set hpriv->flags when ahci_platform_init_host
>>>> according to property in dts.
>>>
>>> The AHCI_HFLAGS are a Linux implementation detail, so it would be nice
>>> to have a good justification for each of these being turned into DT
>>> properties.
>>
>> Do you mean only add required property now?
>
> No you should not add any properties at all using properties to set SoC specific quirks
> is just wrong, if a device is not 100% ahci compatible you should use a SoC specific
> compatible string for it, and set quirks in the kernel driver based on that.
>
> Devicetree is supposed to describe hardware, in this case the quirks are a property
> of the specific model of the hardware, so this should be expressed through the
> compatible string. Extra properties in devicetree are meant to be used for board
> specific things, like having a gpio to enable power to the sata target device.
> Extra properties should not be used in the way you are proposing to use them now.
>

OK, got it.

What I thoutht is using ahci_platform_get_of_property could make 
ahci_platform.c more shareable, adding the chance of removing specific 
compatible.
Just refer mmc_of_parse and sdhci_get_of_property, they are parsing 
property directly from dts.

Anyway, it is fine, here is not so many cases like mmc.

Thanks
Hans de Goede June 20, 2014, 7:38 a.m. UTC | #7
Hi,

On 06/20/2014 07:56 AM, zhangfei wrote:
> 
> 
> On 06/19/2014 03:39 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 06/19/2014 04:22 AM, zhangfei wrote:
>>> Hi Mark,
>>>
>>> On 06/18/2014 10:03 PM, Mark Rutland wrote:
>>>> On Wed, Jun 18, 2014 at 05:54:08AM +0100, Zhangfei Gao wrote:
>>>>> Instead of setting hflags in different files,
>>>>> ahci_platform_get_of_property set hpriv->flags when ahci_platform_init_host
>>>>> according to property in dts.
>>>>
>>>> The AHCI_HFLAGS are a Linux implementation detail, so it would be nice
>>>> to have a good justification for each of these being turned into DT
>>>> properties.
>>>
>>> Do you mean only add required property now?
>>
>> No you should not add any properties at all using properties to set SoC specific quirks
>> is just wrong, if a device is not 100% ahci compatible you should use a SoC specific
>> compatible string for it, and set quirks in the kernel driver based on that.
>>
>> Devicetree is supposed to describe hardware, in this case the quirks are a property
>> of the specific model of the hardware, so this should be expressed through the
>> compatible string. Extra properties in devicetree are meant to be used for board
>> specific things, like having a gpio to enable power to the sata target device.
>> Extra properties should not be used in the way you are proposing to use them now.
>>
> 
> OK, got it.
> 
> What I thoutht is using ahci_platform_get_of_property could make ahci_platform.c more shareable, adding the chance of removing specific compatible.
> Just refer mmc_of_parse and sdhci_get_of_property, they are parsing property directly from dts.

I'm not familiar with sdhci_get_of_property, but mmc_of_parse is all about
describing the board, not controller specific quirks. It sets things like
how many bits the sdcard slot has (just because the controller has x
bits does not mean they are all wired up), things like max speed (which again
is not only a host but also a board property), things like which gpio to use for
card detect, or if the mmc/sdio device is always present as it is soldered
onto the board, etc.

Regards,

Hans
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index c96d8dcf98fd..c0b9f6e76ba4 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -26,6 +26,15 @@  Optional properties:
 - clocks            : must contain the sata, sata_ref and ahb clocks
 - clock-names       : must contain "ahb" for the ahb clock
 
+- no-ncq: when present, controller can't do NCQ, turning off CAP_NCQ
+- 32bit-only: when present, controller can't do 64bit DMA, forcing 32bit
+- no-msi: when present, no PCI MSI
+- no-pmp: when present, controller can't do PMP, turning off CAP_PMP
+- yes-ncq: when present,controller can do NCQ, turning on CAP_NCQ
+- no-suspend: when present, controller can't do suspend
+- yes-fbs: when present, controller can do FBS, turning on CAP_FBS
+- no-fbs: when present, controller can't do FBS, turning off CAP_FBS
+
 Examples:
         sata@ffe08000 {
 		compatible = "snps,spear-ahci";
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index 3a5b4ed25a4f..880b9f360056 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -278,6 +278,44 @@  err_out:
 }
 EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
 
+#ifdef CONFIG_OF
+static void ahci_platform_get_of_property(struct platform_device *pdev,
+					  struct ahci_host_priv *hpriv)
+{
+	struct device_node *np = pdev->dev.of_node;
+
+	if (of_device_is_available(np)) {
+		if (of_get_property(np, "no-ncq", NULL))
+			hpriv->flags |= AHCI_HFLAG_NO_NCQ;
+
+		if (of_get_property(np, "32bit-only", NULL))
+			hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;
+
+		if (of_get_property(np, "no-msi", NULL))
+			hpriv->flags |= AHCI_HFLAG_NO_MSI;
+
+		if (of_get_property(np, "no-pmp", NULL))
+			hpriv->flags |= AHCI_HFLAG_NO_PMP;
+
+		if (of_get_property(np, "yes-ncq", NULL))
+			hpriv->flags |= AHCI_HFLAG_YES_NCQ;
+
+		if (of_get_property(np, "no-suspend", NULL))
+			hpriv->flags |= AHCI_HFLAG_NO_SUSPEND;
+
+		if (of_get_property(np, "yes-fbs", NULL))
+			hpriv->flags |= AHCI_HFLAG_YES_FBS;
+
+		if (of_get_property(np, "no-fbs", NULL))
+			hpriv->flags |= AHCI_HFLAG_NO_FBS;
+	}
+}
+#else
+static void ahci_platform_get_of_property(struct platform_device *pdev,
+					  struct ahci_host_priv *hpriv)
+{}
+#endif /* CONFIG_OF */
+
 /**
  * ahci_platform_init_host - Bring up an ahci-platform host
  * @pdev: platform device pointer for the host
@@ -316,6 +354,7 @@  int ahci_platform_init_host(struct platform_device *pdev,
 	/* prepare host */
 	pi.private_data = (void *)host_flags;
 	hpriv->flags |= host_flags;
+	ahci_platform_get_of_property(pdev, hpriv);
 
 	ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);