Re: [U-Boot] [PATCH] dm: allow setting driver_data before/during bind

2016-05-11 Thread Simon Glass
Hi Stephen,

On 11 May 2016 at 10:52, Stephen Warren  wrote:
> On 05/10/2016 08:25 PM, Simon Glass wrote:
>>
>> Hi Stephen,
>>
>> On 4 May 2016 at 12:42, Stephen Warren  wrote:
>>>
>>> On 05/01/2016 01:27 PM, Simon Glass wrote:


 Hi Stephen,

 On 28 April 2016 at 17:08, Stephen Warren  wrote:
>
>
> From: Stephen Warren 
>
> This will allow a driver's bind function to use the driver data. One
> example is the Tegra186 GPIO driver, which instantiates child devices
> for each of its GPIO ports, yet supports two different HW instances
> each
> with a different set of ports, and identified by the udevice_id .data
> field.
>
> Signed-off-by: Stephen Warren 
> ---
>drivers/core/device.c| 7 ---
>drivers/core/lists.c | 6 +++---
>drivers/gpio/dwapb_gpio.c| 2 +-
>drivers/gpio/s5p_gpio.c  | 2 +-
>drivers/gpio/sunxi_gpio.c| 2 +-
>drivers/gpio/tegra_gpio.c| 2 +-
>drivers/mtd/spi/sandbox.c| 2 +-
>drivers/net/mvpp2.c  | 3 ++-
>drivers/pci/pci-uclass.c | 5 ++---
>drivers/power/pmic/pmic-uclass.c | 2 +-
>drivers/usb/host/usb-uclass.c| 5 ++---
>include/dm/device-internal.h | 5 +++--
>12 files changed, 22 insertions(+), 21 deletions(-)



 I'm not sure this extra parameter carries its weight:

 - most callers just pass 0
>>>
>>>
>>> The same is true of the existing platdata field in many cases.
>>
>>
>> Yes, but platdata is defined to be needed by bind(), whereas
>> driver_data is supposed to be used in probe()  to find out which
>> device tree compatible string matched.
>
>
> This seems to conflict with the documentation in include/dm/device.h; it
> claims that platdata is created by calling ofdata_to_platdata() just before
> calling probe(), at least for the DT case (for the case where U_BOOT_DEVICE
> is used, the platdata is available right from the start).

Exactly. That isn't a conflict. It's just that with DT the platform
data is provided by ofdata_to_platdata() whereas without it (the
degenerate case) it must be provided before bind().

>
> I couldn't find anywhere in the documentation that states when driver_data
> is supposed to be used; could you point me at it so I can read it?

No, but we should add something. See device.h:

 * @of_offset: Device tree node offset for this device (- for none)
 * @driver_data: Driver data word for the entry that matched this device with
 * its driver

It is related to DT, nothing else.

>
>> Remember that the device tree
>>
>> properties are not looked at during bind(), only later. So it makes
>> sense to include platdata in the device_bind() call, but not
>> driver_data.
>
>
> Hmm, drivers/gpio/tegra_gpio.c:gpio_tegra_bind() uses DT (which you wrote or
> at least converted it to DM and chose where to put the DT accesses), and you
> very recently reviewed and applied "video: tegra: refuse to bind to disabled
> dcs" which modified drivers/video/tegra.c:tegra_lcd_bind() to use DT.

Re GPIO, this is because on tegra this information is not present in
the DT - it uses the 'interrupts' property to figure out the number of
GPIO banks. It does not involve using driverdata.

The video thing is checking for a disabled device, something that is
already done in dm_scan_fdt_node().

>
> Admittedly I do now see the following in doc/driver-model/README.txt:
>
>> The device's bind() method is permitted to perform simple actions, but
>> should not scan the device tree node, not initialise hardware, nor set up
>> structures or allocate memory. All of these tasks should be left for
>> the probe() method.
>
>
> ... but then I wonder why that rule was enforced for the patch in this
> thread, but not in the other cases?
>
> This inconsistency in review is extremely frustrating to me.

See above. There are always grey areas, but the two you cite don't
involve core DM changes.

