Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6adfd34e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge master.kernel.org:/home/rmk/linux-2.6-drvmodel

parents b54a063d 2c119aa8
Loading
Loading
Loading
Loading
+126 −27
Original line number Original line Diff line number Diff line
@@ -116,12 +116,115 @@ int platform_add_devices(struct platform_device **devs, int num)
	return ret;
	return ret;
}
}


struct platform_object {
	struct platform_device pdev;
	char name[1];
};

/**
/**
 *	platform_device_register - add a platform-level device
 *	platform_device_put
 *	@pdev:	platform device to free
 *
 *	Free all memory associated with a platform device.  This function
 *	must _only_ be externally called in error cases.  All other usage
 *	is a bug.
 */
void platform_device_put(struct platform_device *pdev)
{
	if (pdev)
		put_device(&pdev->dev);
}
EXPORT_SYMBOL_GPL(platform_device_put);

static void platform_device_release(struct device *dev)
{
	struct platform_object *pa = container_of(dev, struct platform_object, pdev.dev);

	kfree(pa->pdev.dev.platform_data);
	kfree(pa->pdev.resource);
	kfree(pa);
}

/**
 *	platform_device_alloc
 *	@name:	base name of the device we're adding
 *	@id:    instance id
 *
 *	Create a platform device object which can have other objects attached
 *	to it, and which will have attached objects freed when it is released.
 */
struct platform_device *platform_device_alloc(const char *name, unsigned int id)
{
	struct platform_object *pa;

	pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL);
	if (pa) {
		strcpy(pa->name, name);
		pa->pdev.name = pa->name;
		pa->pdev.id = id;
		device_initialize(&pa->pdev.dev);
		pa->pdev.dev.release = platform_device_release;
	}

	return pa ? &pa->pdev : NULL;	
}
EXPORT_SYMBOL_GPL(platform_device_alloc);

/**
 *	platform_device_add_resources
 *	@pdev:	platform device allocated by platform_device_alloc to add resources to
 *	@res:   set of resources that needs to be allocated for the device
 *	@num:	number of resources
 *
 *	Add a copy of the resources to the platform device.  The memory
 *	associated with the resources will be freed when the platform
 *	device is released.
 */
int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num)
{
	struct resource *r;

	r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL);
	if (r) {
		memcpy(r, res, sizeof(struct resource) * num);
		pdev->resource = r;
		pdev->num_resources = num;
	}
	return r ? 0 : -ENOMEM;
}
EXPORT_SYMBOL_GPL(platform_device_add_resources);

/**
 *	platform_device_add_data
 *	@pdev:	platform device allocated by platform_device_alloc to add resources to
 *	@data:	platform specific data for this platform device
 *	@size:	size of platform specific data
 *
 *	Add a copy of platform specific data to the platform device's platform_data
 *	pointer.  The memory associated with the platform data will be freed
 *	when the platform device is released.
 */
int platform_device_add_data(struct platform_device *pdev, void *data, size_t size)
{
	void *d;

	d = kmalloc(size, GFP_KERNEL);
	if (d) {
		memcpy(d, data, size);
		pdev->dev.platform_data = d;
	}
	return d ? 0 : -ENOMEM;
}
EXPORT_SYMBOL_GPL(platform_device_add_data);

/**
 *	platform_device_add - add a platform device to device hierarchy
 *	@pdev:	platform device we're adding
 *	@pdev:	platform device we're adding
 *
 *
 *	This is part 2 of platform_device_register(), though may be called
 *	separately _iff_ pdev was allocated by platform_device_alloc().
 */
 */
int platform_device_register(struct platform_device * pdev)
int platform_device_add(struct platform_device *pdev)
{
{
	int i, ret = 0;
	int i, ret = 0;


@@ -174,6 +277,18 @@ int platform_device_register(struct platform_device * pdev)
			release_resource(&pdev->resource[i]);
			release_resource(&pdev->resource[i]);
	return ret;
	return ret;
}
}
EXPORT_SYMBOL_GPL(platform_device_add);

/**
 *	platform_device_register - add a platform-level device
 *	@pdev:	platform device we're adding
 *
 */
int platform_device_register(struct platform_device * pdev)
{
	device_initialize(&pdev->dev);
	return platform_device_add(pdev);
}


