ide: add ide_host_add() helper

Add ide_host_add() helper which does ide_host_alloc()+ide_host_register(),
then convert ide_setup_pci_device[s](), ide_legacy_device_add() and some
host drivers to use it.

While at it:

* Fix ide_setup_pci_device[s](), ide_arm.c, gayle.c, ide-4drives.c,
  macide.c, q40ide.c, cmd640.c and cs5520.c to return correct error value.

* -ENOENT -> -ENOMEM in rapide.c, ide-h8300.c, ide-generic.c, au1xxx-ide.c
  and pmac.c

* -ENODEV -> -ENOMEM in palm_bk3710.c, ide_platform.c and delkin_cb.c

* -1 -> -ENOMEM in ide-pnp.c

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
index 9efd7a8..176532f 100644
--- a/drivers/ide/arm/ide_arm.c
+++ b/drivers/ide/arm/ide_arm.c
@@ -28,7 +28,6 @@
 
 static int __init ide_arm_init(void)
 {
-	struct ide_host *host;
 	unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206;
 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
@@ -50,11 +49,7 @@
 	hw.irq = IDE_ARM_IRQ;
 	hw.chipset = ide_generic;
 
-	host = ide_host_alloc(NULL, hws);
-	if (host)
-		ide_host_register(host, NULL, hws);
-
-	return 0;
+	return ide_host_add(NULL, hws, NULL);
 }
 
 module_init(ide_arm_init);
diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c
index 24389a5..65bb4b8 100644
--- a/drivers/ide/arm/palm_bk3710.c
+++ b/drivers/ide/arm/palm_bk3710.c
@@ -349,7 +349,7 @@
 	struct resource *mem, *irq;
 	struct ide_host *host;
 	unsigned long base, rate;
-	int i;
+	int i, rc;
 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
 	clk = clk_get(NULL, "IDECLK");
@@ -392,16 +392,14 @@
 	hw.irq = irq->start;
 	hw.chipset = ide_palm3710;
 
-	host = ide_host_alloc(&palm_bk3710_port_info, hws);
-	if (host == NULL)
+	rc = ide_host_add(&palm_bk3710_port_info, hws, NULL);
+	if (rc)
 		goto out;
 
-	ide_host_register(host, &palm_bk3710_port_info, hws);
-
 	return 0;
 out:
 	printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n");
-	return -ENODEV;
+	return rc;
 }
 
 /* work with hotplug and coldplug */
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index 11f3307..2bdd8b7 100644
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -52,13 +52,9 @@
 	hw.chipset = ide_generic;
 	hw.dev = &ec->dev;
 
-	host = ide_host_alloc(&rapide_port_info, hws);
-	if (host == NULL) {
-		ret = -ENOENT;
+	ret = ide_host_add(&rapide_port_info, hws, &host);
+	if (ret)
 		goto release;
-	}
-
-	ide_host_register(host, &rapide_port_info, hws);
 
 	ecard_set_drvdata(ec, host);
 	goto out;
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index 15f7669..bde7a58 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -191,7 +191,6 @@
 
 static int __init h8300_ide_init(void)
 {
-	struct ide_host *host;
 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
 	printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n");
@@ -205,13 +204,7 @@
 
 	hw_setup(&hw);
 
-	host = ide_host_alloc(&h8300_port_info, hws);
-	if (host == NULL)
-		return -ENOENT;
-
-	ide_host_register(host, &h8300_port_info, hws);
-
-	return 0;
+	return ide_host_add(&h8300_port_info, hws, NULL);
 
 out_busy:
 	printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n");
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index e881836..a7082c2 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -28,9 +28,8 @@
 
 static ssize_t store_add(struct class *cls, const char *buf, size_t n)
 {
-	struct ide_host *host;
 	unsigned int base, ctl;
-	int irq;
+	int irq, rc;
 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
 	if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
@@ -41,11 +40,9 @@
 	hw.irq = irq;
 	hw.chipset = ide_generic;
 
-	host = ide_host_alloc(NULL, hws);
-	if (host == NULL)
-		return -ENOENT;
-
-	ide_host_register(host, NULL, hws);
+	rc = ide_host_add(NULL, hws, NULL);
+	if (rc)
+		return rc;
 
 	return n;
 };
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index 4458ca6..bac9b39 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -31,6 +31,7 @@
 {
 	struct ide_host *host;
 	unsigned long base, ctl;
+	int rc;
 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
 	printk(KERN_INFO DRV_NAME ": generic PnP IDE interface\n");
@@ -59,19 +60,18 @@
 	hw.irq = pnp_irq(dev, 0);
 	hw.chipset = ide_generic;
 
-	host = ide_host_alloc(NULL, hws);
-	if (host) {
-		pnp_set_drvdata(dev, host);
+	rc = ide_host_add(NULL, hws, &host);
+	if (rc)
+		goto out;
 
-		ide_host_register(host, NULL, hws);
+	pnp_set_drvdata(dev, host);
 
-		return 0;
-	}
-
+	return 0;
+out:
 	release_region(ctl, 1);
 	release_region(base, 8);
 
-	return -1;
+	return rc;
 }
 
 static void idepnp_remove(struct pnp_dev *dev)
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 84a8956..17a104b 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1677,6 +1677,24 @@
 }
 EXPORT_SYMBOL_GPL(ide_host_register);
 
+int ide_host_add(const struct ide_port_info *d, hw_regs_t **hws,
+		 struct ide_host **hostp)
+{
+	struct ide_host *host;
+
+	host = ide_host_alloc(d, hws);
+	if (host == NULL)
+		return -ENOMEM;
+
+	ide_host_register(host, d, hws);
+
+	if (hostp)
+		*hostp = host;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ide_host_add);
+
 void ide_host_remove(struct ide_host *host)
 {
 	int i;
@@ -1749,7 +1767,6 @@
 
 int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config)
 {
-	struct ide_host *host;
 	hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL };
 
 	memset(&hw, 0, sizeof(hw));
@@ -1762,12 +1779,6 @@
 	    (d->host_flags & IDE_HFLAG_SINGLE))
 		return -ENOENT;
 
-	host = ide_host_alloc(d, hws);
-	if (host == NULL)
-		return -ENOMEM;
-
-	ide_host_register(host, d, hws);
-
-	return 0;
+	return ide_host_add(d, hws, NULL);
 }
 EXPORT_SYMBOL_GPL(ide_legacy_device_add);
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index 2625667..7c2afa9 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -151,7 +151,6 @@
 static int __init buddha_init(void)
 {
 	struct zorro_dev *z = NULL;
-	struct ide_host *host;
 	u_long buddha_board = 0;
 	BuddhaType type;
 	int buddha_num_hwifs, i;
@@ -226,9 +225,7 @@
 			hws[i] = &hw[i];
 		}
 
-		host = ide_host_alloc(NULL, hws);
-		if (host)
-			ide_host_register(host, NULL, hws);
+		ide_host_add(NULL, hws, NULL);
 	}
 
 	return 0;
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index 13d22bd..dd5c467 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -127,7 +127,6 @@
     unsigned long phys_base, res_start, res_n;
     unsigned long base, ctrlport, irqport;
     ide_ack_intr_t *ack_intr;
-    struct ide_host *host;
     int a4000, i;
     hw_regs_t hw[GAYLE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
 
@@ -180,11 +179,7 @@
 	hws[i] = &hw[i];
     }
 
-    host = ide_host_alloc(NULL, hws);
-    if (host)
-	ide_host_register(host, NULL, hws);
-
-    return 0;
+    return ide_host_add(NULL, hws, NULL);
 }
 
 module_init(gayle_init);
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c
index 5935153..c76d55d 100644
--- a/drivers/ide/legacy/ide-4drives.c
+++ b/drivers/ide/legacy/ide-4drives.c
@@ -28,7 +28,6 @@
 
 static int __init ide_4drives_init(void)
 {
-	struct ide_host *host;
 	unsigned long base = 0x1f0, ctl = 0x3f6;
 	hw_regs_t hw, *hws[] = { &hw, &hw, NULL, NULL };
 
@@ -54,11 +53,7 @@
 	hw.irq = 14;
 	hw.chipset = ide_4drives;
 
-	host = ide_host_alloc(&ide_4drives_port_info, hws);
-	if (host)
-		ide_host_register(host, &ide_4drives_port_info, hws);
-
-	return 0;
+	return ide_host_add(&ide_4drives_port_info, hws, NULL);
 }
 
 module_init(ide_4drives_init);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 1a4b9e6..21bfac1 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -162,7 +162,7 @@
 {
     struct ide_host *host;
     ide_hwif_t *hwif;
-    int i;
+    int i, rc;
     hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
     if (!request_region(io, 8, DRV_NAME)) {
@@ -184,12 +184,10 @@
     hw.chipset = ide_pci;
     hw.dev = &handle->dev;
 
-    host = ide_host_alloc(&idecs_port_info, hws);
-    if (host == NULL)
+    rc = ide_host_add(&idecs_port_info, hws, &host);
+    if (rc)
 	goto out_release;
 
-    ide_host_register(host, &idecs_port_info, hws);
-
     hwif = host->ports[0];
 
     if (hwif->present)
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
index 58a942c..051b4ab 100644
--- a/drivers/ide/legacy/ide_platform.c
+++ b/drivers/ide/legacy/ide_platform.c
@@ -99,13 +99,9 @@
 	if (mmio)
 		d.host_flags |= IDE_HFLAG_MMIO;
 
-	host = ide_host_alloc(&d, hws);
-	if (host == NULL) {
-		ret = -ENODEV;
+	ret = ide_host_add(&d, hws, &host);
+	if (ret)
 		goto out;
-	}
-
-	ide_host_register(host, &d, hws);
 
 	platform_set_drvdata(pdev, host);
 
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index b49cf8c..a0bb167 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -92,7 +92,6 @@
 static int __init macide_init(void)
 {
 	ide_ack_intr_t *ack_intr;
-	struct ide_host *host;
 	unsigned long base;
 	int irq;
 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
@@ -125,11 +124,7 @@
 
 	macide_setup_ports(&hw, base, irq, ack_intr);
 
-	host = ide_host_alloc(NULL, hws);
-	if (host)
-		ide_host_register(host, NULL, hws);
-
-	return 0;
+	return ide_host_add(NULL, hws, NULL);
 }
 
 module_init(macide_init);
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index 8fb4438..4abd8fc 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -131,7 +131,6 @@
 
 static int __init q40ide_init(void)
 {
-    struct ide_host *host;
     int i;
     hw_regs_t hw[Q40IDE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
 
@@ -160,11 +159,7 @@
 	hws[i] = &hw[i];
     }
 
-    host = ide_host_alloc(&q40ide_port_info, hws);
-    if (host)
-	ide_host_register(host, &q40ide_port_info, hws);
-
-    return 0;
+    return ide_host_add(&q40ide_port_info, hws, NULL);
 }
 
 module_init(q40ide_init);
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 903c628..11b7f61 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -609,13 +609,9 @@
 	hw.dev = dev;
 	hw.chipset = ide_au1xxx;
 
-	host = ide_host_alloc(&au1xxx_port_info, hws);
-	if (host == NULL) {
-		ret = -ENOENT;
+	ret = ide_host_add(&au1xxx_port_info, hws, &host);
+	if (ret)
 		goto out;
-	}
-
-	ide_host_register(host, &au1xxx_port_info, hws);
 
 	auide_hwif.hwif = host->ports[0];
 
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index b12d9d2..badf79f 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -75,7 +75,7 @@
 	u8 __iomem *base;
 	struct ide_host *host;
 	phys_t offset, size;
-	int i;
+	int i, rc;
 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
 	if (!SIBYTE_HAVE_IDE)
@@ -115,19 +115,17 @@
 	hw.irq = K_INT_GB_IDE;
 	hw.chipset = ide_generic;
 
-	host = ide_host_alloc(&swarm_port_info, hws);
-	if (host == NULL)
+	rc = ide_host_add(&swarm_port_info, hws, &host);
+	if (rc)
 		goto err;
 
-	ide_host_register(host, &swarm_port_info, hws);
-
 	dev_set_drvdata(dev, host);
 
 	return 0;
 err:
 	release_resource(&swarm_ide_resource);
 	iounmap(base);
-	return -ENOMEM;
+	return rc;
 }
 
 static struct device_driver swarm_ide_driver = {
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index 013697b..e6c6200 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -709,7 +709,6 @@
  */
 static int __init cmd640x_init(void)
 {
-	struct ide_host *host;
 	int second_port_cmd640 = 0, rc;
 	const char *bus_type, *port2;
 	u8 b, cfr;
@@ -829,11 +828,7 @@
 	cmd640_dump_regs();
 #endif
 
-	host = ide_host_alloc(&cmd640_port_info, hws);
-	if (host)
-		ide_host_register(host, &cmd640_port_info, hws);
-
-	return 1;
+	return ide_host_add(&cmd640_port_info, hws, NULL);
 }
 
 module_param_named(probe_vlb, cmd640_vlb, bool, 0);
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index b8ec06d..b03d8ae 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -114,7 +114,6 @@
  
 static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	struct ide_host *host;
 	const struct ide_port_info *d = &cyrix_chipsets[id->driver_data];
 	hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL };
 
@@ -140,11 +139,7 @@
 
 	ide_pci_setup_ports(dev, d, 14, &hw[0], &hws[0]);
 
-	host = ide_host_alloc(d, hws);
-	if (host)
-		ide_host_register(host, d, hws);
-
-	return 0;
+	return ide_host_add(d, hws, NULL);
 }
 
 static const struct pci_device_id cs5520_pci_tbl[] = {
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 5eb9d93..f84bfb4 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -86,12 +86,10 @@
 	hw.dev = &dev->dev;
 	hw.chipset = ide_pci;		/* this enables IRQ sharing */
 
-	host = ide_host_alloc(&delkin_cb_port_info, hws);
-	if (host == NULL)
+	rc = ide_host_add(&delkin_cb_port_info, hws, &host);
+	if (rc)
 		goto out_disable;
 
-	ide_host_register(host, &delkin_cb_port_info, hws);
-
 	pci_set_drvdata(dev, host);
 
 	return 0;
@@ -99,7 +97,7 @@
 out_disable:
 	pci_release_regions(dev);
 	pci_disable_device(dev);
-	return -ENODEV;
+	return rc;
 }
 
 static void
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index d5e2ba6..94a7ab86 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -588,7 +588,7 @@
 	struct scc_ports *ports = pci_get_drvdata(dev);
 	struct ide_host *host;
 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-	int i;
