mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-03 18:20:25 +02:00 
			
		
		
		
	ipack: split ipack_device_register() in several functions
One function is ipack_device_init(). If it fails, the caller should execute ipack_put_device(). The second function is ipack_device_add that only adds the device. If it fails, the caller should execute ipack_put_device(). Then the device is removed with refcount = 0, as device_register() kernel documentation says. ipack_device_del() is added to remove the device. Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									fa882867ae
								
							
						
					
					
						commit
						e926301b39
					
				
					 3 changed files with 57 additions and 22 deletions
				
			
		| 
						 | 
				
			
			@ -480,6 +480,7 @@ static void tpci200_release_device(struct ipack_device *dev)
 | 
			
		|||
 | 
			
		||||
static int tpci200_create_device(struct tpci200_board *tpci200, int i)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	enum ipack_space space;
 | 
			
		||||
	struct ipack_device *dev =
 | 
			
		||||
		kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
 | 
			
		||||
| 
						 | 
				
			
			@ -495,7 +496,18 @@ static int tpci200_create_device(struct tpci200_board *tpci200, int i)
 | 
			
		|||
			+ tpci200_space_interval[space] * i;
 | 
			
		||||
		dev->region[space].size = tpci200_space_size[space];
 | 
			
		||||
	}
 | 
			
		||||
	return ipack_device_register(dev);
 | 
			
		||||
 | 
			
		||||
	ret = ipack_device_init(dev);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		ipack_put_device(dev);
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = ipack_device_add(dev);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		ipack_put_device(dev);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int tpci200_pci_probe(struct pci_dev *pdev,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -227,7 +227,7 @@ static int ipack_unregister_bus_member(struct device *dev, void *data)
 | 
			
		|||
	struct ipack_bus_device *bus = data;
 | 
			
		||||
 | 
			
		||||
	if (idev->bus == bus)
 | 
			
		||||
		ipack_device_unregister(idev);
 | 
			
		||||
		ipack_device_del(idev);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -419,7 +419,7 @@ static int ipack_device_read_id(struct ipack_device *dev)
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ipack_device_register(struct ipack_device *dev)
 | 
			
		||||
int ipack_device_init(struct ipack_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -428,6 +428,7 @@ int ipack_device_register(struct ipack_device *dev)
 | 
			
		|||
	dev->dev.parent = dev->bus->parent;
 | 
			
		||||
	dev_set_name(&dev->dev,
 | 
			
		||||
		     "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot);
 | 
			
		||||
	device_initialize(&dev->dev);
 | 
			
		||||
 | 
			
		||||
	if (dev->bus->ops->set_clockrate(dev, 8))
 | 
			
		||||
		dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -447,19 +448,22 @@ int ipack_device_register(struct ipack_device *dev)
 | 
			
		|||
			dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = device_register(&dev->dev);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		kfree(dev->id);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(ipack_device_register);
 | 
			
		||||
EXPORT_SYMBOL_GPL(ipack_device_init);
 | 
			
		||||
 | 
			
		||||
void ipack_device_unregister(struct ipack_device *dev)
 | 
			
		||||
int ipack_device_add(struct ipack_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	device_unregister(&dev->dev);
 | 
			
		||||
	return device_add(&dev->dev);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(ipack_device_unregister);
 | 
			
		||||
EXPORT_SYMBOL_GPL(ipack_device_add);
 | 
			
		||||
 | 
			
		||||
void ipack_device_del(struct ipack_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	device_del(&dev->dev);
 | 
			
		||||
	ipack_put_device(dev);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(ipack_device_del);
 | 
			
		||||
 | 
			
		||||
void ipack_get_device(struct ipack_device *dev)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -207,19 +207,38 @@ int ipack_driver_register(struct ipack_driver *edrv, struct module *owner,
 | 
			
		|||
void ipack_driver_unregister(struct ipack_driver *edrv);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *	ipack_device_register -- register an IPack device with the kernel
 | 
			
		||||
 *	@dev: the new device to register.
 | 
			
		||||
 *	ipack_device_init -- initialize an IPack device
 | 
			
		||||
 * @dev: the new device to initialize.
 | 
			
		||||
 *
 | 
			
		||||
 *	Register a new IPack device ("module" in IndustryPack jargon). The call
 | 
			
		||||
 *	is done by the carrier driver.  The carrier should populate the fields
 | 
			
		||||
 *	bus and slot as well as the region array of @dev prior to calling this
 | 
			
		||||
 *	function.  The rest of the fields will be allocated and populated
 | 
			
		||||
 *	during registration.
 | 
			
		||||
 * Initialize a new IPack device ("module" in IndustryPack jargon). The call
 | 
			
		||||
 * is done by the carrier driver.  The carrier should populate the fields
 | 
			
		||||
 * bus and slot as well as the region array of @dev prior to calling this
 | 
			
		||||
 * function.  The rest of the fields will be allocated and populated
 | 
			
		||||
 * during initalization.
 | 
			
		||||
 *
 | 
			
		||||
 *	Return zero on success or error code on failure.
 | 
			
		||||
 * Return zero on success or error code on failure.
 | 
			
		||||
 *
 | 
			
		||||
 * NOTE: _Never_ directly free @dev after calling this function, even
 | 
			
		||||
 * if it returned an error! Always use ipack_put_device() to give up the
 | 
			
		||||
 * reference initialized in this function instead.
 | 
			
		||||
 */
 | 
			
		||||
int ipack_device_register(struct ipack_device *dev);
 | 
			
		||||
void ipack_device_unregister(struct ipack_device *dev);
 | 
			
		||||
int ipack_device_init(struct ipack_device *dev);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *	ipack_device_add -- Add an IPack device
 | 
			
		||||
 * @dev: the new device to add.
 | 
			
		||||
 *
 | 
			
		||||
 * Add a new IPack device. The call is done by the carrier driver
 | 
			
		||||
 * after calling ipack_device_init().
 | 
			
		||||
 *
 | 
			
		||||
 * Return zero on success or error code on failure.
 | 
			
		||||
 *
 | 
			
		||||
 * NOTE: _Never_ directly free @dev after calling this function, even
 | 
			
		||||
 * if it returned an error! Always use ipack_put_device() to give up the
 | 
			
		||||
 * reference initialized in this function instead.
 | 
			
		||||
 */
 | 
			
		||||
int ipack_device_add(struct ipack_device *dev);
 | 
			
		||||
void ipack_device_del(struct ipack_device *dev);
 | 
			
		||||
 | 
			
		||||
void ipack_get_device(struct ipack_device *dev);
 | 
			
		||||
void ipack_put_device(struct ipack_device *dev);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue