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:
Samuel Iglesias Gonsalvez 2013-03-08 09:21:47 +01:00 committed by Greg Kroah-Hartman
parent fa882867ae
commit e926301b39
3 changed files with 57 additions and 22 deletions

View File

@ -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,

View File

@ -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 @@ out:
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)
{

View File

@ -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);