/**
/**
 *	platform_device_unregister - remove a platform-level device
 *	platform_device_unregister - remove a platform-level device
@@ -197,18 +312,6 @@ void platform_device_unregister(struct platform_device * pdev)
	}
	}
}
}


struct platform_object {
        struct platform_device pdev;
        struct resource resources[0];
};

static void platform_device_release_simple(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);

	kfree(container_of(pdev, struct platform_object, pdev));
}

/**
/**
 *	platform_device_register_simple
 *	platform_device_register_simple
 *	@name:  base name of the device we're adding
 *	@name:  base name of the device we're adding
@@ -225,33 +328,29 @@ static void platform_device_release_simple(struct device *dev)
struct platform_device *platform_device_register_simple(char *name, unsigned int id,
struct platform_device *platform_device_register_simple(char *name, unsigned int id,
							struct resource *res, unsigned int num)
							struct resource *res, unsigned int num)
{
{
	struct platform_object *pobj;
	struct platform_device *pdev;
	int retval;
	int retval;


	pobj = kzalloc(sizeof(*pobj) + sizeof(struct resource) * num, GFP_KERNEL);
	pdev = platform_device_alloc(name, id);
	if (!pobj) {
	if (!pdev) {
		retval = -ENOMEM;
		retval = -ENOMEM;
		goto error;
		goto error;
	}
	}


	pobj->pdev.name = name;
	pobj->pdev.id = id;
	pobj->pdev.dev.release = platform_device_release_simple;

	if (num) {
	if (num) {
		memcpy(pobj->resources, res, sizeof(struct resource) * num);
		retval = platform_device_add_resources(pdev, res, num);
		pobj->pdev.resource = pobj->resources;
		if (retval)
		pobj->pdev.num_resources = num;
			goto error;
	}
	}


	retval = platform_device_register(&pobj->pdev);
	retval = platform_device_add(pdev);
	if (retval)
	if (retval)
		goto error;
		goto error;


	return &pobj->pdev;
	return pdev;


error:
error:
	kfree(pobj);
	platform_device_put(pdev);
	return ERR_PTR(retval);
	return ERR_PTR(retval);
}
}


+7 −17
Original line number Original line Diff line number Diff line
@@ -1470,15 +1470,6 @@ static int __init depca_mca_probe(struct device *device)
** ISA bus I/O device probe
** ISA bus I/O device probe
*/
*/


static void depca_platform_release (struct device *device)
{
	struct platform_device *pldev;

	/* free device */
	pldev = to_platform_device (device);
	kfree (pldev);
}

static void __init depca_platform_probe (void)
static void __init depca_platform_probe (void)
{
{
	int i;
	int i;
@@ -1492,18 +1483,15 @@ static void __init depca_platform_probe (void)
		if (io && io != depca_io_ports[i].iobase)
		if (io && io != depca_io_ports[i].iobase)
			continue;
			continue;


		if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
		pldev = platform_device_alloc(depca_string, i);
		if (!pldev)
			continue;
			continue;


		memset (pldev, 0, sizeof (*pldev));
		pldev->name = depca_string;
		pldev->id   = i;
		pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
		pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
		pldev->dev.release       = depca_platform_release;
		depca_io_ports[i].device = pldev;
		depca_io_ports[i].device = pldev;


		if (platform_device_register (pldev)) {
		if (platform_device_add(pldev)) {
			kfree (pldev);
			platform_device_put(pldev);
			depca_io_ports[i].device = NULL;
			depca_io_ports[i].device = NULL;
			continue;
			continue;
		}
		}
@@ -1515,6 +1503,7 @@ static void __init depca_platform_probe (void)
		 * allocated structure */
		 * allocated structure */
			
			
			depca_io_ports[i].device = NULL;
			depca_io_ports[i].device = NULL;
			pldev->dev.platform_data = NULL;
			platform_device_unregister (pldev);
			platform_device_unregister (pldev);
		}
		}
	}
	}
@@ -2112,6 +2101,7 @@ static void __exit depca_module_exit (void)


	for (i = 0; depca_io_ports[i].iobase; i++) {
	for (i = 0; depca_io_ports[i].iobase; i++) {
		if (depca_io_ports[i].device) {
		if (depca_io_ports[i].device) {
			depca_io_ports[i].device->dev.platform_data = NULL;
			platform_device_unregister (depca_io_ports[i].device);
			platform_device_unregister (depca_io_ports[i].device);
			depca_io_ports[i].device = NULL;
			depca_io_ports[i].device = NULL;
		}
		}
+5 −23
Original line number Original line Diff line number Diff line
@@ -285,18 +285,8 @@ static struct device_driver jazz_sonic_driver = {
	.remove	= __devexit_p(jazz_sonic_device_remove),
	.remove	= __devexit_p(jazz_sonic_device_remove),
};
};


static void jazz_sonic_platform_release (struct device *device)
{
	struct platform_device *pldev;

	/* free device */
	pldev = to_platform_device (device);
	kfree (pldev);
}

static int __init jazz_sonic_init_module(void)
static int __init jazz_sonic_init_module(void)
{
{
	struct platform_device *pldev;
	int err;
	int err;


	if ((err = driver_register(&jazz_sonic_driver))) {
	if ((err = driver_register(&jazz_sonic_driver))) {
@@ -304,27 +294,19 @@ static int __init jazz_sonic_init_module(void)
		return err;
		return err;
	}
	}


	jazz_sonic_device = NULL;
	jazz_sonic_device = platform_device_alloc(jazz_sonic_string, 0);

	if (!jazz_sonnic_device)
	if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
		goto out_unregister;
		goto out_unregister;
	}


	memset(pldev, 0, sizeof (*pldev));
	if (platform_device_add(jazz_sonic_device)) {
	pldev->name		= jazz_sonic_string;
		platform_device_put(jazz_sonic_device);
	pldev->id		= 0;
	pldev->dev.release	= jazz_sonic_platform_release;
	jazz_sonic_device	= pldev;

	if (platform_device_register (pldev)) {
		kfree(pldev);
		jazz_sonic_device = NULL;
		jazz_sonic_device = NULL;
	}
	}


	return 0;
	return 0;


out_unregister:
out_unregister:
	platform_device_unregister(pldev);
	driver_unregister(&jazz_sonic_driver);


	return -ENOMEM;
	return -ENOMEM;
}
}
+5 −22
Original line number Original line Diff line number Diff line
@@ -599,18 +599,8 @@ static struct device_driver mac_sonic_driver = {
	.remove = __devexit_p(mac_sonic_device_remove),
	.remove = __devexit_p(mac_sonic_device_remove),
};
};


static void mac_sonic_platform_release(struct device *device)
{
	struct platform_device *pldev;

	/* free device */
	pldev = to_platform_device (device);
	kfree (pldev);
}

static int __init mac_sonic_init_module(void)
static int __init mac_sonic_init_module(void)
{
{
	struct platform_device *pldev;
	int err;
	int err;


	if ((err = driver_register(&mac_sonic_driver))) {
	if ((err = driver_register(&mac_sonic_driver))) {
@@ -618,27 +608,20 @@ static int __init mac_sonic_init_module(void)
		return err;
		return err;
	}
	}


	mac_sonic_device = NULL;
	mac_sonic_device = platform_device_alloc(mac_sonic_string, 0);

	if (!mac_sonic_device) {
	if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
		goto out_unregister;
		goto out_unregister;
	}
	}


	memset(pldev, 0, sizeof (*pldev));
	if (platform_device_add(mac_sonic_device)) {
	pldev->name		= mac_sonic_string;
		platform_device_put(mac_sonic_device);
	pldev->id		= 0;
	pldev->dev.release	= mac_sonic_platform_release;
	mac_sonic_device	= pldev;

	if (platform_device_register (pldev)) {
		kfree(pldev);
		mac_sonic_device = NULL;
		mac_sonic_device = NULL;
	}
	}


	return 0;
	return 0;


out_unregister:
out_unregister:
	platform_device_unregister(pldev);
	driver_unregister(&mac_sonic_driver);


	return -ENOMEM;
	return -ENOMEM;
}
}
+11 −14
Original line number Original line Diff line number Diff line
@@ -502,10 +502,6 @@ static ssize_t arcfb_write(struct file *file, const char *buf, size_t count,
	return err;
	return err;
}
}


static void arcfb_platform_release(struct device *device)
{
}

static struct fb_ops arcfb_ops = {
static struct fb_ops arcfb_ops = {
	.owner		= THIS_MODULE,
	.owner		= THIS_MODULE,
	.fb_open	= arcfb_open,
	.fb_open	= arcfb_open,
@@ -624,13 +620,7 @@ static struct device_driver arcfb_driver = {
	.remove = arcfb_remove,
	.remove = arcfb_remove,
};
};


static struct platform_device arcfb_device = {
static struct platform_device *arcfb_device;
	.name	= "arcfb",
	.id	= 0,
	.dev	= {
		.release = arcfb_platform_release,
	}
};


static int __init arcfb_init(void)
static int __init arcfb_init(void)
{
{
@@ -641,17 +631,24 @@ static int __init arcfb_init(void)


	ret = driver_register(&arcfb_driver);
	ret = driver_register(&arcfb_driver);
	if (!ret) {
	if (!ret) {
		ret = platform_device_register(&arcfb_device);
		arcfb_device = platform_device_alloc("arcfb", 0);
		if (ret)
		if (arcfb_device) {
			ret = platform_device_add(arcfb_device);
		} else {
			ret = -ENOMEM;
		}
		if (ret) {
			platform_device_put(arcfb_device);
			driver_unregister(&arcfb_driver);
			driver_unregister(&arcfb_driver);
		}
		}
	}
	return ret;
	return ret;


}
}


static void __exit arcfb_exit(void)
static void __exit arcfb_exit(void)
{
{
	platform_device_unregister(&arcfb_device);
	platform_device_unregister(arcfb_device);
	driver_unregister(&arcfb_driver);
	driver_unregister(&arcfb_driver);
}
}


Loading