Re: [PATCH v10 3/9] dt-bindings: phy: tegra-xusb-padctl: Add Tegra210 support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Monday 18 April 2016 05:20 PM, Thierry Reding wrote:
> On Wed, Apr 06, 2016 at 07:08:24PM +0200, Thierry Reding wrote:
> [...]
>> I attached what I came up with. It extends the OF PHY provider registry
>> by allowing an additional node to be specified that if specified will
>> serve as the parent for the child lookup (and hence overrides the
>> default node that's taken from the struct device).
>>
>> It is a fairly trivial patch, and you'll notice the bulk of the changes
>> is adding the additional parameter in a number of different places. The
>> only thing I'm not quite happy about is that we start needing to pass a
>> fairly large number of arguments. But perhaps it's still okay.
>>
>> An alternative would be to make struct phy_provider embeddable into
>> driver private structures. That way they could be completely initialized
>> by a driver before being passed to the __of_phy_provider_register()
>> function (much like struct gpio_chip and others). That would be a fairly
>> intrusive change, one that I'd be willing to take on, though I'd like to
>> have Kishon's opinion on this before going ahead.
>>
>> For reference, here's what I'm imagining:
>>
>> 	struct foo_phy_provider {
>> 		struct phy_provider base;
>> 		...
>> 	};
>>
>> 	int foo_probe(struct platform_device *pdev)
>> 	{
>> 		struct foo_phy_provider *priv;
>> 		...
>>
>> 		priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>> 		if (!priv)
>> 			return -ENOMEM;
>>
>> 		priv->base.dev = &pdev->dev;
>> 		priv->base.of_xlate = foo_of_xlate;
>>
>> 		err = devm_of_phy_provider_register(&priv->base);
>> 		if (err < 0)
>> 			return err;
>>
>> 		...
>> 	}
>>
>> And of course adapt the signature of the __of_phy_provider_register()
>> function and remove the allocation from it.
>>
>> Thierry
>>
>> --- >8 ---
>> From 15e5348a1a63837efd00309fdce5cda979498f77 Mon Sep 17 00:00:00 2001
>> From: Thierry Reding <treding@xxxxxxxxxx>
>> Date: Tue, 5 Apr 2016 17:17:34 +0200
>> Subject: [PATCH] phy: core: Allow children node to be overridden
>>
>> In order to more flexibly support device tree bindings, allow drivers to
>> override the container of the child nodes. By default the device node of
>> the PHY provider is assumed to be the parent for children, but bindings
>> may decide to add additional levels for better organization.
>>
>> Signed-off-by: Thierry Reding <treding@xxxxxxxxxx>
>> ---
>>  Documentation/phy.txt   | 16 ++++++++++++++--
>>  drivers/phy/phy-core.c  | 27 +++++++++++++++++++++------
>>  include/linux/phy/phy.h | 31 +++++++++++++++++++++----------
>>  3 files changed, 56 insertions(+), 18 deletions(-)
> 
> Hi Kishon,
> 
> I'd like to take this through the Tegra tree along with the remainder of
> the XUSB pad controller and XHCI patches that depend on it. The nice
> thing is that it's fairly unintrusive but gives people an easy way to
> support more flexible bindings by allowing the OF node to be overridden
> when registering the PHY provider.
> 
> Are you okay with the change below? If so, could you provide an
> Acked-by? I can provide a stable branch for you to pull into the PHY
> tree that I'd like to use as a base for the remainder of the series.
> I did a fair amount of compile-testing and upon inspection the API that
> the patch modifies isn't called in many places, everyone uses the
> convenience macros. The stable branch will be helpful in fixing up any
> new users, should any appear during the development cycle.
> 
> Thanks,
> Thierry
> 
>> diff --git a/Documentation/phy.txt b/Documentation/phy.txt
>> index b388c5af9e72..0aa994bd9a91 100644
>> --- a/Documentation/phy.txt
>> +++ b/Documentation/phy.txt
>> @@ -31,16 +31,28 @@ should provide its own implementation of of_xlate. of_xlate is used only for
>>  dt boot case.
>>  
>>  #define of_phy_provider_register(dev, xlate)    \
>> -        __of_phy_provider_register((dev), THIS_MODULE, (xlate))
>> +        __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
>>  
>>  #define devm_of_phy_provider_register(dev, xlate)       \
>> -        __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate))
>> +        __devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
>>  
>>  of_phy_provider_register and devm_of_phy_provider_register macros can be used to
>>  register the phy_provider and it takes device and of_xlate as
>>  arguments. For the dt boot case, all PHY providers should use one of the above
>>  2 macros to register the PHY provider.
>>  
>> +Often the device tree nodes associated with a PHY provider will contain a set
>> +of children that each represent a single PHY. Some bindings may nest the child
>> +nodes within extra levels for context and extensibility, in which case the low
>> +level of_phy_provider_register_full() and devm_of_phy_provider_register_full()
>> +macros can be used to override the node containing the children.
>> +
>> +#define of_phy_provider_register_full(dev, children, xlate) \
>> +	__of_phy_provider_register(dev, children, THIS_MODULE, xlate)
>> +
>> +#define devm_of_phy_provider_register_full(dev, children, xlate) \
>> +	__devm_of_phy_provider_register_full(dev, children, THIS_MODULE, xlate)
>> +
>>  void devm_of_phy_provider_unregister(struct device *dev,
>>  	struct phy_provider *phy_provider);
>>  void of_phy_provider_unregister(struct phy_provider *phy_provider);
>> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
>> index e7e574dc667a..7f7da2138c82 100644
>> --- a/drivers/phy/phy-core.c
>> +++ b/drivers/phy/phy-core.c
>> @@ -135,13 +135,19 @@ static struct phy *phy_find(struct device *dev, const char *con_id)
>>  static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
>>  {
>>  	struct phy_provider *phy_provider;
>> +	struct device_node *children;
>>  	struct device_node *child;
>>  
>>  	list_for_each_entry(phy_provider, &phy_provider_list, list) {
>>  		if (phy_provider->dev->of_node == node)
>>  			return phy_provider;
>>  
>> -		for_each_child_of_node(phy_provider->dev->of_node, child)
>> +		if (!phy_provider->children)
>> +			children = phy_provider->dev->of_node;
>> +		else
>> +			children = phy_provider->children;
>> +
>> +		for_each_child_of_node(children, child)
>>  			if (child == node)
>>  				return phy_provider;
>>  	}
>> @@ -811,16 +817,22 @@ EXPORT_SYMBOL_GPL(devm_phy_destroy);
>>  /**
>>   * __of_phy_provider_register() - create/register phy provider with the framework
>>   * @dev: struct device of the phy provider
>> + * @children: device node containing children (if different from dev->of_node)
>>   * @owner: the module owner containing of_xlate
>>   * @of_xlate: function pointer to obtain phy instance from phy provider
>>   *
>>   * Creates struct phy_provider from dev and of_xlate function pointer.
>>   * This is used in the case of dt boot for finding the phy instance from
>>   * phy provider.
>> + *
>> + * If the PHY provider doesn't nest children directly but uses a separate
>> + * child node to contain the individual children, the @children parameter
>> + * can be used to override the default (i.e. dev->of_node).
>>   */
>>  struct phy_provider *__of_phy_provider_register(struct device *dev,
>> -	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
>> -	struct of_phandle_args *args))
>> +	struct device_node *children, struct module *owner,
>> +	struct phy * (*of_xlate)(struct device *dev,
>> +				 struct of_phandle_args *args))
>>  {
>>  	struct phy_provider *phy_provider;
>>  
>> @@ -829,6 +841,7 @@ struct phy_provider *__of_phy_provider_register(struct device *dev,
>>  		return ERR_PTR(-ENOMEM);
>>  
>>  	phy_provider->dev = dev;
>> +	phy_provider->children = children;

I think we should atleast make sure that *children* is actually a subnode of
*dev* whatever level it might be?

Thanks
Kishon

>>  	phy_provider->owner = owner;
>>  	phy_provider->of_xlate = of_xlate;
>>  
>> @@ -854,8 +867,9 @@ EXPORT_SYMBOL_GPL(__of_phy_provider_register);
>>   * on the devres data, then, devres data is freed.
>>   */
>>  struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
>> -	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
>> -	struct of_phandle_args *args))
>> +	struct device_node *children, struct module *owner,
>> +	struct phy * (*of_xlate)(struct device *dev,
>> +				 struct of_phandle_args *args))
>>  {
>>  	struct phy_provider **ptr, *phy_provider;
>>  
>> @@ -863,7 +877,8 @@ struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
>>  	if (!ptr)
>>  		return ERR_PTR(-ENOMEM);
>>  
>> -	phy_provider = __of_phy_provider_register(dev, owner, of_xlate);
>> +	phy_provider = __of_phy_provider_register(dev, children, owner,
>> +						  of_xlate);
>>  	if (!IS_ERR(phy_provider)) {
>>  		*ptr = phy_provider;
>>  		devres_add(dev, ptr);
>> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
>> index 8cf05e341cff..a810f2a18842 100644
>> --- a/include/linux/phy/phy.h
>> +++ b/include/linux/phy/phy.h
>> @@ -77,6 +77,7 @@ struct phy {
>>   */
>>  struct phy_provider {
>>  	struct device		*dev;
>> +	struct device_node	*children;
>>  	struct module		*owner;
>>  	struct list_head	list;
>>  	struct phy * (*of_xlate)(struct device *dev,
>> @@ -93,10 +94,16 @@ struct phy_lookup {
>>  #define	to_phy(a)	(container_of((a), struct phy, dev))
>>  
>>  #define	of_phy_provider_register(dev, xlate)	\
>> -	__of_phy_provider_register((dev), THIS_MODULE, (xlate))
>> +	__of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
>>  
>>  #define	devm_of_phy_provider_register(dev, xlate)	\
>> -	__devm_of_phy_provider_register((dev), THIS_MODULE, (xlate))
>> +	__devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
>> +
>> +#define of_phy_provider_register_full(dev, children, xlate) \
>> +	__of_phy_provider_register(dev, children, THIS_MODULE, xlate)
>> +
>> +#define devm_of_phy_provider_register_full(dev, children, xlate) \
>> +	__devm_of_phy_provider_register(dev, children, THIS_MODULE, xlate)
>>  
>>  static inline void phy_set_drvdata(struct phy *phy, void *data)
>>  {
>> @@ -147,11 +154,13 @@ struct phy *devm_phy_create(struct device *dev, struct device_node *node,
>>  void phy_destroy(struct phy *phy);
>>  void devm_phy_destroy(struct device *dev, struct phy *phy);
>>  struct phy_provider *__of_phy_provider_register(struct device *dev,
>> -	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
>> -	struct of_phandle_args *args));
>> +	struct device_node *children, struct module *owner,
>> +	struct phy * (*of_xlate)(struct device *dev,
>> +				 struct of_phandle_args *args));
>>  struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
>> -	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
>> -	struct of_phandle_args *args));
>> +	struct device_node *children, struct module *owner,
>> +	struct phy * (*of_xlate)(struct device *dev,
>> +				 struct of_phandle_args *args));
>>  void of_phy_provider_unregister(struct phy_provider *phy_provider);
>>  void devm_of_phy_provider_unregister(struct device *dev,
>>  	struct phy_provider *phy_provider);
>> @@ -312,15 +321,17 @@ static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
>>  }
>>  
>>  static inline struct phy_provider *__of_phy_provider_register(
>> -	struct device *dev, struct module *owner, struct phy * (*of_xlate)(
>> -	struct device *dev, struct of_phandle_args *args))
>> +	struct device *dev, struct device_node *children, struct module *owner,
>> +	struct phy * (*of_xlate)(struct device *dev,
>> +				 struct of_phandle_args *args))
>>  {
>>  	return ERR_PTR(-ENOSYS);
>>  }
>>  
>>  static inline struct phy_provider *__devm_of_phy_provider_register(struct device
>> -	*dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev,
>> -	struct of_phandle_args *args))
>> +	*dev, struct device_node *children, struct module *owner,
>> +	struct phy * (*of_xlate)(struct device *dev,
>> +				 struct of_phandle_args *args))
>>  {
>>  	return ERR_PTR(-ENOSYS);
>>  }
>> -- 
>> 2.8.0
>>
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [ARM Kernel]     [Linux ARM]     [Linux ARM MSM]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux