diff mbox

[v2,4/4] scsi: ufs: probe and init of variant driver from the platform device

Message ID 1433324255-27510-5-git-send-email-ygardi@codeaurora.org (mailing list archive)
State Not Applicable, archived
Delegated to: Andy Gross
Headers show

Commit Message

Yaniv Gardi June 3, 2015, 9:37 a.m. UTC
It does so by adding the following changes:
1. Introducing SCSI_UFS_QCOM as a platform device. Its probe
   function registers a set of vops to its driver_data.
2. Adding an optional device tree sub-node, under SCSI_UFSHCD_PLATFORM.
   Now, the probe function of SCSI_UFSHCD_PLATFORM invokes the probe
   function of its sub-node (if it exists), by calling
   of_platform_populate(). It ensures that vops are set, and ready to
   be used, by the time the UFSHCD driver starts its initialization
   procedure.

Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>

---
 .../devicetree/bindings/ufs/ufshcd-pltfrm.txt      |  8 +++++
 drivers/scsi/ufs/ufs-qcom.c                        | 40 ++++++++++++++++++++++
 drivers/scsi/ufs/ufshcd-pltfrm.c                   | 33 +++++++++++-------
 3 files changed, 68 insertions(+), 13 deletions(-)

Comments

Paul Bolle June 4, 2015, 2:07 p.m. UTC | #1
On Wed, 2015-06-03 at 12:37 +0300, Yaniv Gardi wrote:
> --- a/drivers/scsi/ufs/ufs-qcom.c
> +++ b/drivers/scsi/ufs/ufs-qcom.c

>  EXPORT_SYMBOL(ufs_hba_qcom_vops);

Nothing uses this export. It's still a (static) symbol that is not
included in any header. I think this export serves no purpose. Am I
missing something subtle here?

> +/**
> + * ufs_qcom_probe - probe routine of the driver
> + * @pdev: pointer to Platform device handle
> + *
> + * Always return 0
> + */
> +static int ufs_qcom_probe(struct platform_device *pdev)
> +{
> +	dev_set_drvdata(&pdev->dev, (void *)&ufs_hba_qcom_vops);

(Cast to void * should not be needed.)

> +	return 0;
> +}
> +
> +/**
> + * ufs_qcom_remove - set driver_data of the device to NULL
> + * @pdev: pointer to platform device handle
> + *
> + * Always return 0
> + */
> +static int ufs_qcom_remove(struct platform_device *pdev)
> +{
> +	dev_set_drvdata(&pdev->dev, NULL);
> +	return 0;
> +}
> +
> +static const struct of_device_id ufs_qcom_of_match[] = {
> +	{ .compatible = "qcom,ufs_variant"},
> +	{},
> +};
> +
> +static struct platform_driver ufs_qcom_pltform = {
> +	.probe	= ufs_qcom_probe,
> +	.remove	= ufs_qcom_remove,
> +	.driver	= {
> +		.name	= "ufs_qcom",
> +		.owner	= THIS_MODULE,
> +		.of_match_table = of_match_ptr(ufs_qcom_of_match),
> +	},
> +};
> +module_platform_driver(ufs_qcom_pltform);

> --- a/drivers/scsi/ufs/ufshcd-pltfrm.c
> +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c

> +	struct device_node *node = pdev->dev.of_node;
> +	struct device_node *ufs_variant_node;
> +	struct platform_device *ufs_variant_pdev;
 
> -	hba->vops = get_variant_ops(&pdev->dev);
> +	err = of_platform_populate(node, NULL, NULL, &pdev->dev);
> +	if (err)
> +		dev_err(&pdev->dev,
> +			"%s: of_platform_populate() failed\n", __func__);
> +
> +	ufs_variant_node = of_get_next_available_child(node, NULL);
> +
> +	if (!ufs_variant_node) {
> +		dev_dbg(&pdev->dev, "failed to find ufs_variant_node child\n");
> +	} else {
> +		ufs_variant_pdev = of_find_device_by_node(ufs_variant_node);
> +
> +		if (ufs_variant_pdev)
> +			hba->vops = (struct ufs_hba_variant_ops *)
> +				dev_get_drvdata(&ufs_variant_pdev->dev);

(Another cast that I think is not needed.)

> +	}

If I scanned this correctly, the dev_set_drvdata() and dev_get_drvdata()
pair adds an actual user of ufs_hba_qcom_vops. So that ends the obvious
issue I think the code currently has. And I gladly defer to the scsi
people to determine whether that is done the right way.

Thanks,


Paul Bolle

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Akinobu Mita June 4, 2015, 2:32 p.m. UTC | #2
Hi Yaniv,

2015-06-03 18:37 GMT+09:00 Yaniv Gardi <ygardi@codeaurora.org>:
> @@ -321,7 +313,22 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
>                 goto out;
>         }
>
> -       hba->vops = get_variant_ops(&pdev->dev);
> +       err = of_platform_populate(node, NULL, NULL, &pdev->dev);
> +       if (err)
> +               dev_err(&pdev->dev,
> +                       "%s: of_platform_populate() failed\n", __func__);
> +
> +       ufs_variant_node = of_get_next_available_child(node, NULL);
> +
> +       if (!ufs_variant_node) {
> +               dev_dbg(&pdev->dev, "failed to find ufs_variant_node child\n");
> +       } else {
> +               ufs_variant_pdev = of_find_device_by_node(ufs_variant_node);
> +
> +               if (ufs_variant_pdev)
> +                       hba->vops = (struct ufs_hba_variant_ops *)
> +                               dev_get_drvdata(&ufs_variant_pdev->dev);
> +       }

I have no strong objection to 'ufs_variant' sub-node.  But why can't we
simply add an of_device_id to ufs_of_match, like below:

static const struct of_device_id ufs_of_match[] = {
        { .compatible = "jedec,ufs-1.1"},
#if IS_ENABLED(SCSI_UFS_QCOM)
        { .compatible = "qcom,ufs", .data = &ufs_hba_qcom_vops },
#neidf
        {},
};

and get hba->vops by get_variant_ops()?

There is something similar in
drivers/net/ethernet/freescale/fsl_pq_mdio.c
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paul Bolle June 4, 2015, 2:42 p.m. UTC | #3
On Thu, 2015-06-04 at 16:07 +0200, Paul Bolle wrote:
> On Wed, 2015-06-03 at 12:37 +0300, Yaniv Gardi wrote:
> > +static int ufs_qcom_probe(struct platform_device *pdev)
> > +{
> > +	dev_set_drvdata(&pdev->dev, (void *)&ufs_hba_qcom_vops);
> 
> (Cast to void * should not be needed.)

Only if ufs_hba_qcom_vops wasn't a _const_ struct ufs_hba_variant_ops,
that is. Never mind.


Paul Bolle

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yaniv Gardi June 4, 2015, 8:42 p.m. UTC | #4
> On Wed, 2015-06-03 at 12:37 +0300, Yaniv Gardi wrote:
>> --- a/drivers/scsi/ufs/ufs-qcom.c
>> +++ b/drivers/scsi/ufs/ufs-qcom.c
>
>>  EXPORT_SYMBOL(ufs_hba_qcom_vops);
>
> Nothing uses this export. It's still a (static) symbol that is not
> included in any header. I think this export serves no purpose. Am I
> missing something subtle here?
>

correct Paul. I will remove it.


>> +/**
>> + * ufs_qcom_probe - probe routine of the driver
>> + * @pdev: pointer to Platform device handle
>> + *
>> + * Always return 0
>> + */
>> +static int ufs_qcom_probe(struct platform_device *pdev)
>> +{
>> +	dev_set_drvdata(&pdev->dev, (void *)&ufs_hba_qcom_vops);
>
> (Cast to void * should not be needed.)
>
>> +	return 0;
>> +}
>> +
>> +/**
>> + * ufs_qcom_remove - set driver_data of the device to NULL
>> + * @pdev: pointer to platform device handle
>> + *
>> + * Always return 0
>> + */
>> +static int ufs_qcom_remove(struct platform_device *pdev)
>> +{
>> +	dev_set_drvdata(&pdev->dev, NULL);
>> +	return 0;
>> +}
>> +
>> +static const struct of_device_id ufs_qcom_of_match[] = {
>> +	{ .compatible = "qcom,ufs_variant"},
>> +	{},
>> +};
>> +
>> +static struct platform_driver ufs_qcom_pltform = {
>> +	.probe	= ufs_qcom_probe,
>> +	.remove	= ufs_qcom_remove,
>> +	.driver	= {
>> +		.name	= "ufs_qcom",
>> +		.owner	= THIS_MODULE,
>> +		.of_match_table = of_match_ptr(ufs_qcom_of_match),
>> +	},
>> +};
>> +module_platform_driver(ufs_qcom_pltform);
>
>> --- a/drivers/scsi/ufs/ufshcd-pltfrm.c
>> +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
>
>> +	struct device_node *node = pdev->dev.of_node;
>> +	struct device_node *ufs_variant_node;
>> +	struct platform_device *ufs_variant_pdev;
>
>> -	hba->vops = get_variant_ops(&pdev->dev);
>> +	err = of_platform_populate(node, NULL, NULL, &pdev->dev);
>> +	if (err)
>> +		dev_err(&pdev->dev,
>> +			"%s: of_platform_populate() failed\n", __func__);
>> +
>> +	ufs_variant_node = of_get_next_available_child(node, NULL);
>> +
>> +	if (!ufs_variant_node) {
>> +		dev_dbg(&pdev->dev, "failed to find ufs_variant_node child\n");
>> +	} else {
>> +		ufs_variant_pdev = of_find_device_by_node(ufs_variant_node);
>> +
>> +		if (ufs_variant_pdev)
>> +			hba->vops = (struct ufs_hba_variant_ops *)
>> +				dev_get_drvdata(&ufs_variant_pdev->dev);
>
> (Another cast that I think is not needed.)
>
>> +	}
>
> If I scanned this correctly, the dev_set_drvdata() and dev_get_drvdata()
> pair adds an actual user of ufs_hba_qcom_vops. So that ends the obvious
> issue I think the code currently has. And I gladly defer to the scsi
> people to determine whether that is done the right way.
>

yes, you got it right.
these 2 routines use the vops structure, that binds the driver and the
variant (in our case qcom)

thanks for your time, Paul


> Thanks,
>
>
> Paul Bolle
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yaniv Gardi June 4, 2015, 8:53 p.m. UTC | #5
> Hi Yaniv,
>
> 2015-06-03 18:37 GMT+09:00 Yaniv Gardi <ygardi@codeaurora.org>:
>> @@ -321,7 +313,22 @@ static int ufshcd_pltfrm_probe(struct
>> platform_device *pdev)
>>                 goto out;
>>         }
>>
>> -       hba->vops = get_variant_ops(&pdev->dev);
>> +       err = of_platform_populate(node, NULL, NULL, &pdev->dev);
>> +       if (err)
>> +               dev_err(&pdev->dev,
>> +                       "%s: of_platform_populate() failed\n",
>> __func__);
>> +
>> +       ufs_variant_node = of_get_next_available_child(node, NULL);
>> +
>> +       if (!ufs_variant_node) {
>> +               dev_dbg(&pdev->dev, "failed to find ufs_variant_node
>> child\n");
>> +       } else {
>> +               ufs_variant_pdev =
>> of_find_device_by_node(ufs_variant_node);
>> +
>> +               if (ufs_variant_pdev)
>> +                       hba->vops = (struct ufs_hba_variant_ops *)
>> +                               dev_get_drvdata(&ufs_variant_pdev->dev);
>> +       }
>
> I have no strong objection to 'ufs_variant' sub-node.  But why can't we
> simply add an of_device_id to ufs_of_match, like below:
>
> static const struct of_device_id ufs_of_match[] = {
>         { .compatible = "jedec,ufs-1.1"},
> #if IS_ENABLED(SCSI_UFS_QCOM)
>         { .compatible = "qcom,ufs", .data = &ufs_hba_qcom_vops },
> #neidf
>         {},
> };
>
> and get hba->vops by get_variant_ops()?
>

Hi Mita,
thanks for your comments.

The whole idea, of having a sub-node which includes all variant specific
attributes is to separate the UFS Platform device component, from the need
to know "qcom" or any other future variant.
I believe it keeps the code more modular, and clean - meaning - no
#ifdef's and no need to include all variant attributes inside the driver
DT node.
in that case, we simply have a DT node that is compatible to the Jdec
standard, and sub-node to include variant info.

I hope you agree with this new design, since it provides a good answer
to every future variant that will be added, without the need to change the
platform file.

thanks for your time, Mita
please share your thoughts.

> There is something similar in
> drivers/net/ethernet/freescale/fsl_pq_mdio.c
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Akinobu Mita June 5, 2015, 4:47 p.m. UTC | #6
2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>> Hi Yaniv,
>>
>> 2015-06-03 18:37 GMT+09:00 Yaniv Gardi <ygardi@codeaurora.org>:
>>> @@ -321,7 +313,22 @@ static int ufshcd_pltfrm_probe(struct
>>> platform_device *pdev)
>>>                 goto out;
>>>         }
>>>
>>> -       hba->vops = get_variant_ops(&pdev->dev);
>>> +       err = of_platform_populate(node, NULL, NULL, &pdev->dev);
>>> +       if (err)
>>> +               dev_err(&pdev->dev,
>>> +                       "%s: of_platform_populate() failed\n",
>>> __func__);
>>> +
>>> +       ufs_variant_node = of_get_next_available_child(node, NULL);
>>> +
>>> +       if (!ufs_variant_node) {
>>> +               dev_dbg(&pdev->dev, "failed to find ufs_variant_node
>>> child\n");
>>> +       } else {
>>> +               ufs_variant_pdev =
>>> of_find_device_by_node(ufs_variant_node);
>>> +
>>> +               if (ufs_variant_pdev)
>>> +                       hba->vops = (struct ufs_hba_variant_ops *)
>>> +                               dev_get_drvdata(&ufs_variant_pdev->dev);
>>> +       }
>>
>> I have no strong objection to 'ufs_variant' sub-node.  But why can't we
>> simply add an of_device_id to ufs_of_match, like below:
>>
>> static const struct of_device_id ufs_of_match[] = {
>>         { .compatible = "jedec,ufs-1.1"},
>> #if IS_ENABLED(SCSI_UFS_QCOM)
>>         { .compatible = "qcom,ufs", .data = &ufs_hba_qcom_vops },
>> #neidf
>>         {},
>> };
>>
>> and get hba->vops by get_variant_ops()?
>>
>
> Hi Mita,
> thanks for your comments.
>
> The whole idea, of having a sub-node which includes all variant specific
> attributes is to separate the UFS Platform device component, from the need
> to know "qcom" or any other future variant.
> I believe it keeps the code more modular, and clean - meaning - no
> #ifdef's and no need to include all variant attributes inside the driver
> DT node.
> in that case, we simply have a DT node that is compatible to the Jdec
> standard, and sub-node to include variant info.
>
> I hope you agree with this new design, since it provides a good answer
> to every future variant that will be added, without the need to change the
> platform file.

Thanks for your explanation, I agree with it.

I found two problems in the current code, but both can be fixed
relatively easily as described below:

1) If ufshcd-pltfrm driver is loaded before ufs-qcom driver,
ufshcd_pltfrm_probe() can't find a ufs_variant device.

In order to trigger re-probing ufs device when ufs-qcom driver has
been loaded, ufshcd_pltfrm_probe() should return -EPROBE_DEFER in
case 'ufs_variant' sub-node exists and no hba->vops found.

2) Nothing prevents ufs-qcom module from being unloaded while the
variant_ops is referenced by ufshcd-pltfrm.

It can be fixed by incrementing module refcount of ufs_variant module
by __module_get(ufs_variant_pdev->dev.driver->owener) in
ufshcd_pltfrm_probe(), and module_put() in ufshcd_pltfrm_remove()
to descrement the refcount.
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yaniv Gardi June 7, 2015, 3:22 p.m. UTC | #7
Thanks Paul for the review and comments.
please see inline.



> On Wed, 2015-06-03 at 12:37 +0300, Yaniv Gardi wrote:
>> --- a/drivers/scsi/ufs/ufs-qcom.c
>> +++ b/drivers/scsi/ufs/ufs-qcom.c
>
>>  EXPORT_SYMBOL(ufs_hba_qcom_vops);
>
> Nothing uses this export. It's still a (static) symbol that is not
> included in any header. I think this export serves no purpose. Am I
> missing something subtle here?
>

you are correct. it will be removed.

>> +/**
>> + * ufs_qcom_probe - probe routine of the driver
>> + * @pdev: pointer to Platform device handle
>> + *
>> + * Always return 0
>> + */
>> +static int ufs_qcom_probe(struct platform_device *pdev)
>> +{
>> +	dev_set_drvdata(&pdev->dev, (void *)&ufs_hba_qcom_vops);
>
> (Cast to void * should not be needed.)
>

when removing the cast there is compilation error:
ufs-qcom.c: warning: passing argument 2 of ?dev_set_drvdata? discards
?const? qualifier from pointer target type
error, forbidden warning: ufs-qcom.c


>> +	return 0;
>> +}
>> +
>> +/**
>> + * ufs_qcom_remove - set driver_data of the device to NULL
>> + * @pdev: pointer to platform device handle
>> + *
>> + * Always return 0
>> + */
>> +static int ufs_qcom_remove(struct platform_device *pdev)
>> +{
>> +	dev_set_drvdata(&pdev->dev, NULL);
>> +	return 0;
>> +}
>> +
>> +static const struct of_device_id ufs_qcom_of_match[] = {
>> +	{ .compatible = "qcom,ufs_variant"},
>> +	{},
>> +};
>> +
>> +static struct platform_driver ufs_qcom_pltform = {
>> +	.probe	= ufs_qcom_probe,
>> +	.remove	= ufs_qcom_remove,
>> +	.driver	= {
>> +		.name	= "ufs_qcom",
>> +		.owner	= THIS_MODULE,
>> +		.of_match_table = of_match_ptr(ufs_qcom_of_match),
>> +	},
>> +};
>> +module_platform_driver(ufs_qcom_pltform);
>
>> --- a/drivers/scsi/ufs/ufshcd-pltfrm.c
>> +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
>
>> +	struct device_node *node = pdev->dev.of_node;
>> +	struct device_node *ufs_variant_node;
>> +	struct platform_device *ufs_variant_pdev;
>
>> -	hba->vops = get_variant_ops(&pdev->dev);
>> +	err = of_platform_populate(node, NULL, NULL, &pdev->dev);
>> +	if (err)
>> +		dev_err(&pdev->dev,
>> +			"%s: of_platform_populate() failed\n", __func__);
>> +
>> +	ufs_variant_node = of_get_next_available_child(node, NULL);
>> +
>> +	if (!ufs_variant_node) {
>> +		dev_dbg(&pdev->dev, "failed to find ufs_variant_node child\n");
>> +	} else {
>> +		ufs_variant_pdev = of_find_device_by_node(ufs_variant_node);
>> +
>> +		if (ufs_variant_pdev)
>> +			hba->vops = (struct ufs_hba_variant_ops *)
>> +				dev_get_drvdata(&ufs_variant_pdev->dev);
>
> (Another cast that I think is not needed.)

here you are right - this one can be removed and will be
>
>> +	}
>
> If I scanned this correctly, the dev_set_drvdata() and dev_get_drvdata()
> pair adds an actual user of ufs_hba_qcom_vops. So that ends the obvious
> issue I think the code currently has. And I gladly defer to the scsi
> people to determine whether that is done the right way.
>
> Thanks,
>
>
> Paul Bolle
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yaniv Gardi June 7, 2015, 3:32 p.m. UTC | #8
> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>>> Hi Yaniv,
>>>
>>> 2015-06-03 18:37 GMT+09:00 Yaniv Gardi <ygardi@codeaurora.org>:
>>>> @@ -321,7 +313,22 @@ static int ufshcd_pltfrm_probe(struct
>>>> platform_device *pdev)
>>>>                 goto out;
>>>>         }
>>>>
>>>> -       hba->vops = get_variant_ops(&pdev->dev);
>>>> +       err = of_platform_populate(node, NULL, NULL, &pdev->dev);
>>>> +       if (err)
>>>> +               dev_err(&pdev->dev,
>>>> +                       "%s: of_platform_populate() failed\n",
>>>> __func__);
>>>> +
>>>> +       ufs_variant_node = of_get_next_available_child(node, NULL);
>>>> +
>>>> +       if (!ufs_variant_node) {
>>>> +               dev_dbg(&pdev->dev, "failed to find ufs_variant_node
>>>> child\n");
>>>> +       } else {
>>>> +               ufs_variant_pdev =
>>>> of_find_device_by_node(ufs_variant_node);
>>>> +
>>>> +               if (ufs_variant_pdev)
>>>> +                       hba->vops = (struct ufs_hba_variant_ops *)
>>>> +
>>>> dev_get_drvdata(&ufs_variant_pdev->dev);
>>>> +       }
>>>
>>> I have no strong objection to 'ufs_variant' sub-node.  But why can't we
>>> simply add an of_device_id to ufs_of_match, like below:
>>>
>>> static const struct of_device_id ufs_of_match[] = {
>>>         { .compatible = "jedec,ufs-1.1"},
>>> #if IS_ENABLED(SCSI_UFS_QCOM)
>>>         { .compatible = "qcom,ufs", .data = &ufs_hba_qcom_vops },
>>> #neidf
>>>         {},
>>> };
>>>
>>> and get hba->vops by get_variant_ops()?
>>>
>>
>> Hi Mita,
>> thanks for your comments.
>>
>> The whole idea, of having a sub-node which includes all variant specific
>> attributes is to separate the UFS Platform device component, from the
>> need
>> to know "qcom" or any other future variant.
>> I believe it keeps the code more modular, and clean - meaning - no
>> #ifdef's and no need to include all variant attributes inside the driver
>> DT node.
>> in that case, we simply have a DT node that is compatible to the Jdec
>> standard, and sub-node to include variant info.
>>
>> I hope you agree with this new design, since it provides a good answer
>> to every future variant that will be added, without the need to change
>> the
>> platform file.
>
> Thanks for your explanation, I agree with it.
>
> I found two problems in the current code, but both can be fixed
> relatively easily as described below:
>
> 1) If ufshcd-pltfrm driver is loaded before ufs-qcom driver,
> ufshcd_pltfrm_probe() can't find a ufs_variant device.
>
> In order to trigger re-probing ufs device when ufs-qcom driver has
> been loaded, ufshcd_pltfrm_probe() should return -EPROBE_DEFER in
> case 'ufs_variant' sub-node exists and no hba->vops found.
>
> 2) Nothing prevents ufs-qcom module from being unloaded while the
> variant_ops is referenced by ufshcd-pltfrm.
>
> It can be fixed by incrementing module refcount of ufs_variant module
> by __module_get(ufs_variant_pdev->dev.driver->owener) in
> ufshcd_pltfrm_probe(), and module_put() in ufshcd_pltfrm_remove()
> to descrement the refcount.
>

again, Mita, your comments are very appreciated.

1)
If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually happens
always), then the calling to of_platform_populate() which is added,
guarantees that ufs-qcom probe will be called and finish, before
ufshcd_pltfrm probe continues.
so ufs_variant device is always there, and ready.
I think it means we are safe - since either way, we make sure ufs-qcom
probe will be called and finish before dealing with ufs_variant device in
ufshcd_pltfrm probe.

2) you are right. the fix added as you suggested.

let us know your thoughts about the V3 once it's uploaded

thanks



--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Akinobu Mita June 8, 2015, 2:47 p.m. UTC | #9
2015-06-08 0:32 GMT+09:00  <ygardi@codeaurora.org>:
> 1)
> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually happens
> always), then the calling to of_platform_populate() which is added,
> guarantees that ufs-qcom probe will be called and finish, before
> ufshcd_pltfrm probe continues.

I'm worrying the case ufshcd_pltfrm_probe() is called when ufshcd-pltfrm
module is installed but ufs-qcom module is _not_ installed yet, where
ufshcd-pltfrm and ufs-qcom are both built as loadable modules.

In this case, of_platform_populate() in ufshcd_pltfrm_probe() doesn't
invoke ufs-qcom probe, does it?  So I suggested using deferred probe
infrastructure by returning -EPROBE_DEFER.

> so ufs_variant device is always there, and ready.
> I think it means we are safe - since either way, we make sure ufs-qcom
> probe will be called and finish before dealing with ufs_variant device in
> ufshcd_pltfrm probe.
>
> 2) you are right. the fix added as you suggested.

Thanks for fixing it.  But a little more work is needed in v3,
I'll leave a comment to v3.
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring June 8, 2015, 2:51 p.m. UTC | #10
On Thu, Jun 4, 2015 at 9:32 AM, Akinobu Mita <akinobu.mita@gmail.com> wrote:
> Hi Yaniv,
>
> 2015-06-03 18:37 GMT+09:00 Yaniv Gardi <ygardi@codeaurora.org>:
>> @@ -321,7 +313,22 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
>>                 goto out;
>>         }
>>
>> -       hba->vops = get_variant_ops(&pdev->dev);
>> +       err = of_platform_populate(node, NULL, NULL, &pdev->dev);
>> +       if (err)
>> +               dev_err(&pdev->dev,
>> +                       "%s: of_platform_populate() failed\n", __func__);
>> +
>> +       ufs_variant_node = of_get_next_available_child(node, NULL);
>> +
>> +       if (!ufs_variant_node) {
>> +               dev_dbg(&pdev->dev, "failed to find ufs_variant_node child\n");
>> +       } else {
>> +               ufs_variant_pdev = of_find_device_by_node(ufs_variant_node);
>> +
>> +               if (ufs_variant_pdev)
>> +                       hba->vops = (struct ufs_hba_variant_ops *)
>> +                               dev_get_drvdata(&ufs_variant_pdev->dev);
>> +       }
>
> I have no strong objection to 'ufs_variant' sub-node.  But why can't we
> simply add an of_device_id to ufs_of_match, like below:

But I do have objections on both the naming and having a sub-node.

>
> static const struct of_device_id ufs_of_match[] = {
>         { .compatible = "jedec,ufs-1.1"},
> #if IS_ENABLED(SCSI_UFS_QCOM)
>         { .compatible = "qcom,ufs", .data = &ufs_hba_qcom_vops },

Be more specific: qcom,<socname>-ufs

> #neidf

Drop the ifdef.

Rob
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring June 8, 2015, 3:02 p.m. UTC | #11
On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>>>> Hi Yaniv,
>>>>
>>>> 2015-06-03 18:37 GMT+09:00 Yaniv Gardi <ygardi@codeaurora.org>:
>>>>> @@ -321,7 +313,22 @@ static int ufshcd_pltfrm_probe(struct
>>>>> platform_device *pdev)
>>>>>                 goto out;
>>>>>         }
>>>>>
>>>>> -       hba->vops = get_variant_ops(&pdev->dev);
>>>>> +       err = of_platform_populate(node, NULL, NULL, &pdev->dev);
>>>>> +       if (err)
>>>>> +               dev_err(&pdev->dev,
>>>>> +                       "%s: of_platform_populate() failed\n",
>>>>> __func__);
>>>>> +
>>>>> +       ufs_variant_node = of_get_next_available_child(node, NULL);
>>>>> +
>>>>> +       if (!ufs_variant_node) {
>>>>> +               dev_dbg(&pdev->dev, "failed to find ufs_variant_node
>>>>> child\n");
>>>>> +       } else {
>>>>> +               ufs_variant_pdev =
>>>>> of_find_device_by_node(ufs_variant_node);
>>>>> +
>>>>> +               if (ufs_variant_pdev)
>>>>> +                       hba->vops = (struct ufs_hba_variant_ops *)
>>>>> +
>>>>> dev_get_drvdata(&ufs_variant_pdev->dev);
>>>>> +       }
>>>>
>>>> I have no strong objection to 'ufs_variant' sub-node.  But why can't we
>>>> simply add an of_device_id to ufs_of_match, like below:
>>>>
>>>> static const struct of_device_id ufs_of_match[] = {
>>>>         { .compatible = "jedec,ufs-1.1"},
>>>> #if IS_ENABLED(SCSI_UFS_QCOM)
>>>>         { .compatible = "qcom,ufs", .data = &ufs_hba_qcom_vops },
>>>> #neidf
>>>>         {},
>>>> };
>>>>
>>>> and get hba->vops by get_variant_ops()?
>>>>
>>>
>>> Hi Mita,
>>> thanks for your comments.
>>>
>>> The whole idea, of having a sub-node which includes all variant specific
>>> attributes is to separate the UFS Platform device component, from the
>>> need
>>> to know "qcom" or any other future variant.
>>> I believe it keeps the code more modular, and clean - meaning - no
>>> #ifdef's and no need to include all variant attributes inside the driver
>>> DT node.
>>> in that case, we simply have a DT node that is compatible to the Jdec
>>> standard, and sub-node to include variant info.
>>>
>>> I hope you agree with this new design, since it provides a good answer
>>> to every future variant that will be added, without the need to change
>>> the
>>> platform file.
>>
>> Thanks for your explanation, I agree with it.
>>
>> I found two problems in the current code, but both can be fixed
>> relatively easily as described below:
>>
>> 1) If ufshcd-pltfrm driver is loaded before ufs-qcom driver,
>> ufshcd_pltfrm_probe() can't find a ufs_variant device.
>>
>> In order to trigger re-probing ufs device when ufs-qcom driver has
>> been loaded, ufshcd_pltfrm_probe() should return -EPROBE_DEFER in
>> case 'ufs_variant' sub-node exists and no hba->vops found.
>>
>> 2) Nothing prevents ufs-qcom module from being unloaded while the
>> variant_ops is referenced by ufshcd-pltfrm.
>>
>> It can be fixed by incrementing module refcount of ufs_variant module
>> by __module_get(ufs_variant_pdev->dev.driver->owener) in
>> ufshcd_pltfrm_probe(), and module_put() in ufshcd_pltfrm_remove()
>> to descrement the refcount.
>>
>
> again, Mita, your comments are very appreciated.
>
> 1)
> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually happens
> always), then the calling to of_platform_populate() which is added,
> guarantees that ufs-qcom probe will be called and finish, before
> ufshcd_pltfrm probe continues.
> so ufs_variant device is always there, and ready.
> I think it means we are safe - since either way, we make sure ufs-qcom
> probe will be called and finish before dealing with ufs_variant device in
> ufshcd_pltfrm probe.

This is due to the fact that you have 2 platform drivers. You should
only have 1 (and 1 node). If you really think you need 2, then you
should do like many other common *HCIs do and make the base UFS driver
a set of library functions that drivers can use or call. Look at EHCI,
AHCI, SDHCI, etc. for inspiration.

Rob
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
dovl@codeaurora.org June 9, 2015, 5:53 a.m. UTC | #12
> On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
>>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>>>>> Hi Yaniv,
>>>>>
>>>>> 2015-06-03 18:37 GMT+09:00 Yaniv Gardi <ygardi@codeaurora.org>:
>>>>>> @@ -321,7 +313,22 @@ static int ufshcd_pltfrm_probe(struct
>>>>>> platform_device *pdev)
>>>>>>                 goto out;
>>>>>>         }
>>>>>>
>>>>>> -       hba->vops = get_variant_ops(&pdev->dev);
>>>>>> +       err = of_platform_populate(node, NULL, NULL, &pdev->dev);
>>>>>> +       if (err)
>>>>>> +               dev_err(&pdev->dev,
>>>>>> +                       "%s: of_platform_populate() failed\n",
>>>>>> __func__);
>>>>>> +
>>>>>> +       ufs_variant_node = of_get_next_available_child(node, NULL);
>>>>>> +
>>>>>> +       if (!ufs_variant_node) {
>>>>>> +               dev_dbg(&pdev->dev, "failed to find ufs_variant_node
>>>>>> child\n");
>>>>>> +       } else {
>>>>>> +               ufs_variant_pdev =
>>>>>> of_find_device_by_node(ufs_variant_node);
>>>>>> +
>>>>>> +               if (ufs_variant_pdev)
>>>>>> +                       hba->vops = (struct ufs_hba_variant_ops *)
>>>>>> +
>>>>>> dev_get_drvdata(&ufs_variant_pdev->dev);
>>>>>> +       }
>>>>>
>>>>> I have no strong objection to 'ufs_variant' sub-node.  But why can't
>>>>> we
>>>>> simply add an of_device_id to ufs_of_match, like below:
>>>>>
>>>>> static const struct of_device_id ufs_of_match[] = {
>>>>>         { .compatible = "jedec,ufs-1.1"},
>>>>> #if IS_ENABLED(SCSI_UFS_QCOM)
>>>>>         { .compatible = "qcom,ufs", .data = &ufs_hba_qcom_vops },
>>>>> #neidf
>>>>>         {},
>>>>> };
>>>>>
>>>>> and get hba->vops by get_variant_ops()?
>>>>>
>>>>
>>>> Hi Mita,
>>>> thanks for your comments.
>>>>
>>>> The whole idea, of having a sub-node which includes all variant
>>>> specific
>>>> attributes is to separate the UFS Platform device component, from the
>>>> need
>>>> to know "qcom" or any other future variant.
>>>> I believe it keeps the code more modular, and clean - meaning - no
>>>> #ifdef's and no need to include all variant attributes inside the
>>>> driver
>>>> DT node.
>>>> in that case, we simply have a DT node that is compatible to the Jdec
>>>> standard, and sub-node to include variant info.
>>>>
>>>> I hope you agree with this new design, since it provides a good answer
>>>> to every future variant that will be added, without the need to change
>>>> the
>>>> platform file.
>>>
>>> Thanks for your explanation, I agree with it.
>>>
>>> I found two problems in the current code, but both can be fixed
>>> relatively easily as described below:
>>>
>>> 1) If ufshcd-pltfrm driver is loaded before ufs-qcom driver,
>>> ufshcd_pltfrm_probe() can't find a ufs_variant device.
>>>
>>> In order to trigger re-probing ufs device when ufs-qcom driver has
>>> been loaded, ufshcd_pltfrm_probe() should return -EPROBE_DEFER in
>>> case 'ufs_variant' sub-node exists and no hba->vops found.
>>>
>>> 2) Nothing prevents ufs-qcom module from being unloaded while the
>>> variant_ops is referenced by ufshcd-pltfrm.
>>>
>>> It can be fixed by incrementing module refcount of ufs_variant module
>>> by __module_get(ufs_variant_pdev->dev.driver->owener) in
>>> ufshcd_pltfrm_probe(), and module_put() in ufshcd_pltfrm_remove()
>>> to descrement the refcount.
>>>
>>
>> again, Mita, your comments are very appreciated.
>>
>> 1)
>> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually
>> happens
>> always), then the calling to of_platform_populate() which is added,
>> guarantees that ufs-qcom probe will be called and finish, before
>> ufshcd_pltfrm probe continues.
>> so ufs_variant device is always there, and ready.
>> I think it means we are safe - since either way, we make sure ufs-qcom
>> probe will be called and finish before dealing with ufs_variant device
>> in
>> ufshcd_pltfrm probe.
>
> This is due to the fact that you have 2 platform drivers. You should
> only have 1 (and 1 node). If you really think you need 2, then you
> should do like many other common *HCIs do and make the base UFS driver
> a set of library functions that drivers can use or call. Look at EHCI,
> AHCI, SDHCI, etc. for inspiration.

Hi Rob,
We did look at SDHCI and decided to go with this design due to its
simplicity and lack of library functions. Yaniv described the proper flow
of probing and, as we understand things, it is guaranteed to work as
designed.

Furthermore, the design of having a subcore in the dts is used in the
Linux kernel. Please have a look at drivers/usb/dwc3 where - as an example
- both dwc3-msm and dwc3-exynox invoke the probing function in core.c
(i.e. the shared underlying Synopsys USB dwc3 core) by calling
of_platform_populate().

Do you see a benefit in the SDHCi implementation?

>
> Rob
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring June 9, 2015, 12:53 p.m. UTC | #13
On Tue, Jun 9, 2015 at 12:53 AM, Dov Levenglick <dovl@codeaurora.org> wrote:
>> On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
>>>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:

[...]

>>> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually
>>> happens
>>> always), then the calling to of_platform_populate() which is added,
>>> guarantees that ufs-qcom probe will be called and finish, before
>>> ufshcd_pltfrm probe continues.
>>> so ufs_variant device is always there, and ready.
>>> I think it means we are safe - since either way, we make sure ufs-qcom
>>> probe will be called and finish before dealing with ufs_variant device
>>> in
>>> ufshcd_pltfrm probe.
>>
>> This is due to the fact that you have 2 platform drivers. You should
>> only have 1 (and 1 node). If you really think you need 2, then you
>> should do like many other common *HCIs do and make the base UFS driver
>> a set of library functions that drivers can use or call. Look at EHCI,
>> AHCI, SDHCI, etc. for inspiration.
>
> Hi Rob,
> We did look at SDHCI and decided to go with this design due to its
> simplicity and lack of library functions. Yaniv described the proper flow
> of probing and, as we understand things, it is guaranteed to work as
> designed.
>
> Furthermore, the design of having a subcore in the dts is used in the
> Linux kernel. Please have a look at drivers/usb/dwc3 where - as an example
> - both dwc3-msm and dwc3-exynox invoke the probing function in core.c
> (i.e. the shared underlying Synopsys USB dwc3 core) by calling
> of_platform_populate().

That binding has the same problem. Please don't propagate that. There
is no point in a sub-node in this case.

> Do you see a benefit in the SDHCi implementation?

Yes, it does not let the kernel driver design dictate the hardware description.

Rob
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
dovl@codeaurora.org June 17, 2015, 7:42 a.m. UTC | #14
> On Tue, Jun 9, 2015 at 12:53 AM, Dov Levenglick <dovl@codeaurora.org>
> wrote:
>>> On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
>>>>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>
> [...]
>
>>>> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually
>>>> happens
>>>> always), then the calling to of_platform_populate() which is added,
>>>> guarantees that ufs-qcom probe will be called and finish, before
>>>> ufshcd_pltfrm probe continues.
>>>> so ufs_variant device is always there, and ready.
>>>> I think it means we are safe - since either way, we make sure ufs-qcom
>>>> probe will be called and finish before dealing with ufs_variant device
>>>> in
>>>> ufshcd_pltfrm probe.
>>>
>>> This is due to the fact that you have 2 platform drivers. You should
>>> only have 1 (and 1 node). If you really think you need 2, then you
>>> should do like many other common *HCIs do and make the base UFS driver
>>> a set of library functions that drivers can use or call. Look at EHCI,
>>> AHCI, SDHCI, etc. for inspiration.
>>
>> Hi Rob,
>> We did look at SDHCI and decided to go with this design due to its
>> simplicity and lack of library functions. Yaniv described the proper
>> flow
>> of probing and, as we understand things, it is guaranteed to work as
>> designed.
>>
>> Furthermore, the design of having a subcore in the dts is used in the
>> Linux kernel. Please have a look at drivers/usb/dwc3 where - as an
>> example
>> - both dwc3-msm and dwc3-exynox invoke the probing function in core.c
>> (i.e. the shared underlying Synopsys USB dwc3 core) by calling
>> of_platform_populate().
>
> That binding has the same problem. Please don't propagate that. There
> is no point in a sub-node in this case.
>
>> Do you see a benefit in the SDHCi implementation?
>
> Yes, it does not let the kernel driver design dictate the hardware
> description.
>
> Rob
>