>
 - the field is supposed to be set up by device tree and probing tables,
 not code
>>>
>>>
>>> While the existence of this new parameter does allow arbitrary code to
>>> set
>>> the parameter, this patch only actually sets the parameter in the case
>>> where
>>> DT and probing tables have determined that value.
>>
>>
>> I don't think so. That value is set in lists_bind_fdt().
>
>
> Sure, but that function is only used from 3 places, and explicitly accepts a
> parameter to indicate which DT node to instantiate a device for. It won't
> work unless a valid DT node is passed to it, and therefore can only work for
> DT-based probing.
>
>> I wonder if you could set it yourself after calling device_bind()?
>
>
> The Tegra186 GPIO driver explicitly needs to use the data inside the
> driver's bind() function in order to know how 

Re: [U-Boot] [PATCH] dm: allow setting driver_data before/during bind

2016-05-11 Thread Stephen Warren

On 05/10/2016 08:25 PM, Simon Glass wrote:

Hi Stephen,

On 4 May 2016 at 12:42, Stephen Warren  wrote:

On 05/01/2016 01:27 PM, Simon Glass wrote:


Hi Stephen,

On 28 April 2016 at 17:08, Stephen Warren  wrote:


From: Stephen Warren 

This will allow a driver's bind function to use the driver data. One
example is the Tegra186 GPIO driver, which instantiates child devices
for each of its GPIO ports, yet supports two different HW instances each
with a different set of ports, and identified by the udevice_id .data
field.

Signed-off-by: Stephen Warren 
---
   drivers/core/device.c| 7 ---
   drivers/core/lists.c | 6 +++---
   drivers/gpio/dwapb_gpio.c| 2 +-
   drivers/gpio/s5p_gpio.c  | 2 +-
   drivers/gpio/sunxi_gpio.c| 2 +-
   drivers/gpio/tegra_gpio.c| 2 +-
   drivers/mtd/spi/sandbox.c| 2 +-
   drivers/net/mvpp2.c  | 3 ++-
   drivers/pci/pci-uclass.c | 5 ++---
   drivers/power/pmic/pmic-uclass.c | 2 +-
   drivers/usb/host/usb-uclass.c| 5 ++---
   include/dm/device-internal.h | 5 +++--
   12 files changed, 22 insertions(+), 21 deletions(-)



I'm not sure this extra parameter carries its weight:

- most callers just pass 0


The same is true of the existing platdata field in many cases.


Yes, but platdata is defined to be needed by bind(), whereas
driver_data is supposed to be used in probe()  to find out which
device tree compatible string matched.


This seems to conflict with the documentation in include/dm/device.h; it 
claims that platdata is created by calling ofdata_to_platdata() just 
before calling probe(), at least for the DT case (for the case where 
U_BOOT_DEVICE is used, the platdata is available right from the start).


I couldn't find anywhere in the documentation that states when 
driver_data is supposed to be used; could you point me at it so I can 
read it?


> Remember that the device tree

properties are not looked at during bind(), only later. So it makes
sense to include platdata in the device_bind() call, but not
driver_data.


Hmm, drivers/gpio/tegra_gpio.c:gpio_tegra_bind() uses DT (which you 
wrote or at least converted it to DM and chose where to put the DT 
accesses), and you very recently reviewed and applied "video: tegra: 
refuse to bind to disabled dcs" which modified 
drivers/video/tegra.c:tegra_lcd_bind() to use DT.


Admittedly I do now see the following in doc/driver-model/README.txt:


The device's bind() method is permitted to perform simple actions, but
should not scan the device tree node, not initialise hardware, nor set up
structures or allocate memory. All of these tasks should be left for
the probe() method.


... but then I wonder why that rule was enforced for the patch in this 
thread, but not in the other cases?


This inconsistency in review is extremely frustrating to me.


- the field is supposed to be set up by device tree and probing tables,
not code


While the existence of this new parameter does allow arbitrary code to set
the parameter, this patch only actually sets the parameter in the case where
DT and probing tables have determined that value.


I don't think so. That value is set in lists_bind_fdt().


Sure, but that function is only used from 3 places, and explicitly 
accepts a parameter to indicate which DT node to instantiate a device 
for. It won't work unless a valid DT node is passed to it, and therefore 
can only work for DT-based probing.



I wonder if you could set it yourself after calling device_bind()?


The Tegra186 GPIO driver explicitly needs to use the data inside the 
driver's bind() function in order to know how many child devices to 
instantiate. Setting the value after calling device_bind() (which the 
core DM code already does) is too late.


For reference, you can see the exact code at:
http://lists.denx.de/pipermail/u-boot/2016-April/252238.html
"gpio: add Tegra186 GPIO driver"

Search for "tegra186_gpio_bind" and look at the assignment to, and use 
of, ctlr_data.


I had also quoted that part of the code in my previous email.


- bind() methods should not care about the driver data (they are not
allowed to touch hardware), so setting it later is fine


Not touching HW is fine, but the driver data can still feed into purely SW
decisions that bind makes. More details below.


- you can already pass platform data to the driver which is the
preferred communication method from a parent to its children


I don't believe this is possible for devices instantiated from DT is it? In
that case, platform data is always NULL:


That's right. For DT the paltform data is set up in the
ofdata_to_platdata() method. Since you are using DT, you should follow
that convention.


This is the opposite of what you said above, which was that platdata is 
for bind().



int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,

Re: [U-Boot] [PATCH] dm: allow setting driver_data before/during bind

2016-05-10 Thread Simon Glass
Hi Stephen,

On 4 May 2016 at 12:42, Stephen Warren  wrote:
> On 05/01/2016 01:27 PM, Simon Glass wrote:
>>
>> Hi Stephen,
>>
>> On 28 April 2016 at 17:08, Stephen Warren  wrote:
>>>
>>> From: Stephen Warren 
>>>
>>> This will allow a driver's bind function to use the driver data. One
>>> example is the Tegra186 GPIO driver, which instantiates child devices
>>> for each of its GPIO ports, yet supports two different HW instances each
>>> with a different set of ports, and identified by the udevice_id .data
>>> field.
>>>
>>> Signed-off-by: Stephen Warren 
>>> ---
>>>   drivers/core/device.c| 7 ---
>>>   drivers/core/lists.c | 6 +++---
>>>   drivers/gpio/dwapb_gpio.c| 2 +-
>>>   drivers/gpio/s5p_gpio.c  | 2 +-
>>>   drivers/gpio/sunxi_gpio.c| 2 +-
>>>   drivers/gpio/tegra_gpio.c| 2 +-
>>>   drivers/mtd/spi/sandbox.c| 2 +-
>>>   drivers/net/mvpp2.c  | 3 ++-
>>>   drivers/pci/pci-uclass.c | 5 ++---
>>>   drivers/power/pmic/pmic-uclass.c | 2 +-
>>>   drivers/usb/host/usb-uclass.c| 5 ++---
>>>   include/dm/device-internal.h | 5 +++--
>>>   12 files changed, 22 insertions(+), 21 deletions(-)
>>
>>
>> I'm not sure this extra parameter carries its weight:
>>
>> - most callers just pass 0
>
>
> The same is true of the existing platdata field in many cases.

Yes, but platdata is defined to be needed by bind(), whereas
driver_data is supposed to be used in probe()  to find out which
device tree compatible string matched. Remember that the device tree
properties are not looked at during bind(), only later. So it makes
sense to include platdata in the device_bind() call, but not
driver_data.

>
>> - the field is supposed to be set up by device tree and probing tables,
>> not code
>
>
> While the existence of this new parameter does allow arbitrary code to set
> the parameter, this patch only actually sets the parameter in the case where
> DT and probing tables have determined that value.

I don't think so. That value is set in lists_bind_fdt().

I wonder if you could set it yourself after calling device_bind()?

>
>> - bind() methods should not care about the driver data (they are not
>> allowed to touch hardware), so setting it later is fine
>
>
> Not touching HW is fine, but the driver data can still feed into purely SW
> decisions that bind makes. More details below.
>
>> - you can already pass platform data to the driver which is the
>> preferred communication method from a parent to its children
>
>
> I don't believe this is possible for devices instantiated from DT is it? In
> that case, platform data is always NULL:

