mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	driver core: platform: use bus_type functions
This works towards the goal mentioned in 2006 in commit 594c8281f9
("[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>
Link: https://lore.kernel.org/r/20201119124611.2573057-3-u.kleine-koenig@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									16085668ea
								
							
						
					
					
						commit
						9c30921fe7
					
				
					 1 changed files with 65 additions and 67 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue