ide: pass hw_regs_t-s to ide_device_add[_all]() (take 3)

* Add 'hw_regs_t **hws' argument to ide_device_add[_all]() and convert
  host drivers + ide_legacy_init_one() + ide_setup_pci_device[s]() to use
  it instead of calling ide_init_port_hw() directly.

  [ However if host has > 1 port we must still set hwif->chipset to hint
    consecutive ide_find_port() call that the previous slot is occupied. ]

* Unexport ide_init_port_hw().

v2:
* Use defines instead of hard-coded values in buddha.c, gayle.c and q40ide.c.
  (Suggested by Geert Uytterhoeven)

* Better patch description.

v3:
* Fix build problem in ide-cs.c. (Noticed by Stephen Rothwell)

There should be no functional changes caused by this patch.

Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index 0497e7f..c61bc6a 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -37,6 +37,8 @@
 #define CATWEASEL_NUM_HWIFS	3
 #define XSURF_NUM_HWIFS         2
 
+#define MAX_NUM_HWIFS		3
+
     /*
      *  Bases of the IDE interfaces (relative to the board address)
      */
@@ -148,7 +150,6 @@
 
 static int __init buddha_init(void)
 {
-	hw_regs_t hw;
 	ide_hwif_t *hwif;
 	int i;
 
@@ -159,6 +160,7 @@
 
 	while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
 		unsigned long board;
+		hw_regs_t hw[MAX_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
 		u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 		if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
@@ -221,19 +223,19 @@
 				ack_intr = xsurf_ack_intr;
 			}
 
-			buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr);
+			buddha_setup_ports(&hw[i], base, ctl, irq_port,
+					   ack_intr);
 
 			hwif = ide_find_port();
 			if (hwif) {
-				u8 index = hwif->index;
+				hwif->chipset = ide_generic;
 
-				ide_init_port_hw(hwif, &hw);
-
-				idx[i] = index;
+				hws[i] = &hw[i];
+				idx[i] = hwif->index;
 			}
 		}
 
-		ide_device_add(idx, NULL);
+		ide_device_add(idx, NULL, hws);
 	}
 
 	return 0;
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
index 129a812..1bb2aa7 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -91,8 +91,8 @@
 
 static int __init falconide_init(void)
 {
-	hw_regs_t hw;
 	ide_hwif_t *hwif;
+	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
 	if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE))
 		return 0;
@@ -111,14 +111,12 @@
 		u8 index = hwif->index;
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
 
-		ide_init_port_hw(hwif, &hw);
-
 		/* Atari has a byte-swapped IDE interface */
 		hwif->input_data  = falconide_input_data;
 		hwif->output_data = falconide_output_data;
 
 		ide_get_lock(NULL, NULL);
-		ide_device_add(idx, NULL);
+		ide_device_add(idx, NULL, hws);
 		ide_release_lock();
 	}
 
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index 7e74b20..e45c734 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -125,6 +125,7 @@
 static int __init gayle_init(void)
 {
     int a4000, i;
+    hw_regs_t hw[GAYLE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
     u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
     if (!MACH_IS_AMIGA)
@@ -151,7 +152,6 @@
     for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
 	unsigned long base, ctrlport, irqport;
 	ide_ack_intr_t *ack_intr;
-	hw_regs_t hw;
 	ide_hwif_t *hwif;
 	unsigned long phys_base, res_start, res_n;
 
@@ -179,20 +179,19 @@
 	base = (unsigned long)ZTWO_VADDR(phys_base);
 	ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;
 
-	gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr);
+	gayle_setup_ports(&hw[i], base, ctrlport, irqport, ack_intr);
 
 	hwif = ide_find_port();
 	if (hwif) {
-	    u8 index = hwif->index;
+	    hwif->chipset = ide_generic;
 
-	    ide_init_port_hw(hwif, &hw);
-
-	    idx[i] = index;
+	    hws[i] = &hw[i];
+	    idx[i] = hwif->index;
 	} else
 	    release_mem_region(res_start, res_n);
     }
 