That's right. For DT the paltform data is set up in the
ofdata_to_platdata() method. Since you are using DT, you should follow
that convention.

>
> int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
>struct udevice **devp)
> ...
> ret = device_bind(parent, entry, name, NULL, id->data,
>   offset, );
>
> (That quoted code is with this patch applied, and the NULL value is the
> platform data parameter.)
>
>> Also it's not clear from your Tegra 186 GPIO patch where you are using
>> this.
>
>
> Here's the relevant part from the Tegra186 GPIO driver patch I posted:
>
>> +static int tegra186_gpio_bind(struct udevice *parent)
>> +{
>> +   struct tegra186_gpio_platdata *parent_plat = parent->platdata;
>> +   struct tegra186_gpio_ctlr_data *ctlr_data =
>> +   (struct tegra186_gpio_ctlr_data *)parent->driver_data;
>
> ...
>>
>> +   /* If this is a child device, there is nothing to do here */
>> +   if (parent_plat)
>> +   return 0;
>
> ...
>>
>> +   for (port = 0; port < ctlr_data->port_count; port++) {
>
> ...
>>
>> +   plat->name = ctlr_data->ports[port].name;
>> +   plat->regs = &(regs[ctlr_data->ports[port].offset / 4]);
>
>
> The data is used to determine how many child devices (one per port) to
> create, and the name and register offset of each one. This is modelled after
> the logic in the previous Tegra GPIO driver that you wrote, with the
> unfortunate modification that the register layout is more "interesting" on
> Tegra186, and so we can't determine the number of and parameters for the
> child devices purely algorithmically, since the register layout is decidedly
> non-linear.

OK I see. This feels like something that your device tree should
describe. Failing that, how about a hard-coded table of information in
the source code? You can look through the table and create the
appropriate child devices.

>
> I suppose an alternative would be to create separate U_BOOT_DRIVER()s for
> each compatible value with different register layout, and then have the
> bind() for each of those call into some common implementation with a
> hard-coded parameter. Still, it seems like 

Re: [U-Boot] [PATCH] dm: allow setting driver_data before/during bind

2016-05-10 Thread Stephen Warren

On 05/04/2016 12:42 PM, Stephen Warren wrote:

On 05/01/2016 01:27 PM, Simon Glass wrote:

Hi Stephen,

On 28 April 2016 at 17:08, Stephen Warren  wrote:

From: Stephen Warren 

This will allow a driver's bind function to use the driver data. One
example is the Tegra186 GPIO driver, which instantiates child devices
for each of its GPIO ports, yet supports two different HW instances each
with a different set of ports, and identified by the udevice_id .data
field.

Signed-off-by: Stephen Warren 
---
  drivers/core/device.c| 7 ---
  drivers/core/lists.c | 6 +++---
  drivers/gpio/dwapb_gpio.c| 2 +-
  drivers/gpio/s5p_gpio.c  | 2 +-
  drivers/gpio/sunxi_gpio.c| 2 +-
  drivers/gpio/tegra_gpio.c| 2 +-
  drivers/mtd/spi/sandbox.c| 2 +-
  drivers/net/mvpp2.c  | 3 ++-
  drivers/pci/pci-uclass.c | 5 ++---
  drivers/power/pmic/pmic-uclass.c | 2 +-
  drivers/usb/host/usb-uclass.c| 5 ++---
  include/dm/device-internal.h | 5 +++--
  12 files changed, 22 insertions(+), 21 deletions(-)


I'm not sure this extra parameter carries its weight:

- most callers just pass 0


The same is true of the existing platdata field in many cases.


- the field is supposed to be set up by device tree and probing
tables, not code


While the existence of this new parameter does allow arbitrary code to
set the parameter, this patch only actually sets the parameter in the
case where DT and probing tables have determined that value.


- bind() methods should not care about the driver data (they are not
allowed to touch hardware), so setting it later is fine


Not touching HW is fine, but the driver data can still feed into purely
SW decisions that bind makes. More details below.


- you can already pass platform data to the driver which is the
preferred communication method from a parent to its children


I don't believe this is possible for devices instantiated from DT is it?
In that case, platform data is always NULL:

int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
struct udevice **devp)
...
 ret = device_bind(parent, entry, name, NULL, id->data,
   offset, );

(That quoted code is with this patch applied, and the NULL value is the
platform data parameter.)


Also it's not clear from your Tegra 186 GPIO patch where you are using
this.


Here's the relevant part from the Tegra186 GPIO driver patch I posted:


+static int tegra186_gpio_bind(struct udevice *parent)
+{
+struct tegra186_gpio_platdata *parent_plat = parent->platdata;
+struct tegra186_gpio_ctlr_data *ctlr_data =
+(struct tegra186_gpio_ctlr_data *)parent->driver_data;

...

+/* If this is a child device, there is nothing to do here */
+if (parent_plat)
+return 0;

...

+for (port = 0; port < ctlr_data->port_count; port++) {

...

+plat->name = ctlr_data->ports[port].name;
+plat->regs = &(regs[ctlr_data->ports[port].offset / 4]);


The data is used to determine how many child devices (one per port) to
create, and the name and register offset of each one. This is modelled
after the logic in the previous Tegra GPIO driver that you wrote, with
the unfortunate modification that the register layout is more
"interesting" on Tegra186, and so we can't determine the number of and
parameters for the child devices purely algorithmically, since the
register layout is decidedly non-linear.

I suppose an alternative would be to create separate U_BOOT_DRIVER()s
for each compatible value with different register layout, and then have
the bind() for each of those call into some common implementation with a
hard-coded parameter. Still, it seems like the usage in the current code
is exactly what udevice_id.data is for; to avoid having to implement
separate functions that do that.

Perhaps the creation of the child devices could happen in probe() rather
than bind()? I imagine there's some reason this wouldn't work (such as
this causing the devices to be created too late to be referenced by
other drivers?) or you would have done this in the existing Tegra GPIO
driver.


Simon, any more thoughts on how the Tegra186 GPIO should handle the need 
for HW knowledge in bind()? I'd like to repost that driver soon, and 
doing so requires resolving this discussion. Thanks.

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH] dm: allow setting driver_data before/during bind

2016-05-04 Thread Stephen Warren

On 05/01/2016 01:27 PM, Simon Glass wrote:

Hi Stephen,

On 28 April 2016 at 17:08, Stephen Warren  wrote:

From: Stephen Warren 

This will allow a driver's bind function to use the driver data. One
example is the Tegra186 GPIO driver, which instantiates child devices
for each of its GPIO ports, yet supports two different HW instances each
with a different set of ports, and identified by the udevice_id .data
field.

Signed-off-by: Stephen Warren 
---
  drivers/core/device.c| 7 ---
  drivers/core/lists.c | 6 +++---
  drivers/gpio/dwapb_gpio.c| 2 +-
  drivers/gpio/s5p_gpio.c  | 2 +-
  drivers/gpio/sunxi_gpio.c| 2 +-
  drivers/gpio/tegra_gpio.c| 2 +-
  drivers/mtd/spi/sandbox.c| 2 +-
  drivers/net/mvpp2.c  | 3 ++-
  drivers/pci/pci-uclass.c | 5 ++---
  drivers/power/pmic/pmic-uclass.c | 2 +-
  drivers/usb/host/usb-uclass.c| 5 ++---
  include/dm/device-internal.h | 5 +++--
  12 files changed, 22 insertions(+), 21 deletions(-)


I'm not sure this extra parameter carries its weight:

- most callers just pass 0


The same is true of the existing platdata field in many cases.


- the field is supposed to be set up by device tree and probing tables, not code


While the existence of this new parameter does allow arbitrary code to 
set the parameter, this patch only actually sets the parameter in the 
case where DT and probing tables have determined that value.



- bind() methods should not care about the driver data (they are not
allowed to touch hardware), so setting it later is fine


Not touching HW is fine, but the driver data can still feed into purely 
SW decisions that bind makes. More details below.



- you can already pass platform data to the driver which is the
preferred communication method from a parent to its children


I don't believe this is possible for devices instantiated from DT is it? 
In that case, platform data is always NULL:


int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
   struct udevice **devp)
...
ret = device_bind(parent, entry, name, NULL, id->data,
  offset, );

(That quoted code is with this patch applied, and the NULL value is the 
platform data parameter.)



Also it's not clear from your Tegra 186 GPIO patch where you are using this.


Here's the relevant part from the Tegra186 GPIO driver patch I posted:


+static int tegra186_gpio_bind(struct udevice *parent)
+{
+   struct tegra186_gpio_platdata *parent_plat = parent->platdata;
+   struct tegra186_gpio_ctlr_data *ctlr_data =
+   (struct tegra186_gpio_ctlr_data *)parent->driver_data;

...

+   /* If this is a child device, there is nothing to do here */
+   if (parent_plat)
+   return 0;

...

+   for (port = 0; port < ctlr_data->port_count; port++) {

...

+   plat->name = ctlr_data->ports[port].name;
+   plat->regs = &(regs[ctlr_data->ports[port].offset / 4]);


The data is used to determine how many child devices (one per port) to 
create, and the name and register offset of each one. This is modelled 
after the logic in the previous Tegra GPIO driver that you wrote, with 
the unfortunate modification that the register layout is more 
"interesting" on Tegra186, and so we can't determine the number of and 
parameters for the child devices purely algorithmically, since the 
register layout is decidedly non-linear.


I suppose an alternative would be to create separate U_BOOT_DRIVER()s 
for each compatible value with different register layout, and then have 
the bind() for each of those call into some common implementation with a 
hard-coded parameter. Still, it seems like the usage in the current code 
is exactly what udevice_id.data is for; to avoid having to implement 
separate functions that do that.


Perhaps the creation of the child devices could happen in probe() rather 
than bind()? I imagine there's some reason this wouldn't work (such as 
this causing the devices to be created too late to be referenced by 
other drivers?) or you would have done this in the existing Tegra GPIO 
driver.

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH] dm: allow setting driver_data before/during bind

2016-05-01 Thread Simon Glass
Hi Stephen,

On 28 April 2016 at 17:08, Stephen Warren  wrote:
> From: Stephen Warren 
>
> This will allow a driver's bind function to use the driver data. One
> example is the Tegra186 GPIO driver, which instantiates child devices
> for each of its GPIO ports, yet supports two different HW instances each
> with a different set of ports, and identified by the udevice_id .data
> field.
>
> Signed-off-by: Stephen Warren 
> ---
>  drivers/core/device.c| 7 ---
>  drivers/core/lists.c | 6 +++---
>  drivers/gpio/dwapb_gpio.c| 2 +-
>  drivers/gpio/s5p_gpio.c  | 2 +-
>  drivers/gpio/sunxi_gpio.c| 2 +-
>  drivers/gpio/tegra_gpio.c| 2 +-
>  drivers/mtd/spi/sandbox.c| 2 +-
>  drivers/net/mvpp2.c  | 3 ++-
>  drivers/pci/pci-uclass.c | 5 ++---
>  drivers/power/pmic/pmic-uclass.c | 2 +-
>  drivers/usb/host/usb-uclass.c| 5 ++---
>  include/dm/device-internal.h | 5 +++--
>  12 files changed, 22 insertions(+), 21 deletions(-)

I'm not sure this extra parameter carries its weight:

- most callers just pass 0
- the field is supposed to be set up by device tree and probing tables, not code
- bind() methods should not care about the driver data (they are not
allowed to touch hardware), so setting it later is fine
- you can already pass platform data to the driver which is the
preferred communication method from a parent to its children

Also it's not clear from your Tegra 186 GPIO patch where you are using this.

Regards,
Simon
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


[U-Boot] [PATCH] dm: allow setting driver_data before/during bind

2016-04-28 Thread Stephen Warren
From: Stephen Warren 

This will allow a driver's bind function to use the driver data. One
example is the Tegra186 GPIO driver, which instantiates child devices
for each of its GPIO ports, yet supports two different HW instances each
with a different set of ports, and identified by the udevice_id .data
field.

Signed-off-by: Stephen Warren 
---
 drivers/core/device.c| 7 ---
 drivers/core/lists.c | 6 +++---
 drivers/gpio/dwapb_gpio.c| 2 +-
 drivers/gpio/s5p_gpio.c  | 2 +-
 drivers/gpio/sunxi_gpio.c| 2 +-
 drivers/gpio/tegra_gpio.c| 2 +-
 drivers/mtd/spi/sandbox.c| 2 +-
 drivers/net/mvpp2.c  | 3 ++-
 drivers/pci/pci-uclass.c | 5 ++---
 drivers/power/pmic/pmic-uclass.c | 2 +-
 drivers/usb/host/usb-uclass.c| 5 ++---
 include/dm/device-internal.h | 5 +++--
 12 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 74688dc95075..dc66e2400de6 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -27,8 +27,8 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 int device_bind(struct udevice *parent, const struct driver *drv,
-   const char *name, void *platdata, int of_offset,
-   struct udevice **devp)
+   const char *name, void *platdata, ulong driver_data,
+   int of_offset, struct udevice **devp)
 {
struct udevice *dev, *dev2;
struct uclass *uc;
@@ -56,6 +56,7 @@ int device_bind(struct udevice *parent, const struct driver 
*drv,
INIT_LIST_HEAD(>devres_head);
 #endif
dev->platdata = platdata;
+   dev->driver_data = driver_data;
dev->name = name;
dev->of_offset = of_offset;
dev->parent = parent;
@@ -227,7 +228,7 @@ int device_bind_by_name(struct udevice *parent, bool 
pre_reloc_only,
return -EPERM;
 
return device_bind(parent, drv, info->name, (void *)info->platdata,
-  -1, devp);
+  0, -1, devp);
 }
 
 static void *alloc_priv(int size, uint flags)
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index a72db13a119a..ac5a788e7e2b 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -89,7 +89,7 @@ int device_bind_driver_to_node(struct udevice *parent, const 
char *drv_name,
debug("Cannot find driver '%s'\n", drv_name);
return -ENOENT;
}
-   ret = device_bind(parent, drv, dev_name, NULL, node, devp);
+   ret = device_bind(parent, drv, dev_name, NULL, 0, node, devp);
if (ret) {
debug("Cannot create device named '%s' (err=%d)\n",
  dev_name, ret);
@@ -170,7 +170,8 @@ int lists_bind_fdt(struct udevice *parent, const void 
*blob, int offset,
}
 
dm_dbg("   - found match at '%s'\n", entry->name);
-   ret = device_bind(parent, entry, name, NULL, offset, );
+   ret = device_bind(parent, entry, name, NULL, id->data,
+ offset, );
if (ret == -ENODEV) {
dm_dbg("Driver '%s' refuses to bind\n", entry->name);
continue;
@@ -180,7 +181,6 @@ int lists_bind_fdt(struct udevice *parent, const void 
*blob, int offset,
ret);
return ret;
} else {
-   dev->driver_data = id->data;
found = true;
if (devp)
*devp = dev;
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index 72cec4880095..dcbf4c7b0877 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -137,7 +137,7 @@ static int gpio_dwapb_bind(struct udevice *dev)
goto err;
 
ret = device_bind(dev, dev->driver, plat->name,
- plat, -1, );
+ plat, 0, -1, );
if (ret)
goto err;
 
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 0f22b238ba99..d4e1822c3646 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -344,7 +344,7 @@ static int gpio_exynos_bind(struct udevice *parent)
 
plat->bank_name = fdt_get_name(blob, node, NULL);
ret = device_bind(parent, parent->driver,
- plat->bank_name, plat, -1, );
+ plat->bank_name, plat, 0, -1, );
if (ret)
return ret;
 
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index a7cec18d57fb..715239dae38e 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -306,7 +306,7 @@ static int gpio_sunxi_bind(struct udevice *parent)
plat->gpio_count = SUNXI_GPIOS_PER_BANK;