Hi Rob,
We appear to be having a philosophical disagreement on the practicality of
designing the ufshcd variant's implementation - in other words, we
disagree on the proper design pattern to follow here.
If I understand correctly, you are concerned with a design pattern wherein
a generic implementation is wrapped - at the device-tree level - in a
variant implementation. The main reason for your concern is that you don't
want the "kernel driver design dictate the hardware description".

We considered this point when we suggested our implementation (both before
and after you raised it) and reached the conclusion that - while an
important consideration - it should not be the prevailing one. I believe
that you will agree once you read the reasoning. What guided us was the
following:
1. Keep our change minimal.
2. Keep our patch in line with known design patterns in the kernel.
3. Have our patch extend the existing solution rather than reinvent it.

It is the 3rd point that is most important to this discussion, since UFS
has already been deployed by various vendors and is used by OEM. Changing
ufshcd to a set of library functions that would be called by variants
would necessarily introduce a significant change to the code flow in many
places and would pose a backward compatibility issue. By using the tried
and tested pattern of subnodes in the dts we were able to keep the change
simple, succinct, understandable, maintainable and backward compatible. In
fact, the entire logic tying of the generic implementation to the variant
takes ~20 lines of code - both short and elegant.

As to your concern, while I understand it and understand the underlying
logic, I don't think that it should outweigh the other considerations that
I outlined here.

Dov

QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring June 17, 2015, 12:46 p.m. UTC | #15
On Wed, Jun 17, 2015 at 2:42 AM, Dov Levenglick <dovl@codeaurora.org> wrote:
>> On Tue, Jun 9, 2015 at 12:53 AM, Dov Levenglick <dovl@codeaurora.org>
>> wrote:
>>>> On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
>>>>>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>>
>> [...]
>>
>>>>> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually
>>>>> happens
>>>>> always), then the calling to of_platform_populate() which is added,
>>>>> guarantees that ufs-qcom probe will be called and finish, before
>>>>> ufshcd_pltfrm probe continues.
>>>>> so ufs_variant device is always there, and ready.
>>>>> I think it means we are safe - since either way, we make sure ufs-qcom
>>>>> probe will be called and finish before dealing with ufs_variant device
>>>>> in
>>>>> ufshcd_pltfrm probe.
>>>>
>>>> This is due to the fact that you have 2 platform drivers. You should
>>>> only have 1 (and 1 node). If you really think you need 2, then you
>>>> should do like many other common *HCIs do and make the base UFS driver
>>>> a set of library functions that drivers can use or call. Look at EHCI,
>>>> AHCI, SDHCI, etc. for inspiration.
>>>
>>> Hi Rob,
>>> We did look at SDHCI and decided to go with this design due to its
>>> simplicity and lack of library functions. Yaniv described the proper
>>> flow
>>> of probing and, as we understand things, it is guaranteed to work as
>>> designed.
>>>
>>> Furthermore, the design of having a subcore in the dts is used in the
>>> Linux kernel. Please have a look at drivers/usb/dwc3 where - as an
>>> example
>>> - both dwc3-msm and dwc3-exynox invoke the probing function in core.c
>>> (i.e. the shared underlying Synopsys USB dwc3 core) by calling
>>> of_platform_populate().
>>
>> That binding has the same problem. Please don't propagate that. There
>> is no point in a sub-node in this case.
>>
>>> Do you see a benefit in the SDHCi implementation?
>>
>> Yes, it does not let the kernel driver design dictate the hardware
>> description.
>>
>> Rob
>>
>
> Hi Rob,
> We appear to be having a philosophical disagreement on the practicality of
> designing the ufshcd variant's implementation - in other words, we
> disagree on the proper design pattern to follow here.
> If I understand correctly, you are concerned with a design pattern wherein
> a generic implementation is wrapped - at the device-tree level - in a
> variant implementation. The main reason for your concern is that you don't
> want the "kernel driver design dictate the hardware description".
>
> We considered this point when we suggested our implementation (both before
> and after you raised it) and reached the conclusion that - while an
> important consideration - it should not be the prevailing one. I believe
> that you will agree once you read the reasoning. What guided us was the
> following:
> 1. Keep our change minimal.
> 2. Keep our patch in line with known design patterns in the kernel.
> 3. Have our patch extend the existing solution rather than reinvent it.
>
> It is the 3rd point that is most important to this discussion, since UFS
> has already been deployed by various vendors and is used by OEM. Changing
> ufshcd to a set of library functions that would be called by variants
> would necessarily introduce a significant change to the code flow in many
> places and would pose a backward compatibility issue. By using the tried
> and tested pattern of subnodes in the dts we were able to keep the change
> simple, succinct, understandable, maintainable and backward compatible. In
> fact, the entire logic tying of the generic implementation to the variant
> takes ~20 lines of code - both short and elegant.

The DWC3 binding does this and nothing else that I'm aware of. This
hardly makes for a common pattern. If you really want to split this to
2 devices, you can create platform devices without having a DT node.

If you want to convince me this is the right approach for the binding
then you need to convince me the h/w is actually split this way and
there is functionality separate from the licensed IP.

Rob
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
dovl@codeaurora.org June 17, 2015, 1:17 p.m. UTC | #16
> On Wed, Jun 17, 2015 at 2:42 AM, Dov Levenglick <dovl@codeaurora.org>
> wrote:
>>> On Tue, Jun 9, 2015 at 12:53 AM, Dov Levenglick <dovl@codeaurora.org>
>>> wrote:
>>>>> On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
>>>>>>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>>>
>>> [...]
>>>
>>>>>> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually
>>>>>> happens
>>>>>> always), then the calling to of_platform_populate() which is added,
>>>>>> guarantees that ufs-qcom probe will be called and finish, before
>>>>>> ufshcd_pltfrm probe continues.
>>>>>> so ufs_variant device is always there, and ready.
>>>>>> I think it means we are safe - since either way, we make sure
>>>>>> ufs-qcom
>>>>>> probe will be called and finish before dealing with ufs_variant
>>>>>> device
>>>>>> in
>>>>>> ufshcd_pltfrm probe.
>>>>>
>>>>> This is due to the fact that you have 2 platform drivers. You should
>>>>> only have 1 (and 1 node). If you really think you need 2, then you
>>>>> should do like many other common *HCIs do and make the base UFS
>>>>> driver
>>>>> a set of library functions that drivers can use or call. Look at
>>>>> EHCI,
>>>>> AHCI, SDHCI, etc. for inspiration.
>>>>
>>>> Hi Rob,
>>>> We did look at SDHCI and decided to go with this design due to its
>>>> simplicity and lack of library functions. Yaniv described the proper
>>>> flow
>>>> of probing and, as we understand things, it is guaranteed to work as
>>>> designed.
>>>>
>>>> Furthermore, the design of having a subcore in the dts is used in the
>>>> Linux kernel. Please have a look at drivers/usb/dwc3 where - as an
>>>> example
>>>> - both dwc3-msm and dwc3-exynox invoke the probing function in core.c
>>>> (i.e. the shared underlying Synopsys USB dwc3 core) by calling
>>>> of_platform_populate().
>>>
>>> That binding has the same problem. Please don't propagate that. There
>>> is no point in a sub-node in this case.
>>>
>>>> Do you see a benefit in the SDHCi implementation?
>>>
>>> Yes, it does not let the kernel driver design dictate the hardware
>>> description.
>>>
>>> Rob
>>>
>>
>> Hi Rob,
>> We appear to be having a philosophical disagreement on the practicality
>> of
>> designing the ufshcd variant's implementation - in other words, we
>> disagree on the proper design pattern to follow here.
>> If I understand correctly, you are concerned with a design pattern
>> wherein
>> a generic implementation is wrapped - at the device-tree level - in a
>> variant implementation. The main reason for your concern is that you
>> don't
>> want the "kernel driver design dictate the hardware description".
>>
>> We considered this point when we suggested our implementation (both
>> before
>> and after you raised it) and reached the conclusion that - while an
>> important consideration - it should not be the prevailing one. I believe
>> that you will agree once you read the reasoning. What guided us was the
>> following:
>> 1. Keep our change minimal.
>> 2. Keep our patch in line with known design patterns in the kernel.
>> 3. Have our patch extend the existing solution rather than reinvent it.
>>
>> It is the 3rd point that is most important to this discussion, since UFS
>> has already been deployed by various vendors and is used by OEM.
>> Changing
>> ufshcd to a set of library functions that would be called by variants
>> would necessarily introduce a significant change to the code flow in
>> many
>> places and would pose a backward compatibility issue. By using the tried
>> and tested pattern of subnodes in the dts we were able to keep the
>> change
>> simple, succinct, understandable, maintainable and backward compatible.
>> In
>> fact, the entire logic tying of the generic implementation to the
>> variant
>> takes ~20 lines of code - both short and elegant.
>
> The DWC3 binding does this and nothing else that I'm aware of. This
> hardly makes for a common pattern. If you really want to split this to
> 2 devices, you can create platform devices without having a DT node.
>
> If you want to convince me this is the right approach for the binding
> then you need to convince me the h/w is actually split this way and
> there is functionality separate from the licensed IP.
>
> Rob
>

I don't understand the challenge that you just posed. It is clear from our
implementation that there is the standard and variants thereof. I know
this to be a fact on the processors that we are working on.

