mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-11 07:24:46 +00:00
common: Move autoprobe out to board init
Rather than doing autoprobe within the driver model code, move it out to the board-init code. This makes it clear that it is a separate step from binding devices. For now this is always done twice, before and after relocation, but we should discuss whether it might be possible to drop the post-relocation probe. For boards with SPL, the autoprobe is still done there as well. Note that with this change, autoprobe happens after the EVT_DM_POST_INIT_R/F events are sent, rather than before. Link: https://lore.kernel.org/u-boot/20240626235717.272219-1-marex@denx.de/ Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
21dd873572
commit
6995f2c8be
6 changed files with 62 additions and 2 deletions
|
@ -826,6 +826,10 @@ static int initf_dm(void)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = dm_autoprobe();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (IS_ENABLED(CONFIG_TIMER_EARLY)) {
|
||||
ret = dm_timer_init();
|
||||
if (ret)
|
||||
|
|
|
@ -250,7 +250,7 @@ static int initr_dm(void)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
return dm_autoprobe();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -500,6 +500,10 @@ static int spl_common_init(bool setup_malloc)
|
|||
debug("dm_init_and_scan() returned error %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dm_autoprobe();
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -842,6 +842,23 @@ steps (see device_probe()):
|
|||
cause the uclass to do some housekeeping to record the device as
|
||||
activated and 'known' by the uclass.
|
||||
|
||||
For some platforms, certain devices must be probed to get the platform into
|
||||
a working state. To help with this, drivers marked with DM_FLAG_PROBE_AFTER_BIND
|
||||
will be probed immediately after all devices are bound. For now, this happens in
|
||||
SPL, before relocation and after relocation. See the call to ``dm_autoprobe()``
|
||||
for where this is done.
|
||||
|
||||
The auto-probe feature is tricky because it bypasses the normal ordering of
|
||||
probing. General, if device A (e.g. video) needs device B (e.g. clock), then
|
||||
A's probe() method uses ``clk_get_by_index()`` and B is probed before A. But
|
||||
A is only probed when it is used. Therefore care should be taken when using
|
||||
auto-probe, limiting it to devices which truly are essential, such as power
|
||||
domains or critical clocks.
|
||||
|
||||
See here for more discussion of this feature:
|
||||
|
||||
:Link: https://patchwork.ozlabs.org/project/uboot/patch/20240626235717.272219-1-marex@denx.de/
|
||||
|
||||
Running stage
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -288,6 +288,15 @@ void *dm_priv_to_rw(void *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dm_probe_devices() - Check whether to probe a device and all children
|
||||
*
|
||||
* Probes the device if DM_FLAG_PROBE_AFTER_BIND is enabled for it. Then scans
|
||||
* all its children recursively to do the same.
|
||||
*
|
||||
* @dev: Device to (maybe) probe
|
||||
* Return 0 if OK, -ve on error
|
||||
*/
|
||||
static int dm_probe_devices(struct udevice *dev)
|
||||
{
|
||||
struct udevice *child;
|
||||
|
@ -306,6 +315,17 @@ static int dm_probe_devices(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int dm_autoprobe(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_probe_devices(gd->dm_root);
|
||||
if (ret)
|
||||
return log_msg_ret("pro", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_scan() - Scan tables to bind devices
|
||||
*
|
||||
|
@ -338,7 +358,7 @@ static int dm_scan(bool pre_reloc_only)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return dm_probe_devices(gd->dm_root);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_init_and_scan(bool pre_reloc_only)
|
||||
|
|
|
@ -136,6 +136,21 @@ int dm_scan_other(bool pre_reloc_only);
|
|||
*/
|
||||
int dm_init_and_scan(bool pre_reloc_only);
|
||||
|
||||
/**
|
||||
* dm_autoprobe() - Probe devices which are marked for probe-after-bind
|
||||
*
|
||||
* This probes all devices with a DM_FLAG_PROBE_AFTER_BIND flag. It checks the
|
||||
* entire tree, so parent nodes need not have the flag set.
|
||||
*
|
||||
* It recursively probes parent nodes, so they do not need to have the flag
|
||||
* set themselves. Since parents are always probed before children, if a child
|
||||
* has the flag set, then its parent (and any devices up the chain to the root
|
||||
* device) will be probed too.
|
||||
*
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_autoprobe(void);
|
||||
|
||||
/**
|
||||
* dm_init() - Initialise Driver Model structures
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue