diff options
Diffstat (limited to 'drivers/base/platform.c')
| -rw-r--r-- | drivers/base/platform.c | 518 | 
1 files changed, 224 insertions, 294 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f051cfff18a..eee48c49f5d 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -13,6 +13,7 @@  #include <linux/string.h>  #include <linux/platform_device.h>  #include <linux/of_device.h> +#include <linux/of_irq.h>  #include <linux/module.h>  #include <linux/init.h>  #include <linux/dma-mapping.h> @@ -20,11 +21,14 @@  #include <linux/err.h>  #include <linux/slab.h>  #include <linux/pm_runtime.h> +#include <linux/idr.h> +#include <linux/acpi.h>  #include "base.h" +#include "power/power.h" -#define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \ -				 driver)) +/* For automatically allocated device IDs */ +static DEFINE_IDA(platform_devid_ida);  struct device platform_bus = {  	.init_name	= "platform", @@ -32,6 +36,25 @@ struct device platform_bus = {  EXPORT_SYMBOL_GPL(platform_bus);  /** + * arch_setup_pdev_archdata - Allow manipulation of archdata before its used + * @pdev: platform device + * + * This is called before platform_device_add() such that any pdev_archdata may + * be setup before the platform_notifier is called.  So if a user needs to + * manipulate any relevant information in the pdev_archdata they can do: + * + *	platform_device_alloc() + *	... manipulate ... + *	platform_device_add() + * + * And if they don't care they can just call platform_device_register() and + * everything will just work out. + */ +void __weak arch_setup_pdev_archdata(struct platform_device *pdev) +{ +} + +/**   * platform_get_resource - get a resource for a device   * @dev: platform device   * @type: resource type @@ -59,9 +82,25 @@ EXPORT_SYMBOL_GPL(platform_get_resource);   */  int platform_get_irq(struct platform_device *dev, unsigned int num)  { -	struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); +#ifdef CONFIG_SPARC +	/* sparc does not have irqs represented as IORESOURCE_IRQ resources */ +	if (!dev || num >= dev->archdata.num_irqs) +		return -ENXIO; +	return dev->archdata.irqs[num]; +#else +	struct resource *r; +	if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) { +		int ret; + +		ret = of_irq_get(dev->dev.of_node, num); +		if (ret >= 0 || ret == -EPROBE_DEFER) +			return ret; +	} + +	r = platform_get_resource(dev, IORESOURCE_IRQ, num);  	return r ? r->start : -ENXIO; +#endif  }  EXPORT_SYMBOL_GPL(platform_get_irq); @@ -80,6 +119,9 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,  	for (i = 0; i < dev->num_resources; i++) {  		struct resource *r = &dev->resource[i]; +		if (unlikely(!r->name)) +			continue; +  		if (type == resource_type(r) && !strcmp(r->name, name))  			return r;  	} @@ -88,15 +130,23 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,  EXPORT_SYMBOL_GPL(platform_get_resource_byname);  /** - * platform_get_irq - get an IRQ for a device + * platform_get_irq_byname - get an IRQ for a device by name   * @dev: platform device   * @name: IRQ name   */  int platform_get_irq_byname(struct platform_device *dev, const char *name)  { -	struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, -							  name); +	struct resource *r; + +	if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) { +		int ret; +		ret = of_irq_get_byname(dev->dev.of_node, name); +		if (ret >= 0 || ret == -EPROBE_DEFER) +			return ret; +	} + +	r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);  	return r ? r->start : -ENXIO;  }  EXPORT_SYMBOL_GPL(platform_get_irq_byname); @@ -149,6 +199,7 @@ static void platform_device_release(struct device *dev)  	of_device_node_put(&pa->pdev.dev);  	kfree(pa->pdev.dev.platform_data); +	kfree(pa->pdev.mfd_cell);  	kfree(pa->pdev.resource);  	kfree(pa);  } @@ -172,6 +223,7 @@ struct platform_device *platform_device_alloc(const char *name, int id)  		pa->pdev.id = id;  		device_initialize(&pa->pdev.dev);  		pa->pdev.dev.release = platform_device_release; +		arch_setup_pdev_archdata(&pa->pdev);  	}  	return pa ? &pa->pdev : NULL; @@ -191,18 +243,18 @@ EXPORT_SYMBOL_GPL(platform_device_alloc);  int platform_device_add_resources(struct platform_device *pdev,  				  const struct resource *res, unsigned int num)  { -	struct resource *r; +	struct resource *r = NULL; -	if (!res) -		return 0; - -	r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); -	if (r) { -		pdev->resource = r; -		pdev->num_resources = num; -		return 0; +	if (res) { +		r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); +		if (!r) +			return -ENOMEM;  	} -	return -ENOMEM; + +	kfree(pdev->resource); +	pdev->resource = r; +	pdev->num_resources = num; +	return 0;  }  EXPORT_SYMBOL_GPL(platform_device_add_resources); @@ -219,17 +271,17 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources);  int platform_device_add_data(struct platform_device *pdev, const void *data,  			     size_t size)  { -	void *d; - -	if (!data) -		return 0; +	void *d = NULL; -	d = kmemdup(data, size, GFP_KERNEL); -	if (d) { -		pdev->dev.platform_data = d; -		return 0; +	if (data) { +		d = kmemdup(data, size, GFP_KERNEL); +		if (!d) +			return -ENOMEM;  	} -	return -ENOMEM; + +	kfree(pdev->dev.platform_data); +	pdev->dev.platform_data = d; +	return 0;  }  EXPORT_SYMBOL_GPL(platform_device_add_data); @@ -242,7 +294,7 @@ EXPORT_SYMBOL_GPL(platform_device_add_data);   */  int platform_device_add(struct platform_device *pdev)  { -	int i, ret = 0; +	int i, ret;  	if (!pdev)  		return -EINVAL; @@ -252,10 +304,27 @@ int platform_device_add(struct platform_device *pdev)  	pdev->dev.bus = &platform_bus_type; -	if (pdev->id != -1) +	switch (pdev->id) { +	default:  		dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id); -	else +		break; +	case PLATFORM_DEVID_NONE:  		dev_set_name(&pdev->dev, "%s", pdev->name); +		break; +	case PLATFORM_DEVID_AUTO: +		/* +		 * Automatically allocated device ID. We mark it as such so +		 * that we remember it must be freed, and we append a suffix +		 * to avoid namespace collision with explicit IDs. +		 */ +		ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL); +		if (ret < 0) +			goto err_out; +		pdev->id = ret; +		pdev->id_auto = true; +		dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id); +		break; +	}  	for (i = 0; i < pdev->num_resources; i++) {  		struct resource *p, *r = &pdev->resource[i]; @@ -272,9 +341,7 @@ int platform_device_add(struct platform_device *pdev)  		}  		if (p && insert_resource(p, r)) { -			printk(KERN_ERR -			       "%s: failed to claim resource %d\n", -			       dev_name(&pdev->dev), i); +			dev_err(&pdev->dev, "failed to claim resource %d\n", i);  			ret = -EBUSY;  			goto failed;  		} @@ -288,6 +355,11 @@ int platform_device_add(struct platform_device *pdev)  		return ret;   failed: +	if (pdev->id_auto) { +		ida_simple_remove(&platform_devid_ida, pdev->id); +		pdev->id = PLATFORM_DEVID_AUTO; +	} +  	while (--i >= 0) {  		struct resource *r = &pdev->resource[i];  		unsigned long type = resource_type(r); @@ -296,6 +368,7 @@ int platform_device_add(struct platform_device *pdev)  			release_resource(r);  	} + err_out:  	return ret;  }  EXPORT_SYMBOL_GPL(platform_device_add); @@ -315,6 +388,11 @@ void platform_device_del(struct platform_device *pdev)  	if (pdev) {  		device_del(&pdev->dev); +		if (pdev->id_auto) { +			ida_simple_remove(&platform_devid_ida, pdev->id); +			pdev->id = PLATFORM_DEVID_AUTO; +		} +  		for (i = 0; i < pdev->num_resources; i++) {  			struct resource *r = &pdev->resource[i];  			unsigned long type = resource_type(r); @@ -333,6 +411,7 @@ EXPORT_SYMBOL_GPL(platform_device_del);  int platform_device_register(struct platform_device *pdev)  {  	device_initialize(&pdev->dev); +	arch_setup_pdev_archdata(pdev);  	return platform_device_add(pdev);  }  EXPORT_SYMBOL_GPL(platform_device_register); @@ -353,59 +432,85 @@ void platform_device_unregister(struct platform_device *pdev)  EXPORT_SYMBOL_GPL(platform_device_unregister);  /** - * platform_device_register_resndata - add a platform-level device with + * platform_device_register_full - add a platform-level device with   * resources and platform-specific data   * - * @parent: parent device for the device we're adding - * @name: base name of the device we're adding - * @id: instance id - * @res: set of resources that needs to be allocated for the device - * @num: number of resources - * @data: platform specific data for this platform device - * @size: size of platform specific data + * @pdevinfo: data used to create device   *   * Returns &struct platform_device pointer on success, or ERR_PTR() on error.   */ -struct platform_device *__init_or_module platform_device_register_resndata( -		struct device *parent, -		const char *name, int id, -		const struct resource *res, unsigned int num, -		const void *data, size_t size) +struct platform_device *platform_device_register_full( +		const struct platform_device_info *pdevinfo)  {  	int ret = -ENOMEM;  	struct platform_device *pdev; -	pdev = platform_device_alloc(name, id); +	pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id);  	if (!pdev) -		goto err; - -	pdev->dev.parent = parent; +		goto err_alloc; + +	pdev->dev.parent = pdevinfo->parent; +	ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion); + +	if (pdevinfo->dma_mask) { +		/* +		 * This memory isn't freed when the device is put, +		 * I don't have a nice idea for that though.  Conceptually +		 * dma_mask in struct device should not be a pointer. +		 * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 +		 */ +		pdev->dev.dma_mask = +			kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); +		if (!pdev->dev.dma_mask) +			goto err; + +		*pdev->dev.dma_mask = pdevinfo->dma_mask; +		pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; +	} -	ret = platform_device_add_resources(pdev, res, num); +	ret = platform_device_add_resources(pdev, +			pdevinfo->res, pdevinfo->num_res);  	if (ret)  		goto err; -	ret = platform_device_add_data(pdev, data, size); +	ret = platform_device_add_data(pdev, +			pdevinfo->data, pdevinfo->size_data);  	if (ret)  		goto err;  	ret = platform_device_add(pdev);  	if (ret) {  err: +		ACPI_COMPANION_SET(&pdev->dev, NULL); +		kfree(pdev->dev.dma_mask); + +err_alloc:  		platform_device_put(pdev);  		return ERR_PTR(ret);  	}  	return pdev;  } -EXPORT_SYMBOL_GPL(platform_device_register_resndata); +EXPORT_SYMBOL_GPL(platform_device_register_full);  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; -	return drv->probe(dev); +	acpi_dev_pm_attach(_dev, true); + +	ret = drv->probe(dev); +	if (ret) +		acpi_dev_pm_detach(_dev, true); + +	if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { +		dev_warn(_dev, "probe deferral not supported\n"); +		ret = -ENXIO; +	} + +	return ret;  }  static int platform_drv_probe_fail(struct device *_dev) @@ -417,8 +522,12 @@ 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; -	return drv->remove(dev); +	ret = drv->remove(dev); +	acpi_dev_pm_detach(_dev, true); + +	return ret;  }  static void platform_drv_shutdown(struct device *_dev) @@ -427,14 +536,18 @@ static void platform_drv_shutdown(struct device *_dev)  	struct platform_device *dev = to_platform_device(_dev);  	drv->shutdown(dev); +	acpi_dev_pm_detach(_dev, true);  }  /** - * platform_driver_register - register a driver for platform-level devices + * __platform_driver_register - register a driver for platform-level devices   * @drv: platform driver structure + * @owner: owning module/driver   */ -int platform_driver_register(struct platform_driver *drv) +int __platform_driver_register(struct platform_driver *drv, +				struct module *owner)  { +	drv->driver.owner = owner;  	drv->driver.bus = &platform_bus_type;  	if (drv->probe)  		drv->driver.probe = platform_drv_probe; @@ -445,7 +558,7 @@ int platform_driver_register(struct platform_driver *drv)  	return driver_register(&drv->driver);  } -EXPORT_SYMBOL_GPL(platform_driver_register); +EXPORT_SYMBOL_GPL(__platform_driver_register);  /**   * platform_driver_unregister - unregister a driver for platform-level devices @@ -471,6 +584,8 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister);   * into system-on-chip processors, where the controller devices have been   * configured as part of board setup.   * + * Note that this is incompatible with deferred probing. + *   * Returns zero if the driver registered and bound to a device, else returns   * a negative error code and with the driver not registered.   */ @@ -479,6 +594,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,  {  	int retval, code; +	/* +	 * Prevent driver from requesting probe deferral to avoid further +	 * futile probe attempts. +	 */ +	drv->prevent_deferred_probe = true; +  	/* make sure driver won't have bind/unbind attributes */  	drv->driver.suppress_bind_attrs = true; @@ -571,15 +692,27 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,  			     char *buf)  {  	struct platform_device	*pdev = to_platform_device(dev); -	int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); +	int len; + +	len = of_device_get_modalias(dev, buf, PAGE_SIZE -1); +	if (len != -ENODEV) +		return len; + +	len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); +	if (len != -ENODEV) +		return len; + +	len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);  	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;  } +static DEVICE_ATTR_RO(modalias); -static struct device_attribute platform_dev_attrs[] = { -	__ATTR_RO(modalias), -	__ATTR_NULL, +static struct attribute *platform_dev_attrs[] = { +	&dev_attr_modalias.attr, +	NULL,  }; +ATTRIBUTE_GROUPS(platform_dev);  static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)  { @@ -587,12 +720,16 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)  	int rc;  	/* Some devices have extra OF data and an OF-style MODALIAS */ -	rc = of_device_uevent(dev,env); +	rc = of_device_uevent_modalias(dev, env); +	if (rc != -ENODEV) +		return rc; + +	rc = acpi_device_uevent_modalias(dev, env);  	if (rc != -ENODEV)  		return rc;  	add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, -		(pdev->id_entry) ? pdev->id_entry->name : pdev->name); +			pdev->name);  	return 0;  } @@ -632,6 +769,10 @@ static int platform_match(struct device *dev, struct device_driver *drv)  	if (of_driver_match_device(dev, drv))  		return 1; +	/* Then try ACPI style match */ +	if (acpi_driver_match_device(dev, drv)) +		return 1; +  	/* Then try to match against the id table */  	if (pdrv->id_table)  		return platform_match_id(pdrv->id_table, pdev) != NULL; @@ -666,35 +807,11 @@ static int platform_legacy_resume(struct device *dev)  	return ret;  } -static int platform_pm_prepare(struct device *dev) -{ -	struct device_driver *drv = dev->driver; -	int ret = 0; - -	if (drv && drv->pm && drv->pm->prepare) -		ret = drv->pm->prepare(dev); - -	return ret; -} - -static void platform_pm_complete(struct device *dev) -{ -	struct device_driver *drv = dev->driver; - -	if (drv && drv->pm && drv->pm->complete) -		drv->pm->complete(dev); -} - -#else /* !CONFIG_PM_SLEEP */ - -#define platform_pm_prepare		NULL -#define platform_pm_complete		NULL - -#endif /* !CONFIG_PM_SLEEP */ +#endif /* CONFIG_PM_SLEEP */  #ifdef CONFIG_SUSPEND -int __weak platform_pm_suspend(struct device *dev) +int platform_pm_suspend(struct device *dev)  {  	struct device_driver *drv = dev->driver;  	int ret = 0; @@ -712,23 +829,7 @@ int __weak platform_pm_suspend(struct device *dev)  	return ret;  } -int __weak platform_pm_suspend_noirq(struct device *dev) -{ -	struct device_driver *drv = dev->driver; -	int ret = 0; - -	if (!drv) -		return 0; - -	if (drv->pm) { -		if (drv->pm->suspend_noirq) -			ret = drv->pm->suspend_noirq(dev); -	} - -	return ret; -} - -int __weak platform_pm_resume(struct device *dev) +int platform_pm_resume(struct device *dev)  {  	struct device_driver *drv = dev->driver;  	int ret = 0; @@ -746,34 +847,11 @@ int __weak platform_pm_resume(struct device *dev)  	return ret;  } -int __weak platform_pm_resume_noirq(struct device *dev) -{ -	struct device_driver *drv = dev->driver; -	int ret = 0; - -	if (!drv) -		return 0; - -	if (drv->pm) { -		if (drv->pm->resume_noirq) -			ret = drv->pm->resume_noirq(dev); -	} - -	return ret; -} +#endif /* CONFIG_SUSPEND */ -#else /* !CONFIG_SUSPEND */ +#ifdef CONFIG_HIBERNATE_CALLBACKS -#define platform_pm_suspend		NULL -#define platform_pm_resume		NULL -#define platform_pm_suspend_noirq	NULL -#define platform_pm_resume_noirq	NULL - -#endif /* !CONFIG_SUSPEND */ - -#ifdef CONFIG_HIBERNATION - -static int platform_pm_freeze(struct device *dev) +int platform_pm_freeze(struct device *dev)  {  	struct device_driver *drv = dev->driver;  	int ret = 0; @@ -791,23 +869,7 @@ static int platform_pm_freeze(struct device *dev)  	return ret;  } -static int platform_pm_freeze_noirq(struct device *dev) -{ -	struct device_driver *drv = dev->driver; -	int ret = 0; - -	if (!drv) -		return 0; - -	if (drv->pm) { -		if (drv->pm->freeze_noirq) -			ret = drv->pm->freeze_noirq(dev); -	} - -	return ret; -} - -static int platform_pm_thaw(struct device *dev) +int platform_pm_thaw(struct device *dev)  {  	struct device_driver *drv = dev->driver;  	int ret = 0; @@ -825,23 +887,7 @@ static int platform_pm_thaw(struct device *dev)  	return ret;  } -static int platform_pm_thaw_noirq(struct device *dev) -{ -	struct device_driver *drv = dev->driver; -	int ret = 0; - -	if (!drv) -		return 0; - -	if (drv->pm) { -		if (drv->pm->thaw_noirq) -			ret = drv->pm->thaw_noirq(dev); -	} - -	return ret; -} - -static int platform_pm_poweroff(struct device *dev) +int platform_pm_poweroff(struct device *dev)  {  	struct device_driver *drv = dev->driver;  	int ret = 0; @@ -859,23 +905,7 @@ static int platform_pm_poweroff(struct device *dev)  	return ret;  } -static int platform_pm_poweroff_noirq(struct device *dev) -{ -	struct device_driver *drv = dev->driver; -	int ret = 0; - -	if (!drv) -		return 0; - -	if (drv->pm) { -		if (drv->pm->poweroff_noirq) -			ret = drv->pm->poweroff_noirq(dev); -	} - -	return ret; -} - -static int platform_pm_restore(struct device *dev) +int platform_pm_restore(struct device *dev)  {  	struct device_driver *drv = dev->driver;  	int ret = 0; @@ -893,124 +923,23 @@ static int platform_pm_restore(struct device *dev)  	return ret;  } -static int platform_pm_restore_noirq(struct device *dev) -{ -	struct device_driver *drv = dev->driver; -	int ret = 0; - -	if (!drv) -		return 0; - -	if (drv->pm) { -		if (drv->pm->restore_noirq) -			ret = drv->pm->restore_noirq(dev); -	} - -	return ret; -} - -#else /* !CONFIG_HIBERNATION */ - -#define platform_pm_freeze		NULL -#define platform_pm_thaw		NULL -#define platform_pm_poweroff		NULL -#define platform_pm_restore		NULL -#define platform_pm_freeze_noirq	NULL -#define platform_pm_thaw_noirq		NULL -#define platform_pm_poweroff_noirq	NULL -#define platform_pm_restore_noirq	NULL - -#endif /* !CONFIG_HIBERNATION */ - -#ifdef CONFIG_PM_RUNTIME - -int __weak platform_pm_runtime_suspend(struct device *dev) -{ -	return pm_generic_runtime_suspend(dev); -}; - -int __weak platform_pm_runtime_resume(struct device *dev) -{ -	return pm_generic_runtime_resume(dev); -}; - -int __weak platform_pm_runtime_idle(struct device *dev) -{ -	return pm_generic_runtime_idle(dev); -}; - -#else /* !CONFIG_PM_RUNTIME */ - -#define platform_pm_runtime_suspend NULL -#define platform_pm_runtime_resume NULL -#define platform_pm_runtime_idle NULL - -#endif /* !CONFIG_PM_RUNTIME */ +#endif /* CONFIG_HIBERNATE_CALLBACKS */  static const struct dev_pm_ops platform_dev_pm_ops = { -	.prepare = platform_pm_prepare, -	.complete = platform_pm_complete, -	.suspend = platform_pm_suspend, -	.resume = platform_pm_resume, -	.freeze = platform_pm_freeze, -	.thaw = platform_pm_thaw, -	.poweroff = platform_pm_poweroff, -	.restore = platform_pm_restore, -	.suspend_noirq = platform_pm_suspend_noirq, -	.resume_noirq = platform_pm_resume_noirq, -	.freeze_noirq = platform_pm_freeze_noirq, -	.thaw_noirq = platform_pm_thaw_noirq, -	.poweroff_noirq = platform_pm_poweroff_noirq, -	.restore_noirq = platform_pm_restore_noirq, -	.runtime_suspend = platform_pm_runtime_suspend, -	.runtime_resume = platform_pm_runtime_resume, -	.runtime_idle = platform_pm_runtime_idle, +	.runtime_suspend = pm_generic_runtime_suspend, +	.runtime_resume = pm_generic_runtime_resume, +	USE_PLATFORM_PM_SLEEP_OPS  };  struct bus_type platform_bus_type = {  	.name		= "platform", -	.dev_attrs	= platform_dev_attrs, +	.dev_groups	= platform_dev_groups,  	.match		= platform_match,  	.uevent		= platform_uevent,  	.pm		= &platform_dev_pm_ops,  };  EXPORT_SYMBOL_GPL(platform_bus_type); -/** - * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops - * - * This function can be used by platform code to get the current - * set of dev_pm_ops functions used by the platform_bus_type. - */ -const struct dev_pm_ops * __init platform_bus_get_pm_ops(void) -{ -	return platform_bus_type.pm; -} - -/** - * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type - * - * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type - * - * Platform code can override the dev_pm_ops methods of - * platform_bus_type by using this function.  It is expected that - * platform code will first do a platform_bus_get_pm_ops(), then - * kmemdup it, then customize selected methods and pass a pointer to - * the new struct dev_pm_ops to this function. - * - * Since platform-specific code is customizing methods for *all* - * devices (not just platform-specific devices) it is expected that - * any custom overrides of these functions will keep existing behavior - * and simply extend it.  For example, any customization of the - * runtime PM methods should continue to call the pm_generic_* - * functions as the default ones do in addition to the - * platform-specific behavior. - */ -void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm) -{ -	platform_bus_type.pm = pm; -} -  int __init platform_bus_init(void)  {  	int error; @@ -1125,6 +1054,7 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)  		dev = &devs[i]->dev;  		if (!dev->devres_head.next) { +			pm_runtime_early_init(dev);  			INIT_LIST_HEAD(&dev->devres_head);  			list_add_tail(&dev->devres_head,  				      &early_platform_device_list); @@ -1164,7 +1094,7 @@ void __init early_platform_driver_register_all(char *class_str)   * @epdrv: early platform driver structure   * @id: id to match against   */ -static  __init struct platform_device * +static struct platform_device * __init  early_platform_match(struct early_platform_driver *epdrv, int id)  {  	struct platform_device *pd; @@ -1182,7 +1112,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id)   * @epdrv: early platform driver structure   * @id: return true if id or above exists   */ -static  __init int early_platform_left(struct early_platform_driver *epdrv, +static int __init early_platform_left(struct early_platform_driver *epdrv,  				       int id)  {  	struct platform_device *pd; @@ -1237,8 +1167,8 @@ static int __init early_platform_driver_probe_id(char *class_str,  		switch (match_id) {  		case EARLY_PLATFORM_ID_ERROR: -			pr_warning("%s: unable to parse %s parameter\n", -				   class_str, epdrv->pdrv->driver.name); +			pr_warn("%s: unable to parse %s parameter\n", +				class_str, epdrv->pdrv->driver.name);  			/* fall-through */  		case EARLY_PLATFORM_ID_UNSET:  			match = NULL; @@ -1269,8 +1199,8 @@ static int __init early_platform_driver_probe_id(char *class_str,  			}  			if (epdrv->pdrv->probe(match)) -				pr_warning("%s: unable to probe %s early.\n", -					   class_str, match->name); +				pr_warn("%s: unable to probe %s early.\n", +					class_str, match->name);  			else  				n++;  		}  | 