Furthermore, although I didn't check each and every result in the search,
of_platform_populate is used in more locations than dwc3 and at least a
few of them seem have be using the same paradigm as ours
(http://lxr.free-electrons.com/ident?i=of_platform_populate).

QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring June 17, 2015, 1:37 p.m. UTC | #17
On Wed, Jun 17, 2015 at 8:17 AM, Dov Levenglick <dovl@codeaurora.org> wrote:
>> On Wed, Jun 17, 2015 at 2:42 AM, Dov Levenglick <dovl@codeaurora.org>
>> wrote:
>>>> On Tue, Jun 9, 2015 at 12:53 AM, Dov Levenglick <dovl@codeaurora.org>
>>>> wrote:
>>>>>> On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
>>>>>>>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>>>>
>>>> [...]
>>>>
>>>>>>> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually
>>>>>>> happens
>>>>>>> always), then the calling to of_platform_populate() which is added,
>>>>>>> guarantees that ufs-qcom probe will be called and finish, before
>>>>>>> ufshcd_pltfrm probe continues.
>>>>>>> so ufs_variant device is always there, and ready.
>>>>>>> I think it means we are safe - since either way, we make sure
>>>>>>> ufs-qcom
>>>>>>> probe will be called and finish before dealing with ufs_variant
>>>>>>> device
>>>>>>> in
>>>>>>> ufshcd_pltfrm probe.
>>>>>>
>>>>>> This is due to the fact that you have 2 platform drivers. You should
>>>>>> only have 1 (and 1 node). If you really think you need 2, then you
>>>>>> should do like many other common *HCIs do and make the base UFS
>>>>>> driver
>>>>>> a set of library functions that drivers can use or call. Look at
>>>>>> EHCI,
>>>>>> AHCI, SDHCI, etc. for inspiration.
>>>>>
>>>>> Hi Rob,
>>>>> We did look at SDHCI and decided to go with this design due to its
>>>>> simplicity and lack of library functions. Yaniv described the proper
>>>>> flow
>>>>> of probing and, as we understand things, it is guaranteed to work as
>>>>> designed.
>>>>>
>>>>> Furthermore, the design of having a subcore in the dts is used in the
>>>>> Linux kernel. Please have a look at drivers/usb/dwc3 where - as an
>>>>> example
>>>>> - both dwc3-msm and dwc3-exynox invoke the probing function in core.c
>>>>> (i.e. the shared underlying Synopsys USB dwc3 core) by calling
>>>>> of_platform_populate().
>>>>
>>>> That binding has the same problem. Please don't propagate that. There
>>>> is no point in a sub-node in this case.
>>>>
>>>>> Do you see a benefit in the SDHCi implementation?
>>>>
>>>> Yes, it does not let the kernel driver design dictate the hardware
>>>> description.
>>>>
>>>> Rob
>>>>
>>>
>>> Hi Rob,
>>> We appear to be having a philosophical disagreement on the practicality
>>> of
>>> designing the ufshcd variant's implementation - in other words, we
>>> disagree on the proper design pattern to follow here.
>>> If I understand correctly, you are concerned with a design pattern
>>> wherein
>>> a generic implementation is wrapped - at the device-tree level - in a
>>> variant implementation. The main reason for your concern is that you
>>> don't
>>> want the "kernel driver design dictate the hardware description".
>>>
>>> We considered this point when we suggested our implementation (both
>>> before
>>> and after you raised it) and reached the conclusion that - while an
>>> important consideration - it should not be the prevailing one. I believe
>>> that you will agree once you read the reasoning. What guided us was the
>>> following:
>>> 1. Keep our change minimal.
>>> 2. Keep our patch in line with known design patterns in the kernel.
>>> 3. Have our patch extend the existing solution rather than reinvent it.
>>>
>>> It is the 3rd point that is most important to this discussion, since UFS
>>> has already been deployed by various vendors and is used by OEM.
>>> Changing
>>> ufshcd to a set of library functions that would be called by variants
>>> would necessarily introduce a significant change to the code flow in
>>> many
>>> places and would pose a backward compatibility issue. By using the tried
>>> and tested pattern of subnodes in the dts we were able to keep the
>>> change
>>> simple, succinct, understandable, maintainable and backward compatible.
>>> In
>>> fact, the entire logic tying of the generic implementation to the
>>> variant
>>> takes ~20 lines of code - both short and elegant.
>>
>> The DWC3 binding does this and nothing else that I'm aware of. This
>> hardly makes for a common pattern. If you really want to split this to
>> 2 devices, you can create platform devices without having a DT node.
>>
>> If you want to convince me this is the right approach for the binding
>> then you need to convince me the h/w is actually split this way and
>> there is functionality separate from the licensed IP.
>>
>> Rob
>>
>
> I don't understand the challenge that you just posed. It is clear from our
> implementation that there is the standard and variants thereof. I know
> this to be a fact on the processors that we are working on.
>
> Furthermore, although I didn't check each and every result in the search,
> of_platform_populate is used in more locations than dwc3 and at least a
> few of them seem have be using the same paradigm as ours
> (http://lxr.free-electrons.com/ident?i=of_platform_populate).

You can ignore everything under arch/ as those are root level calls.
Most of the rest of the list are devices which have multiple unrelated
functions such as PMICs or system controllers which are perfectly
valid uses of of_platform_populate. That leaves at most 10 examples
that may or may not have good bindings. 10 out of hundreds of drivers
in the kernel hardly makes for a pattern to follow.

Let me be perfectly clear on the binding as is: NAK. I'm done replying
until you propose something different.

Rob
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
dovl@codeaurora.org June 17, 2015, 2:21 p.m. UTC | #18
Hi James,
Rob raises a point that we don't agree with. On the other hand, we are not
capable of convincing him in the validity of our approach - we are at an
impasse.
I would like to point out that our approach was reviewed by Paul and Mita
(external reviewers) and neither of them had the objection that Rob has.
I urge you to go over this thread, where both sides raised points and
argued their cases. We are going to need your call on this so that we can
move forward.

Thanks,
Dov


> On Wed, Jun 17, 2015 at 8:17 AM, Dov Levenglick <dovl@codeaurora.org>
> wrote:
>>> On Wed, Jun 17, 2015 at 2:42 AM, Dov Levenglick <dovl@codeaurora.org>
>>> wrote:
>>>>> On Tue, Jun 9, 2015 at 12:53 AM, Dov Levenglick <dovl@codeaurora.org>
>>>>> wrote:
>>>>>>> On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
>>>>>>>>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>>>>>
>>>>> [...]
>>>>>
>>>>>>>> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually
>>>>>>>> happens
>>>>>>>> always), then the calling to of_platform_populate() which is
>>>>>>>> added,
>>>>>>>> guarantees that ufs-qcom probe will be called and finish, before
>>>>>>>> ufshcd_pltfrm probe continues.
>>>>>>>> so ufs_variant device is always there, and ready.
>>>>>>>> I think it means we are safe - since either way, we make sure
>>>>>>>> ufs-qcom
>>>>>>>> probe will be called and finish before dealing with ufs_variant
>>>>>>>> device
>>>>>>>> in
>>>>>>>> ufshcd_pltfrm probe.
>>>>>>>
>>>>>>> This is due to the fact that you have 2 platform drivers. You
>>>>>>> should
>>>>>>> only have 1 (and 1 node). If you really think you need 2, then you
>>>>>>> should do like many other common *HCIs do and make the base UFS
>>>>>>> driver
>>>>>>> a set of library functions that drivers can use or call. Look at
>>>>>>> EHCI,
>>>>>>> AHCI, SDHCI, etc. for inspiration.
>>>>>>
>>>>>> Hi Rob,
>>>>>> We did look at SDHCI and decided to go with this design due to its
>>>>>> simplicity and lack of library functions. Yaniv described the proper
>>>>>> flow
>>>>>> of probing and, as we understand things, it is guaranteed to work as
>>>>>> designed.
>>>>>>
>>>>>> Furthermore, the design of having a subcore in the dts is used in
>>>>>> the
>>>>>> Linux kernel. Please have a look at drivers/usb/dwc3 where - as an
>>>>>> example
>>>>>> - both dwc3-msm and dwc3-exynox invoke the probing function in
>>>>>> core.c
>>>>>> (i.e. the shared underlying Synopsys USB dwc3 core) by calling
>>>>>> of_platform_populate().
>>>>>
>>>>> That binding has the same problem. Please don't propagate that. There
>>>>> is no point in a sub-node in this case.
>>>>>
>>>>>> Do you see a benefit in the SDHCi implementation?
>>>>>
>>>>> Yes, it does not let the kernel driver design dictate the hardware
>>>>> description.
>>>>>
>>>>> Rob
>>>>>
>>>>
>>>> Hi Rob,
>>>> We appear to be having a philosophical disagreement on the
>>>> practicality
>>>> of
>>>> designing the ufshcd variant's implementation - in other words, we
>>>> disagree on the proper design pattern to follow here.
>>>> If I understand correctly, you are concerned with a design pattern
>>>> wherein
>>>> a generic implementation is wrapped - at the device-tree level - in a
>>>> variant implementation. The main reason for your concern is that you
>>>> don't
>>>> want the "kernel driver design dictate the hardware description".
>>>>
>>>> We considered this point when we suggested our implementation (both
>>>> before
>>>> and after you raised it) and reached the conclusion that - while an
>>>> important consideration - it should not be the prevailing one. I
>>>> believe
>>>> that you will agree once you read the reasoning. What guided us was
>>>> the
>>>> following:
>>>> 1. Keep our change minimal.
>>>> 2. Keep our patch in line with known design patterns in the kernel.
>>>> 3. Have our patch extend the existing solution rather than reinvent
>>>> it.
>>>>
>>>> It is the 3rd point that is most important to this discussion, since
>>>> UFS
>>>> has already been deployed by various vendors and is used by OEM.
>>>> Changing
>>>> ufshcd to a set of library functions that would be called by variants
>>>> would necessarily introduce a significant change to the code flow in
>>>> many
>>>> places and would pose a backward compatibility issue. By using the
>>>> tried
>>>> and tested pattern of subnodes in the dts we were able to keep the
>>>> change
>>>> simple, succinct, understandable, maintainable and backward
>>>> compatible.
>>>> In
>>>> fact, the entire logic tying of the generic implementation to the
>>>> variant
>>>> takes ~20 lines of code - both short and elegant.
>>>
>>> The DWC3 binding does this and nothing else that I'm aware of. This
>>> hardly makes for a common pattern. If you really want to split this to
>>> 2 devices, you can create platform devices without having a DT node.
>>>
>>> If you want to convince me this is the right approach for the binding
>>> then you need to convince me the h/w is actually split this way and
>>> there is functionality separate from the licensed IP.
>>>
>>> Rob
>>>
>>
>> I don't understand the challenge that you just posed. It is clear from
>> our
>> implementation that there is the standard and variants thereof. I know
>> this to be a fact on the processors that we are working on.
>>
>> Furthermore, although I didn't check each and every result in the
>> search,
>> of_platform_populate is used in more locations than dwc3 and at least a
>> few of them seem have be using the same paradigm as ours
>> (http://lxr.free-electrons.com/ident?i=of_platform_populate).
>
> You can ignore everything under arch/ as those are root level calls.
> Most of the rest of the list are devices which have multiple unrelated
> functions such as PMICs or system controllers which are perfectly
> valid uses of of_platform_populate. That leaves at most 10 examples
> that may or may not have good bindings. 10 out of hundreds of drivers
> in the kernel hardly makes for a pattern to follow.
>
> Let me be perfectly clear on the binding as is: NAK. I'm done replying
> until you propose something different.
>
> Rob
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
James Bottomley June 17, 2015, 2:31 p.m. UTC | #19
On Wed, 2015-06-17 at 14:21 +0000, Dov Levenglick wrote:
> Hi James,
> Rob raises a point that we don't agree with. On the other hand, we are not
> capable of convincing him in the validity of our approach - we are at an
> impasse.
> I would like to point out that our approach was reviewed by Paul and Mita
> (external reviewers) and neither of them had the objection that Rob has.
> I urge you to go over this thread, where both sides raised points and
> argued their cases. We are going to need your call on this so that we can
> move forward.

The dispute is about device tree bindings.  While I could override a NAK
in the subsystem I maintain, I'm not going to when it comes from the
maintainer of the device tree subsystem on a subject that's his province
of expertise, not mine.

Please agree on what the bindings should look like and then resubmit the
driver.

James


> Thanks,
> Dov
> 
> 
> > On Wed, Jun 17, 2015 at 8:17 AM, Dov Levenglick <dovl@codeaurora.org>
> > wrote:
> >>> On Wed, Jun 17, 2015 at 2:42 AM, Dov Levenglick <dovl@codeaurora.org>
> >>> wrote:
> >>>>> On Tue, Jun 9, 2015 at 12:53 AM, Dov Levenglick <dovl@codeaurora.org>
> >>>>> wrote:
> >>>>>>> On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
> >>>>>>>>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
> >>>>>
> >>>>> [...]
> >>>>>
> >>>>>>>> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what actually
> >>>>>>>> happens
> >>>>>>>> always), then the calling to of_platform_populate() which is
> >>>>>>>> added,
> >>>>>>>> guarantees that ufs-qcom probe will be called and finish, before
> >>>>>>>> ufshcd_pltfrm probe continues.
> >>>>>>>> so ufs_variant device is always there, and ready.
> >>>>>>>> I think it means we are safe - since either way, we make sure
> >>>>>>>> ufs-qcom
> >>>>>>>> probe will be called and finish before dealing with ufs_variant
> >>>>>>>> device
> >>>>>>>> in
> >>>>>>>> ufshcd_pltfrm probe.
> >>>>>>>
> >>>>>>> This is due to the fact that you have 2 platform drivers. You
> >>>>>>> should
> >>>>>>> only have 1 (and 1 node). If you really think you need 2, then you
> >>>>>>> should do like many other common *HCIs do and make the base UFS
> >>>>>>> driver
> >>>>>>> a set of library functions that drivers can use or call. Look at
> >>>>>>> EHCI,
> >>>>>>> AHCI, SDHCI, etc. for inspiration.
> >>>>>>
> >>>>>> Hi Rob,
> >>>>>> We did look at SDHCI and decided to go with this design due to its
> >>>>>> simplicity and lack of library functions. Yaniv described the proper
> >>>>>> flow
> >>>>>> of probing and, as we understand things, it is guaranteed to work as
> >>>>>> designed.
> >>>>>>
> >>>>>> Furthermore, the design of having a subcore in the dts is used in
> >>>>>> the
> >>>>>> Linux kernel. Please have a look at drivers/usb/dwc3 where - as an
> >>>>>> example
> >>>>>> - both dwc3-msm and dwc3-exynox invoke the probing function in
> >>>>>> core.c
> >>>>>> (i.e. the shared underlying Synopsys USB dwc3 core) by calling
> >>>>>> of_platform_populate().
> >>>>>
> >>>>> That binding has the same problem. Please don't propagate that. There
> >>>>> is no point in a sub-node in this case.
> >>>>>
> >>>>>> Do you see a benefit in the SDHCi implementation?
> >>>>>
> >>>>> Yes, it does not let the kernel driver design dictate the hardware
> >>>>> description.
> >>>>>
> >>>>> Rob
> >>>>>
> >>>>
> >>>> Hi Rob,
> >>>> We appear to be having a philosophical disagreement on the
> >>>> practicality
> >>>> of
> >>>> designing the ufshcd variant's implementation - in other words, we
> >>>> disagree on the proper design pattern to follow here.
> >>>> If I understand correctly, you are concerned with a design pattern
> >>>> wherein
> >>>> a generic implementation is wrapped - at the device-tree level - in a
> >>>> variant implementation. The main reason for your concern is that you
> >>>> don't
> >>>> want the "kernel driver design dictate the hardware description".
> >>>>
> >>>> We considered this point when we suggested our implementation (both
> >>>> before
> >>>> and after you raised it) and reached the conclusion that - while an
> >>>> important consideration - it should not be the prevailing one. I
> >>>> believe
> >>>> that you will agree once you read the reasoning. What guided us was
> >>>> the
> >>>> following:
> >>>> 1. Keep our change minimal.
> >>>> 2. Keep our patch in line with known design patterns in the kernel.
> >>>> 3. Have our patch extend the existing solution rather than reinvent
> >>>> it.
> >>>>
> >>>> It is the 3rd point that is most important to this discussion, since
> >>>> UFS
> >>>> has already been deployed by various vendors and is used by OEM.
> >>>> Changing
> >>>> ufshcd to a set of library functions that would be called by variants
> >>>> would necessarily introduce a significant change to the code flow in
> >>>> many
> >>>> places and would pose a backward compatibility issue. By using the
> >>>> tried
> >>>> and tested pattern of subnodes in the dts we were able to keep the
> >>>> change
> >>>> simple, succinct, understandable, maintainable and backward
> >>>> compatible.
> >>>> In
> >>>> fact, the entire logic tying of the generic implementation to the
> >>>> variant
> >>>> takes ~20 lines of code - both short and elegant.
> >>>
> >>> The DWC3 binding does this and nothing else that I'm aware of. This
> >>> hardly makes for a common pattern. If you really want to split this to
> >>> 2 devices, you can create platform devices without having a DT node.
> >>>
> >>> If you want to convince me this is the right approach for the binding
> >>> then you need to convince me the h/w is actually split this way and
> >>> there is functionality separate from the licensed IP.
> >>>
> >>> Rob
> >>>
> >>
> >> I don't understand the challenge that you just posed. It is clear from
> >> our
> >> implementation that there is the standard and variants thereof. I know
> >> this to be a fact on the processors that we are working on.
> >>
> >> Furthermore, although I didn't check each and every result in the
> >> search,
> >> of_platform_populate is used in more locations than dwc3 and at least a
> >> few of them seem have be using the same paradigm as ours
> >> (http://lxr.free-electrons.com/ident?i=of_platform_populate).
> >
> > You can ignore everything under arch/ as those are root level calls.
> > Most of the rest of the list are devices which have multiple unrelated
> > functions such as PMICs or system controllers which are perfectly
> > valid uses of of_platform_populate. That leaves at most 10 examples
> > that may or may not have good bindings. 10 out of hundreds of drivers
> > in the kernel hardly makes for a pattern to follow.
> >
> > Let me be perfectly clear on the binding as is: NAK. I'm done replying
> > until you propose something different.
> >
> > Rob
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> 
> 
> QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
dovl@codeaurora.org June 17, 2015, 2:38 p.m. UTC | #20
> On Wed, 2015-06-17 at 14:21 +0000, Dov Levenglick wrote:
>> Hi James,
>> Rob raises a point that we don't agree with. On the other hand, we are
>> not
>> capable of convincing him in the validity of our approach - we are at an
>> impasse.
>> I would like to point out that our approach was reviewed by Paul and
>> Mita
>> (external reviewers) and neither of them had the objection that Rob has.
>> I urge you to go over this thread, where both sides raised points and
>> argued their cases. We are going to need your call on this so that we
>> can
>> move forward.
>
> The dispute is about device tree bindings.  While I could override a NAK
> in the subsystem I maintain, I'm not going to when it comes from the
> maintainer of the device tree subsystem on a subject that's his province
> of expertise, not mine.
>
> Please agree on what the bindings should look like and then resubmit the
> driver.
>
> James
>

Hi James & Rob,
Until this point I thought that this was a disagreement within the
confines of the scsi list. I was not aware of Rob's position as a
maintainer of the device tree subsystem.
We will take this offline with Rob and come back with a solution that
works for everyone.

Thanks,
Dov

>
>> Thanks,
>> Dov
>>
>>
>> > On Wed, Jun 17, 2015 at 8:17 AM, Dov Levenglick <dovl@codeaurora.org>
>> > wrote:
>> >>> On Wed, Jun 17, 2015 at 2:42 AM, Dov Levenglick
>> <dovl@codeaurora.org>
>> >>> wrote:
>> >>>>> On Tue, Jun 9, 2015 at 12:53 AM, Dov Levenglick
>> >>>>> <dovl@codeaurora.org>
>> >>>>> wrote:
>> >>>>>>> On Sun, Jun 7, 2015 at 10:32 AM,  <ygardi@codeaurora.org> wrote:
>> >>>>>>>>> 2015-06-05 5:53 GMT+09:00  <ygardi@codeaurora.org>:
>> >>>>>
>> >>>>> [...]
>> >>>>>
>> >>>>>>>> If ufshcd-pltfrm driver is loaded before ufs-qcom, (what
>> actually
>> >>>>>>>> happens
>> >>>>>>>> always), then the calling to of_platform_populate() which is
>> >>>>>>>> added,
>> >>>>>>>> guarantees that ufs-qcom probe will be called and finish,
>> before
>> >>>>>>>> ufshcd_pltfrm probe continues.
>> >>>>>>>> so ufs_variant device is always there, and ready.
>> >>>>>>>> I think it means we are safe - since either way, we make sure
>> >>>>>>>> ufs-qcom
>> >>>>>>>> probe will be called and finish before dealing with ufs_variant
>> >>>>>>>> device
>> >>>>>>>> in
>> >>>>>>>> ufshcd_pltfrm probe.
>> >>>>>>>
>> >>>>>>> This is due to the fact that you have 2 platform drivers. You
>> >>>>>>> should
>> >>>>>>> only have 1 (and 1 node). If you really think you need 2, then
>> you
>> >>>>>>> should do like many other common *HCIs do and make the base UFS
>> >>>>>>> driver
>> >>>>>>> a set of library functions that drivers can use or call. Look at
>> >>>>>>> EHCI,
>> >>>>>>> AHCI, SDHCI, etc. for inspiration.
>> >>>>>>
>> >>>>>> Hi Rob,
>> >>>>>> We did look at SDHCI and decided to go with this design due to
>> its
>> >>>>>> simplicity and lack of library functions. Yaniv described the
>> >>>>>> proper
>> >>>>>> flow
>> >>>>>> of probing and, as we understand things, it is guaranteed to work
>> >>>>>> as
>> >>>>>> designed.
>> >>>>>>
>> >>>>>> Furthermore, the design of having a subcore in the dts is used in
>> >>>>>> the
>> >>>>>> Linux kernel. Please have a look at drivers/usb/dwc3 where - as
>> an
>> >>>>>> example
>> >>>>>> - both dwc3-msm and dwc3-exynox invoke the probing function in
>> >>>>>> core.c
>> >>>>>> (i.e. the shared underlying Synopsys USB dwc3 core) by calling
>> >>>>>> of_platform_populate().
>> >>>>>
>> >>>>> That binding has the same problem. Please don't propagate that.
>> >>>>> There
>> >>>>> is no point in a sub-node in this case.
>> >>>>>
>> >>>>>> Do you see a benefit in the SDHCi implementation?
>> >>>>>
>> >>>>> Yes, it does not let the kernel driver design dictate the hardware
>> >>>>> description.
>> >>>>>
>> >>>>> Rob
>> >>>>>
>> >>>>
>> >>>> Hi Rob,
>> >>>> We appear to be having a philosophical disagreement on the
>> >>>> practicality
>> >>>> of
>> >>>> designing the ufshcd variant's implementation - in other words, we
>> >>>> disagree on the proper design pattern to follow here.
>> >>>> If I understand correctly, you are concerned with a design pattern
>> >>>> wherein
>> >>>> a generic implementation is wrapped - at the device-tree level - in
>> a
>> >>>> variant implementation. The main reason for your concern is that
>> you
>> >>>> don't
>> >>>> want the "kernel driver design dictate the hardware description".
>> >>>>
>> >>>> We considered this point when we suggested our implementation (both
>> >>>> before
>> >>>> and after you raised it) and reached the conclusion that - while an
>> >>>> important consideration - it should not be the prevailing one. I
>> >>>> believe
>> >>>> that you will agree once you read the reasoning. What guided us was
>> >>>> the
>> >>>> following:
>> >>>> 1. Keep our change minimal.
>> >>>> 2. Keep our patch in line with known design patterns in the kernel.
>> >>>> 3. Have our patch extend the existing solution rather than reinvent
>> >>>> it.
>> >>>>
>> >>>> It is the 3rd point that is most important to this discussion,
>> since
>> >>>> UFS
>> >>>> has already been deployed by various vendors and is used by OEM.
>> >>>> Changing
>> >>>> ufshcd to a set of library functions that would be called by
>> variants
>> >>>> would necessarily introduce a significant change to the code flow
>> in
>> >>>> many
>> >>>> places and would pose a backward compatibility issue. By using the
>> >>>> tried
>> >>>> and tested pattern of subnodes in the dts we were able to keep the
>> >>>> change
>> >>>> simple, succinct, understandable, maintainable and backward
>> >>>> compatible.
>> >>>> In
>> >>>> fact, the entire logic tying of the generic implementation to the
>> >>>> variant
>> >>>> takes ~20 lines of code - both short and elegant.
>> >>>
>> >>> The DWC3 binding does this and nothing else that I'm aware of. This
>> >>> hardly makes for a common pattern. If you really want to split this
>> to
>> >>> 2 devices, you can create platform devices without having a DT node.
>> >>>
>> >>> If you want to convince me this is the right approach for the
>> binding
>> >>> then you need to convince me the h/w is actually split this way and
>> >>> there is functionality separate from the licensed IP.
>> >>>
>> >>> Rob
>> >>>
>> >>
>> >> I don't understand the challenge that you just posed. It is clear
>> from
>> >> our
>> >> implementation that there is the standard and variants thereof. I
>> know
>> >> this to be a fact on the processors that we are working on.
>> >>
>> >> Furthermore, although I didn't check each and every result in the
>> >> search,
>> >> of_platform_populate is used in more locations than dwc3 and at least
>> a
>> >> few of them seem have be using the same paradigm as ours
>> >> (http://lxr.free-electrons.com/ident?i=of_platform_populate).
>> >
>> > You can ignore everything under arch/ as those are root level calls.
>> > Most of the rest of the list are devices which have multiple unrelated
>> > functions such as PMICs or system controllers which are perfectly
>> > valid uses of of_platform_populate. That leaves at most 10 examples
>> > that may or may not have good bindings. 10 out of hundreds of drivers
>> > in the kernel hardly makes for a pattern to follow.
>> >
>> > Let me be perfectly clear on the binding as is: NAK. I'm done replying
>> > until you propose something different.
>> >
>> > Rob
>> > --
>> > To unsubscribe from this list: send the line "unsubscribe linux-scsi"
>> in
>> > the body of a message to majordomo@vger.kernel.org
>> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >
>>
>>
>> QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc.
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
>> Forum,
>> a Linux Foundation Collaborative Project
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
>
>
>


QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
index 5357919..e2f3058 100644
--- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
+++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
@@ -55,3 +55,11 @@  Example:
 		clock-names = "core_clk", "ref_clk", "iface_clk";
 		freq-table-hz = <100000000 200000000>, <0 0>, <0 0>;
 	};
+
+This is an example to a variant sub-node of ufshc:
+	ufs_variant {
+		compatible = "qcom,ufs_variant";
+	};
+
+This sub-node holds various specific information that is not defined in the
+standard and that may differ between platforms.
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 6671a8e..ad5ffa8 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -1018,4 +1018,44 @@  static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
 };
 EXPORT_SYMBOL(ufs_hba_qcom_vops);
 
+/**
+ * ufs_qcom_probe - probe routine of the driver
+ * @pdev: pointer to Platform device handle
+ *
+ * Always return 0
+ */
+static int ufs_qcom_probe(struct platform_device *pdev)
+{
+	dev_set_drvdata(&pdev->dev, (void *)&ufs_hba_qcom_vops);
+	return 0;
+}
+
+/**
+ * ufs_qcom_remove - set driver_data of the device to NULL
+ * @pdev: pointer to platform device handle
+ *
+ * Always return 0
+ */
+static int ufs_qcom_remove(struct platform_device *pdev)
+{
+	dev_set_drvdata(&pdev->dev, NULL);
+	return 0;
+}
+
+static const struct of_device_id ufs_qcom_of_match[] = {
+	{ .compatible = "qcom,ufs_variant"},
+	{},
+};
+
+static struct platform_driver ufs_qcom_pltform = {
+	.probe	= ufs_qcom_probe,
+	.remove	= ufs_qcom_remove,
+	.driver	= {
+		.name	= "ufs_qcom",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(ufs_qcom_of_match),
+	},
+};
+module_platform_driver(ufs_qcom_pltform);
+
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index 7db9564..7bf2f44 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -36,22 +36,11 @@ 
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 
 #include "ufshcd.h"
 
 static const struct of_device_id ufs_of_match[];
-static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev)
-{
-	if (dev->of_node) {
-		const struct of_device_id *match;
-
-		match = of_match_node(ufs_of_match, dev->of_node);
-		if (match)
-			return (struct ufs_hba_variant_ops *)match->data;
-	}
-
-	return NULL;
-}
 
 static int ufshcd_parse_clock_info(struct ufs_hba *hba)
 {
@@ -300,6 +289,9 @@  static int ufshcd_pltfrm_probe(struct platform_device *pdev)
 	struct resource *mem_res;
 	int irq, err;
 	struct device *dev = &pdev->dev;
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *ufs_variant_node;
+	struct platform_device *ufs_variant_pdev;
 
 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mmio_base = devm_ioremap_resource(dev, mem_res);
@@ -321,7 +313,22 @@  static int ufshcd_pltfrm_probe(struct platform_device *pdev)
 		goto out;
 	}
 
-	hba->vops = get_variant_ops(&pdev->dev);
+	err = of_platform_populate(node, NULL, NULL, &pdev->dev);
+	if (err)
+		dev_err(&pdev->dev,
+			"%s: of_platform_populate() failed\n", __func__);
+
+	ufs_variant_node = of_get_next_available_child(node, NULL);
+
+	if (!ufs_variant_node) {
+		dev_dbg(&pdev->dev, "failed to find ufs_variant_node child\n");
+	} else {
+		ufs_variant_pdev = of_find_device_by_node(ufs_variant_node);
+
+		if (ufs_variant_pdev)
+			hba->vops = (struct ufs_hba_variant_ops *)
+				dev_get_drvdata(&ufs_variant_pdev->dev);
+	}
 
 	err = ufshcd_parse_clock_info(hba);
 	if (err) {