Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Tomasz Figa @ 2013-07-23 21:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1307231708020.1304-100000@iolanthe.rowland.org>

On Tuesday 23 of July 2013 17:14:20 Alan Stern wrote:
> On Tue, 23 Jul 2013, Tomasz Figa wrote:
> > > 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.
> 
> There's no reason the phy_address things have to be arrays.  A separate
> individual pointer for each PHY would work just as well.
> 
> > 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.
> 
> If everybody agrees DT has a nice scheme for specifying relations
> between devices, why not use that same scheme in the PHY core?

It is already used, for cases when consumer device has a DT node attached. 
In non-DT case this kind lookup translates loosely to something that is 
being done in regulator framework - you can't bind devices by pointers, 
because you don't have those pointers, so you need to use device names.

> > 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.
> 
> The phy_address things don't have to be defined or allocated in the
> board file; they could be set up along with the platform data.

There is no platform data when booting with DT.

> In any case, this was simply meant to be a suggestion to show that it
> is relatively easy to do what you need without using name or ID
> strings.

Sure. It's good to have different options discussed as well.

Best regards,
Tomasz


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Greg KH @ 2013-07-23 21:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1769609.rbAYfG9ir3@flatron>

On Tue, Jul 23, 2013 at 11:05:48PM +0200, Tomasz Figa wrote:
> > 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.

> > 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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Alan Stern @ 2013-07-23 21:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1374129984-765-2-git-send-email-kishon@ti.com>

On Tue, 23 Jul 2013, Tomasz Figa wrote:

> > 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.

There's no reason the phy_address things have to be arrays.  A separate
individual pointer for each PHY would work just as well.

> 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.

If everybody agrees DT has a nice scheme for specifying relations
between devices, why not use that same scheme in the PHY core?

> 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.

The phy_address things don't have to be defined or allocated in the 
board file; they could be set up along with the platform data.

In any case, this was simply meant to be a suggestion to show that it 
is relatively easy to do what you need without using name or ID 
strings.

Alan Stern


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Tomasz Figa @ 2013-07-23 21:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723205007.GA27166@kroah.com>

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:
> > 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:
> > > > > 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.

> > 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


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Tomasz Figa @ 2013-07-23 21:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1307231632580.1304-100000@iolanthe.rowland.org>

On Tuesday 23 of July 2013 16:53:55 Alan Stern wrote:
> On Tue, 23 Jul 2013, Tomasz Figa wrote:
> > > 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).
> 
> 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.

> > > 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.

> > > > 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.

> > 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


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Alan Stern @ 2013-07-23 20:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1374129984-765-2-git-send-email-kishon@ti.com>

On Tue, 23 Jul 2013, Tomasz Figa wrote:

> > 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).

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.

> > 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.

> > > 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


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Greg KH @ 2013-07-23 20:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1731726.KENstTPhkb@flatron>

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:
> > On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
> > > > 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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Tomasz Figa @ 2013-07-23 20:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723180414.GA9630@kroah.com>

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:
> > 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:
> > > > > 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.
> > 
> > > > 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?
> > > 
> > > 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?
> > 
> > > > > 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
> > ;-).
> > 
> > > > > 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


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Tomasz Figa @ 2013-07-23 20:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1307231518310.1304-100000@iolanthe.rowland.org>

On Tuesday 23 of July 2013 15:36:00 Alan Stern wrote:
> 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?

Right. A copy-pasto.

> 
> > 	/* ... */
> > 	.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);
> 
> 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...

> 
> > ----------------------------------------------------------------------
> > --><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.

> > 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/focus\x101661

Best regards,
Tomasz


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Tomasz Figa @ 2013-07-23 20:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723194423.GA22984@kroah.com>

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:
> > > 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");
	/* ... */
}

> > > > 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?

> > 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


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Greg KH @ 2013-07-23 19:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723193105.GP9858@sirena.org.uk>

On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
> > 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.

> > > 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.

> 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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Alan Stern @ 2013-07-23 19:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1374129984-765-2-git-send-email-kishon@ti.com>

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?

> 	/* ... */
> 	.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);

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


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Mark Brown @ 2013-07-23 19:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723180110.GA8688@kroah.com>

