diff mbox

[v6,04/22] of: add function to allow probing a device from a OF node

Message ID 1442844182-27787-5-git-send-email-tomeu.vizoso@collabora.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tomeu Vizoso Sept. 21, 2015, 2:02 p.m. UTC
Walks the OF tree up and finds the closest ancestor that has a struct
device associated with it, probing it if isn't bound to a driver yet.

The above should ensure that the dependency represented by the passed OF
node is available, because probing a device should cause its descendants
to be probed as well (when they get registered).

Subsystems can use this when looking up resources for drivers, to reduce
the chances of deferred probes because of the probing order of devices.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
---

Changes in v5:
- Move the assignment to device_node->device for AMBA devices to another
  commit.
- Hold a reference to the struct device while it's in use in
  of_device_probe().

Changes in v4:
- Rename of_platform_probe to of_device_probe
- Use device_node.device instead of device_node.platform_dev

Changes in v3:
- Set and use device_node.platform_dev instead of reversing the logic to
  find the platform device that encloses a device node.
- Drop the fwnode API to probe firmware nodes and add OF-only API for
  now. I think this same scheme could be used for machines with ACPI,
  but I haven't been able to find one that had to defer its probes because
  of the device probe order.

 drivers/of/device.c       | 61 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_device.h |  3 +++
 2 files changed, 64 insertions(+)

Comments

Rafael J. Wysocki Oct. 22, 2015, 1:06 a.m. UTC | #1
On Monday, September 21, 2015 04:02:44 PM Tomeu Vizoso wrote:
> Walks the OF tree up and finds the closest ancestor that has a struct
> device associated with it, probing it if isn't bound to a driver yet.
> 
> The above should ensure that the dependency represented by the passed OF
> node is available, because probing a device should cause its descendants
> to be probed as well (when they get registered).
> 
> Subsystems can use this when looking up resources for drivers, to reduce
> the chances of deferred probes because of the probing order of devices.
> 
> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
> ---
> 
> Changes in v5:
> - Move the assignment to device_node->device for AMBA devices to another
>   commit.
> - Hold a reference to the struct device while it's in use in
>   of_device_probe().
> 
> Changes in v4:
> - Rename of_platform_probe to of_device_probe
> - Use device_node.device instead of device_node.platform_dev
> 
> Changes in v3:
> - Set and use device_node.platform_dev instead of reversing the logic to
>   find the platform device that encloses a device node.
> - Drop the fwnode API to probe firmware nodes and add OF-only API for
>   now. I think this same scheme could be used for machines with ACPI,
>   but I haven't been able to find one that had to defer its probes because
>   of the device probe order.
> 
>  drivers/of/device.c       | 61 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_device.h |  3 +++
>  2 files changed, 64 insertions(+)
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 8b91ea241b10..836be71fc90e 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -286,3 +286,64 @@ int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
>  
>  	return 0;
>  }
> +
> +/**
> + * of_device_probe() - Probe device associated with OF node
> + * @np: node to probe
> + *
> + * Probe the device associated with the passed device node.
> + */
> +void of_device_probe(struct device_node *np)

Same question as from Greg: How does a subsystem know whether or not to use
this function?

