From: Kishon Vijay Abraham I <hidden> Date: 2013-07-18 06:47:11
Added a generic PHY framework that provides a set of APIs for the PHY drivers
to create/destroy a PHY and APIs for the PHY users to obtain a reference to
the PHY with or without using phandle.
This framework will be of use only to devices that uses external PHY (PHY
functionality is not embedded within the controller).
The intention of creating this framework is to bring the phy drivers spread
all over the Linux kernel to drivers/phy to increase code re-use and to
increase code maintainability.
Comments to make PHY as bus wasn't done because PHY devices can be part of
other bus and making a same device attached to multiple bus leads to bad
design.
If the PHY driver has to send notification on connect/disconnect, the PHY
driver should make use of the extcon framework. Using this susbsystem
to use extcon framwork will have to be analysed.
Exynos MIPI CSIS/DSIM PHY and Displayport PHY have started using this
framework. Have included those patches also in this series.
twl4030-usb and omap-usb2 have also been adapted to this framework.
These patches are also available @
git://gitorious.org/linuxphy/linuxphy.git tags/phy-for-v3.12
Jingoo Han (3):
phy: Add driver for Exynos DP PHY
video: exynos_dp: remove non-DT support for Exynos Display Port
video: exynos_dp: Use the generic PHY driver
Kishon Vijay Abraham I (8):
drivers: phy: add generic PHY framework
usb: phy: omap-usb2: use the new generic PHY framework
usb: phy: twl4030: use the new generic PHY framework
ARM: OMAP: USB: Add phy binding information
ARM: dts: omap: update usb_otg_hs data
usb: musb: omap2430: use the new generic PHY framework
usb: phy: omap-usb2: remove *set_suspend* callback from omap-usb2
usb: phy: twl4030-usb: remove *set_suspend* and *phy_init* ops
Sylwester Nawrocki (4):
phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs
video: exynos_mipi_dsim: Use the generic PHY driver
exynos4-is: Use the generic MIPI CSIS PHY driver
ARM: Samsung: Remove the MIPI PHY setup code
.../devicetree/bindings/phy/phy-bindings.txt | 66 +++
.../devicetree/bindings/phy/samsung-phy.txt | 22 +
Documentation/devicetree/bindings/usb/omap-usb.txt | 5 +
Documentation/devicetree/bindings/usb/usb-phy.txt | 6 +
.../devicetree/bindings/video/exynos_dp.txt | 18 +-
Documentation/phy.txt | 129 +++++
MAINTAINERS | 7 +
arch/arm/boot/dts/omap3-beagle-xm.dts | 2 +
arch/arm/boot/dts/omap3-evm.dts | 2 +
arch/arm/boot/dts/omap3-overo.dtsi | 2 +
arch/arm/boot/dts/omap4.dtsi | 3 +
arch/arm/boot/dts/twl4030.dtsi | 1 +
arch/arm/mach-exynos/include/mach/regs-pmu.h | 5 -
arch/arm/mach-omap2/usb-musb.c | 3 +
arch/arm/mach-s5pv210/include/mach/regs-clock.h | 4 -
arch/arm/plat-samsung/Kconfig | 5 -
arch/arm/plat-samsung/Makefile | 1 -
arch/arm/plat-samsung/setup-mipiphy.c | 60 ---
drivers/Kconfig | 2 +
drivers/Makefile | 2 +
drivers/media/platform/exynos4-is/mipi-csis.c | 16 +-
drivers/phy/Kconfig | 28 +
drivers/phy/Makefile | 7 +
drivers/phy/phy-core.c | 544 ++++++++++++++++++++
drivers/phy/phy-exynos-dp-video.c | 111 ++++
drivers/phy/phy-exynos-mipi-video.c | 169 ++++++
drivers/usb/musb/Kconfig | 1 +
drivers/usb/musb/musb_core.c | 1 +
drivers/usb/musb/musb_core.h | 3 +
drivers/usb/musb/omap2430.c | 26 +-
drivers/usb/phy/Kconfig | 1 +
drivers/usb/phy/phy-omap-usb2.c | 60 ++-
drivers/usb/phy/phy-twl4030-usb.c | 63 ++-
drivers/video/exynos/Kconfig | 2 +-
drivers/video/exynos/exynos_dp_core.c | 132 ++---
drivers/video/exynos/exynos_dp_core.h | 110 ++++
drivers/video/exynos/exynos_dp_reg.c | 2 -
drivers/video/exynos/exynos_mipi_dsi.c | 19 +-
include/linux/phy/phy.h | 344 +++++++++++++
include/linux/platform_data/mipi-csis.h | 11 +-
include/linux/usb/musb.h | 3 +
include/video/exynos_dp.h | 131 -----
include/video/exynos_mipi_dsim.h | 6 +-
43 files changed, 1746 insertions(+), 389 deletions(-)
create mode 100644 Documentation/devicetree/bindings/phy/phy-bindings.txt
create mode 100644 Documentation/devicetree/bindings/phy/samsung-phy.txt
create mode 100644 Documentation/phy.txt
delete mode 100644 arch/arm/plat-samsung/setup-mipiphy.c
create mode 100644 drivers/phy/Kconfig
create mode 100644 drivers/phy/Makefile
create mode 100644 drivers/phy/phy-core.c
create mode 100644 drivers/phy/phy-exynos-dp-video.c
create mode 100644 drivers/phy/phy-exynos-mipi-video.c
create mode 100644 include/linux/phy/phy.h
delete mode 100644 include/video/exynos_dp.h
--
1.7.10.4
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-18 06:47:24
The PHY framework provides a set of APIs for the PHY drivers to
create/destroy a PHY and APIs for the PHY users to obtain a reference to the
PHY with or without using phandle. For dt-boot, the PHY drivers should
also register *PHY provider* with the framework.
PHY drivers should create the PHY by passing id and ops like init, exit,
power_on and power_off. This framework is also pm runtime enabled.
The documentation for the generic PHY framework is added in
Documentation/phy.txt and the documentation for dt binding can be found at
Documentation/devicetree/bindings/phy/phy-bindings.txt
Signed-off-by: Kishon Vijay Abraham I <redacted>
Acked-by: Felipe Balbi <redacted>
Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
.../devicetree/bindings/phy/phy-bindings.txt | 66 +++
Documentation/phy.txt | 129 +++++
MAINTAINERS | 7 +
drivers/Kconfig | 2 +
drivers/Makefile | 2 +
drivers/phy/Kconfig | 13 +
drivers/phy/Makefile | 5 +
drivers/phy/phy-core.c | 544 ++++++++++++++++++++
include/linux/phy/phy.h | 344 +++++++++++++
9 files changed, 1112 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/phy-bindings.txt
create mode 100644 Documentation/phy.txt
create mode 100644 drivers/phy/Kconfig
create mode 100644 drivers/phy/Makefile
create mode 100644 drivers/phy/phy-core.c
create mode 100644 include/linux/phy/phy.h
@@ -0,0 +1,66 @@+This document explains only the device tree data binding. For general+information about PHY subsystem refer to Documentation/phy.txt++PHY device node+=======++Required Properties:+#phy-cells: Number of cells in a PHY specifier; The meaning of all those+ cells is defined by the binding for the phy node. The PHY+ provider can use the values in cells to find the appropriate+ PHY.++For example:++phys: phy {+ compatible = "xxx";+ reg = <...>;+ .+ .+ #phy-cells = <1>;+ .+ .+};++That node describes an IP block (PHY provider) that implements 2 different PHYs.+In order to differentiate between these 2 PHYs, an additonal specifier should be+given while trying to get a reference to it.++PHY user node+======++Required Properties:+phys : the phandle for the PHY device (used by the PHY subsystem)+phy-names : the names of the PHY corresponding to the PHYs present in the+ *phys* phandle++Example 1:+usb1: usb_otg_ss@xxx {+ compatible = "xxx";+ reg = <xxx>;+ .+ .+ phys = <&usb2_phy>, <&usb3_phy>;+ phy-names = "usb2phy", "usb3phy";+ .+ .+};++This node represents a controller that uses two PHYs, one for usb2 and one for+usb3.++Example 2:+usb2: usb_otg_ss@xxx {+ compatible = "xxx";+ reg = <xxx>;+ .+ .+ phys = <&phys 1>;+ phy-names = "usbphy";+ .+ .+};++This node represents a controller that uses one of the PHYs of the PHY provider+device defined previously. Note that the phy handle has an additional specifier+"1" to differentiate between the two PHYs.
@@ -0,0 +1,129 @@+ PHY SUBSYSTEM+ Kishon Vijay Abraham I <kishon@ti.com>++This document explains the Generic PHY Framework along with the APIs provided,+and how-to-use.++1. Introduction++*PHY* is the abbreviation for physical layer. It is used to connect a device+to the physical medium e.g., the USB controller has a PHY to provide functions+such as serialization, de-serialization, encoding, decoding and is responsible+for obtaining the required data transmission rate. Note that some USB+controllers have PHY functionality embedded into it and others use an external+PHY. Other peripherals that use PHY include Wireless LAN, Ethernet,+SATA etc.++The intention of creating this framework is to bring the PHY drivers spread+all over the Linux kernel to drivers/phy to increase code re-use and for+better code maintainability.++This framework will be of use only to devices that use external PHY (PHY+functionality is not embedded within the controller).++2. Registering/Unregistering the PHY provider++PHY provider refers to an entity that implements one or more PHY instances.+For the simple case where the PHY provider implements only a single instance of+the PHY, the framework provides its own implementation of of_xlate in+of_phy_simple_xlate. If the PHY provider implements multiple instances, it+should provide its own implementation of of_xlate. of_xlate is used only for+dt boot case.++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 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))++__of_phy_provider_register and __devm_of_phy_provider_register can be used to+register the phy_provider and it takes device, owner and of_xlate as+arguments. For the dt boot case, all PHY providers should use one of the above+2 APIs to register the PHY provider.++void devm_of_phy_provider_unregister(struct device *dev,+ struct phy_provider *phy_provider);+void of_phy_provider_unregister(struct phy_provider *phy_provider);++devm_of_phy_provider_unregister and of_phy_provider_unregister can be used to+unregister the PHY.++3. Creating the PHY++The PHY driver should create the PHY in order for other peripheral controllers+to make use of it. The PHY framework provides 2 APIs to create the PHY.++struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,+ const char *label);+extern struct phy *devm_phy_create(struct device *dev, u8 id,+ const struct phy_ops *ops, const char *label);++The PHY drivers can use one of the above 2 APIs to create the PHY by passing+the device pointer, id, phy ops, label and a driver data.+phy_ops is a set of function pointers for performing PHY operations such as+init, exit, power_on and power_off. *label* is mandatory for non-dt boot case+and it should be unique as well.++Inorder to dereference the private data (in phy_ops), the phy provider driver+can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in+phy_ops to get back the private data.++4. Getting a reference to the PHY++Before the controller can make use of the PHY, it has to get a reference to+it. This framework provides the following APIs to get a reference to the PHY.++struct phy *phy_get(struct device *dev, const char *string);+struct phy *devm_phy_get(struct device *dev, const char *string);++phy_get and devm_phy_get can be used to get the PHY. In the case of dt boot,+the string arguments should contain the phy name as given in the dt data and+in the case of non-dt boot, it should contain the label of the PHY.+The only difference between the two APIs is that devm_phy_get associates the+device with the PHY using devres on successful PHY get. On driver detach,+release function is invoked on the the devres data and devres data is freed.++5. Releasing a reference to the PHY++When the controller no longer needs the PHY, it has to release the reference+to the PHY it has obtained using the APIs mentioned in the above section. The+PHY framework provides 2 APIs to release a reference to the PHY.++void phy_put(struct phy *phy);+void devm_phy_put(struct device *dev, struct phy *phy);++Both these APIs are used to release a reference to the PHY and devm_phy_put+destroys the devres associated with this PHY.++6. Destroying the PHY++When the driver that created the PHY is unloaded, it should destroy the PHY it+created using one of the following 2 APIs.++void phy_destroy(struct phy *phy);+void devm_phy_destroy(struct device *dev, struct phy *phy);++Both these APIs destroy the PHY and devm_phy_destroy destroys the devres+associated with this PHY.++7. PM Runtime++This subsystem is pm runtime enabled. So while creating the PHY,+pm_runtime_enable of the phy device created by this subsystem is called and+while destroying the PHY, pm_runtime_disable is called. Note that the phy+device created by this subsystem will be a child of the device that calls+phy_create (PHY provider device).++So pm_runtime_get_sync of the phy_device created by this subsystem will invoke+pm_runtime_get_sync of PHY provider device because of parent-child relationship.+It should also be noted that phy_power_on and phy_power_off performs+phy_pm_runtime_get_sync and phy_pm_runtime_put respectively.+There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync,+phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and+phy_pm_runtime_forbid for performing PM operations.++8. DeviceTree Binding++The documentation for PHY dt binding can be found @+Documentation/devicetree/bindings/phy/phy-bindings.txt
@@ -8,6 +8,8 @@obj-y+=irqchip/obj-y+=bus/+obj-$(CONFIG_GENERIC_PHY)+=phy/+# GPIO must come after pinctrl as gpios may need to mux pins etcobj-y+=pinctrl/obj-y+=gpio/
@@ -0,0 +1,544 @@+/*+*phy-core.c--GenericPhyframework.+*+*Copyright(C)2013TexasInstruments+*+*Author:KishonVijayAbrahamI<kishon@ti.com>+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodifyit+*underthetermsoftheGNUGeneralPublicLicenseaspublishedbythe+*FreeSoftwareFoundation;eitherversion2oftheLicense,or(atyour+*option)anylaterversion.+*+*Thisprogramisdistributedinthehopethatitwillbeuseful,+*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof+*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe+*GNUGeneralPublicLicenseformoredetails.+*+*YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense+*alongwiththisprogram.Ifnot,see<http://www.gnu.org/licenses/>.+*/++#include<linux/kernel.h>+#include<linux/export.h>+#include<linux/module.h>+#include<linux/err.h>+#include<linux/device.h>+#include<linux/slab.h>+#include<linux/of.h>+#include<linux/phy/phy.h>+#include<linux/pm_runtime.h>++staticstructclass*phy_class;+staticDEFINE_MUTEX(phy_provider_mutex);+staticLIST_HEAD(phy_provider_list);++staticvoiddevm_phy_release(structdevice*dev,void*res)+{+structphy*phy=*(structphy**)res;++phy_put(phy);+}++staticvoiddevm_phy_provider_release(structdevice*dev,void*res)+{+structphy_provider*phy_provider=*(structphy_provider**)res;++of_phy_provider_unregister(phy_provider);+}++staticvoiddevm_phy_consume(structdevice*dev,void*res)+{+structphy*phy=*(structphy**)res;++phy_destroy(phy);+}++staticintdevm_phy_match(structdevice*dev,void*res,void*match_data)+{+returnres=match_data;+}++staticstructphy*phy_lookup(constchar*phy_name)+{+structphy*phy;+structdevice*dev;+structclass_dev_iteriter;++class_dev_iter_init(&iter,phy_class,NULL,NULL);+while((dev=class_dev_iter_next(&iter))){+phy=to_phy(dev);+if(strcmp(phy->label,phy_name))+continue;++class_dev_iter_exit(&iter);+returnphy;+}++class_dev_iter_exit(&iter);+returnERR_PTR(-ENODEV);+}++staticstructphy_provider*of_phy_provider_lookup(structdevice_node*node)+{+structphy_provider*phy_provider;++list_for_each_entry(phy_provider,&phy_provider_list,list){+if(phy_provider->dev->of_node=node)+returnphy_provider;+}++returnERR_PTR(-EPROBE_DEFER);+}++/**+*of_phy_get()-lookupandobtainareferencetoaphybyphandle+*@dev:devicethatrequeststhisphy+*@index:theindexofthephy+*+*Returnsthephyassociatedwiththegivenphandlevalue,+*aftergettingarefcounttoitor-ENODEVifthereisnosuchphyor+*-EPROBE_DEFERifthereisaphandletothephy,butthedeviceis+*notyetloaded.Thisfunctionusesof_xlatecallbackfunctionprovided+*whileregisteringthephy_providertofindthephyinstance.+*/+staticstructphy*of_phy_get(structdevice*dev,intindex)+{+intret;+structphy_provider*phy_provider;+structphy*phy=NULL;+structof_phandle_argsargs;++ret=of_parse_phandle_with_args(dev->of_node,"phys","#phy-cells",+index,&args);+if(ret){+dev_dbg(dev,"failed to get phy in %s node\n",+dev->of_node->full_name);+returnERR_PTR(-ENODEV);+}++mutex_lock(&phy_provider_mutex);+phy_provider=of_phy_provider_lookup(args.np);+if(IS_ERR(phy_provider)||!try_module_get(phy_provider->owner)){+phy=ERR_PTR(-EPROBE_DEFER);+gotoerr0;+}++phy=phy_provider->of_xlate(phy_provider->dev,&args);+module_put(phy_provider->owner);++err0:+mutex_unlock(&phy_provider_mutex);+of_node_put(args.np);++returnphy;+}++/**+*phy_put()-releasethePHY+*@phy:thephyreturnedbyphy_get()+*+*Releasesarefcountthecallerreceivedfromphy_get().+*/+voidphy_put(structphy*phy)+{+if(IS_ERR(phy))+return;++module_put(phy->ops->owner);+put_device(&phy->dev);+}+EXPORT_SYMBOL_GPL(phy_put);++/**+*devm_phy_put()-releasethePHY+*@dev:devicethatwantstoreleasethisphy+*@phy:thephyreturnedbydevm_phy_get()+*+*destroysthedevresassociatedwiththisphyandinvokesphy_put+*toreleasethephy.+*/+voiddevm_phy_put(structdevice*dev,structphy*phy)+{+intr;++r=devres_destroy(dev,devm_phy_release,devm_phy_match,phy);+dev_WARN_ONCE(dev,r,"couldn't find PHY resource\n");+}+EXPORT_SYMBOL_GPL(devm_phy_put);++/**+*of_phy_simple_xlate()-returnsthephyinstancefromphyprovider+*@dev:thePHYproviderdevice+*@args:of_phandle_args(notusedhere)+*+*Intendedtobeusedbyphyproviderforthecommoncasewhere#phy-cellsis+*0.Forothercaseswhere#phy-cellsisgreaterthan'0',thephyprovider+*shouldprovideacustomof_xlatefunctionthatreadsthe*args*andreturns+*theappropriatephy.+*/+structphy*of_phy_simple_xlate(structdevice*dev,structof_phandle_args+*args)+{+structphy*phy;+structclass_dev_iteriter;+structdevice_node*node=dev->of_node;++class_dev_iter_init(&iter,phy_class,NULL,NULL);+while((dev=class_dev_iter_next(&iter))){+phy=to_phy(dev);+if(node!=phy->dev.of_node)+continue;++class_dev_iter_exit(&iter);+returnphy;+}++class_dev_iter_exit(&iter);+returnERR_PTR(-ENODEV);+}+EXPORT_SYMBOL_GPL(of_phy_simple_xlate);++/**+*phy_get()-lookupandobtainareferencetoaphy.+*@dev:devicethatrequeststhisphy+*@string:thephynameasgiveninthedtdataorphydevicename+*fornon-dtcase+*+*Returnsthephydriver,aftergettingarefcounttoit;or+*-ENODEVifthereisnosuchphy.Thecallerisresponsiblefor+*callingphy_put()toreleasethatcount.+*/+structphy*phy_get(structdevice*dev,constchar*string)+{+intindex=0;+structphy*phy=NULL;++if(string=NULL){+dev_WARN(dev,"missing string\n");+returnERR_PTR(-EINVAL);+}++if(dev->of_node){+index=of_property_match_string(dev->of_node,"phy-names",+string);+phy=of_phy_get(dev,index);+if(IS_ERR(phy)){+dev_WARN(dev,"unable to find phy\n");+returnphy;+}+}else{+phy=phy_lookup(string);+if(IS_ERR(phy)){+dev_WARN(dev,"unable to find phy\n");+returnphy;+}+}++if(!try_module_get(phy->ops->owner))+returnERR_PTR(-EPROBE_DEFER);++get_device(&phy->dev);++returnphy;+}+EXPORT_SYMBOL_GPL(phy_get);++/**+*devm_phy_get()-lookupandobtainareferencetoaphy.+*@dev:devicethatrequeststhisphy+*@string:thephynameasgiveninthedtdataorphydevicename+*fornon-dtcase+*+*Getsthephyusingphy_get(),andassociatesadevicewithitusing+*devres.Ondriverdetach,releasefunctionisinvokedonthedevresdata,+*then,devresdataisfreed.+*/+structphy*devm_phy_get(structdevice*dev,constchar*string)+{+structphy**ptr,*phy;++ptr=devres_alloc(devm_phy_release,sizeof(*ptr),GFP_KERNEL);+if(!ptr)+returnERR_PTR(-ENOMEM);++phy=phy_get(dev,string);+if(!IS_ERR(phy)){+*ptr=phy;+devres_add(dev,ptr);+}else{+devres_free(ptr);+}++returnphy;+}+EXPORT_SYMBOL_GPL(devm_phy_get);++/**+*phy_create()-createanewphy+*@dev:devicethatiscreatingthenewphy+*@id:idofthephy+*@ops:functionpointersforperformingphyoperations+*@label:labelgiventothephy+*+*Calledtocreateaphyusingphyframework.+*/+structphy*phy_create(structdevice*dev,u8id,conststructphy_ops*ops,+constchar*label)+{+intret;+structphy*phy;++if(!dev){+dev_WARN(dev,"no device provided for PHY\n");+ret=-EINVAL;+gotoerr0;+}++phy=kzalloc(sizeof(*phy),GFP_KERNEL);+if(!phy){+ret=-ENOMEM;+gotoerr0;+}++device_initialize(&phy->dev);+mutex_init(&phy->mutex);++phy->dev.class=phy_class;+phy->dev.parent=dev;+phy->dev.of_node=dev->of_node;+phy->id=id;+phy->ops=ops;+phy->label=kstrdup(label,GFP_KERNEL);++ret=dev_set_name(&phy->dev,"%s.%d",dev_name(dev),id);+if(ret)+gotoerr1;++ret=device_add(&phy->dev);+if(ret)+gotoerr1;++if(pm_runtime_enabled(dev)){+pm_runtime_enable(&phy->dev);+pm_runtime_no_callbacks(&phy->dev);+}++returnphy;++err1:+put_device(&phy->dev);+kfree(phy->label);+kfree(phy);++err0:+returnERR_PTR(ret);+}+EXPORT_SYMBOL_GPL(phy_create);++/**+*devm_phy_create()-createanewphy+*@dev:devicethatiscreatingthenewphy+*@id:idofthephy+*@ops:functionpointersforperformingphyoperations+*@label:labelgiventothephy+*+*CreatesanewPHYdeviceaddingittothePHYclass.+*Whileatthat,italsoassociatesthedevicewiththephyusingdevres.+*Ondriverdetach,releasefunctionisinvokedonthedevresdata,+*then,devresdataisfreed.+*/+structphy*devm_phy_create(structdevice*dev,u8id,+conststructphy_ops*ops,constchar*label)+{+structphy**ptr,*phy;++ptr=devres_alloc(devm_phy_consume,sizeof(*ptr),GFP_KERNEL);+if(!ptr)+returnERR_PTR(-ENOMEM);++phy=phy_create(dev,id,ops,label);+if(!IS_ERR(phy)){+*ptr=phy;+devres_add(dev,ptr);+}else{+devres_free(ptr);+}++returnphy;+}+EXPORT_SYMBOL_GPL(devm_phy_create);++/**+*phy_destroy()-destroythephy+*@phy:thephytobedestroyed+*+*Calledtodestroythephy.+*/+voidphy_destroy(structphy*phy)+{+pm_runtime_disable(&phy->dev);+device_unregister(&phy->dev);+}+EXPORT_SYMBOL_GPL(phy_destroy);++/**+*devm_phy_destroy()-destroythePHY+*@dev:devicethatwantstoreleasethisphy+*@phy:thephyreturnedbydevm_phy_get()+*+*destroysthedevresassociatedwiththisphyandinvokesphy_destroy+*todestroythephy.+*/+voiddevm_phy_destroy(structdevice*dev,structphy*phy)+{+intr;++r=devres_destroy(dev,devm_phy_consume,devm_phy_match,phy);+dev_WARN_ONCE(dev,r,"couldn't find PHY resource\n");+}+EXPORT_SYMBOL_GPL(devm_phy_destroy);++/**+*__of_phy_provider_register()-create/registerphyproviderwiththeframework+*@dev:structdeviceofthephyprovider+*@owner:themoduleownercontainingof_xlate+*@of_xlate:functionpointertoobtainphyinstancefromphyprovider+*+*Createsstructphy_providerfromdevandof_xlatefunctionpointer.+*Thisisusedinthecaseofdtbootforfindingthephyinstancefrom+*phyprovider.+*/+structphy_provider*__of_phy_provider_register(structdevice*dev,+structmodule*owner,structphy*(*of_xlate)(structdevice*dev,+structof_phandle_args*args))+{+structphy_provider*phy_provider;++phy_provider=kzalloc(sizeof(*phy_provider),GFP_KERNEL);+if(!phy_provider)+returnERR_PTR(-ENOMEM);++phy_provider->dev=dev;+phy_provider->owner=owner;+phy_provider->of_xlate=of_xlate;++mutex_lock(&phy_provider_mutex);+list_add_tail(&phy_provider->list,&phy_provider_list);+mutex_unlock(&phy_provider_mutex);++returnphy_provider;+}+EXPORT_SYMBOL_GPL(__of_phy_provider_register);++/**+*__devm_of_phy_provider_register()-create/registerphyproviderwiththe+*framework+*@dev:structdeviceofthephyprovider+*@owner:themoduleownercontainingof_xlate+*@of_xlate:functionpointertoobtainphyinstancefromphyprovider+*+*Createsstructphy_providerfromdevandof_xlatefunctionpointer.+*Thisisusedinthecaseofdtbootforfindingthephyinstancefrom+*phyprovider.Whileatthat,italsoassociatesthedevicewiththe+*phyproviderusingdevres.Ondriverdetach,releasefunctionisinvoked+*onthedevresdata,then,devresdataisfreed.+*/+structphy_provider*__devm_of_phy_provider_register(structdevice*dev,+structmodule*owner,structphy*(*of_xlate)(structdevice*dev,+structof_phandle_args*args))+{+structphy_provider**ptr,*phy_provider;++ptr=devres_alloc(devm_phy_provider_release,sizeof(*ptr),GFP_KERNEL);+if(!ptr)+returnERR_PTR(-ENOMEM);++phy_provider=__of_phy_provider_register(dev,owner,of_xlate);+if(!IS_ERR(phy_provider)){+*ptr=phy_provider;+devres_add(dev,ptr);+}else{+devres_free(ptr);+}++returnphy_provider;+}+EXPORT_SYMBOL_GPL(__devm_of_phy_provider_register);++/**+*of_phy_provider_unregister()-unregisterphyproviderfromtheframework+*@phy_provider:phyproviderreturnedbyof_phy_provider_register()+*+*Removesthephy_providercreatedusingof_phy_provider_register().+*/+voidof_phy_provider_unregister(structphy_provider*phy_provider)+{+if(IS_ERR(phy_provider))+return;++mutex_lock(&phy_provider_mutex);+list_del(&phy_provider->list);+kfree(phy_provider);+mutex_unlock(&phy_provider_mutex);+}+EXPORT_SYMBOL_GPL(of_phy_provider_unregister);++/**+*devm_of_phy_provider_unregister()-removephyproviderfromtheframework+*@dev:structdeviceofthephyprovider+*+*destroysthedevresassociatedwiththisphyproviderandinvokes+*of_phy_provider_unregistertounregisterthephyprovider.+*/+voiddevm_of_phy_provider_unregister(structdevice*dev,+structphy_provider*phy_provider){+intr;++r=devres_destroy(dev,devm_phy_provider_release,devm_phy_match,+phy_provider);+dev_WARN_ONCE(dev,r,"couldn't find PHY provider device resource\n");+}+EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister);++/**+*phy_release()-releasethephy+*@dev:thedevmemberwithinphy+*+*Whenthelastreferencetothedeviceisremoved,itiscalled+*fromtheembeddedkobjectasreleasemethod.+*/+staticvoidphy_release(structdevice*dev)+{+structphy*phy;++phy=to_phy(dev);+dev_vdbg(dev,"releasing '%s'\n",dev_name(dev));+kfree(phy->label);+kfree(phy);+}++staticint__initphy_core_init(void)+{+phy_class=class_create(THIS_MODULE,"phy");+if(IS_ERR(phy_class)){+pr_err("failed to create phy class --> %ld\n",+PTR_ERR(phy_class));+returnPTR_ERR(phy_class);+}++phy_class->dev_release=phy_release;++return0;+}+module_init(phy_core_init);++staticvoid__exitphy_core_exit(void)+{+class_destroy(phy_class);+}+module_exit(phy_core_exit);++MODULE_DESCRIPTION("Generic PHY Framework");+MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");+MODULE_LICENSE("GPL v2");
On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote:
+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 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))
+
+__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+register the phy_provider and it takes device, owner and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 APIs to register the PHY provider.
Why do you have __ for the prefix of a public function? Is that really
the way that OF handles this type of thing?
Again, please reverse this. The drivers that use it should select it,
not depend on it, which will then enable this option. I will never know
if I need to enable it, and based on your follow-on patches, if I don't,
drivers that were working just fine, now disappeared from my build,
which isn't nice, and a pain to notice and fix up.
+/**
+ * phy_create() - create a new phy
+ * @dev: device that is creating the new phy
+ * @id: id of the phy
+ * @ops: function pointers for performing phy operations
+ * @label: label given to the phy
+ *
+ * Called to create a phy using phy framework.
+ */
+struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
+ const char *label)
+{
+ int ret;
+ struct phy *phy;
+
+ if (!dev) {
+ dev_WARN(dev, "no device provided for PHY\n");
+ ret = -EINVAL;
+ goto err0;
+ }
+
+ phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+ if (!phy) {
+ ret = -ENOMEM;
+ goto err0;
+ }
+
+ device_initialize(&phy->dev);
+ mutex_init(&phy->mutex);
+
+ phy->dev.class = phy_class;
+ phy->dev.parent = dev;
+ phy->dev.of_node = dev->of_node;
+ phy->id = id;
+ phy->ops = ops;
+ phy->label = kstrdup(label, GFP_KERNEL);
+
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+ if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+ return -EINVAL;
Why would phy ever not be valid and a error pointer? And why dump the
stack if that happens, that seems really extreme.
This, and the other inline functions in this .h file seem huge, why are
they inline and not in the .c file? There's no speed issues, and it
should save space overall in the .c file. Please move them.
+static inline int phy_init(struct phy *phy)
+{
+ int ret;
+
+ ret = phy_pm_runtime_get_sync(phy);
+ if (ret < 0 && ret != -ENOTSUPP)
+ return ret;
+
+ mutex_lock(&phy->mutex);
+ if (phy->init_count++ = 0 && phy->ops->init) {
+ ret = phy->ops->init(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy init failed --> %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+ phy_pm_runtime_put(phy);
+ return ret;
+}
+
+static inline int phy_exit(struct phy *phy)
+{
+ int ret;
+
+ ret = phy_pm_runtime_get_sync(phy);
+ if (ret < 0 && ret != -ENOTSUPP)
+ return ret;
+
+ mutex_lock(&phy->mutex);
+ if (--phy->init_count = 0 && phy->ops->exit) {
+ ret = phy->ops->exit(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+ phy_pm_runtime_put(phy);
+ return ret;
+}
+
+static inline int phy_power_on(struct phy *phy)
+{
+ int ret = -ENOTSUPP;
+
+ ret = phy_pm_runtime_get_sync(phy);
+ if (ret < 0 && ret != -ENOTSUPP)
+ return ret;
+
+ mutex_lock(&phy->mutex);
+ if (phy->power_count++ = 0 && phy->ops->power_on) {
+ ret = phy->ops->power_on(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+
+static inline int phy_power_off(struct phy *phy)
+{
+ int ret = -ENOTSUPP;
+
+ mutex_lock(&phy->mutex);
+ if (--phy->power_count = 0 && phy->ops->power_off) {
+ ret = phy->ops->power_off(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+ phy_pm_runtime_put(phy);
+
+ return ret;
+}
Look at those 3 functions, they are all "real" and not an inline
function at all, please move them.
thanks,
greg k-h
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-18 09:00:40
Hi,
On Thursday 18 July 2013 12:50 PM, Greg KH wrote:
On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote:
quoted
+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 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))
+
+__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+register the phy_provider and it takes device, owner and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 APIs to register the PHY provider.
Why do you have __ for the prefix of a public function? Is that really
the way that OF handles this type of thing?
I have a macro of_phy_provider_register/devm_of_phy_provider_register that
calls these functions and should be used by the PHY drivers. Probably I should
make a mention of it in the Documentation.
Again, please reverse this. The drivers that use it should select it,
not depend on it, which will then enable this option. I will never know
if I need to enable it, and based on your follow-on patches, if I don't,
drivers that were working just fine, now disappeared from my build,
which isn't nice, and a pain to notice and fix up.
ok.
quoted
+/**
+ * phy_create() - create a new phy
+ * @dev: device that is creating the new phy
+ * @id: id of the phy
+ * @ops: function pointers for performing phy operations
+ * @label: label given to the phy
+ *
+ * Called to create a phy using phy framework.
+ */
+struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
+ const char *label)
+{
+ int ret;
+ struct phy *phy;
+
+ if (!dev) {
+ dev_WARN(dev, "no device provided for PHY\n");
+ ret = -EINVAL;
+ goto err0;
+ }
+
+ phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+ if (!phy) {
+ ret = -ENOMEM;
+ goto err0;
+ }
+
+ device_initialize(&phy->dev);
+ mutex_init(&phy->mutex);
+
+ phy->dev.class = phy_class;
+ phy->dev.parent = dev;
+ phy->dev.of_node = dev->of_node;
+ phy->id = id;
+ phy->ops = ops;
+ phy->label = kstrdup(label, GFP_KERNEL);
+
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
quoted
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+ if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+ return -EINVAL;
Why would phy ever not be valid and a error pointer? And why dump the
stack if that happens, that seems really extreme.
hmm.. there might be cases where the same controller in one soc needs PHY
control and in some other soc does not need PHY control. In such cases, we
might get error pointer here.
I'll change WARN to dev_err.
This, and the other inline functions in this .h file seem huge, why are
they inline and not in the .c file? There's no speed issues, and it
should save space overall in the .c file. Please move them.
ok
quoted
+static inline int phy_init(struct phy *phy)
+{
+ int ret;
+
+ ret = phy_pm_runtime_get_sync(phy);
+ if (ret < 0 && ret != -ENOTSUPP)
+ return ret;
+
+ mutex_lock(&phy->mutex);
+ if (phy->init_count++ = 0 && phy->ops->init) {
+ ret = phy->ops->init(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy init failed --> %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+ phy_pm_runtime_put(phy);
+ return ret;
+}
+
+static inline int phy_exit(struct phy *phy)
+{
+ int ret;
+
+ ret = phy_pm_runtime_get_sync(phy);
+ if (ret < 0 && ret != -ENOTSUPP)
+ return ret;
+
+ mutex_lock(&phy->mutex);
+ if (--phy->init_count = 0 && phy->ops->exit) {
+ ret = phy->ops->exit(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+ phy_pm_runtime_put(phy);
+ return ret;
+}
+
+static inline int phy_power_on(struct phy *phy)
+{
+ int ret = -ENOTSUPP;
+
+ ret = phy_pm_runtime_get_sync(phy);
+ if (ret < 0 && ret != -ENOTSUPP)
+ return ret;
+
+ mutex_lock(&phy->mutex);
+ if (phy->power_count++ = 0 && phy->ops->power_on) {
+ ret = phy->ops->power_on(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+
+static inline int phy_power_off(struct phy *phy)
+{
+ int ret = -ENOTSUPP;
+
+ mutex_lock(&phy->mutex);
+ if (--phy->power_count = 0 && phy->ops->power_off) {
+ ret = phy->ops->power_off(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+ phy_pm_runtime_put(phy);
+
+ return ret;
+}
Look at those 3 functions, they are all "real" and not an inline
function at all, please move them.
On Thu, Jul 18, 2013 at 02:29:52PM +0530, Kishon Vijay Abraham I wrote:
Hi,
On Thursday 18 July 2013 12:50 PM, Greg KH wrote:
quoted
On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote:
quoted
+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 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))
+
+__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+register the phy_provider and it takes device, owner and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 APIs to register the PHY provider.
Why do you have __ for the prefix of a public function? Is that really
the way that OF handles this type of thing?
I have a macro of_phy_provider_register/devm_of_phy_provider_register that
calls these functions and should be used by the PHY drivers. Probably I should
make a mention of it in the Documentation.
Yes, mention those as you never want to be calling __* functions
directly, right?
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
rip out all of the "search for a phy by a string" logic, as that's not
needed either. Just stick to the pointer, it's easier, and safer that
way.
quoted
quoted
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+ if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+ return -EINVAL;
Why would phy ever not be valid and a error pointer? And why dump the
stack if that happens, that seems really extreme.
hmm.. there might be cases where the same controller in one soc needs PHY
control and in some other soc does not need PHY control. In such cases, we
might get error pointer here.
I'll change WARN to dev_err.
I still don't understand. You have control over the code that calls
these functions, just ensure that they pass in a valid pointer, it's
that simple. Or am I missing something?
thanks,
greg k-h
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-19 05:37:59
Hi,
On Thursday 18 July 2013 09:19 PM, Greg KH wrote:
On Thu, Jul 18, 2013 at 02:29:52PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Thursday 18 July 2013 12:50 PM, Greg KH wrote:
quoted
On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote:
quoted
+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 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))
+
+__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+register the phy_provider and it takes device, owner and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 APIs to register the PHY provider.
Why do you have __ for the prefix of a public function? Is that really
the way that OF handles this type of thing?
I have a macro of_phy_provider_register/devm_of_phy_provider_register that
calls these functions and should be used by the PHY drivers. Probably I should
make a mention of it in the Documentation.
Yes, mention those as you never want to be calling __* functions
directly, right?
correct.
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
needed either. Just stick to the pointer, it's easier, and safer that
way.
quoted
quoted
quoted
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+ if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+ return -EINVAL;
Why would phy ever not be valid and a error pointer? And why dump the
stack if that happens, that seems really extreme.
hmm.. there might be cases where the same controller in one soc needs PHY
control and in some other soc does not need PHY control. In such cases, we
might get error pointer here.
I'll change WARN to dev_err.
I still don't understand. You have control over the code that calls
these functions, just ensure that they pass in a valid pointer, it's
that simple. Or am I missing something?
You are right. Valid pointer check can be done in controller code as well.
Thanks
Kishon
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand. They registered the phy, and got back a pointer to
it. Why can't they save it in their local structure to use it again
later if needed? They should never have to "ask" for the device, as the
device id might be unknown if there are multiple devices in the system.
Or am I missing something?
thanks,
greg k-h
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-19 05:56:30
Hi,
On Friday 19 July 2013 11:13 AM, Greg KH wrote:
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand. They registered the phy, and got back a pointer to
it. Why can't they save it in their local structure to use it again
later if needed? They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).
device id might be unknown if there are multiple devices in the system.
I agree with you on the device id part. That need not be known to the PHY driver.
Thanks
Kishon
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
Hi,
On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand. They registered the phy, and got back a pointer to
it. Why can't they save it in their local structure to use it again
later if needed? They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).
quoted
device id might be unknown if there are multiple devices in the system.
I agree with you on the device id part. That need not be known to the PHY driver.
How does a consumer know which "label" to use in a non-dt system if
there are multiple PHYs in the system?
Do you have any drivers that are non-dt using this yet?
greg k-h
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-19 06:36:47
Hi,
On Friday 19 July 2013 11:59 AM, Greg KH wrote:
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand. They registered the phy, and got back a pointer to
it. Why can't they save it in their local structure to use it again
later if needed? They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).
quoted
device id might be unknown if there are multiple devices in the system.
I agree with you on the device id part. That need not be known to the PHY driver.
How does a consumer know which "label" to use in a non-dt system if
there are multiple PHYs in the system?
That should be passed using platform data.
Do you have any drivers that are non-dt using this yet?
yes. tw4030 (used in OMAP3) supports non-dt.
[PATCH 04/15] ARM: OMAP: USB: Add phy binding information
[PATCH 06/15] usb: musb: omap2430: use the new generic PHY framework
of this patch series shows how it's used.
Thanks
Kishon
From: Stephen Warren <hidden> Date: 2013-07-19 15:54:37
On 07/19/2013 12:36 AM, Kishon Vijay Abraham I wrote:
Hi,
On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand. They registered the phy, and got back a pointer to
it. Why can't they save it in their local structure to use it again
later if needed? They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).
quoted
device id might be unknown if there are multiple devices in the system.
I agree with you on the device id part. That need not be known to the PHY driver.
How does a consumer know which "label" to use in a non-dt system if
there are multiple PHYs in the system?
That should be passed using platform data.
I don't think that's right. That's just like passing clock names in
platform data, which I believe is frowned upon.
Instead, why not take the approach that e.g. regulators have taken? Each
driver defines the names of the objects that it requires. There is a
table (registered by a board file) that has lookup key (device name,
regulator name), and the output is the regulator device (or global
regulator name).
This is almost the same way that DT works, except that in DT, the table
is represented as properties in the DT. The DT binding defines the names
of those properties, or the strings that must be in the foo-names
properties, just like a driver in non-DT Linux is going to define the
names it expects to be provided with.
That way, you don't need platform data to define the names.
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-20 03:16:24
Hi,
On Friday 19 July 2013 09:24 PM, Stephen Warren wrote:
On 07/19/2013 12:36 AM, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand. They registered the phy, and got back a pointer to
it. Why can't they save it in their local structure to use it again
later if needed? They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).
quoted
device id might be unknown if there are multiple devices in the system.
I agree with you on the device id part. That need not be known to the PHY driver.
How does a consumer know which "label" to use in a non-dt system if
there are multiple PHYs in the system?
That should be passed using platform data.
I don't think that's right. That's just like passing clock names in
platform data, which I believe is frowned upon.
Instead, why not take the approach that e.g. regulators have taken? Each
driver defines the names of the objects that it requires. There is a
table (registered by a board file) that has lookup key (device name,
We were using a similar approach with USB PHY layer but things started
breaking after the device names are created using PLATFORM_DEVID_AUTO.
Now theres no way to reliably know the device names in advance.
Btw I had such device name binding in my v3 of this patch series [1] and
had some discussion with Grant during that time [2].
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130320.091200.721a6fb5.hu.html
[2] -> https://lkml.org/lkml/2013/4/22/26
Thanks
Kishon
On Fri, Jul 19, 2013 at 12:06:01PM +0530, Kishon Vijay Abraham I wrote:
Hi,
On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand. They registered the phy, and got back a pointer to
it. Why can't they save it in their local structure to use it again
later if needed? They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).
quoted
device id might be unknown if there are multiple devices in the system.
I agree with you on the device id part. That need not be known to the PHY driver.
How does a consumer know which "label" to use in a non-dt system if
there are multiple PHYs in the system?
That should be passed using platform data.
Ick, don't pass strings around, pass pointers. If you have platform
data you can get to, then put the pointer there, don't use a "name".
thanks,
greg k-h
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-20 03:20:31
Hi,
On Saturday 20 July 2013 05:20 AM, Greg KH wrote:
On Fri, Jul 19, 2013 at 12:06:01PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand. They registered the phy, and got back a pointer to
it. Why can't they save it in their local structure to use it again
later if needed? They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).
quoted
device id might be unknown if there are multiple devices in the system.
I agree with you on the device id part. That need not be known to the PHY driver.
How does a consumer know which "label" to use in a non-dt system if
there are multiple PHYs in the system?
That should be passed using platform data.
Ick, don't pass strings around, pass pointers. If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer when we
create the device for the controller no?(it'll be done in board file).
Probably I'm missing something.
Thanks
Kishon
On Sat, Jul 20, 2013 at 08:49:32AM +0530, Kishon Vijay Abraham I wrote:
Hi,
On Saturday 20 July 2013 05:20 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 12:06:01PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+ ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it? You rely on the sender to
never send a duplicate name.id pair? Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.
[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id? No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device. Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand. They registered the phy, and got back a pointer to
it. Why can't they save it in their local structure to use it again
later if needed? They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).
quoted
device id might be unknown if there are multiple devices in the system.
I agree with you on the device id part. That need not be known to the PHY driver.
How does a consumer know which "label" to use in a non-dt system if
there are multiple PHYs in the system?
That should be passed using platform data.
Ick, don't pass strings around, pass pointers. If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer? You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?
Don't use names, especially as ids can, and will, change, that is going
to cause big problems. Use pointers, this is C, we are supposed to be
doing that :)
thanks,
greg k-h
From: Alan Stern <stern@rowland.harvard.edu> Date: 2013-07-21 02:32:29
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers. If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer? You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?
Don't use names, especially as ids can, and will, change, that is going
to cause big problems. Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this: The name you are using must
be stored somewhere in a data structure constructed by the board file,
right? Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.
Greg's suggestion is that you store the address of that data structure
in the platform data instead of storing the name string. Have the
consumer pass the data structure's address when it calls phy_create,
instead of passing the name. Then you don't have to worry about two
PHYs accidentally ending up with the same name or any other similar
problems.
Alan Stern
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers. If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer? You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?
Don't use names, especially as ids can, and will, change, that is going
to cause big problems. Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this: The name you are using must
be stored somewhere in a data structure constructed by the board file,
right? Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.
Greg's suggestion is that you store the address of that data structure
in the platform data instead of storing the name string. Have the
consumer pass the data structure's address when it calls phy_create,
instead of passing the name. Then you don't have to worry about two
PHYs accidentally ending up with the same name or any other similar
problems.
Close, but the issue is that whatever returns from phy_create() should
then be used, no need to call any "find" functions, as you can just use
the pointer that phy_create() returns. Much like all other class api
functions in the kernel work.
thanks,
greg k-h
On Sat, Jul 20, 2013 at 07:59:10PM -0700, Greg KH wrote:
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers. If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer? You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?
Don't use names, especially as ids can, and will, change, that is going
to cause big problems. Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this: The name you are using must
be stored somewhere in a data structure constructed by the board file,
right? Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.
Greg's suggestion is that you store the address of that data structure
in the platform data instead of storing the name string. Have the
consumer pass the data structure's address when it calls phy_create,
instead of passing the name. Then you don't have to worry about two
PHYs accidentally ending up with the same name or any other similar
problems.
Close, but the issue is that whatever returns from phy_create() should
then be used, no need to call any "find" functions, as you can just use
the pointer that phy_create() returns. Much like all other class api
functions in the kernel work.
I think the problem here is to connect two from the bus structure
completely independent devices. Several frameworks (ASoC, soc-camera)
had this problem and this wasn't solved until the advent of devicetrees
and their phandles.
phy_create might be called from the probe function of some i2c device
(the phy device) and the resulting pointer is then needed in some other
platform devices (the user of the phy) probe function.
The best solution we have right now is implemented in the clk framework
which uses a string matching of the device names in clk_get() (at least
in the non-dt case).
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On Sun, Jul 21, 2013 at 12:22:48PM +0200, Sascha Hauer wrote:
On Sat, Jul 20, 2013 at 07:59:10PM -0700, Greg KH wrote:
quoted
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers. If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer? You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?
Don't use names, especially as ids can, and will, change, that is going
to cause big problems. Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this: The name you are using must
be stored somewhere in a data structure constructed by the board file,
right? Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.
Greg's suggestion is that you store the address of that data structure
in the platform data instead of storing the name string. Have the
consumer pass the data structure's address when it calls phy_create,
instead of passing the name. Then you don't have to worry about two
PHYs accidentally ending up with the same name or any other similar
problems.
Close, but the issue is that whatever returns from phy_create() should
then be used, no need to call any "find" functions, as you can just use
the pointer that phy_create() returns. Much like all other class api
functions in the kernel work.
I think the problem here is to connect two from the bus structure
completely independent devices. Several frameworks (ASoC, soc-camera)
had this problem and this wasn't solved until the advent of devicetrees
and their phandles.
phy_create might be called from the probe function of some i2c device
(the phy device) and the resulting pointer is then needed in some other
platform devices (the user of the phy) probe function.
The best solution we have right now is implemented in the clk framework
which uses a string matching of the device names in clk_get() (at least
in the non-dt case).
I would argue that clocks are wrong here as well, as others have already
pointed out.
What's wrong with the platform_data structure, why can't that be used
for this?
Or, if not, we can always add pointers to the platform device structure,
or even the main 'struct device' as well, that's what it is there for.
thanks,
greg k-h
On Sun, Jul 21, 2013 at 12:22:48PM +0200, Sascha Hauer wrote:
quoted
On Sat, Jul 20, 2013 at 07:59:10PM -0700, Greg KH wrote:
quoted
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers. If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer? You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?
Don't use names, especially as ids can, and will, change, that is going
to cause big problems. Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this: The name you are using must
be stored somewhere in a data structure constructed by the board file,
right? Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.
Greg's suggestion is that you store the address of that data structure
in the platform data instead of storing the name string. Have the
consumer pass the data structure's address when it calls phy_create,
instead of passing the name. Then you don't have to worry about two
PHYs accidentally ending up with the same name or any other similar
problems.
Close, but the issue is that whatever returns from phy_create() should
then be used, no need to call any "find" functions, as you can just use
the pointer that phy_create() returns. Much like all other class api
functions in the kernel work.
I think the problem here is to connect two from the bus structure
completely independent devices. Several frameworks (ASoC, soc-camera)
had this problem and this wasn't solved until the advent of devicetrees
and their phandles.
phy_create might be called from the probe function of some i2c device
(the phy device) and the resulting pointer is then needed in some other
platform devices (the user of the phy) probe function.
The best solution we have right now is implemented in the clk framework
which uses a string matching of the device names in clk_get() (at least
in the non-dt case).
I would argue that clocks are wrong here as well, as others have already
pointed out.
What's wrong with the platform_data structure, why can't that be used
for this?
At the point the platform data of some driver is initialized, e.g. in
board setup code the PHY pointer is not known, since the PHY supplier
driver has not initialized yet. Even though we wanted to pass pointer
to a PHY through some notifier call, it would have been not clear
which PHY user driver should match on such notifier. A single PHY
supplier driver can create M PHY objects and this needs to be mapped
to N PHY user drivers. This mapping needs to be defined somewhere by
the system integrator. It works well with device tree, but except that
there seems to be no other reliable infrastructure in the kernel to
define links/dependencies between devices, since device identifiers are
not known in advance in all cases.
What Tomasz proposed seems currently most reasonable to me for non-dt.
Or, if not, we can always add pointers to the platform device structure,
or even the main 'struct device' as well, that's what it is there for.
Still we would need to solve a problem which platform device structure
gets which PHY pointer.
--
Regards,
Sylwester
From: Alan Stern <stern@rowland.harvard.edu> Date: 2013-07-21 19:22:25
On Sun, 21 Jul 2013, Sylwester Nawrocki wrote:
quoted
What's wrong with the platform_data structure, why can't that be used
for this?
At the point the platform data of some driver is initialized, e.g. in
board setup code the PHY pointer is not known, since the PHY supplier
driver has not initialized yet. Even though we wanted to pass pointer
to a PHY through some notifier call, it would have been not clear
which PHY user driver should match on such notifier. A single PHY
supplier driver can create M PHY objects and this needs to be mapped
to N PHY user drivers. This mapping needs to be defined somewhere by
the system integrator. It works well with device tree, but except that
there seems to be no other reliable infrastructure in the kernel to
define links/dependencies between devices, since device identifiers are
not known in advance in all cases.
What Tomasz proposed seems currently most reasonable to me for non-dt.
quoted
Or, if not, we can always add pointers to the platform device structure,
or even the main 'struct device' as well, that's what it is there for.
Still we would need to solve a problem which platform device structure
gets which PHY pointer.
Can you explain the issues in more detail? I don't fully understand
the situation.
Here's what I think I know:
The PHY and the controller it is attached to are both physical
devices.
The connection between them is hardwired by the system
manufacturer and cannot be changed by software.
PHYs are generally described by fixed system-specific board
files or by Device Tree information. Are they ever discovered
dynamically?
Is the same true for the controllers attached to the PHYs?
If not -- if both a PHY and a controller are discovered
dynamically -- how does the kernel know whether they are
connected to each other?
The kernel needs to know which controller is attached to which
PHY. Currently this information is represented by name or ID
strings embedded in platform data.
The PHY's driver (the supplier) uses the platform data to
construct a platform_device structure that represents the PHY.
Until this is done, the controller's driver (the client) cannot
use the PHY.
Since there is no parent-child relation between the PHY and the
controller, there is no guarantee that the PHY's driver will be
ready when the controller's driver wants to use it. A deferred
probe may be needed.
The issue (or one of the issues) in this discussion is that
Greg does not like the idea of using names or IDs to associate
PHYs with controllers, because they are too prone to
duplications or other errors. Pointers are more reliable.
But pointers to what? Since the only data known to be
available to both the PHY driver and controller driver is the
platform data, the obvious answer is a pointer to platform data
(either for the PHY or for the controller, or maybe both).
Probably some of the details above are wrong; please indicate where I
have gone astray. Also, I'm not clear about the role played by various
APIs. For example, where does phy_create() fit into this picture?
Alan Stern
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-22 07:26:35
Hi,
On Monday 22 July 2013 12:52 AM, Alan Stern wrote:
On Sun, 21 Jul 2013, Sylwester Nawrocki wrote:
quoted
quoted
What's wrong with the platform_data structure, why can't that be used
for this?
At the point the platform data of some driver is initialized, e.g. in
board setup code the PHY pointer is not known, since the PHY supplier
driver has not initialized yet. Even though we wanted to pass pointer
to a PHY through some notifier call, it would have been not clear
which PHY user driver should match on such notifier. A single PHY
supplier driver can create M PHY objects and this needs to be mapped
to N PHY user drivers. This mapping needs to be defined somewhere by
the system integrator. It works well with device tree, but except that
there seems to be no other reliable infrastructure in the kernel to
define links/dependencies between devices, since device identifiers are
not known in advance in all cases.
What Tomasz proposed seems currently most reasonable to me for non-dt.
quoted
Or, if not, we can always add pointers to the platform device structure,
or even the main 'struct device' as well, that's what it is there for.
Still we would need to solve a problem which platform device structure
gets which PHY pointer.
Can you explain the issues in more detail? I don't fully understand
the situation.
Here's what I think I know:
The PHY and the controller it is attached to are both physical
devices.
The connection between them is hardwired by the system
manufacturer and cannot be changed by software.
PHYs are generally described by fixed system-specific board
files or by Device Tree information. Are they ever discovered
dynamically?
No. They are created just like any other platform devices are created.
Is the same true for the controllers attached to the PHYs?
If not -- if both a PHY and a controller are discovered
dynamically -- how does the kernel know whether they are
connected to each other?
No differences here. Both PHY and controller will have dt information or hwmod
data using which platform devices will be created.
The kernel needs to know which controller is attached to which
PHY. Currently this information is represented by name or ID
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
The PHY's driver (the supplier) uses the platform data to
construct a platform_device structure that represents the PHY.
Currently the driver assigns static labels (corresponding to the label used in
the platform data of the controller).
Until this is done, the controller's driver (the client) cannot
use the PHY.
right.
Since there is no parent-child relation between the PHY and the
controller, there is no guarantee that the PHY's driver will be
ready when the controller's driver wants to use it. A deferred
probe may be needed.
right.
The issue (or one of the issues) in this discussion is that
Greg does not like the idea of using names or IDs to associate
PHYs with controllers, because they are too prone to
duplications or other errors. Pointers are more reliable.
But pointers to what? Since the only data known to be
available to both the PHY driver and controller driver is the
platform data, the obvious answer is a pointer to platform data
(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for the PHY and
controller can be created in entirely different places. e.g., in some cases the
PHY device is a child of some mfd core device (the device will be created in
drivers/mfd) and the controller driver (usually) is created in board file. I
guess then we have to come up with something to share a pointer in two
different files.
Probably some of the details above are wrong; please indicate where I
have gone astray. Also, I'm not clear about the role played by various
APIs. For example, where does phy_create() fit into this picture?
phy_create is the API by which the PHY's driver (the supplier) hook into the
PHY framework. It's like the controller driver will always interact with the
PHY driver through the PHY framework.
Thanks
Kishon
From: Alan Stern <stern@rowland.harvard.edu> Date: 2013-07-22 14:44:44
On Mon, 22 Jul 2013, Kishon Vijay Abraham I wrote:
quoted
The PHY and the controller it is attached to are both physical
devices.
The connection between them is hardwired by the system
manufacturer and cannot be changed by software.
PHYs are generally described by fixed system-specific board
files or by Device Tree information. Are they ever discovered
dynamically?
No. They are created just like any other platform devices are created.
Okay. Are PHYs _always_ platform devices?
quoted
Is the same true for the controllers attached to the PHYs?
If not -- if both a PHY and a controller are discovered
dynamically -- how does the kernel know whether they are
connected to each other?
No differences here. Both PHY and controller will have dt information or hwmod
data using which platform devices will be created.
quoted
The kernel needs to know which controller is attached to which
PHY. Currently this information is represented by name or ID
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
quoted
The PHY's driver (the supplier) uses the platform data to
construct a platform_device structure that represents the PHY.
Currently the driver assigns static labels (corresponding to the label used in
the platform data of the controller).
quoted
Until this is done, the controller's driver (the client) cannot
use the PHY.
right.
quoted
Since there is no parent-child relation between the PHY and the
controller, there is no guarantee that the PHY's driver will be
ready when the controller's driver wants to use it. A deferred
probe may be needed.
right.
quoted
The issue (or one of the issues) in this discussion is that
Greg does not like the idea of using names or IDs to associate
PHYs with controllers, because they are too prone to
duplications or other errors. Pointers are more reliable.
But pointers to what? Since the only data known to be
available to both the PHY driver and controller driver is the
platform data, the obvious answer is a pointer to platform data
(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for the PHY and
controller can be created in entirely different places. e.g., in some cases the
PHY device is a child of some mfd core device (the device will be created in
drivers/mfd) and the controller driver (usually) is created in board file. I
guess then we have to come up with something to share a pointer in two
different files.
The ability for two different source files to share a pointer to a data
item defined in a third source file has been around since long before
the C language was invented. :-)
In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is. Let's take a simple
example. Suppose the system design includes a PHY named "foo". Then
the board file could contain:
struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);
and a header file would contain:
extern struct phy_info phy_foo;
The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo). Or something like that; make up
your own structure tags and function names.
It's still possible to have conflicts, but now two PHYs with the same
name (or a misspelled name somewhere) will cause an error at link time.
quoted
Probably some of the details above are wrong; please indicate where I
have gone astray. Also, I'm not clear about the role played by various
APIs. For example, where does phy_create() fit into this picture?
phy_create is the API by which the PHY's driver (the supplier) hook into the
PHY framework. It's like the controller driver will always interact with the
PHY driver through the PHY framework.
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-23 05:48:55
Hi,
On Monday 22 July 2013 08:14 PM, Alan Stern wrote:
On Mon, 22 Jul 2013, Kishon Vijay Abraham I wrote:
quoted
quoted
The PHY and the controller it is attached to are both physical
devices.
The connection between them is hardwired by the system
manufacturer and cannot be changed by software.
PHYs are generally described by fixed system-specific board
files or by Device Tree information. Are they ever discovered
dynamically?
No. They are created just like any other platform devices are created.
Okay. Are PHYs _always_ platform devices?
Not always. It can be any other device also.
quoted
quoted
Is the same true for the controllers attached to the PHYs?
If not -- if both a PHY and a controller are discovered
dynamically -- how does the kernel know whether they are
connected to each other?
No differences here. Both PHY and controller will have dt information or hwmod
data using which platform devices will be created.
quoted
The kernel needs to know which controller is attached to which
PHY. Currently this information is represented by name or ID
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
quoted
quoted
The PHY's driver (the supplier) uses the platform data to
construct a platform_device structure that represents the PHY.
Currently the driver assigns static labels (corresponding to the label used in
the platform data of the controller).
quoted
Until this is done, the controller's driver (the client) cannot
use the PHY.
right.
quoted
Since there is no parent-child relation between the PHY and the
controller, there is no guarantee that the PHY's driver will be
ready when the controller's driver wants to use it. A deferred
probe may be needed.
right.
quoted
The issue (or one of the issues) in this discussion is that
Greg does not like the idea of using names or IDs to associate
PHYs with controllers, because they are too prone to
duplications or other errors. Pointers are more reliable.
But pointers to what? Since the only data known to be
available to both the PHY driver and controller driver is the
platform data, the obvious answer is a pointer to platform data
(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for the PHY and
controller can be created in entirely different places. e.g., in some cases the
PHY device is a child of some mfd core device (the device will be created in
drivers/mfd) and the controller driver (usually) is created in board file. I
guess then we have to come up with something to share a pointer in two
different files.
The ability for two different source files to share a pointer to a data
item defined in a third source file has been around since long before
the C language was invented. :-)
In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is. Let's take a simple
example. Suppose the system design includes a PHY named "foo". Then
the board file could contain:
struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);
and a header file would contain:
extern struct phy_info phy_foo;
The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo). Or something like that; make up
your own structure tags and function names.
From: Tomasz Figa <hidden> Date: 2013-07-23 07:29:43
Hi Alan,
On Monday 22 of July 2013 10:44:39 Alan Stern wrote:
On Mon, 22 Jul 2013, Kishon Vijay Abraham I wrote:
quoted
quoted
The PHY and the controller it is attached to are both physical
devices.
The connection between them is hardwired by the system
manufacturer and cannot be changed by software.
PHYs are generally described by fixed system-specific board
files or by Device Tree information. Are they ever discovered
dynamically?
No. They are created just like any other platform devices are created.
Okay. Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
quoted
quoted
Is the same true for the controllers attached to the PHYs?
If not -- if both a PHY and a controller are discovered
dynamically -- how does the kernel know whether they are
connected to each other?
No differences here. Both PHY and controller will have dt information
or hwmod data using which platform devices will be created.
quoted
The kernel needs to know which controller is attached to which
PHY. Currently this information is represented by name or ID
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous replies.
Without any extra data in platform data. (I have even posted a code
example.)
quoted
quoted
The PHY's driver (the supplier) uses the platform data to
construct a platform_device structure that represents the PHY.
Currently the driver assigns static labels (corresponding to the label
used in the platform data of the controller).
quoted
Until this is done, the controller's driver (the client) cannot
use the PHY.
right.
quoted
Since there is no parent-child relation between the PHY and the
controller, there is no guarantee that the PHY's driver will be
ready when the controller's driver wants to use it. A deferred
probe may be needed.
right.
quoted
The issue (or one of the issues) in this discussion is that
Greg does not like the idea of using names or IDs to associate
PHYs with controllers, because they are too prone to
duplications or other errors. Pointers are more reliable.
But pointers to what? Since the only data known to be
available to both the PHY driver and controller driver is the
platform data, the obvious answer is a pointer to platform data
(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for
the PHY and controller can be created in entirely different places.
e.g., in some cases the PHY device is a child of some mfd core device
(the device will be created in drivers/mfd) and the controller driver
(usually) is created in board file. I guess then we have to come up
with something to share a pointer in two different files.
The ability for two different source files to share a pointer to a data
item defined in a third source file has been around since long before
the C language was invented. :-)
In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is. Let's take a simple
example. Suppose the system design includes a PHY named "foo". Then
the board file could contain:
struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);
and a header file would contain:
extern struct phy_info phy_foo;
The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo). Or something like that; make up
your own structure tags and function names.
It's still possible to have conflicts, but now two PHYs with the same
name (or a misspelled name somewhere) will cause an error at link time.
This is incorrect, sorry. First of all it's a layering violation - you
export random driver-specific symbols from one driver to another. Then
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2 and
there are two types of consumer drivers (e.g. USB host controllers). Now
consider following mapping:
SoC PHY consumer
A PHY1 HOST1
B PHY1 HOST2
C PHY2 HOST1
D PHY2 HOST2
So we have to be able to use any of the PHYs with any of the host drivers.
This means you would have to export symbol with the same name from both
PHY drivers, which obviously would not work in this case, because having
both drivers enabled (in a multiplatform aware configuration) would lead
to linking conflict.
Best regards,
Tomasz
From: Tomasz Figa <hidden> Date: 2013-07-23 07:55:19
[Fixed address of devicetree mailing list and added more people on CC.]
For reference, full thread can be found under following link:
http://thread.gmane.org/gmane.linux.ports.arm.kernel/252813
Best regards,
Tomasz
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
Hi Alan,
On Monday 22 of July 2013 10:44:39 Alan Stern wrote:
quoted
On Mon, 22 Jul 2013, Kishon Vijay Abraham I wrote:
quoted
quoted
The PHY and the controller it is attached to are both
physical
quoted
quoted
quoted
devices.
The connection between them is hardwired by the system
manufacturer and cannot be changed by software.
PHYs are generally described by fixed system-specific
board
quoted
quoted
quoted
files or by Device Tree information. Are they ever
discovered
quoted
quoted
quoted
dynamically?
No. They are created just like any other platform devices are
created.
Okay. Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
quoted
quoted
quoted
Is the same true for the controllers attached to the PHYs?
If not -- if both a PHY and a controller are discovered
dynamically -- how does the kernel know whether they are
connected to each other?
No differences here. Both PHY and controller will have dt
information
or hwmod data using which platform devices will be created.
quoted
The kernel needs to know which controller is attached to
which
quoted
quoted
quoted
PHY. Currently this information is represented by name or
ID
quoted
quoted
quoted
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted a
code example.)
quoted
quoted
quoted
The PHY's driver (the supplier) uses the platform data to
construct a platform_device structure that represents the
PHY.
quoted
quoted
Currently the driver assigns static labels (corresponding to the
label
used in the platform data of the controller).
quoted
Until this is done, the controller's driver (the client)
cannot
quoted
quoted
quoted
use the PHY.
right.
quoted
Since there is no parent-child relation between the PHY
and the
quoted
quoted
quoted
controller, there is no guarantee that the PHY's driver
will be
quoted
quoted
quoted
ready when the controller's driver wants to use it. A
deferred
quoted
quoted
quoted
probe may be needed.
right.
quoted
The issue (or one of the issues) in this discussion is
that
quoted
quoted
quoted
Greg does not like the idea of using names or IDs to
associate
quoted
quoted
quoted
PHYs with controllers, because they are too prone to
duplications or other errors. Pointers are more reliable.
But pointers to what? Since the only data known to be
available to both the PHY driver and controller driver is
the
quoted
quoted
quoted
platform data, the obvious answer is a pointer to platform
data
quoted
quoted
quoted
(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for
the PHY and controller can be created in entirely different places.
e.g., in some cases the PHY device is a child of some mfd core
device
(the device will be created in drivers/mfd) and the controller
driver
(usually) is created in board file. I guess then we have to come up
with something to share a pointer in two different files.
The ability for two different source files to share a pointer to a
data
item defined in a third source file has been around since long before
the C language was invented. :-)
In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is. Let's take a simple
example. Suppose the system design includes a PHY named "foo". Then
the board file could contain:
struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);
and a header file would contain:
extern struct phy_info phy_foo;
The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo). Or something like that; make up
your own structure tags and function names.
It's still possible to have conflicts, but now two PHYs with the same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation - you
export random driver-specific symbols from one driver to another. Then
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2 and
there are two types of consumer drivers (e.g. USB host controllers). Now
consider following mapping:
SoC PHY consumer
A PHY1 HOST1
B PHY1 HOST2
C PHY2 HOST1
D PHY2 HOST2
So we have to be able to use any of the PHYs with any of the host
drivers. This means you would have to export symbol with the same name
from both PHY drivers, which obviously would not work in this case,
because having both drivers enabled (in a multiplatform aware
configuration) would lead to linking conflict.
Best regards,
Tomasz
From: Alan Stern <stern@rowland.harvard.edu> Date: 2013-07-23 14:37:11
On Tue, 23 Jul 2013, Tomasz Figa wrote:
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
Okay. Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device. Then how does the
kernel know which controller is attached to the PHY? Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
quoted
quoted
quoted
quoted
PHY. Currently this information is represented by name or
ID
quoted
quoted
quoted
quoted
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.
quoted
quoted
In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is. Let's take a simple
example. Suppose the system design includes a PHY named "foo". Then
the board file could contain:
struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);
and a header file would contain:
extern struct phy_info phy_foo;
The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo). Or something like that; make up
your own structure tags and function names.
It's still possible to have conflicts, but now two PHYs with the same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation - you
export random driver-specific symbols from one driver to another. Then
No, that's not what I said. Neither the PHY driver nor the controller
driver exports anything to the other. Instead, both drivers use data
exported by the board file.
quoted
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2 and
there are two types of consumer drivers (e.g. USB host controllers). Now
consider following mapping:
SoC PHY consumer
A PHY1 HOST1
B PHY1 HOST2
C PHY2 HOST1
D PHY2 HOST2
So we have to be able to use any of the PHYs with any of the host
drivers. This means you would have to export symbol with the same name
from both PHY drivers, which obviously would not work in this case,
because having both drivers enabled (in a multiplatform aware
configuration) would lead to linking conflict.
You're right; the scheme was too simple. Instead, the board file must
export two types of data structures, one for PHYs and one for
controllers. Like this:
struct phy_info {
/* Info for the controller attached to this PHY */
struct controller_info *hinfo;
};
struct controller_info {
/* Info for the PHY which this controller is attached to */
struct phy_info *pinfo;
};
The board file for SoC A would contain:
struct phy_info phy1 = {&host1);
EXPORT_SYMBOL(phy1);
struct controller_info host1 = {&phy1};
EXPORT_SYMBOL(host1);
The board file for SoC B would contain:
struct phy_info phy1 = {&host2);
EXPORT_SYMBOL(phy1);
struct controller_info host2 = {&phy1};
EXPORT_SYMBOL(host2);
And so on. This explicitly gives the connection between PHYs and
controllers. The PHY providers would use &phy1 or &phy2, and the PHY
consumers would use &host1 or &host2.
Alan Stern
From: Tomasz Figa <hidden> Date: 2013-07-23 14:51:03
On Tuesday 23 of July 2013 10:37:05 Alan Stern wrote:
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay. Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device. Then how does the
kernel know which controller is attached to the PHY? Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
quoted
quoted
quoted
quoted
quoted
PHY. Currently this information is represented by name or
ID
quoted
quoted
quoted
quoted
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted
a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.
In this case, it doesn't matter where the platform_device
structures
are created or where the driver source code is. Let's take a
simple
example. Suppose the system design includes a PHY named "foo".
Then
the board file could contain:
struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);
and a header file would contain:
extern struct phy_info phy_foo;
The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo). Or something like that; make
up
your own structure tags and function names.
It's still possible to have conflicts, but now two PHYs with the
same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation -
you
export random driver-specific symbols from one driver to another.
Then
No, that's not what I said. Neither the PHY driver nor the controller
driver exports anything to the other. Instead, both drivers use data
exported by the board file.
It's still a random, driver-specific global symbol exported from board file
to drivers.
quoted
quoted
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2
and
there are two types of consumer drivers (e.g. USB host controllers).
Now
consider following mapping:
SoC PHY consumer
A PHY1 HOST1
B PHY1 HOST2
C PHY2 HOST1
D PHY2 HOST2
So we have to be able to use any of the PHYs with any of the host
drivers. This means you would have to export symbol with the same
name
from both PHY drivers, which obviously would not work in this case,
because having both drivers enabled (in a multiplatform aware
configuration) would lead to linking conflict.
You're right; the scheme was too simple. Instead, the board file must
export two types of data structures, one for PHYs and one for
controllers. Like this:
struct phy_info {
/* Info for the controller attached to this PHY */
struct controller_info *hinfo;
};
struct controller_info {
/* Info for the PHY which this controller is attached to */
struct phy_info *pinfo;
};
The board file for SoC A would contain:
struct phy_info phy1 = {&host1);
EXPORT_SYMBOL(phy1);
struct controller_info host1 = {&phy1};
EXPORT_SYMBOL(host1);
The board file for SoC B would contain:
struct phy_info phy1 = {&host2);
EXPORT_SYMBOL(phy1);
struct controller_info host2 = {&phy1};
EXPORT_SYMBOL(host2);
And so on. This explicitly gives the connection between PHYs and
controllers. The PHY providers would use &phy1 or &phy2, and the PHY
consumers would use &host1 or &host2.
This could work assuming that only one SoC and one board is supported in
single kernel image. However it's not the case.
We've used to support multiple boards since a long time already and now for
selected platforms we even support multiplatform, i.e. multiple SoCs in
single zImage. Such solution will not work.
Best regards,
Tomasz
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-23 15:19:28
Hi,
On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay. Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device. Then how does the
kernel know which controller is attached to the PHY? Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
Yes. I think we could use i2c_board_info for passing platform data.
quoted
quoted
quoted
quoted
quoted
PHY. Currently this information is represented by name or
ID
quoted
quoted
quoted
quoted
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.
It is how the PHY framework finds a PHY, when the controller (say USB)requests
a PHY from the PHY framework.
quoted
quoted
quoted
In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is. Let's take a simple
example. Suppose the system design includes a PHY named "foo". Then
the board file could contain:
struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);
and a header file would contain:
extern struct phy_info phy_foo;
The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo). Or something like that; make up
your own structure tags and function names.
It's still possible to have conflicts, but now two PHYs with the same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation - you
export random driver-specific symbols from one driver to another. Then
No, that's not what I said. Neither the PHY driver nor the controller
driver exports anything to the other. Instead, both drivers use data
exported by the board file.
I think instead we can use the same data while creating the platform data of
the controller and the PHY.
The PHY driver while creating the PHY (using PHY framework) will also pass the
*data* it actually got from the platform data to the framework.
The PHY user driver (USB), while requesting for the PHY (from the PHY
framework) will pass the *data* it got from its platform data.
The PHY framework can do a comparison of the *data* pointers it has and return
the appropriate PHY to the controller.
quoted
quoted
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2 and
there are two types of consumer drivers (e.g. USB host controllers). Now
consider following mapping:
SoC PHY consumer
A PHY1 HOST1
B PHY1 HOST2
C PHY2 HOST1
D PHY2 HOST2
So we have to be able to use any of the PHYs with any of the host
drivers. This means you would have to export symbol with the same name
from both PHY drivers, which obviously would not work in this case,
because having both drivers enabled (in a multiplatform aware
configuration) would lead to linking conflict.
You're right; the scheme was too simple. Instead, the board file must
export two types of data structures, one for PHYs and one for
controllers. Like this:
struct phy_info {
/* Info for the controller attached to this PHY */
struct controller_info *hinfo;
};
struct controller_info {
/* Info for the PHY which this controller is attached to */
struct phy_info *pinfo;
};
The board file for SoC A would contain:
struct phy_info phy1 = {&host1);
EXPORT_SYMBOL(phy1);
struct controller_info host1 = {&phy1};
EXPORT_SYMBOL(host1);
The board file for SoC B would contain:
struct phy_info phy1 = {&host2);
EXPORT_SYMBOL(phy1);
struct controller_info host2 = {&phy1};
EXPORT_SYMBOL(host2);
I meant something like this
struct phy_info {
const char *name;
};
struct phy_platform_data {
.
.
struct phy_info *info;
};
struct usb_controller_platform_data {
.
.
struct phy_info *info;
};
struct phy_info phy_info;
While creating the phy device
struct phy_platform_data phy_data;
phy_data.info = &info;
platform_device_add_data(pdev, &phy_data, sizeof(*phy_data))
platform_device_add();
While creating the controller device
struct usb_controller_platform_data controller_data;
controller_data.info = &info;
platform_device_add_data(pdev, &controller_data, sizeof(*controller_data))
platform_device_add();
Then modify PHY framework API phy create
phy_create((struct device *dev, const struct phy_ops *ops,
void *priv) {//API changed to take void pointer instead of label
. //existing implementation
.
phy->priv = priv;
}
struct phy *phy_get(struct device *dev, const char *string, void *priv) {
//API changed to take an additional pointer
phy_lookup(priv)
}
static struct phy *phy_lookup(void *priv) {
.
.
if (phy->priv=priv) //instead of string comparison, we'll use pointer
return phy;
}
PHY driver should be like
phy_create((dev, ops, pdata->info);
The controller driver would do
phy_get(dev, NULL, pdata->info);
Now the PHY framework will check for a match of *priv* pointer and return the PHY.
I think this should be possible?
Thanks
Kishon
On Tue, Jul 23, 2013 at 08:48:24PM +0530, Kishon Vijay Abraham I wrote:
Hi,
On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
quoted
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay. Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device. Then how does the
kernel know which controller is attached to the PHY? Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
Yes. I think we could use i2c_board_info for passing platform data.
quoted
quoted
quoted
quoted
quoted
quoted
PHY. Currently this information is represented by name or
ID
quoted
quoted
quoted
quoted
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.
It is how the PHY framework finds a PHY, when the controller (say USB)requests
a PHY from the PHY framework.
quoted
quoted
quoted
quoted
In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is. Let's take a simple
example. Suppose the system design includes a PHY named "foo". Then
the board file could contain:
struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);
and a header file would contain:
extern struct phy_info phy_foo;
The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo). Or something like that; make up
your own structure tags and function names.
It's still possible to have conflicts, but now two PHYs with the same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation - you
export random driver-specific symbols from one driver to another. Then
No, that's not what I said. Neither the PHY driver nor the controller
driver exports anything to the other. Instead, both drivers use data
exported by the board file.
I think instead we can use the same data while creating the platform data of
the controller and the PHY.
The PHY driver while creating the PHY (using PHY framework) will also pass the
*data* it actually got from the platform data to the framework.
The PHY user driver (USB), while requesting for the PHY (from the PHY
framework) will pass the *data* it got from its platform data.
The PHY framework can do a comparison of the *data* pointers it has and return
the appropriate PHY to the controller.
quoted
quoted
quoted
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2 and
there are two types of consumer drivers (e.g. USB host controllers). Now
consider following mapping:
SoC PHY consumer
A PHY1 HOST1
B PHY1 HOST2
C PHY2 HOST1
D PHY2 HOST2
So we have to be able to use any of the PHYs with any of the host
drivers. This means you would have to export symbol with the same name
from both PHY drivers, which obviously would not work in this case,
because having both drivers enabled (in a multiplatform aware
configuration) would lead to linking conflict.
You're right; the scheme was too simple. Instead, the board file must
export two types of data structures, one for PHYs and one for
controllers. Like this:
struct phy_info {
/* Info for the controller attached to this PHY */
struct controller_info *hinfo;
};
struct controller_info {
/* Info for the PHY which this controller is attached to */
struct phy_info *pinfo;
};
The board file for SoC A would contain:
struct phy_info phy1 = {&host1);
EXPORT_SYMBOL(phy1);
struct controller_info host1 = {&phy1};
EXPORT_SYMBOL(host1);
The board file for SoC B would contain:
struct phy_info phy1 = {&host2);
EXPORT_SYMBOL(phy1);
struct controller_info host2 = {&phy1};
EXPORT_SYMBOL(host2);
I meant something like this
struct phy_info {
const char *name;
};
struct phy_platform_data {
.
.
struct phy_info *info;
};
struct usb_controller_platform_data {
.
.
struct phy_info *info;
};
struct phy_info phy_info;
While creating the phy device
struct phy_platform_data phy_data;
phy_data.info = &info;
platform_device_add_data(pdev, &phy_data, sizeof(*phy_data))
platform_device_add();
While creating the controller device
struct usb_controller_platform_data controller_data;
controller_data.info = &info;
platform_device_add_data(pdev, &controller_data, sizeof(*controller_data))
platform_device_add();
Then modify PHY framework API phy create
phy_create((struct device *dev, const struct phy_ops *ops,
void *priv) {//API changed to take void pointer instead of label
. //existing implementation
.
phy->priv = priv;
}
struct phy *phy_get(struct device *dev, const char *string, void *priv) {
//API changed to take an additional pointer
phy_lookup(priv)
}
static struct phy *phy_lookup(void *priv) {
.
.
if (phy->priv=priv) //instead of string comparison, we'll use pointer
return phy;
}
PHY driver should be like
phy_create((dev, ops, pdata->info);
The controller driver would do
phy_get(dev, NULL, pdata->info);
Now the PHY framework will check for a match of *priv* pointer and return the PHY.
I think this should be possible?
Ick, no. Why can't you just pass the pointer to the phy itself? If you
had a "priv" pointer to search from, then you could have just passed the
original phy pointer in the first place, right?
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
Please just pass the real "phy" pointer around, that's what it is there
for. Your "board binding" logic/code should be able to handle this, as
it somehow was going to do the same thing with a "name".
thanks,
greg k-h
From: Kishon Vijay Abraham I <hidden> Date: 2013-07-23 16:29:39
Hi Greg,
On Tuesday 23 July 2013 09:48 PM, Greg KH wrote:
On Tue, Jul 23, 2013 at 08:48:24PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
quoted
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay. Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device. Then how does the
kernel know which controller is attached to the PHY? Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
.
.
<snip>
.
.
quoted
static struct phy *phy_lookup(void *priv) {
.
.
if (phy->priv=priv) //instead of string comparison, we'll use pointer
return phy;
}
PHY driver should be like
phy_create((dev, ops, pdata->info);
The controller driver would do
phy_get(dev, NULL, pdata->info);
Now the PHY framework will check for a match of *priv* pointer and return the PHY.
I think this should be possible?
Ick, no. Why can't you just pass the pointer to the phy itself? If you
had a "priv" pointer to search from, then you could have just passed the
original phy pointer in the first place, right?
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
Please just pass the real "phy" pointer around, that's what it is there
for. Your "board binding" logic/code should be able to handle this, as
it somehow was going to do the same thing with a "name".
The problem is the board file won't have the *phy* pointer. *phy* pointer is
created at a much later time when the phy driver is probed.
Thanks
Kishon
On Tue, Jul 23, 2013 at 09:58:34PM +0530, Kishon Vijay Abraham I wrote:
Hi Greg,
On Tuesday 23 July 2013 09:48 PM, Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 08:48:24PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
quoted
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay. Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device. Then how does the
kernel know which controller is attached to the PHY? Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
.
.
<snip>
.
.
quoted
quoted
static struct phy *phy_lookup(void *priv) {
.
.
if (phy->priv=priv) //instead of string comparison, we'll use pointer
return phy;
}
PHY driver should be like
phy_create((dev, ops, pdata->info);
The controller driver would do
phy_get(dev, NULL, pdata->info);
Now the PHY framework will check for a match of *priv* pointer and return the PHY.
I think this should be possible?
Ick, no. Why can't you just pass the pointer to the phy itself? If you
had a "priv" pointer to search from, then you could have just passed the
original phy pointer in the first place, right?
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
Please just pass the real "phy" pointer around, that's what it is there
for. Your "board binding" logic/code should be able to handle this, as
it somehow was going to do the same thing with a "name".
The problem is the board file won't have the *phy* pointer. *phy* pointer is
created at a much later time when the phy driver is probed.
Ok, then save it then, as no one could have used it before then, right?
All I don't want to see is any "get by name/void *" functions in the
api, as that way is fragile and will break, as people have already
shown.
Just pass the real pointer around. If that is somehow a problem, then
something larger is a problem with how board devices are tied together :)
thanks,
greg k-h
From: Tomasz Figa <hidden> Date: 2013-07-23 16:50:41
On Tuesday 23 of July 2013 09:18:46 Greg KH wrote:
On Tue, Jul 23, 2013 at 08:48:24PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,
On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
quoted
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay. Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device. Then how does the
kernel know which controller is attached to the PHY? Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever
parent?
Yes. I think we could use i2c_board_info for passing platform data.
quoted
quoted
quoted
quoted
quoted
quoted
PHY. Currently this information is represented by name or
ID
quoted
quoted
quoted
quoted
strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even
posted a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.
It is how the PHY framework finds a PHY, when the controller (say
USB)requests a PHY from the PHY framework.
quoted
quoted
quoted
quoted
In this case, it doesn't matter where the platform_device
structures
are created or where the driver source code is. Let's take a
simple
example. Suppose the system design includes a PHY named "foo".
Then
the board file could contain:
struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);
and a header file would contain:
extern struct phy_info phy_foo;
The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo). Or something like that;
make up
your own structure tags and function names.
It's still possible to have conflicts, but now two PHYs with the
same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation -
you
export random driver-specific symbols from one driver to another.
Then
No, that's not what I said. Neither the PHY driver nor the
controller
driver exports anything to the other. Instead, both drivers use data
exported by the board file.
I think instead we can use the same data while creating the platform
data of the controller and the PHY.
The PHY driver while creating the PHY (using PHY framework) will also
pass the *data* it actually got from the platform data to the
framework. The PHY user driver (USB), while requesting for the PHY
(from the PHY framework) will pass the *data* it got from its platform
data.
The PHY framework can do a comparison of the *data* pointers it has and
return the appropriate PHY to the controller.
quoted
quoted
quoted
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2
and
there are two types of consumer drivers (e.g. USB host
controllers). Now
consider following mapping:
SoC PHY consumer
A PHY1 HOST1
B PHY1 HOST2
C PHY2 HOST1
D PHY2 HOST2
So we have to be able to use any of the PHYs with any of the host
drivers. This means you would have to export symbol with the same
name
from both PHY drivers, which obviously would not work in this case,
because having both drivers enabled (in a multiplatform aware
configuration) would lead to linking conflict.
You're right; the scheme was too simple. Instead, the board file
must
export two types of data structures, one for PHYs and one for
controllers. Like this:
struct phy_info {
/* Info for the controller attached to this PHY */
struct controller_info *hinfo;
};
struct controller_info {
/* Info for the PHY which this controller is attached to */
struct phy_info *pinfo;
};
The board file for SoC A would contain:
struct phy_info phy1 = {&host1);
EXPORT_SYMBOL(phy1);
struct controller_info host1 = {&phy1};
EXPORT_SYMBOL(host1);
The board file for SoC B would contain:
struct phy_info phy1 = {&host2);
EXPORT_SYMBOL(phy1);
struct controller_info host2 = {&phy1};
EXPORT_SYMBOL(host2);
I meant something like this
struct phy_info {
const char *name;
};
struct phy_platform_data {
.
.
struct phy_info *info;
};
struct usb_controller_platform_data {
.
.
struct phy_info *info;
};
struct phy_info phy_info;
While creating the phy device
struct phy_platform_data phy_data;
phy_data.info = &info;
platform_device_add_data(pdev, &phy_data, sizeof(*phy_data))
platform_device_add();
While creating the controller device
struct usb_controller_platform_data controller_data;
controller_data.info = &info;
platform_device_add_data(pdev, &controller_data,
sizeof(*controller_data)) platform_device_add();
Then modify PHY framework API phy create
phy_create((struct device *dev, const struct phy_ops *ops,
void *priv) {//API changed to take void pointer instead of
label
. //existing implementation
.
phy->priv = priv;
}
struct phy *phy_get(struct device *dev, const char *string, void
*priv) {>
//API changed to take an additional pointer
phy_lookup(priv)
}
static struct phy *phy_lookup(void *priv) {
.
.
if (phy->priv=priv) //instead of string comparison, we'll use
pointer
return phy;
}
PHY driver should be like
phy_create((dev, ops, pdata->info);
The controller driver would do
phy_get(dev, NULL, pdata->info);
Now the PHY framework will check for a match of *priv* pointer and
return the PHY.
I think this should be possible?
Ick, no. Why can't you just pass the pointer to the phy itself? If you
had a "priv" pointer to search from, then you could have just passed the
original phy pointer in the first place, right?
IMHO it would be better if you provided some code example, but let's try to
check if I understood you correctly.
8><------------------------------------------------------------------------
[Board file]
static struct phy my_phy;
static struct platform_device phy_pdev = {
/* ... */
.platform_data = &my_phy;
/* ... */
};
static struct platform_device phy_pdev = {
/* ... */
.platform_data = &my_phy;
/* ... */
};
[Provider driver]
struct phy *phy = pdev->dev.platform_data;
ret = phy_create(phy);
[Consumer driver]
struct phy *phy = pdev->dev.platform_data;
ret = phy_get(&pdev->dev, phy);
------------------------------------------------------------------------><8
Is this what you mean?
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
I fully agree that a simple, single string will not scale even in some, not
so uncommon cases, but there is already a lot of existing lookup solutions
over the kernel and so there is no point in introducing another one.
Please just pass the real "phy" pointer around, that's what it is there
for. Your "board binding" logic/code should be able to handle this, as
it somehow was going to do the same thing with a "name".
It's technically correct, but quality of this solution isn't really nice,
because it's a layering violation (at least if I understood what you mean).
This is because you need to have full definition of struct phy in board file
and a structure that is used as private data in PHY core comes from
platform code.
Best regards,
Tomasz
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
Ick, no. Why can't you just pass the pointer to the phy itself? If you
had a "priv" pointer to search from, then you could have just passed the
original phy pointer in the first place, right?
IMHO it would be better if you provided some code example, but let's try to
check if I understood you correctly.
It's not my code that I want to have added, so I don't have to write
examples, I just get to complain about the existing stuff :)
No. Well, kind of. What's wrong with using the platform data structure
unique to the board to have the pointer?
For example (just randomly picking one), the ata-pxa driver would change
include/linux/platform_data/ata-pxa.h to have a phy pointer in it:
struct phy;
struct pata_pxa_pdata {
/* PXA DMA DREQ<0:2> pin */
uint32_t dma_dreq;
/* Register shift */
uint32_t reg_shift;
/* IRQ flags */
uint32_t irq_flags;
/* PHY */
struct phy *phy;
};
Then, when you create the platform, set the phy* pointer with a call to
phy_create(). Then you can use that pointer wherever that plaform data
is available (i.e. whereever platform_data is at).
quoted
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
I fully agree that a simple, single string will not scale even in some, not
so uncommon cases, but there is already a lot of existing lookup solutions
over the kernel and so there is no point in introducing another one.
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should. I'll go tackle those other ones after this one
is taken care of, to show how the others should be handled as well.
quoted
Please just pass the real "phy" pointer around, that's what it is there
for. Your "board binding" logic/code should be able to handle this, as
it somehow was going to do the same thing with a "name".
It's technically correct, but quality of this solution isn't really nice,
because it's a layering violation (at least if I understood what you mean).
This is because you need to have full definition of struct phy in board file
and a structure that is used as private data in PHY core comes from
platform code.
No, just a pointer, you don't need the "full" structure until you get to
some .c code that actually manipulates the phy itself, for all other
places, you are just dealing with a pointer and a structure you never
reference.
Does that make more sense?
thanks,
greg k-h
From: Mark Brown <broonie@kernel.org> Date: 2013-07-23 17:45:55
On Tue, Jul 23, 2013 at 10:37:11AM -0700, Greg KH wrote:
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
I fully agree that a simple, single string will not scale even in some, not
so uncommon cases, but there is already a lot of existing lookup solutions
over the kernel and so there is no point in introducing another one.
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should. I'll go tackle those other ones after this one
is taken care of, to show how the others should be handled as well.
What are the problems you are seeing with doing things with lookups?
Having to write platform data for everything gets old fast and the code
duplication is pretty tedious...
On Tue, Jul 23, 2013 at 06:44:56PM +0100, Mark Brown wrote:
On Tue, Jul 23, 2013 at 10:37:11AM -0700, Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
quoted
I fully agree that a simple, single string will not scale even in some, not
so uncommon cases, but there is already a lot of existing lookup solutions
over the kernel and so there is no point in introducing another one.
quoted
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should. I'll go tackle those other ones after this one
is taken care of, to show how the others should be handled as well.
What are the problems you are seeing with doing things with lookups?
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier in
this thread for details about that.)
Having to write platform data for everything gets old fast and the code
duplication is pretty tedious...
Adding a single pointer is "tedious"? Where is the "name" that you are
going to lookup going to come from? That code doesn't write itself...
thanks,
greg k-h
From: Mark Brown <broonie@kernel.org> Date: 2013-07-23 19:32:10
On Tue, Jul 23, 2013 at 11:01:10AM -0700, Greg KH wrote:
On Tue, Jul 23, 2013 at 06:44:56PM +0100, Mark Brown wrote:
quoted
What are the problems you are seeing with doing things with lookups?
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm afraid,
I did try looking at web archives but didn't see a clear problem
statement. In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
quoted
Having to write platform data for everything gets old fast and the code
duplication is pretty tedious...
Adding a single pointer is "tedious"? Where is the "name" that you are
going to lookup going to come from? That code doesn't write itself...
It's adding platform data in the first place that gets tedious - and of
course there's also DT and ACPI to worry about, it's not just a case of
platform data and then you're done. Pushing the lookup into library
code means that drivers don't have to worry about any of this stuff.
For most of the APIs doing this there is a clear and unambiguous name in
the hardware that can be used (and for hardware process reasons is
unlikely to get changed). The major exception to this is the clock API
since it is relatively rare to have clear, segregated IP level
information for IPs baked into larger chips. The other APIs tend to be
establishing chip to chip links.
On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
quoted
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm afraid,
I did try looking at web archives but didn't see a clear problem
statement. In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
What do you mean by "locally"?
The problem with the api was that the phy core wanted a id and a name to
create a phy, and then later other code was doing a "lookup" based on
the name and id (mushed together), because it "knew" that this device
was the one it wanted.
Just like the clock api, which, for multiple devices, has proven to
cause problems. I don't want to see us accept an api that we know has
issues in it now, I'd rather us fix it up properly.
Subsystems should be able to create ids how ever they want to, and not
rely on the code calling them to specify the names of the devices that
way, otherwise the api is just too fragile.
I think, that if you create a device, then just carry around the pointer
to that device (in this case a phy) and pass it to whatever other code
needs it. No need to do lookups on "known names" or anything else, just
normal pointers, with no problems for multiple devices, busses, or
naming issues.
quoted
quoted
Having to write platform data for everything gets old fast and the code
duplication is pretty tedious...
quoted
Adding a single pointer is "tedious"? Where is the "name" that you are
going to lookup going to come from? That code doesn't write itself...
It's adding platform data in the first place that gets tedious - and of
course there's also DT and ACPI to worry about, it's not just a case of
platform data and then you're done. Pushing the lookup into library
code means that drivers don't have to worry about any of this stuff.
I agree, so just pass around the pointer to the phy and all is good. No
need to worry about DT or ACPI or anything else.
For most of the APIs doing this there is a clear and unambiguous name in
the hardware that can be used (and for hardware process reasons is
unlikely to get changed). The major exception to this is the clock API
since it is relatively rare to have clear, segregated IP level
information for IPs baked into larger chips. The other APIs tend to be
establishing chip to chip links.
The clock api is having problems with multiple "names" due to dynamic
devices from what I was told. I want to prevent the PHY interface from
having that same issue.
thanks,
greg k-h
From: Tomasz Figa <hidden> Date: 2013-07-23 20:08:04
On Tuesday 23 of July 2013 12:44:23 Greg KH wrote:
On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
quoted
quoted
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier
in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm afraid,
I did try looking at web archives but didn't see a clear problem
statement. In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
What do you mean by "locally"?
The problem with the api was that the phy core wanted a id and a name to
create a phy, and then later other code was doing a "lookup" based on
the name and id (mushed together), because it "knew" that this device
was the one it wanted.
Just like the clock api, which, for multiple devices, has proven to
cause problems. I don't want to see us accept an api that we know has
issues in it now, I'd rather us fix it up properly.
Subsystems should be able to create ids how ever they want to, and not
rely on the code calling them to specify the names of the devices that
way, otherwise the api is just too fragile.
I think, that if you create a device, then just carry around the pointer
to that device (in this case a phy) and pass it to whatever other code
needs it. No need to do lookups on "known names" or anything else,
just normal pointers, with no problems for multiple devices, busses, or
naming issues.
PHY object is not a device, it is something that a device driver creates
(one or more instances of) when it is being probed. You don't have a clean
way to export this PHY object to other driver, other than keeping this PHY
on a list inside PHY core with some well-known ID (e.g. device name +
consumer port name/index, like in regulator core) and then to use this
well-known ID inside consumer driver as a lookup key passed to phy_get();
Actually I think for PHY case, exactly the same way as used for regulators
might be completely fine:
1. Each PHY would have some kind of platform, non-unique name, that is
just used to print some messages (like the platform/board name of a
regulator).
2. Each PHY would have an array of consumers. Consumer specifier would
consist of consumer device name and consumer port name - just like in
regulator subsystem.
3. PHY driver receives an array of, let's say, phy_init_data inside its
platform data that it would use to register its PHYs.
4. Consumer drivers would have constant consumer port names and wouldn't
receive any information about PHYs from platform code.
Code example:
[Board file]
static const struct phy_consumer_data usb_20_phy0_consumers[] = {
{
.devname = "foo-ehci",
.port = "usbphy",
},
};
static const struct phy_consumer_data usb_20_phy1_consumers[] = {
{
.devname = "foo-otg",
.port = "otgphy",
},
};
static const struct phy_init_data my_phys[] = {
{
.name = "USB 2.0 PHY 0",
.consumers = usb_20_phy0_consumers,
.num_consumers = ARRAY_SIZE(usb_20_phy0_consumers),
},
{
.name = "USB 2.0 PHY 1",
.consumers = usb_20_phy1_consumers,
.num_consumers = ARRAY_SIZE(usb_20_phy1_consumers),
},
{ }
};
static const struct platform_device usb_phy_pdev = {
.name = "foo-usbphy",
.id = -1,
.dev = {
.platform_data = my_phys,
},
};
[PHY driver]
static int foo_usbphy_probe(pdev)
{
struct foo_usbphy *foo;
struct phy_init_data *init_data = pdev->dev.platform_data;
/* ... */
// for each PHY in init_data {
phy_register(&foo->phy[i], &init_data[i]);
// }
/* ... */
}
[EHCI driver]
static int foo_ehci_probe(pdev)
{
struct phy *phy;
/* ... */
phy = phy_get(&pdev->dev, "usbphy");
/* ... */
}
[OTG driver]
static int foo_otg_probe(pdev)
{
struct phy *phy;
/* ... */
phy = phy_get(&pdev->dev, "otgphy");
/* ... */
}
quoted
quoted
quoted
Having to write platform data for everything gets old fast and the
code
duplication is pretty tedious...
Adding a single pointer is "tedious"? Where is the "name" that you
are
going to lookup going to come from? That code doesn't write
itself...
It's adding platform data in the first place that gets tedious - and
of
course there's also DT and ACPI to worry about, it's not just a case
of
platform data and then you're done. Pushing the lookup into library
code means that drivers don't have to worry about any of this stuff.
I agree, so just pass around the pointer to the phy and all is good. No
need to worry about DT or ACPI or anything else.
With Device Tree we don't have board files anymore. How would you pass any
pointers between provider and consumer drivers in this case?
quoted
For most of the APIs doing this there is a clear and unambiguous name
in the hardware that can be used (and for hardware process reasons is
unlikely to get changed). The major exception to this is the clock
API since it is relatively rare to have clear, segregated IP level
information for IPs baked into larger chips. The other APIs tend to
be establishing chip to chip links.
The clock api is having problems with multiple "names" due to dynamic
devices from what I was told. I want to prevent the PHY interface from
having that same issue.
Yes, the clock API has a problem related to the clock namespace being
global for all registered clock controllers. This is not a problem with
lookup in general, but with wrong lookup key chosen.
Best regards,
Tomasz
On Tue, Jul 23, 2013 at 10:07:52PM +0200, Tomasz Figa wrote:
On Tuesday 23 of July 2013 12:44:23 Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
quoted
quoted
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier
in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm afraid,
I did try looking at web archives but didn't see a clear problem
statement. In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
What do you mean by "locally"?
The problem with the api was that the phy core wanted a id and a name to
create a phy, and then later other code was doing a "lookup" based on
the name and id (mushed together), because it "knew" that this device
was the one it wanted.
Just like the clock api, which, for multiple devices, has proven to
cause problems. I don't want to see us accept an api that we know has
issues in it now, I'd rather us fix it up properly.
Subsystems should be able to create ids how ever they want to, and not
rely on the code calling them to specify the names of the devices that
way, otherwise the api is just too fragile.
I think, that if you create a device, then just carry around the pointer
to that device (in this case a phy) and pass it to whatever other code
needs it. No need to do lookups on "known names" or anything else,
just normal pointers, with no problems for multiple devices, busses, or
naming issues.
PHY object is not a device, it is something that a device driver creates
(one or more instances of) when it is being probed.
But you created a 'struct device' for it, so I think of it as a "device"
be it "virtual" or "real" :)
You don't have a clean way to export this PHY object to other driver,
other than keeping this PHY on a list inside PHY core with some
well-known ID (e.g. device name + consumer port name/index, like in
regulator core) and then to use this well-known ID inside consumer
driver as a lookup key passed to phy_get();
Actually I think for PHY case, exactly the same way as used for
regulators might be completely fine:
1. Each PHY would have some kind of platform, non-unique name, that is
just used to print some messages (like the platform/board name of a
regulator).
2. Each PHY would have an array of consumers. Consumer specifier would
consist of consumer device name and consumer port name - just like in
regulator subsystem.
3. PHY driver receives an array of, let's say, phy_init_data inside its
platform data that it would use to register its PHYs.
4. Consumer drivers would have constant consumer port names and wouldn't
receive any information about PHYs from platform code.
Code example:
[Board file]
static const struct phy_consumer_data usb_20_phy0_consumers[] = {
{
.devname = "foo-ehci",
.port = "usbphy",
},
};
static const struct phy_consumer_data usb_20_phy1_consumers[] = {
{
.devname = "foo-otg",
.port = "otgphy",
},
};
static const struct phy_init_data my_phys[] = {
{
.name = "USB 2.0 PHY 0",
.consumers = usb_20_phy0_consumers,
.num_consumers = ARRAY_SIZE(usb_20_phy0_consumers),
},
{
.name = "USB 2.0 PHY 1",
.consumers = usb_20_phy1_consumers,
.num_consumers = ARRAY_SIZE(usb_20_phy1_consumers),
},
{ }
};
static const struct platform_device usb_phy_pdev = {
.name = "foo-usbphy",
.id = -1,
.dev = {
.platform_data = my_phys,
},
};
[PHY driver]
static int foo_usbphy_probe(pdev)
{
struct foo_usbphy *foo;
struct phy_init_data *init_data = pdev->dev.platform_data;
/* ... */
// for each PHY in init_data {
phy_register(&foo->phy[i], &init_data[i]);
// }
/* ... */
}
[EHCI driver]
static int foo_ehci_probe(pdev)
{
struct phy *phy;
/* ... */
phy = phy_get(&pdev->dev, "usbphy");
/* ... */
}
[OTG driver]
static int foo_otg_probe(pdev)
{
struct phy *phy;
/* ... */
phy = phy_get(&pdev->dev, "otgphy");
/* ... */
}
That's not so bad, as long as you let the phy core use whatever name it
wants for the device when it registers it with sysfs. Use the name you
are requesting as a "tag" or some such "hint" as to what the phy can be
looked up by.
Good luck handling duplicate "tags" :)
thanks,
greg k-h
From: Tomasz Figa <hidden> Date: 2013-07-23 21:05:59
On Tuesday 23 of July 2013 13:50:07 Greg KH wrote:
On Tue, Jul 23, 2013 at 10:07:52PM +0200, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 12:44:23 Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
quoted
quoted
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back
earlier
in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm
afraid,
I did try looking at web archives but didn't see a clear problem
statement. In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
What do you mean by "locally"?
The problem with the api was that the phy core wanted a id and a
name to create a phy, and then later other code was doing a
"lookup" based on the name and id (mushed together), because it
"knew" that this device was the one it wanted.
Just like the clock api, which, for multiple devices, has proven to
cause problems. I don't want to see us accept an api that we know
has
issues in it now, I'd rather us fix it up properly.
Subsystems should be able to create ids how ever they want to, and
not
rely on the code calling them to specify the names of the devices
that
way, otherwise the api is just too fragile.
I think, that if you create a device, then just carry around the
pointer to that device (in this case a phy) and pass it to whatever
other code needs it. No need to do lookups on "known names" or
anything else, just normal pointers, with no problems for multiple
devices, busses, or naming issues.
PHY object is not a device, it is something that a device driver
creates (one or more instances of) when it is being probed.
But you created a 'struct device' for it, so I think of it as a "device"
be it "virtual" or "real" :)
Keep in mind that those virtual devices are created by PHY driver bound to
a real device and one real device can have multiple virtual devices behind
it.
quoted
You don't have a clean way to export this PHY object to other driver,
other than keeping this PHY on a list inside PHY core with some
well-known ID (e.g. device name + consumer port name/index, like in
regulator core) and then to use this well-known ID inside consumer
driver as a lookup key passed to phy_get();
Actually I think for PHY case, exactly the same way as used for
regulators might be completely fine:
1. Each PHY would have some kind of platform, non-unique name, that is
just used to print some messages (like the platform/board name of a
regulator).
2. Each PHY would have an array of consumers. Consumer specifier would
consist of consumer device name and consumer port name - just like in
regulator subsystem.
3. PHY driver receives an array of, let's say, phy_init_data inside
its
platform data that it would use to register its PHYs.
4. Consumer drivers would have constant consumer port names and
wouldn't receive any information about PHYs from platform code.
Code example:
[Board file]
static const struct phy_consumer_data usb_20_phy0_consumers[] = {
{
.devname = "foo-ehci",
.port = "usbphy",
},
};
static const struct phy_consumer_data usb_20_phy1_consumers[] = {
{
.devname = "foo-otg",
.port = "otgphy",
},
};
static const struct phy_init_data my_phys[] = {
{
.name = "USB 2.0 PHY 0",
.consumers = usb_20_phy0_consumers,
.num_consumers = ARRAY_SIZE(usb_20_phy0_consumers),
},
{
.name = "USB 2.0 PHY 1",
.consumers = usb_20_phy1_consumers,
.num_consumers = ARRAY_SIZE(usb_20_phy1_consumers),
},
{ }
};
static const struct platform_device usb_phy_pdev = {
.name = "foo-usbphy",
.id = -1,
.dev = {
.platform_data = my_phys,
},
};
[PHY driver]
static int foo_usbphy_probe(pdev)
{
struct foo_usbphy *foo;
struct phy_init_data *init_data = pdev->dev.platform_data;
/* ... */
// for each PHY in init_data {
phy_register(&foo->phy[i], &init_data[i]);
// }
/* ... */
}
[EHCI driver]
static int foo_ehci_probe(pdev)
{
struct phy *phy;
/* ... */
phy = phy_get(&pdev->dev, "usbphy");
/* ... */
}
[OTG driver]
static int foo_otg_probe(pdev)
{
struct phy *phy;
/* ... */
phy = phy_get(&pdev->dev, "otgphy");
/* ... */
}
That's not so bad, as long as you let the phy core use whatever name it
wants for the device when it registers it with sysfs.
Yes, in regulator core consumer names are completely separated from this.
Regulator core simply assigns a sequential integer ID to each regulator
and registers /sys/class/regulator/regulator.ID for each regulator.
Use the name you
are requesting as a "tag" or some such "hint" as to what the phy can be
looked up by.
Good luck handling duplicate "tags" :)
The tag alone is not a key. Lookup key consists of two components,
consumer device name and consumer tag. What kind of duplicate tags can be
a problem here?
Best regards,
Tomasz
On Tue, Jul 23, 2013 at 11:05:48PM +0200, Tomasz Figa wrote:
quoted
That's not so bad, as long as you let the phy core use whatever name it
wants for the device when it registers it with sysfs.
Yes, in regulator core consumer names are completely separated from this.
Regulator core simply assigns a sequential integer ID to each regulator
and registers /sys/class/regulator/regulator.ID for each regulator.
Yes, that's fine.
quoted
Use the name you
are requesting as a "tag" or some such "hint" as to what the phy can be
looked up by.
Good luck handling duplicate "tags" :)
The tag alone is not a key. Lookup key consists of two components,
consumer device name and consumer tag. What kind of duplicate tags can be
a problem here?
Ok, I didn't realize it looked at both parts, that makes sense, thanks.
greg k-h
From: Mark Brown <broonie@kernel.org> Date: 2013-07-23 23:49:29
On Tue, Jul 23, 2013 at 12:44:23PM -0700, Greg KH wrote:
On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
quoted
statement. In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
What do you mean by "locally"?
Within themselves - for example a regulator consumer asks for a given
supply on the device in terms of the supply names the device has.
The problem with the api was that the phy core wanted a id and a name to
create a phy, and then later other code was doing a "lookup" based on
the name and id (mushed together), because it "knew" that this device
was the one it wanted.
Ah, that sounds like the API is missing a component to link things
together. But I could be wrong. What I would expect to see is that the
consumer says "I want the PHY called X" and the PHY driver says "I
provide this set of PHYs" with a layer in between that plugs those
together. This would normally involve talking about the parent device
rather than the PHY itself.
I think, that if you create a device, then just carry around the pointer
to that device (in this case a phy) and pass it to whatever other code
needs it. No need to do lookups on "known names" or anything else, just
normal pointers, with no problems for multiple devices, busses, or
naming issues.
I think you're not really talking about the lookup API at all here but
rather about one way in which the matching code can be written. What
everything *really* wants to do is work in terms of resources namespaced
within struct devices since every bit of hardware in the system should
have one of those it can use and if you have a struct device you can do
useful things like call dev_printk() and find the device tree data to do
device tree based lookups.
Unfortunately for a number of buses even when statically registering the
struct device doesn't get allocated until the device is probed so what
everyone fell back on doing was using dev_name() in cases where the
struct device wasn't there yet, or just always using it for consistency
since for most of the affected buses dev_name() is fixed for human
interface reasons. I think this is the issue you're concerned about
here since if the dev_name() is dynamically allocated this breaks down.
This only affects board files, DT and ACPI can both use their own data
structures to do the mapping.
I had thought you were talking about picking the names that the
consumers use (which isn't actually that big a deal, it's just a bit
annoying for the clock API).
quoted
It's adding platform data in the first place that gets tedious - and of
course there's also DT and ACPI to worry about, it's not just a case of
platform data and then you're done. Pushing the lookup into library
code means that drivers don't have to worry about any of this stuff.
I agree, so just pass around the pointer to the phy and all is good. No
need to worry about DT or ACPI or anything else.
No, in practice passing around the pointer gets tricky if you're using
something other than board files (or even are doing any kind of dynamic
stuff with board files) since the two devices need to find each other
and if you're using platform data then the code doing the matching has
to know about the platform data for every device it might need to match
which is just miserable.
Something would need to do something like allocate the PHY objects and
then arrange for them to be passed to both provider and consumer devices
prior to those being registered, knowing where to place the pointers in
the platform data for each device. This is straightforward with board
files but not otherwise, people have tried this before.
quoted
For most of the APIs doing this there is a clear and unambiguous name in
the hardware that can be used (and for hardware process reasons is
unlikely to get changed). The major exception to this is the clock API
since it is relatively rare to have clear, segregated IP level
information for IPs baked into larger chips. The other APIs tend to be
establishing chip to chip links.
The clock api is having problems with multiple "names" due to dynamic
devices from what I was told. I want to prevent the PHY interface from
having that same issue.
I think the underlying issue here is that we don't have a good enough
general way for board files (or other C code but mostly them) to talk
about devices prior to their being registered - rather than have the
pointer you're talking about be the PHY object itself have the pointer
be something which allows us to match the struct device when it's
created. This should be transparent to drivers and would be usable by
all the existing APIs.
From: Tomasz Figa <hidden> Date: 2013-07-23 17:48:21
On Tuesday 23 of July 2013 10:37:11 Greg KH wrote:
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
quoted
Ick, no. Why can't you just pass the pointer to the phy itself? If
you
had a "priv" pointer to search from, then you could have just passed
the
original phy pointer in the first place, right?
IMHO it would be better if you provided some code example, but let's
try to check if I understood you correctly.
It's not my code that I want to have added, so I don't have to write
examples, I just get to complain about the existing stuff :)
Still, I think that some small code snippets illustrating the idea are
really helpful.
No. Well, kind of. What's wrong with using the platform data structure
unique to the board to have the pointer?
For example (just randomly picking one), the ata-pxa driver would change
include/linux/platform_data/ata-pxa.h to have a phy pointer in it:
struct phy;
struct pata_pxa_pdata {
/* PXA DMA DREQ<0:2> pin */
uint32_t dma_dreq;
/* Register shift */
uint32_t reg_shift;
/* IRQ flags */
uint32_t irq_flags;
/* PHY */
struct phy *phy;
};
Then, when you create the platform, set the phy* pointer with a call to
phy_create(). Then you can use that pointer wherever that plaform data
is available (i.e. whereever platform_data is at).
Hmm? So, do you suggest to call phy_create() from board file? What phy_ops
struct and other hardware parameters would it take?
quoted
quoted
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
I fully agree that a simple, single string will not scale even in some,
not so uncommon cases, but there is already a lot of existing lookup
solutions over the kernel and so there is no point in introducing
another one.
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should. I'll go tackle those other ones after this one
is taken care of, to show how the others should be handled as well.
There was a reason for introducing lookup solutions. The reason was that in
board file there is no way to get a pointer to something that is going to be
created much later in time. We don't do time travel ;-).
quoted
quoted
Please just pass the real "phy" pointer around, that's what it is
there
for. Your "board binding" logic/code should be able to handle this,
as
it somehow was going to do the same thing with a "name".
It's technically correct, but quality of this solution isn't really
nice, because it's a layering violation (at least if I understood what
you mean). This is because you need to have full definition of struct
phy in board file and a structure that is used as private data in PHY
core comes from platform code.
No, just a pointer, you don't need the "full" structure until you get to
some .c code that actually manipulates the phy itself, for all other
places, you are just dealing with a pointer and a structure you never
reference.
Does that make more sense?
Well, to the point that I think I now understood your suggestion.
Unfortunately the suggestion alone isn't really something that can be done,
considering how driver core and generic frameworks work.
Best regards,
Tomasz
On Tue, Jul 23, 2013 at 07:48:11PM +0200, Tomasz Figa wrote:
On Tuesday 23 of July 2013 10:37:11 Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
quoted
Ick, no. Why can't you just pass the pointer to the phy itself? If
you
had a "priv" pointer to search from, then you could have just passed
the
original phy pointer in the first place, right?
IMHO it would be better if you provided some code example, but let's
try to check if I understood you correctly.
It's not my code that I want to have added, so I don't have to write
examples, I just get to complain about the existing stuff :)
Still, I think that some small code snippets illustrating the idea are
really helpful.
No. Well, kind of. What's wrong with using the platform data structure
unique to the board to have the pointer?
For example (just randomly picking one), the ata-pxa driver would change
include/linux/platform_data/ata-pxa.h to have a phy pointer in it:
struct phy;
struct pata_pxa_pdata {
/* PXA DMA DREQ<0:2> pin */
uint32_t dma_dreq;
/* Register shift */
uint32_t reg_shift;
/* IRQ flags */
uint32_t irq_flags;
/* PHY */
struct phy *phy;
};
Then, when you create the platform, set the phy* pointer with a call to
phy_create(). Then you can use that pointer wherever that plaform data
is available (i.e. whereever platform_data is at).
Hmm? So, do you suggest to call phy_create() from board file? What phy_ops
struct and other hardware parameters would it take?
quoted
quoted
quoted
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
I fully agree that a simple, single string will not scale even in some,
not so uncommon cases, but there is already a lot of existing lookup
solutions over the kernel and so there is no point in introducing
another one.
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should. I'll go tackle those other ones after this one
is taken care of, to show how the others should be handled as well.
There was a reason for introducing lookup solutions. The reason was that in
board file there is no way to get a pointer to something that is going to be
created much later in time. We don't do time travel ;-).
quoted
quoted
quoted
Please just pass the real "phy" pointer around, that's what it is
there
for. Your "board binding" logic/code should be able to handle this,
as
it somehow was going to do the same thing with a "name".
It's technically correct, but quality of this solution isn't really
nice, because it's a layering violation (at least if I understood what
you mean). This is because you need to have full definition of struct
phy in board file and a structure that is used as private data in PHY
core comes from platform code.
No, just a pointer, you don't need the "full" structure until you get to
some .c code that actually manipulates the phy itself, for all other
places, you are just dealing with a pointer and a structure you never
reference.
Does that make more sense?
Well, to the point that I think I now understood your suggestion.
Unfortunately the suggestion alone isn't really something that can be done,
considering how driver core and generic frameworks work.
Ok, given that I seem to be totally confused as to exactly how the
board-specific frameworks work, I'll take your word for it.
But again, I will not accept "lookup by name" type solutions, when the
"name" is dynamic and will change. Because you are using a "name", you
can deal with a pointer, putting it _somewhere_ in your board-specific
data structures, as you are going to need to store it anyway (hint, you
had to get that "name" from somewhere, right?)
And maybe the way that these "generic frameworks" are created is wrong,
given that you don't feel that a generic pointer can be passed to the
needed devices. That seems like a huge problem, one that has already
been pointed out is causing issues with other subsystems.
So maybe they need to be fixed?
thanks,
greg k-h
From: Tomasz Figa <hidden> Date: 2013-07-23 20:47:05
On Tuesday 23 of July 2013 11:04:14 Greg KH wrote:
On Tue, Jul 23, 2013 at 07:48:11PM +0200, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 10:37:11 Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
quoted
Ick, no. Why can't you just pass the pointer to the phy itself?
If
you
had a "priv" pointer to search from, then you could have just
passed
the
original phy pointer in the first place, right?
IMHO it would be better if you provided some code example, but
let's
try to check if I understood you correctly.
It's not my code that I want to have added, so I don't have to write
examples, I just get to complain about the existing stuff :)
Still, I think that some small code snippets illustrating the idea are
really helpful.
No. Well, kind of. What's wrong with using the platform data
structure unique to the board to have the pointer?
For example (just randomly picking one), the ata-pxa driver would
change include/linux/platform_data/ata-pxa.h to have a phy pointer
in it:
struct phy;
struct pata_pxa_pdata {
/* PXA DMA DREQ<0:2> pin */
uint32_t dma_dreq;
/* Register shift */
uint32_t reg_shift;
/* IRQ flags */
uint32_t irq_flags;
/* PHY */
struct phy *phy;
};
Then, when you create the platform, set the phy* pointer with a call
to
phy_create(). Then you can use that pointer wherever that plaform
data
is available (i.e. whereever platform_data is at).
Hmm? So, do you suggest to call phy_create() from board file? What
phy_ops struct and other hardware parameters would it take?
quoted
quoted
quoted
The issue is that a string "name" is not going to scale at all,
as it
requires hard-coded information that will change over time (as
the
existing clock interface is already showing.)
I fully agree that a simple, single string will not scale even in
some,
not so uncommon cases, but there is already a lot of existing
lookup
solutions over the kernel and so there is no point in introducing
another one.
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should. I'll go tackle those other ones after this
one
is taken care of, to show how the others should be handled as well.
There was a reason for introducing lookup solutions. The reason was
that in board file there is no way to get a pointer to something that
is going to be created much later in time. We don't do time travel
;-).
quoted
quoted
quoted
Please just pass the real "phy" pointer around, that's what it
is
there
for. Your "board binding" logic/code should be able to handle
this,
as
it somehow was going to do the same thing with a "name".
It's technically correct, but quality of this solution isn't
really
nice, because it's a layering violation (at least if I understood
what
you mean). This is because you need to have full definition of
struct
phy in board file and a structure that is used as private data in
PHY
core comes from platform code.
No, just a pointer, you don't need the "full" structure until you
get to some .c code that actually manipulates the phy itself, for
all other places, you are just dealing with a pointer and a
structure you never reference.
Does that make more sense?
Well, to the point that I think I now understood your suggestion.
Unfortunately the suggestion alone isn't really something that can be
done, considering how driver core and generic frameworks work.
Ok, given that I seem to be totally confused as to exactly how the
board-specific frameworks work, I'll take your word for it.
Well, they are working in a way that keeps separation of layers, making
things clean. Platform code should not (well, there might exist some in
tree hacks, but this should not be propagated) used to exchange data
between drivers, but rather to specify board specific parameters for
generic drivers. If drivers need to cooperate, there must be a dedicated
interface for this, like the PHY framework Kishon is introducing here.
Sure, with platform code you can do a lot of hacky things, for example you
can simply provide PHY callbacks inside platform_data, like it was being
done historically, but that's just ugly.
Anyway, board files should now be rather considered a historical thing. We
are moving towards full DT-based description on ARM systems and so board
files and related things, like name-based lookups, statically registered
platform devices and so one are going away. Device Tree handles such
provider-consumer links automatically using specifiers with phandles and
lookup by node + provider-specific specifier args, so all the problems
with binding things together just go away.
But again, I will not accept "lookup by name" type solutions, when the
"name" is dynamic and will change. Because you are using a "name", you
can deal with a pointer, putting it _somewhere_ in your board-specific
data structures, as you are going to need to store it anyway (hint, you
had to get that "name" from somewhere, right?)
Yes. This kind of artificial names passed to both provider and consumer
isn't really a good way of lookup. This is just an example of bad lookup
key, though. IMHO for a good example of lookup you should see regulator
framework.
And maybe the way that these "generic frameworks" are created is wrong,
given that you don't feel that a generic pointer can be passed to the
needed devices. That seems like a huge problem, one that has already
been pointed out is causing issues with other subsystems.
What problem are you talking about here? AFAIK frameworks using correctly
designed lookup do work fine for most, if not all, people. See the
regulator framework.
So maybe they need to be fixed?
I don't really think anything is broken here, so there is nothing to fix.
Best regards,
Tomasz
From: Alan Stern <stern@rowland.harvard.edu> Date: 2013-07-23 19:36:04
On Tue, 23 Jul 2013, Tomasz Figa wrote:
IMHO it would be better if you provided some code example, but let's try to
check if I understood you correctly.
8><------------------------------------------------------------------------
[Board file]
static struct phy my_phy;
static struct platform_device phy_pdev = {
/* ... */
.platform_data = &my_phy;
/* ... */
};
static struct platform_device phy_pdev = {
This should be controller_pdev, not phy_pdev, yes?
Or even just phy_get(&pdev->dev), because phy_get() could be smart
enough to to set phy = dev->platform_data.
------------------------------------------------------------------------><8
Is this what you mean?
That's what I was going to suggest too. The struct phy is defined in
the board file, which already knows about all the PHYs that exist in
the system. (Or perhaps it is allocated dynamically, so that when many
board files are present in the same kernel, only the entries listed in
the board file for the current system get created.) Then the
structure's address is stored in the platform data and made available
to both the provider and the consumer.
Even though the struct phy is defined (or allocated) in the board file,
its contents don't get filled in until the PHY driver provides the
details.
It's technically correct, but quality of this solution isn't really nice,
because it's a layering violation (at least if I understood what you mean).
This is because you need to have full definition of struct phy in board file
and a structure that is used as private data in PHY core comes from
platform code.
You don't have to have a full definition in the board file. Just a
partial definition -- most of the contents can be filled in later, when
the PHY driver is ready to store the private data.
It's not a layering violation for one region of the kernel to store
private data in a structure defined by another part of the kernel.
This happens all the time (e.g., dev_set_drvdata).
Alan Stern
From: Tomasz Figa <hidden> Date: 2013-07-23 20:21:06
On Tuesday 23 of July 2013 15:36:00 Alan Stern wrote:
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
IMHO it would be better if you provided some code example, but let's
try to check if I understood you correctly.
8><-------------------------------------------------------------------
-----
[Board file]
static struct phy my_phy;
static struct platform_device phy_pdev = {
/* ... */
.platform_data = &my_phy;
/* ... */
};
static struct platform_device phy_pdev = {
This should be controller_pdev, not phy_pdev, yes?
Or even just phy_get(&pdev->dev), because phy_get() could be smart
enough to to set phy = dev->platform_data.
Unless you need more than one PHY in this driver...
quoted
----------------------------------------------------------------------
--><8
Is this what you mean?
That's what I was going to suggest too. The struct phy is defined in
the board file, which already knows about all the PHYs that exist in
the system. (Or perhaps it is allocated dynamically, so that when many
board files are present in the same kernel, only the entries listed in
the board file for the current system get created.)
Well, such dynamic allocation is a must. We don't accept non-multiplatform
aware code anymore, not even saying about multiboard.
Then the
structure's address is stored in the platform data and made available
to both the provider and the consumer.
Yes, technically this can work. You would still have to perform some kind
of synchronization to make sure that the PHY bound to this structure is
actually present. This is again technically doable (e.g. a list of
registered struct phys inside PHY core).
Even though the struct phy is defined (or allocated) in the board file,
its contents don't get filled in until the PHY driver provides the
details.
You can't assure this. Board file is free to do whatever it wants with
this struct. A clean solution would prevent this.
quoted
It's technically correct, but quality of this solution isn't really
nice, because it's a layering violation (at least if I understood
what you mean). This is because you need to have full definition of
struct phy in board file and a structure that is used as private data
in PHY core comes from platform code.
You don't have to have a full definition in the board file. Just a
partial definition -- most of the contents can be filled in later, when
the PHY driver is ready to store the private data.
It's not a layering violation for one region of the kernel to store
private data in a structure defined by another part of the kernel.
This happens all the time (e.g., dev_set_drvdata).
Not really. The phy struct is something that _is_ private data of PHY
subsystem, not something that can store private data of PHY subsystem
(sure it can store private data of particular PHY driver, but that's
another story) and only PHY subsystem should have access to its contents.
By the way, we need to consider other cases here as well, for example it
would be nice to have a single phy_get() function that works for both non-
DT and DT cases to make the consumer driver not have to worry whether it's
being probed from DT or not.
I'd suggest simply reusing the lookup method of regulator framework, just
as I suggested here:
http://thread.gmane.org/gmane.linux.ports.arm.kernel/252813/focus1661
Best regards,
Tomasz
From: Alan Stern <stern@rowland.harvard.edu> Date: 2013-07-23 20:54:09
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
That's what I was going to suggest too. The struct phy is defined in
the board file, which already knows about all the PHYs that exist in
the system. (Or perhaps it is allocated dynamically, so that when many
board files are present in the same kernel, only the entries listed in
the board file for the current system get created.)
Well, such dynamic allocation is a must. We don't accept non-multiplatform
aware code anymore, not even saying about multiboard.
quoted
Then the
structure's address is stored in the platform data and made available
to both the provider and the consumer.
Yes, technically this can work. You would still have to perform some kind
of synchronization to make sure that the PHY bound to this structure is
actually present. This is again technically doable (e.g. a list of
registered struct phys inside PHY core).
The synchronization takes place inside phy_get. If phy_create hasn't
been called for this structure by the time phy_get runs, phy_get will
return an error.
quoted
Even though the struct phy is defined (or allocated) in the board file,
its contents don't get filled in until the PHY driver provides the
details.
You can't assure this. Board file is free to do whatever it wants with
this struct. A clean solution would prevent this.
I'm not sure what you mean here. Of course I can't prevent a board
file from messing up a data structure. I can't prevent it from causing
memory access violations either; in fact, I can't prevent any bugs in
other people's code.
Besides, why do you say the board file is free to do whatever it wants
with the struct phy? Currently the struct phy is created by the PHY
provider and the PHY core, right? It's not even mentioned in the board
file.
quoted
quoted
It's technically correct, but quality of this solution isn't really
nice, because it's a layering violation (at least if I understood
what you mean). This is because you need to have full definition of
struct phy in board file and a structure that is used as private data
in PHY core comes from platform code.
You don't have to have a full definition in the board file. Just a
partial definition -- most of the contents can be filled in later, when
the PHY driver is ready to store the private data.
It's not a layering violation for one region of the kernel to store
private data in a structure defined by another part of the kernel.
This happens all the time (e.g., dev_set_drvdata).
Not really. The phy struct is something that _is_ private data of PHY
subsystem, not something that can store private data of PHY subsystem
(sure it can store private data of particular PHY driver, but that's
another story) and only PHY subsystem should have access to its contents.
If you want to keep the phy struct completely separate from the board
file, there's an easy way to do it. Let's say the board file knows
about N different PHYs in the system. Then you define an array of N
pointers to phys:
struct phy *(phy_address[N]);
In the platform data for both PHY j and its controller, store
&phy_address[j]. The PHY provider passes this cookie to phy_create:
cookie = pdev->dev.platform_data;
ret = phy_create(phy, cookie);
and phy_create simply stores: *cookie = phy. The PHY consumer does
much the same the same thing:
cookie = pdev->dev.platform_data;
phy = phy_get(cookie);
phy_get returns *cookie if it isn't NULL, or an ERR_PTR otherwise.
By the way, we need to consider other cases here as well, for example it
would be nice to have a single phy_get() function that works for both non-
DT and DT cases to make the consumer driver not have to worry whether it's
being probed from DT or not.
You ought to be able to adapt this scheme to work with DT. Maybe by
having multiple "phy_address" arrays.
Alan Stern
From: Tomasz Figa <hidden> Date: 2013-07-23 21:03:09
On Tuesday 23 of July 2013 16:53:55 Alan Stern wrote:
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
quoted
That's what I was going to suggest too. The struct phy is defined
in
the board file, which already knows about all the PHYs that exist in
the system. (Or perhaps it is allocated dynamically, so that when
many
board files are present in the same kernel, only the entries listed
in
the board file for the current system get created.)
Well, such dynamic allocation is a must. We don't accept
non-multiplatform aware code anymore, not even saying about
multiboard.
quoted
Then the
structure's address is stored in the platform data and made
available
to both the provider and the consumer.
Yes, technically this can work. You would still have to perform some
kind of synchronization to make sure that the PHY bound to this
structure is actually present. This is again technically doable (e.g.
a list of registered struct phys inside PHY core).
The synchronization takes place inside phy_get. If phy_create hasn't
been called for this structure by the time phy_get runs, phy_get will
return an error.
Yes, this is the solution that I had in mind when saying that this is
doable.
quoted
quoted
Even though the struct phy is defined (or allocated) in the board
file,
its contents don't get filled in until the PHY driver provides the
details.
You can't assure this. Board file is free to do whatever it wants with
this struct. A clean solution would prevent this.
I'm not sure what you mean here. Of course I can't prevent a board
file from messing up a data structure. I can't prevent it from causing
memory access violations either; in fact, I can't prevent any bugs in
other people's code.
Besides, why do you say the board file is free to do whatever it wants
with the struct phy? Currently the struct phy is created by the PHY
provider and the PHY core, right? It's not even mentioned in the board
file.
I mean, if you have a struct type of which full declaration is available
for some code, this code can access any memeber of it without any hacks,
which is not something that we want to have in board files. The phy struct
should be opaque for them.
quoted
quoted
quoted
It's technically correct, but quality of this solution isn't
really
nice, because it's a layering violation (at least if I understood
what you mean). This is because you need to have full definition
of
struct phy in board file and a structure that is used as private
data
in PHY core comes from platform code.
You don't have to have a full definition in the board file. Just a
partial definition -- most of the contents can be filled in later,
when
the PHY driver is ready to store the private data.
It's not a layering violation for one region of the kernel to store
private data in a structure defined by another part of the kernel.
This happens all the time (e.g., dev_set_drvdata).
Not really. The phy struct is something that _is_ private data of PHY
subsystem, not something that can store private data of PHY subsystem
(sure it can store private data of particular PHY driver, but that's
another story) and only PHY subsystem should have access to its
contents.
If you want to keep the phy struct completely separate from the board
file, there's an easy way to do it. Let's say the board file knows
about N different PHYs in the system. Then you define an array of N
pointers to phys:
struct phy *(phy_address[N]);
In the platform data for both PHY j and its controller, store
&phy_address[j]. The PHY provider passes this cookie to phy_create:
cookie = pdev->dev.platform_data;
ret = phy_create(phy, cookie);
and phy_create simply stores: *cookie = phy. The PHY consumer does
much the same the same thing:
cookie = pdev->dev.platform_data;
phy = phy_get(cookie);
phy_get returns *cookie if it isn't NULL, or an ERR_PTR otherwise.
OK, this can work. Again, just technically, because it's rather ugly.
quoted
By the way, we need to consider other cases here as well, for example
it would be nice to have a single phy_get() function that works for
both non- DT and DT cases to make the consumer driver not have to
worry whether it's being probed from DT or not.
You ought to be able to adapt this scheme to work with DT. Maybe by
having multiple "phy_address" arrays.
Where would you want to have those phy_address arrays stored? There are no
board files when booting with DT. Not even saying that you don't need to
use any hacky schemes like this when you have DT that nicely specifies
relations between devices.
Anyway, board file should not be considered as a method to exchange data
between drivers. It should be used only to pass data from it to drivers,
not the other way. Ideally all data in a board file should be marked as
const and __init and dropped after system initialization.
Best regards,
Tomasz