Messages in this thread Patch in this message | | | Subject | Re: [PATCH 3/3] driver core: platform: use bus_type functions | From | Marek Szyprowski <> | Date | Fri, 11 Dec 2020 17:12:16 +0100 |
| |
Hi Uwe,
On 19.11.2020 13:46, Uwe Kleine-König wrote: > This works towards the goal mentioned in 2006 in commit 594c8281f905 > ("[PATCH] Add bus_type probe, remove, shutdown methods."). > > The functions are moved to where the other bus_type functions are > defined and renamed to match the already established naming scheme. > > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> > --- > drivers/base/platform.c | 132 ++++++++++++++++++++-------------------- > 1 file changed, 65 insertions(+), 67 deletions(-) > > diff --git a/drivers/base/platform.c b/drivers/base/platform.c > index b847f5f8f992..8ad06daa2eaa 100644 > --- a/drivers/base/platform.c > +++ b/drivers/base/platform.c > @@ -743,70 +743,6 @@ struct platform_device *platform_device_register_full( > } > EXPORT_SYMBOL_GPL(platform_device_register_full); > > -static int platform_probe_fail(struct platform_device *pdev); > - > -static int platform_drv_probe(struct device *_dev) > -{ > - struct platform_driver *drv = to_platform_driver(_dev->driver); > - struct platform_device *dev = to_platform_device(_dev); > - int ret; > - > - /* > - * A driver registered using platform_driver_probe() cannot be bound > - * again later because the probe function usually lives in __init code > - * and so is gone. For these drivers .probe is set to > - * platform_probe_fail in __platform_driver_probe(). Don't even > - * prepare clocks and PM domains for these to match the traditional > - * behaviour. > - */ > - if (unlikely(drv->probe == platform_probe_fail)) > - return -ENXIO; > - > - ret = of_clk_set_defaults(_dev->of_node, false); > - if (ret < 0) > - return ret; > - > - ret = dev_pm_domain_attach(_dev, true); > - if (ret) > - goto out; > - > - if (drv->probe) { > - ret = drv->probe(dev); > - if (ret) > - dev_pm_domain_detach(_dev, true); > - } > - > -out: > - if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { > - dev_warn(_dev, "probe deferral not supported\n"); > - ret = -ENXIO; > - } > - > - return ret; > -} > - > -static int platform_drv_remove(struct device *_dev) > -{ > - struct platform_driver *drv = to_platform_driver(_dev->driver); > - struct platform_device *dev = to_platform_device(_dev); > - int ret = 0; > - > - if (drv->remove) > - ret = drv->remove(dev); > - dev_pm_domain_detach(_dev, true); > - > - return ret; > -} > - > -static void platform_drv_shutdown(struct device *_dev) > -{ > - struct platform_driver *drv = to_platform_driver(_dev->driver); > - struct platform_device *dev = to_platform_device(_dev); > - > - if (drv->shutdown) > - drv->shutdown(dev); > -} > - > /** > * __platform_driver_register - register a driver for platform-level devices > * @drv: platform driver structure > @@ -817,9 +753,6 @@ int __platform_driver_register(struct platform_driver *drv, > { > drv->driver.owner = owner; > drv->driver.bus = &platform_bus_type; > - drv->driver.probe = platform_drv_probe; > - drv->driver.remove = platform_drv_remove; > - drv->driver.shutdown = platform_drv_shutdown; > > return driver_register(&drv->driver); > } > @@ -1349,6 +1282,68 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) > return 0; > } > > +static int platform_probe(struct device *_dev) > +{ > + struct platform_driver *drv = to_platform_driver(_dev->driver); > + struct platform_device *dev = to_platform_device(_dev); > + int ret; > + > + /* > + * A driver registered using platform_driver_probe() cannot be bound > + * again later because the probe function usually lives in __init code > + * and so is gone. For these drivers .probe is set to > + * platform_probe_fail in __platform_driver_probe(). Don't even prepare > + * clocks and PM domains for these to match the traditional behaviour. > + */ > + if (unlikely(drv->probe == platform_probe_fail)) > + return -ENXIO; > + > + ret = of_clk_set_defaults(_dev->of_node, false); > + if (ret < 0) > + return ret; > + > + ret = dev_pm_domain_attach(_dev, true); > + if (ret) > + goto out; > + > + if (drv->probe) { > + ret = drv->probe(dev); > + if (ret) > + dev_pm_domain_detach(_dev, true); > + } > + > +out: > + if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { > + dev_warn(_dev, "probe deferral not supported\n"); > + ret = -ENXIO; > + } > + > + return ret; > +} > + > +static int platform_remove(struct device *_dev) > +{ > + struct platform_driver *drv = to_platform_driver(_dev->driver); > + struct platform_device *dev = to_platform_device(_dev); > + int ret = 0; > + > + if (drv->remove) > + ret = drv->remove(dev); > + dev_pm_domain_detach(_dev, true); > + > + return ret; > +} > + > +static void platform_shutdown(struct device *_dev) > +{ > + struct platform_driver *drv = to_platform_driver(_dev->driver); > + struct platform_device *dev = to_platform_device(_dev); > + > + if (drv->shutdown) > + drv->shutdown(dev); > +}
This will be called on unbound devices, what causes crash (observed on today's linux-next):
Will now restart. 8<--- cut here --- Unable to handle kernel paging request at virtual address fffffff4 pgd = 289f4b67 [fffffff4] *pgd=6ffff841, *pte=00000000, *ppte=00000000 Internal error: Oops: 27 [#1] SMP ARM Modules linked in: usb_f_ecm g_ether usb_f_rndis u_ether libcomposite brcmfmac sha256_generic libsha256 sha256_arm cfg80211 brcmutil panel_samsung_s6e8aa0 s5p_csi CPU: 0 PID: 1715 Comm: reboot Not tainted 5.10.0-rc7-next-20201211-00069-g1e8aa883315f #9935 Hardware name: Samsung Exynos (Flattened Device Tree) PC is at platform_shutdown+0x8/0x18 LR is at device_shutdown+0x18c/0x25c ... Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c5387d Table: 4348404a DAC: 00000051 Process reboot (pid: 1715, stack limit = 0xd050391e) Stack: (0xc3405e60 to 0xc3406000) [<c0a38bfc>] (platform_shutdown) from [<c0a34f78>] (device_shutdown+0x18c/0x25c) [<c0a34f78>] (device_shutdown) from [<c036d3cc>] (kernel_restart+0xc/0x68) [<c036d3cc>] (kernel_restart) from [<c036d680>] (__do_sys_reboot+0x154/0x1f0) [<c036d680>] (__do_sys_reboot) from [<c03000c0>] (ret_fast_syscall+0x0/0x58) Exception stack(0xc3405fa8 to 0xc3405ff0) ... ---[ end trace f39e94d5d6fd45bf ]---
> + > + > int platform_dma_configure(struct device *dev) > { > enum dev_dma_attr attr; > @@ -1375,6 +1370,9 @@ struct bus_type platform_bus_type = { > .dev_groups = platform_dev_groups, > .match = platform_match, > .uevent = platform_uevent, > + .probe = platform_probe, > + .remove = platform_remove, > + .shutdown = platform_shutdown, > .dma_configure = platform_dma_configure, > .pm = &platform_dev_pm_ops, > };
Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland
| |