[-- Attachment #1: Type: text/plain, Size: 1634 bytes --]

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:

> > 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.

> > 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.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Greg KH @ 2013-07-23 18:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <19656720.FrnhefyPXl@amdc1227>

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:
> > On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
> > > > 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.
> 
> > > 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?
> > 
> > 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?
> 
> > > > 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 ;-).
> 
> > > > 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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Greg KH @ 2013-07-23 18:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723174456.GM9858@sirena.org.uk>

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:
> > On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
> 
> > > 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?

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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Tomasz Figa @ 2013-07-23 17:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723173710.GB28284@kroah.com>

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:
> > > 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.

> > 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?
> 
> 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?

> > > 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 ;-).

> > > 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


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Mark Brown @ 2013-07-23 17:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723173710.GB28284@kroah.com>

[-- Attachment #1: Type: text/plain, Size: 757 bytes --]

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:

> > 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...

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Greg KH @ 2013-07-23 17:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1446965.6APW5ZgLBW@amdc1227>

On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
> > 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 :)

> 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?

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).

> > 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.

> > 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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Mark Brown @ 2013-07-23 17:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1307231017290.1304-100000@iolanthe.rowland.org>

[-- Attachment #1: Type: text/plain, Size: 646 bytes --]

On Tue, Jul 23, 2013 at 10:37:05AM -0400, Alan Stern wrote:
> On Tue, 23 Jul 2013, Tomasz Figa wrote:

> > > > 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?

Platform data is nothing to do with the platform bus - it's board
specific data (ie, data for the platform) and can be done with any
device.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Tomasz Figa @ 2013-07-23 16:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723161846.GD2486@kroah.com>

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:
> > Hi,
> > 
> > On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
> > > On Tue, 23 Jul 2013, Tomasz Figa wrote:
> > >> On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
> > >>> Hi Alan,
> > > 
> > > Thanks for helping to clarify the issues here.
> > > 
> > >>>> 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.
> > 
> > >>>>>> 	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.)
> > > 
> > > 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.
> > 
> > >>>> 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.
> > 
> > >>> 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


^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Kishon Vijay Abraham I @ 2013-07-23 16:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130723161846.GD2486@kroah.com>

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:
>> Hi,
>>
>> On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
>>> On Tue, 23 Jul 2013, Tomasz Figa wrote:
>>>
>>>> On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
>>>>> Hi Alan,
>>>
>>> Thanks for helping to clarify the issues here.
>>>
>>>>>> 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>
.
.
>>
>> 	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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Greg KH @ 2013-07-23 16:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <51EEAF32.4040905@ti.com>

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:
> > 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:
> >>> On Tue, 23 Jul 2013, Tomasz Figa wrote:
> >>>
> >>>> On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
> >>>>> Hi Alan,
> >>>
> >>> Thanks for helping to clarify the issues here.
> >>>
> >>>>>> 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>
> .
> .
> >>
> >> 	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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Greg KH @ 2013-07-23 16:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <51EE9EC0.6060905@ti.com>

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:
> > On Tue, 23 Jul 2013, Tomasz Figa wrote:
> > 
> >> On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
> >>> Hi Alan,
> > 
> > Thanks for helping to clarify the issues here.
> > 
> >>>> 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.
> > 
> >>>>>> 	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.)
> > 
> > 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.
> > 
> >>>> 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.
> > 
> >>> 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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Kishon Vijay Abraham I @ 2013-07-23 15:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1307231017290.1304-100000@iolanthe.rowland.org>

Hi,

On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
> On Tue, 23 Jul 2013, Tomasz Figa wrote:
> 
>> On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
>>> Hi Alan,
> 
> Thanks for helping to clarify the issues here.
> 
>>>> 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.
> 
>>>>>> 	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.)
> 
> 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.
> 
>>>> 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.
> 
>>> 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

^ permalink raw reply

* Re: [PATCH 01/15] drivers: phy: add generic PHY framework
From: Tomasz Figa @ 2013-07-23 14:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1307231017290.1304-100000@iolanthe.rowland.org>

On Tuesday 23 of July 2013 10:37:05 Alan Stern wrote:
> On Tue, 23 Jul 2013, Tomasz Figa wrote:
> > On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
> > > Hi Alan,
> 
> Thanks for helping to clarify the issues here.
> 
> > > > 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?
> 
> > > > > > 	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.)
> 
> I don't understand, because I don't know what "a PHY lookup" does.

I have provided a code example in [1]. Feel free to ask questions about 
those code snippets.

[1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/252813/focus 889

> > > > 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.

> > > 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


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox