Commit e926301b authored by Samuel Iglesias Gonsalvez's avatar Samuel Iglesias Gonsalvez Committed by Greg Kroah-Hartman
Browse files

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: default avatarSamuel Iglesias Gonsalvez <siglesias@igalia.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fa882867
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -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,
+14 −10
Original line number Diff line number Diff line
@@ -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 0;
}
EXPORT_SYMBOL_GPL(ipack_device_init);

	return ret;
int ipack_device_add(struct ipack_device *dev)
{
	return device_add(&dev->dev);
}
EXPORT_SYMBOL_GPL(ipack_device_register);
EXPORT_SYMBOL_GPL(ipack_device_add);

void ipack_device_unregister(struct ipack_device *dev)
void ipack_device_del(struct ipack_device *dev)
{
	device_unregister(&dev->dev);
	device_del(&dev->dev);
	ipack_put_device(dev);
}
EXPORT_SYMBOL_GPL(ipack_device_unregister);
EXPORT_SYMBOL_GPL(ipack_device_del);

void ipack_get_device(struct ipack_device *dev)
{
+29 −10
Original line number Diff line number Diff line
@@ -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
 * 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 registration.
 * during initalization.
 *
 * 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_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_register(struct ipack_device *dev);
void ipack_device_unregister(struct ipack_device *dev);
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);