+	int i, rc;
 
 	memset(&hw, 0, sizeof(hw));
 	for (i = 0; i <= 8; i++)
@@ -597,11 +597,9 @@
 	hw.dev = &dev->dev;
 	hw.chipset = ide_pci;
 
-	host = ide_host_alloc(d, hws);
-	if (host == NULL)
-		return -ENOMEM;
-
-	ide_host_register(host, d, hws);
+	rc = ide_host_add(d, hws, &host);
+	if (rc)
+		return rc;
 
 	ports->host = host;
 
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index ecd2f28..c521bf6 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1043,6 +1043,7 @@
 	ide_hwif_t *hwif;
 	hw_regs_t *hws[] = { hw, NULL, NULL, NULL };
 	struct ide_port_info d = pmac_port_info;
+	int rc;
 
 	pmif->broken_dma = pmif->broken_dma_warn = 0;
 	if (of_device_is_compatible(np, "shasta-ata")) {
@@ -1118,11 +1119,9 @@
 			 pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id,
 			 pmif->mediabay ? " (mediabay)" : "", hw->irq);
 
-	host = ide_host_alloc(&d, hws);
-	if (host == NULL)
-		return -ENOENT;
-
-	ide_host_register(host, &d, hws);
+	rc = ide_host_add(&d, hws, &host);
+	if (rc)
+		return rc;
 
 	hwif = host->ports[0];
 
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 1c0c557..b15cad5 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -541,7 +541,6 @@
 
 int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d)
 {
-	struct ide_host *host;
 	hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL };
 	int ret;
 
@@ -551,9 +550,7 @@
 		/* FIXME: silent failure can happen */
 		ide_pci_setup_ports(dev, d, ret, &hw[0], &hws[0]);
 
-		host = ide_host_alloc(d, hws);
-		if (host)
-			ide_host_register(host, d, hws);
+		ret = ide_host_add(d, hws, NULL);
 	}
 
 	return ret;
@@ -564,7 +561,6 @@
 			  const struct ide_port_info *d)
 {
 	struct pci_dev *pdev[] = { dev1, dev2 };
-	struct ide_host *host;
 	int ret, i;
 	hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL };
 
@@ -582,9 +578,7 @@
 		ide_pci_setup_ports(pdev[i], d, ret, &hw[i*2], &hws[i*2]);
 	}
 
-	host = ide_host_alloc(d, hws);
-	if (host)
-		ide_host_register(host, d, hws);
+	ret = ide_host_add(d, hws, NULL);
 out:
 	return ret;
 }
diff --git a/include/linux/ide.h b/include/linux/ide.h
index a41ae57..764afd9 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1238,6 +1238,8 @@
 struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **);
 int ide_host_register(struct ide_host *, const struct ide_port_info *,
 		      hw_regs_t **);
+int ide_host_add(const struct ide_port_info *, hw_regs_t **,
+		 struct ide_host **);
 void ide_host_remove(struct ide_host *);
 int ide_legacy_device_add(const struct ide_port_info *, unsigned long);
 void ide_port_unregister_devices(ide_hwif_t *);