-    ide_device_add(idx, NULL);
+    ide_device_add(idx, NULL, hws);
 
     return 0;
 }
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c
index 89c8ff0..6310dc5 100644
--- a/drivers/ide/legacy/ide-4drives.c
+++ b/drivers/ide/legacy/ide-4drives.c
@@ -30,8 +30,8 @@
 {
 	ide_hwif_t *hwif, *mate;
 	unsigned long base = 0x1f0, ctl = 0x3f6;
+	hw_regs_t hw, *hws[] = { NULL, NULL, NULL, NULL };
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-	hw_regs_t hw;
 
 	if (probe_4drives == 0)
 		return -ENODEV;
@@ -57,17 +57,19 @@
 
 	hwif = ide_find_port();
 	if (hwif) {
-		ide_init_port_hw(hwif, &hw);
+		hwif->chipset = ide_4drives;
+
+		hws[0] = &hw;
 		idx[0] = hwif->index;
 	}
 
 	mate = ide_find_port();
 	if (mate) {
-		ide_init_port_hw(mate, &hw);
+		hws[1] = &hw;
 		idx[1] = mate->index;
 	}
 
-	ide_device_add(idx, &ide_4drives_port_info);
+	ide_device_add(idx, &ide_4drives_port_info, hws);
 
 	return 0;
 }
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 27b1e0b..f93d5454eb 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -161,8 +161,8 @@
 				unsigned long irq, struct pcmcia_device *handle)
 {
     ide_hwif_t *hwif;
-    hw_regs_t hw;
     int i;
+    hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
     u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
     if (!request_region(io, 8, DRV_NAME)) {
@@ -188,13 +188,9 @@
     if (hwif == NULL)
 	goto out_release;
 
-    i = hwif->index;
+    idx[0] = hwif->index;
 
-    ide_init_port_hw(hwif, &hw);
-
-    idx[0] = i;
-
-    ide_device_add(idx, &idecs_port_info);
+    ide_device_add(idx, &idecs_port_info, hws);
 
     if (hwif->present)
 	return hwif;
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
index a249562..609da0d 100644
--- a/drivers/ide/legacy/ide_platform.c
+++ b/drivers/ide/legacy/ide_platform.c
@@ -54,10 +54,9 @@
 	void __iomem *base, *alt_base;
 	ide_hwif_t *hwif;
 	struct pata_platform_info *pdata;
+	int ret = 0, mmio = 0;
+	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-	int ret = 0;
-	int mmio = 0;
-	hw_regs_t hw;
 	struct ide_port_info d = platform_ide_port_info;
 
 	pdata = pdev->dev.platform_data;
@@ -104,8 +103,6 @@
 	plat_ide_setup_ports(&hw, base, alt_base, pdata, res_irq->start);
 	hw.dev = &pdev->dev;
 
-	ide_init_port_hw(hwif, &hw);
-
 	if (mmio) {
 		d.host_flags |= IDE_HFLAG_MMIO;
 		default_hwif_mmiops(hwif);
@@ -113,7 +110,7 @@
 
 	idx[0] = hwif->index;
 
-	ide_device_add(idx, &d);
+	ide_device_add(idx, &d, hws);
 
 	platform_set_drvdata(pdev, hwif);
 
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index 0a6195b..d839df2 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -95,7 +95,7 @@
 	ide_ack_intr_t *ack_intr;
 	unsigned long base;
 	int irq;
-	hw_regs_t hw;
+	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
 	if (!MACH_IS_MAC)
 		return -ENODEV;
@@ -130,9 +130,7 @@
 		u8 index = hwif->index;
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
 
-		ide_init_port_hw(hwif, &hw);
-
-		ide_device_add(idx, NULL);
+		ide_device_add(idx, NULL, hws);
 	}
 
 	return 0;
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index 9c2b9d0..fcb04b8 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -112,7 +112,7 @@
 {
     int i;
     ide_hwif_t *hwif;
-    const char *name;
+    hw_regs_t hw[Q40IDE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
     u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
     if (!MACH_IS_Q40)
@@ -121,9 +121,8 @@
     printk(KERN_INFO "ide: Q40 IDE controller\n");
 
     for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
-	hw_regs_t hw;
+	const char *name = q40_ide_names[i];
 
-	name = q40_ide_names[i];
 	if (!request_region(pcide_bases[i], 8, name)) {
 		printk("could not reserve ports %lx-%lx for %s\n",
 		       pcide_bases[i],pcide_bases[i]+8,name);
@@ -135,24 +134,23 @@
 		release_region(pcide_bases[i], 8);
 		continue;
 	}
-	q40_ide_setup_ports(&hw, pcide_bases[i],
-			NULL,
-//			m68kide_iops,
+	q40_ide_setup_ports(&hw[i], pcide_bases[i], NULL,
 			q40ide_default_irq(pcide_bases[i]));
 
 	hwif = ide_find_port();
 	if (hwif) {
-		ide_init_port_hw(hwif, &hw);
+		hwif->chipset = ide_generic;
 
 		/* Q40 has a byte-swapped IDE interface */
 		hwif->input_data  = q40ide_input_data;
 		hwif->output_data = q40ide_output_data;
 
+		hws[i] = &hw[i];
 		idx[i] = hwif->index;
 	}
     }
 
-    ide_device_add(idx, NULL);
+    ide_device_add(idx, NULL, hws);
 
     return 0;
 }