diff options
Diffstat (limited to 'drivers/base/platform.c')
| -rw-r--r-- | drivers/base/platform.c | 50 | 
1 files changed, 31 insertions, 19 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index cd7157575e5..4573f5ec936 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -375,52 +375,64 @@ 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 *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( +		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; +		goto err_alloc; + +	pdev->dev.parent = pdevinfo->parent; -	pdev->dev.parent = parent; +	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; -	ret = platform_device_add_resources(pdev, res, num); +		*pdev->dev.dma_mask = pdevinfo->dma_mask; +		pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; +	} + +	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: +		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)  {  |