> +{
> +	struct device_node *target;
> +	struct device *dev = NULL;
> +
> +	if (!of_root || !of_node_check_flag(of_root, OF_POPULATED_BUS))
> +		return;
> +
> +	if (!np)
> +		return;
> +
> +	of_node_get(np);
> +
> +	/* Find the closest ancestor that has a device associated */
> +	for (target = np;
> +	     !of_node_is_root(target);
> +	     target = of_get_next_parent(target))
> +		if (get_device(target->device)) {
> +			dev = target->device;
> +			break;
> +		}
> +
> +	of_node_put(target);
> +
> +	if (!dev) {
> +		pr_warn("Couldn't find a device for node '%s'\n",
> +			of_node_full_name(np));
> +		return;
> +	}
> +
> +	/*
> +	 * Device is bound or is being probed right now. If we have bad luck
> +	 * and the dependency isn't ready when it's needed, deferred probe
> +	 * will save us.
> +	 */
> +	if (dev->driver)
> +		goto out;
> +
> +	/*
> +	 * Probing a device should cause its descendants to be probed as
> +	 * well, which includes the passed device node.
> +	 */
> +	if (device_attach(dev) != 1)
> +		/*
> +		 * This cannot be a warning for now because clock nodes have a
> +		 * compatible string but the clock framework doesn't follow
> +		 * the device/driver model yet.
> +		 */
> +		dev_dbg(dev, "Probe failed for %s\n", of_node_full_name(np));
> +
> +out:
> +	put_device(dev);
> +}
> +EXPORT_SYMBOL_GPL(of_device_probe);
> diff --git a/include/linux/of_device.h b/include/linux/of_device.h
> index cc7dd687a89d..da8d489e73ad 100644
> --- a/include/linux/of_device.h
> +++ b/include/linux/of_device.h
> @@ -40,6 +40,7 @@ extern ssize_t of_device_get_modalias(struct device *dev,
>  
>  extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
>  extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
> +extern void of_device_probe(struct device_node *np);
>  
>  static inline void of_device_node_put(struct device *dev)
>  {
> @@ -84,6 +85,8 @@ static inline int of_device_uevent_modalias(struct device *dev,
>  	return -ENODEV;
>  }
>  
> +static inline void of_device_probe(struct device_node *np) { }
> +
>  static inline void of_device_node_put(struct device *dev) { }
>  
>  static inline const struct of_device_id *__of_match_device(
>
Tomeu Vizoso Oct. 22, 2015, 1:03 p.m. UTC | #2
On 22 October 2015 at 03:06, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Monday, September 21, 2015 04:02:44 PM Tomeu Vizoso wrote:
>> Walks the OF tree up and finds the closest ancestor that has a struct
>> device associated with it, probing it if isn't bound to a driver yet.
>>
>> The above should ensure that the dependency represented by the passed OF
>> node is available, because probing a device should cause its descendants
>> to be probed as well (when they get registered).
>>
>> Subsystems can use this when looking up resources for drivers, to reduce
>> the chances of deferred probes because of the probing order of devices.
>>
>> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
>> ---
>>
>> Changes in v5:
>> - Move the assignment to device_node->device for AMBA devices to another
>>   commit.
>> - Hold a reference to the struct device while it's in use in
>>   of_device_probe().
>>
>> Changes in v4:
>> - Rename of_platform_probe to of_device_probe
>> - Use device_node.device instead of device_node.platform_dev
>>
>> Changes in v3:
>> - Set and use device_node.platform_dev instead of reversing the logic to
>>   find the platform device that encloses a device node.
>> - Drop the fwnode API to probe firmware nodes and add OF-only API for
>>   now. I think this same scheme could be used for machines with ACPI,
>>   but I haven't been able to find one that had to defer its probes because
>>   of the device probe order.
>>
>>  drivers/of/device.c       | 61 +++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/of_device.h |  3 +++
>>  2 files changed, 64 insertions(+)
>>
>> diff --git a/drivers/of/device.c b/drivers/of/device.c
>> index 8b91ea241b10..836be71fc90e 100644
>> --- a/drivers/of/device.c
>> +++ b/drivers/of/device.c
>> @@ -286,3 +286,64 @@ int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
>>
>>       return 0;
>>  }
>> +
>> +/**
>> + * of_device_probe() - Probe device associated with OF node
>> + * @np: node to probe
>> + *
>> + * Probe the device associated with the passed device node.
>> + */
>> +void of_device_probe(struct device_node *np)
>
> Same question as from Greg: How does a subsystem know whether or not to use
> this function?

Maybe I don't understand the comment, but as the commit message says,
subsystems can use this when looking up resources for drivers. Or you
mean that this information should be in the API docs?

Thanks,

Tomeu

>> +{
>> +     struct device_node *target;
>> +     struct device *dev = NULL;
>> +
>> +     if (!of_root || !of_node_check_flag(of_root, OF_POPULATED_BUS))
>> +             return;
>> +
>> +     if (!np)
>> +             return;
>> +
>> +     of_node_get(np);
>> +
>> +     /* Find the closest ancestor that has a device associated */
>> +     for (target = np;
>> +          !of_node_is_root(target);
>> +          target = of_get_next_parent(target))
>> +             if (get_device(target->device)) {
>> +                     dev = target->device;
>> +                     break;
>> +             }
>> +
>> +     of_node_put(target);
>> +
>> +     if (!dev) {
>> +             pr_warn("Couldn't find a device for node '%s'\n",
>> +                     of_node_full_name(np));
>> +             return;
>> +     }
>> +
>> +     /*
>> +      * Device is bound or is being probed right now. If we have bad luck
>> +      * and the dependency isn't ready when it's needed, deferred probe
>> +      * will save us.
>> +      */
>> +     if (dev->driver)
>> +             goto out;
>> +
>> +     /*
>> +      * Probing a device should cause its descendants to be probed as
>> +      * well, which includes the passed device node.
>> +      */
>> +     if (device_attach(dev) != 1)
>> +             /*
>> +              * This cannot be a warning for now because clock nodes have a
>> +              * compatible string but the clock framework doesn't follow
>> +              * the device/driver model yet.
>> +              */
>> +             dev_dbg(dev, "Probe failed for %s\n", of_node_full_name(np));
>> +
>> +out:
>> +     put_device(dev);
>> +}
>> +EXPORT_SYMBOL_GPL(of_device_probe);
>> diff --git a/include/linux/of_device.h b/include/linux/of_device.h
>> index cc7dd687a89d..da8d489e73ad 100644
>> --- a/include/linux/of_device.h
>> +++ b/include/linux/of_device.h
>> @@ -40,6 +40,7 @@ extern ssize_t of_device_get_modalias(struct device *dev,
>>
>>  extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
>>  extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
>> +extern void of_device_probe(struct device_node *np);
>>
>>  static inline void of_device_node_put(struct device *dev)
>>  {
>> @@ -84,6 +85,8 @@ static inline int of_device_uevent_modalias(struct device *dev,
>>       return -ENODEV;
>>  }
>>
>> +static inline void of_device_probe(struct device_node *np) { }
>> +
>>  static inline void of_device_node_put(struct device *dev) { }
>>
>>  static inline const struct of_device_id *__of_match_device(
>>
>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
Mark Brown Oct. 22, 2015, 11:54 p.m. UTC | #3
On Thu, Oct 22, 2015 at 03:03:37PM +0200, Tomeu Vizoso wrote:
> On 22 October 2015 at 03:06, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:

> > Same question as from Greg: How does a subsystem know whether or not to use
> > this function?

> Maybe I don't understand the comment, but as the commit message says,
> subsystems can use this when looking up resources for drivers. Or you
> mean that this information should be in the API docs?

I'm pretty sure what he's suggesting here is changing to "should always"
(ie, explain the situations when a subsystem would do this, including
decision criteria if it's optional).
Rafael J. Wysocki Oct. 24, 2015, 1:55 p.m. UTC | #4
On Thursday, October 22, 2015 03:03:37 PM Tomeu Vizoso wrote:
> On 22 October 2015 at 03:06, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Monday, September 21, 2015 04:02:44 PM Tomeu Vizoso wrote:
> >> Walks the OF tree up and finds the closest ancestor that has a struct
> >> device associated with it, probing it if isn't bound to a driver yet.
> >>
> >> The above should ensure that the dependency represented by the passed OF
> >> node is available, because probing a device should cause its descendants
> >> to be probed as well (when they get registered).
> >>
> >> Subsystems can use this when looking up resources for drivers, to reduce
> >> the chances of deferred probes because of the probing order of devices.
> >>
> >> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
> >> ---
> >>
> >> Changes in v5:
> >> - Move the assignment to device_node->device for AMBA devices to another
> >>   commit.
> >> - Hold a reference to the struct device while it's in use in
> >>   of_device_probe().
> >>
> >> Changes in v4:
> >> - Rename of_platform_probe to of_device_probe
> >> - Use device_node.device instead of device_node.platform_dev
> >>
> >> Changes in v3:
> >> - Set and use device_node.platform_dev instead of reversing the logic to
> >>   find the platform device that encloses a device node.
> >> - Drop the fwnode API to probe firmware nodes and add OF-only API for
> >>   now. I think this same scheme could be used for machines with ACPI,
> >>   but I haven't been able to find one that had to defer its probes because
> >>   of the device probe order.
> >>
> >>  drivers/of/device.c       | 61 +++++++++++++++++++++++++++++++++++++++++++++++
> >>  include/linux/of_device.h |  3 +++
> >>  2 files changed, 64 insertions(+)
> >>
> >> diff --git a/drivers/of/device.c b/drivers/of/device.c
> >> index 8b91ea241b10..836be71fc90e 100644
> >> --- a/drivers/of/device.c
> >> +++ b/drivers/of/device.c
> >> @@ -286,3 +286,64 @@ int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
> >>
> >>       return 0;
> >>  }
> >> +
> >> +/**
> >> + * of_device_probe() - Probe device associated with OF node
> >> + * @np: node to probe
> >> + *
> >> + * Probe the device associated with the passed device node.
> >> + */
> >> +void of_device_probe(struct device_node *np)
> >
> > Same question as from Greg: How does a subsystem know whether or not to use
> > this function?
> 
> Maybe I don't understand the comment, but as the commit message says,
> subsystems can use this when looking up resources for drivers. Or you
> mean that this information should be in the API docs?

I'm not really sure this is the only case.

Most likely, you'd end up with that being called by every subsystem using DT
just in case.

And then each of those subsystems would need to call acpi_device_probe(), and
then another_platform_firmware_interface_device_probe() and so on.

Don't you see a problem here?

Thanks,
Rafael
Rafael J. Wysocki Oct. 24, 2015, 2:28 p.m. UTC | #5
On Friday, October 23, 2015 08:54:19 AM Mark Brown wrote:
> 
> --7cm2iqirTL37Ot+N
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
> 
> On Thu, Oct 22, 2015 at 03:03:37PM +0200, Tomeu Vizoso wrote:
> > On 22 October 2015 at 03:06, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> 
> > > Same question as from Greg: How does a subsystem know whether or not to use
> > > this function?
> 
> > Maybe I don't understand the comment, but as the commit message says,
> > subsystems can use this when looking up resources for drivers. Or you
> > mean that this information should be in the API docs?
> 
> I'm pretty sure what he's suggesting here is changing to "should always"
> (ie, explain the situations when a subsystem would do this, including
> decision criteria if it's optional).

Right.

Thanks,
Rafael
Rob Herring Oct. 24, 2015, 8:09 p.m. UTC | #6
On 10/24/2015 08:55 AM, Rafael J. Wysocki wrote:
> On Thursday, October 22, 2015 03:03:37 PM Tomeu Vizoso wrote:
>> On 22 October 2015 at 03:06, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>>> On Monday, September 21, 2015 04:02:44 PM Tomeu Vizoso wrote:
>>>> Walks the OF tree up and finds the closest ancestor that has a struct
>>>> device associated with it, probing it if isn't bound to a driver yet.
>>>>
>>>> The above should ensure that the dependency represented by the passed OF
>>>> node is available, because probing a device should cause its descendants
>>>> to be probed as well (when they get registered).
>>>>
>>>> Subsystems can use this when looking up resources for drivers, to reduce
>>>> the chances of deferred probes because of the probing order of devices.
>>>>
>>>> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
>>>> ---
>>>>
>>>> Changes in v5:
>>>> - Move the assignment to device_node->device for AMBA devices to another
>>>>   commit.
>>>> - Hold a reference to the struct device while it's in use in
>>>>   of_device_probe().
>>>>
>>>> Changes in v4:
>>>> - Rename of_platform_probe to of_device_probe
>>>> - Use device_node.device instead of device_node.platform_dev
>>>>
>>>> Changes in v3:
>>>> - Set and use device_node.platform_dev instead of reversing the logic to
>>>>   find the platform device that encloses a device node.
>>>> - Drop the fwnode API to probe firmware nodes and add OF-only API for
>>>>   now. I think this same scheme could be used for machines with ACPI,
>>>>   but I haven't been able to find one that had to defer its probes because
>>>>   of the device probe order.
>>>>
>>>>  drivers/of/device.c       | 61 +++++++++++++++++++++++++++++++++++++++++++++++
>>>>  include/linux/of_device.h |  3 +++
>>>>  2 files changed, 64 insertions(+)
>>>>
>>>> diff --git a/drivers/of/device.c b/drivers/of/device.c
>>>> index 8b91ea241b10..836be71fc90e 100644
>>>> --- a/drivers/of/device.c
>>>> +++ b/drivers/of/device.c
>>>> @@ -286,3 +286,64 @@ int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
>>>>
>>>>       return 0;
>>>>  }
>>>> +
>>>> +/**
>>>> + * of_device_probe() - Probe device associated with OF node
>>>> + * @np: node to probe
>>>> + *
>>>> + * Probe the device associated with the passed device node.
>>>> + */
>>>> +void of_device_probe(struct device_node *np)
>>>
>>> Same question as from Greg: How does a subsystem know whether or not to use
>>> this function?
>>
>> Maybe I don't understand the comment, but as the commit message says,
>> subsystems can use this when looking up resources for drivers. Or you
>> mean that this information should be in the API docs?
> 
> I'm not really sure this is the only case.
> 
> Most likely, you'd end up with that being called by every subsystem using DT
> just in case.

No, it is binding dependent. If a consumer is looking up the provider
from the binding, then yes it needs a call. There may be some cases
where it doesn't make sense. But that is why it is called from the
binding specific code.

> And then each of those subsystems would need to call acpi_device_probe(), and
> then another_platform_firmware_interface_device_probe() and so on.
> 
> Don't you see a problem here?

Only for the 3rd firmware interface. ;)

Let's get agreement on the flow and structure and how to address other
issues like suspend, then we can worry about whether this needs to be
abstracted from subsystems. We can discuss more this week at KS.

Rob
Mark Brown Oct. 26, 2015, 12:13 a.m. UTC | #7
On Sat, Oct 24, 2015 at 03:09:06PM -0500, Rob Herring wrote:

> Let's get agreement on the flow and structure and how to address other
> issues like suspend, then we can worry about whether this needs to be
> abstracted from subsystems. We can discuss more this week at KS.

Should we try to schedule an ad-hoc session today (Monday) for those of
us who are here to talk this over?
Dmitry Torokhov Oct. 26, 2015, 12:15 a.m. UTC | #8
On October 26, 2015 9:13:01 AM GMT+09:00, Mark Brown <broonie@kernel.org> wrote:
>On Sat, Oct 24, 2015 at 03:09:06PM -0500, Rob Herring wrote:
>
>> Let's get agreement on the flow and structure and how to address
>other
>> issues like suspend, then we can worry about whether this needs to be
>> abstracted from subsystems. We can discuss more this week at KS.
>
>Should we try to schedule an ad-hoc session today (Monday) for those of
>us who are here to talk this over?


That would be great.

Thanks.
Rafael J. Wysocki Oct. 26, 2015, 2:48 a.m. UTC | #9
On Mon, Oct 26, 2015 at 1:13 AM, Mark Brown <broonie@kernel.org> wrote:
> On Sat, Oct 24, 2015 at 03:09:06PM -0500, Rob Herring wrote:
>
>> Let's get agreement on the flow and structure and how to address other
>> issues like suspend, then we can worry about whether this needs to be
>> abstracted from subsystems. We can discuss more this week at KS.
>
> Should we try to schedule an ad-hoc session today (Monday) for those of
> us who are here to talk this over?

I won't mind doing that, what about after the Linus+Dirk session?

Thanks,
Rafael
Mark Brown Oct. 26, 2015, 3:09 a.m. UTC | #10
On Mon, Oct 26, 2015 at 03:48:44AM +0100, Rafael J. Wysocki wrote:
> On Mon, Oct 26, 2015 at 1:13 AM, Mark Brown <broonie@kernel.org> wrote:

> > Should we try to schedule an ad-hoc session today (Monday) for those of
> > us who are here to talk this over?

> I won't mind doing that, what about after the Linus+Dirk session?

It's looking hard to round people up...  I asked Ted for a slot
tomorrow, hopefully we can get one and if not it's probably going to be
easier to find everyone at once.
Geert Uytterhoeven Oct. 26, 2015, 8:16 a.m. UTC | #11
On Mon, Sep 21, 2015 at 4:02 PM, Tomeu Vizoso
<tomeu.vizoso@collabora.com> wrote:
> Walks the OF tree up and finds the closest ancestor that has a struct
> device associated with it, probing it if isn't bound to a driver yet.
>
> The above should ensure that the dependency represented by the passed OF
> node is available, because probing a device should cause its descendants
> to be probed as well (when they get registered).
>
> Subsystems can use this when looking up resources for drivers, to reduce
> the chances of deferred probes because of the probing order of devices.
>
> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>

Don't know to which response I should post this comment, so I'm responding
to the original email.

Some subsystems already do this.
If you call e.g. syscon_regmap_lookup_by_phandle(), it will call
of_syscon_register() if the syscon device pointed to hasn't been registered yet.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Tomeu Vizoso Oct. 27, 2015, 2:46 p.m. UTC | #12
On 26 October 2015 at 09:16, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Mon, Sep 21, 2015 at 4:02 PM, Tomeu Vizoso
> <tomeu.vizoso@collabora.com> wrote:
>> Walks the OF tree up and finds the closest ancestor that has a struct
>> device associated with it, probing it if isn't bound to a driver yet.
>>
>> The above should ensure that the dependency represented by the passed OF
>> node is available, because probing a device should cause its descendants
>> to be probed as well (when they get registered).
>>
>> Subsystems can use this when looking up resources for drivers, to reduce
>> the chances of deferred probes because of the probing order of devices.
>>
>> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
>
> Don't know to which response I should post this comment, so I'm responding
> to the original email.
>
> Some subsystems already do this.
> If you call e.g. syscon_regmap_lookup_by_phandle(), it will call
> of_syscon_register() if the syscon device pointed to hasn't been registered yet.

Hi Geert,

I think I prefer if devices are registered as early as possible and
then only probed on-demand, as registration is very much
device-specific but probing is the same for all devices.

But I think in general we should be doing more things on demand and
depending less on the order in which we mass initialize stuff
(devices, classes, drivers, etc).

Regards,

Tomeu

> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
diff mbox

Patch

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 8b91ea241b10..836be71fc90e 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -286,3 +286,64 @@  int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
 
 	return 0;
 }
+
+/**
+ * of_device_probe() - Probe device associated with OF node
+ * @np: node to probe
+ *
+ * Probe the device associated with the passed device node.
+ */
+void of_device_probe(struct device_node *np)
+{
+	struct device_node *target;
+	struct device *dev = NULL;
+
+	if (!of_root || !of_node_check_flag(of_root, OF_POPULATED_BUS))
+		return;
+
+	if (!np)
+		return;
+
+	of_node_get(np);
+
+	/* Find the closest ancestor that has a device associated */
+	for (target = np;
+	     !of_node_is_root(target);
+	     target = of_get_next_parent(target))
+		if (get_device(target->device)) {
+			dev = target->device;
+			break;
+		}
+
+	of_node_put(target);
+
+	if (!dev) {
+		pr_warn("Couldn't find a device for node '%s'\n",
+			of_node_full_name(np));
+		return;
+	}
+
+	/*
+	 * Device is bound or is being probed right now. If we have bad luck
+	 * and the dependency isn't ready when it's needed, deferred probe
+	 * will save us.
+	 */
+	if (dev->driver)
+		goto out;
+
+	/*
+	 * Probing a device should cause its descendants to be probed as
+	 * well, which includes the passed device node.
+	 */
+	if (device_attach(dev) != 1)
+		/*
+		 * This cannot be a warning for now because clock nodes have a
+		 * compatible string but the clock framework doesn't follow
+		 * the device/driver model yet.
+		 */
+		dev_dbg(dev, "Probe failed for %s\n", of_node_full_name(np));
+
+out:
+	put_device(dev);
+}
+EXPORT_SYMBOL_GPL(of_device_probe);
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index cc7dd687a89d..da8d489e73ad 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -40,6 +40,7 @@  extern ssize_t of_device_get_modalias(struct device *dev,
 
 extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
 extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
+extern void of_device_probe(struct device_node *np);
 
 static inline void of_device_node_put(struct device *dev)
 {
@@ -84,6 +85,8 @@  static inline int of_device_uevent_modalias(struct device *dev,
 	return -ENODEV;
 }
 
+static inline void of_device_probe(struct device_node *np) { }
+
 static inline void of_device_node_put(struct device *dev) { }
 
 static inline const struct of_device_id *__of_match_device(