Staging: ipack: Make ipack_device_register() analogous to device_register().

ipack_device_register() is no longer creating the struct ipack_device
but only registering it.  Instead of releasing memory directly the new
ipack_device->release callback is called.

This is preparational work for later patches.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 2f48dd5..ee66129 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -640,6 +640,23 @@
 	return 0;
 }
 
+static void tpci200_release_device(struct ipack_device *dev)
+{
+	kfree(dev);
+}
+
+static int tpci200_create_device(struct tpci200_board *tpci200, int i)
+{
+	struct ipack_device *dev =
+		kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+	dev->slot = i;
+	dev->bus = tpci200->info->ipack_bus;
+	dev->release = tpci200_release_device;
+	return ipack_device_register(dev);
+}
+
 static int tpci200_pci_probe(struct pci_dev *pdev,
 			     const struct pci_device_id *id)
 {
@@ -715,7 +732,7 @@
 	dev_set_drvdata(&pdev->dev, tpci200);
 
 	for (i = 0; i < TPCI200_NB_SLOT; i++)
-		ipack_device_register(tpci200->info->ipack_bus, i);
+		tpci200_create_device(tpci200, i);
 	return 0;
 
 out_err_bus_register:
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index ca8cb327..d2ed9f5 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -24,7 +24,7 @@
 {
 	struct ipack_device *device = to_ipack_dev(dev);
 	kfree(device->id);
-	kfree(device);
+	device->release(device);
 }
 
 static inline const struct ipack_device_id *
@@ -426,51 +426,39 @@
 	return ret;
 }
 
-struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
-					   int slot)
+int ipack_device_register(struct ipack_device *dev)
 {
 	int ret;
-	struct ipack_device *dev;
-
-	dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
-	if (!dev)
-		return NULL;
 
 	dev->dev.bus = &ipack_bus_type;
 	dev->dev.release = ipack_device_release;
-	dev->dev.parent = bus->parent;
-	dev->slot = slot;
-	dev->bus = bus;
+	dev->dev.parent = dev->bus->parent;
 	dev_set_name(&dev->dev,
 		     "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot);
 
-	if (bus->ops->set_clockrate(dev, 8))
+	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");
-	if (bus->ops->reset_timeout(dev))
+	if (dev->bus->ops->reset_timeout(dev))
 		dev_warn(&dev->dev, "failed to reset potential timeout.");
 
 	ret = ipack_device_read_id(dev);
 	if (ret < 0) {
 		dev_err(&dev->dev, "error reading device id section.\n");
-		kfree(dev);
-		return NULL;
+		return ret;
 	}
 
 	/* if the device supports 32 MHz operation, use it. */
 	if (dev->speed_32mhz) {
-		ret = bus->ops->set_clockrate(dev, 32);
+		ret = dev->bus->ops->set_clockrate(dev, 32);
 		if (ret < 0)
 			dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n");
 	}
 
 	ret = device_register(&dev->dev);
-	if (ret < 0) {
+	if (ret < 0)
 		kfree(dev->id);
-		kfree(dev);
-		return NULL;
-	}
 
-	return dev;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(ipack_device_register);
 
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 33fdea5..e2987d5 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -71,6 +71,7 @@
 	struct ipack_addr_space int_space;
 	struct ipack_addr_space mem_space;
 	struct device dev;
+	void (*release) (struct ipack_device *dev);
 	u8                      *id;
 	size_t			 id_avail;
 	u32			 id_vendor;
@@ -179,15 +180,17 @@
 void ipack_driver_unregister(struct ipack_driver *edrv);
 
 /**
- *	ipack_device_register -- register a new mezzanine device
+ *	ipack_device_register -- register an IPack device with the kernel
+ *	@dev: the new device to register.
  *
- * @bus: ipack bus device it is plugged to.
- * @slot: slot position in the bus device.
+ *	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 of @dev prior to calling this function.  The rest of the
+ *	fields will be allocated and populated during registration.
  *
- * Register a new ipack device (mezzanine device). The call is done by
- * the carrier device driver.
+ *	Return zero on success or error code on failure.
  */
-struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot);
+int ipack_device_register(struct ipack_device *dev);
 void ipack_device_unregister(struct ipack_device *dev);
 
 /**