OSDN Git Service

m68k/q40: Replace q40ide driver with pata_falcon and falconide
authorFinn Thain <fthain@linux-m68k.org>
Thu, 10 Jun 2021 01:15:06 +0000 (11:15 +1000)
committerJens Axboe <axboe@kernel.dk>
Thu, 10 Jun 2021 22:30:12 +0000 (16:30 -0600)
This allows m68k q40 systems to switch from the deprecated IDE subsystem
to libata.

Enhance the byte-swapping falconide and pata_falcon platform drivers to
accept an irq resource, for use on q40. Atari ST-DMA IRQ arrangements seem
to co-exist with q40 IRQ arrangements without too much mess.

The new IO resources were added solely for the purpose of making
request_region() reservations identical to those made by q40ide: these
regions aren't used for actual IO.

Cc: Michael Schmitz <schmitzmic@gmail.com>
Cc: Richard Zidlicky <rz@linux-m68k.org>
Reviewed-and-tested-by: Michael Schmitz <schmitzmic@gmail.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Finn Thain <fthain@linux-m68k.org>
Link: https://lore.kernel.org/r/eefb7e9c2291e09fb4e065ce06bc105f05bb9e06.1623287706.git.fthain@linux-m68k.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
arch/m68k/atari/config.c
arch/m68k/configs/multi_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/q40/config.c
drivers/ata/Kconfig
drivers/ata/pata_falcon.c
drivers/ide/Kconfig
drivers/ide/Makefile
drivers/ide/falconide.c
drivers/ide/q40ide.c [deleted file]

index 44f9b52..261a0f5 100644 (file)
@@ -875,16 +875,8 @@ static const struct resource atari_scsi_tt_rsrc[] __initconst = {
 #define FALCON_IDE_BASE        0xfff00000
 
 static const struct resource atari_falconide_rsrc[] __initconst = {
-       {
-               .flags = IORESOURCE_MEM,
-               .start = FALCON_IDE_BASE,
-               .end   = FALCON_IDE_BASE + 0x39,
-       },
-       {
-               .flags = IORESOURCE_IRQ,
-               .start = IRQ_MFP_FSCSI,
-               .end   = IRQ_MFP_FSCSI,
-       },
+       DEFINE_RES_MEM(FALCON_IDE_BASE, 0x38),
+       DEFINE_RES_MEM(FALCON_IDE_BASE + 0x38, 2),
 };
 
 int __init atari_platform_init(void)
index f40093a..f099243 100644 (file)
@@ -351,7 +351,6 @@ CONFIG_BLK_DEV_PLATFORM=y
 CONFIG_BLK_DEV_GAYLE=y
 CONFIG_BLK_DEV_BUDDHA=y
 CONFIG_BLK_DEV_FALCON_IDE=y
-CONFIG_BLK_DEV_Q40IDE=y
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
index 664025a..b893163 100644 (file)
@@ -317,7 +317,7 @@ CONFIG_DUMMY_IRQ=m
 CONFIG_IDE=y
 CONFIG_IDE_GD_ATAPI=y
 CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_Q40IDE=y
+CONFIG_BLK_DEV_FALCON_IDE=y
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
index d6a4238..5caf1e5 100644 (file)
@@ -286,14 +286,39 @@ static int q40_set_rtc_pll(struct rtc_pll_info *pll)
                return -EINVAL;
 }
 
-static __init int q40_add_kbd_device(void)
-{
-       struct platform_device *pdev;
+#define PCIDE_BASE1    0x1f0
+#define PCIDE_BASE2    0x170
+#define PCIDE_CTL      0x206
+
+static const struct resource q40_pata_rsrc_0[] __initconst = {
+       DEFINE_RES_MEM(q40_isa_io_base + PCIDE_BASE1 * 4, 0x38),
+       DEFINE_RES_MEM(q40_isa_io_base + (PCIDE_BASE1 + PCIDE_CTL) * 4, 2),
+       DEFINE_RES_IO(PCIDE_BASE1, 8),
+       DEFINE_RES_IO(PCIDE_BASE1 + PCIDE_CTL, 1),
+       DEFINE_RES_IRQ(14),
+};
 
+static const struct resource q40_pata_rsrc_1[] __initconst = {
+       DEFINE_RES_MEM(q40_isa_io_base + PCIDE_BASE2 * 4, 0x38),
+       DEFINE_RES_MEM(q40_isa_io_base + (PCIDE_BASE2 + PCIDE_CTL) * 4, 2),
+       DEFINE_RES_IO(PCIDE_BASE2, 8),
+       DEFINE_RES_IO(PCIDE_BASE2 + PCIDE_CTL, 1),
+       DEFINE_RES_IRQ(15),
+};
+
+static __init int q40_platform_init(void)
+{
        if (!MACH_IS_Q40)
                return -ENODEV;
 
-       pdev = platform_device_register_simple("q40kbd", -1, NULL, 0);
-       return PTR_ERR_OR_ZERO(pdev);
+       platform_device_register_simple("q40kbd", -1, NULL, 0);
+
+       platform_device_register_simple("atari-falcon-ide", 0, q40_pata_rsrc_0,
+                                       ARRAY_SIZE(q40_pata_rsrc_0));
+
+       platform_device_register_simple("atari-falcon-ide", 1, q40_pata_rsrc_1,
+                                       ARRAY_SIZE(q40_pata_rsrc_1));
+
+       return 0;
 }
-arch_initcall(q40_add_kbd_device);
+arch_initcall(q40_platform_init);
index 030cb32..b7a5abe 100644 (file)
@@ -1015,11 +1015,11 @@ config PATA_CMD640_PCI
          If unsure, say N.
 
 config PATA_FALCON
-       tristate "Atari Falcon PATA support"
-       depends on M68K && ATARI
+       tristate "Atari Falcon and Q40/Q60 PATA support"
+       depends on M68K && (ATARI || Q40)
        help
          This option enables support for the on-board IDE
-         interface on the Atari Falcon.
+         interface on the Atari Falcon and Q40/Q60.
 
          If unsure, say N.
 
index 27b0952..9d0dd8f 100644 (file)
@@ -33,8 +33,6 @@
 #define DRV_NAME "pata_falcon"
 #define DRV_VERSION "0.1.0"
 
-#define ATA_HD_CONTROL 0x39
-
 static struct scsi_host_template pata_falcon_sht = {
        ATA_PIO_SHT(DRV_NAME),
 };
@@ -121,23 +119,42 @@ static struct ata_port_operations pata_falcon_ops = {
 
 static int __init pata_falcon_init_one(struct platform_device *pdev)
 {
-       struct resource *res;
+       struct resource *base_mem_res, *ctl_mem_res;
+       struct resource *base_res, *ctl_res, *irq_res;
        struct ata_host *host;
        struct ata_port *ap;
        void __iomem *base;
+       int irq = 0;
 
-       dev_info(&pdev->dev, "Atari Falcon PATA controller\n");
+       dev_info(&pdev->dev, "Atari Falcon and Q40/Q60 PATA controller\n");
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -ENODEV;
+       base_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (base_res && !devm_request_region(&pdev->dev, base_res->start,
+                                          resource_size(base_res), DRV_NAME)) {
+               dev_err(&pdev->dev, "resources busy\n");
+               return -EBUSY;
+       }
 
-       if (!devm_request_mem_region(&pdev->dev, res->start,
-                                    resource_size(res), DRV_NAME)) {
+       ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1);
+       if (ctl_res && !devm_request_region(&pdev->dev, ctl_res->start,
+                                           resource_size(ctl_res), DRV_NAME)) {
                dev_err(&pdev->dev, "resources busy\n");
                return -EBUSY;
        }
 
+       base_mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!base_mem_res)
+               return -ENODEV;
+       if (!devm_request_mem_region(&pdev->dev, base_mem_res->start,
+                                    resource_size(base_mem_res), DRV_NAME)) {
+               dev_err(&pdev->dev, "resources busy\n");
+               return -EBUSY;
+       }
+
+       ctl_mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!ctl_mem_res)
+               return -ENODEV;
+
        /* allocate host */
        host = ata_host_alloc(&pdev->dev, 1);
        if (!host)
@@ -147,10 +164,10 @@ static int __init pata_falcon_init_one(struct platform_device *pdev)
        ap->ops = &pata_falcon_ops;
        ap->pio_mask = ATA_PIO4;
        ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY;
-       ap->flags |= ATA_FLAG_PIO_POLLING;
 
-       base = (void __iomem *)res->start;
-       ap->ioaddr.data_addr            = base;
+       base = (void __iomem *)base_mem_res->start;
+       /* N.B. this assumes data_addr will be used for word-sized I/O only */
+       ap->ioaddr.data_addr            = base + 0 + 0 * 4;
        ap->ioaddr.error_addr           = base + 1 + 1 * 4;
        ap->ioaddr.feature_addr         = base + 1 + 1 * 4;
        ap->ioaddr.nsect_addr           = base + 1 + 2 * 4;
@@ -161,14 +178,25 @@ static int __init pata_falcon_init_one(struct platform_device *pdev)
        ap->ioaddr.status_addr          = base + 1 + 7 * 4;
        ap->ioaddr.command_addr         = base + 1 + 7 * 4;
 
-       ap->ioaddr.altstatus_addr       = base + ATA_HD_CONTROL;
-       ap->ioaddr.ctl_addr             = base + ATA_HD_CONTROL;
+       base = (void __iomem *)ctl_mem_res->start;
+       ap->ioaddr.altstatus_addr       = base + 1;
+       ap->ioaddr.ctl_addr             = base + 1;
 
-       ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", (unsigned long)base,
-                     (unsigned long)base + ATA_HD_CONTROL);
+       ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx",
+                     (unsigned long)base_mem_res->start,
+                     (unsigned long)ctl_mem_res->start);
+
+       irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (irq_res && irq_res->start > 0) {
+               irq = irq_res->start;
+       } else {
+               ap->flags |= ATA_FLAG_PIO_POLLING;
+               ata_port_desc(ap, "no IRQ, using PIO polling");
+       }
 
        /* activate */
-       return ata_host_activate(host, 0, NULL, 0, &pata_falcon_sht);
+       return ata_host_activate(host, irq, irq ? ata_sff_interrupt : NULL,
+                                IRQF_SHARED, &pata_falcon_sht);
 }
 
 static int __exit pata_falcon_remove_one(struct platform_device *pdev)
index 8ce4a58..8af1ac6 100644 (file)
@@ -731,21 +731,13 @@ config BLK_DEV_BUDDHA
          to one of its IDE interfaces.
 
 config BLK_DEV_FALCON_IDE
-       tristate "Falcon IDE interface support"
-       depends on ATARI
+       tristate "Falcon and Q40/Q60 IDE interface support"
+       depends on ATARI || Q40
        help
          This is the IDE driver for the on-board IDE interface on the Atari
-         Falcon. Say Y if you have a Falcon and want to use IDE devices (hard
-         disks, CD-ROM drives, etc.) that are connected to the on-board IDE
-         interface.
-
-config BLK_DEV_Q40IDE
-       tristate "Q40/Q60 IDE interface support"
-       depends on Q40
-       help
-         Enable the on-board IDE controller in the Q40/Q60.  This should
-         normally be on; disable it only if you are running a custom hard
-         drive subsystem through an expansion card.
+         Falcon and Q40/Q60. Say Y if you have such a machine and want to use
+         IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
+         the on-board IDE interface.
 
 config BLK_DEV_PALMCHIP_BK3710
        tristate "Palmchip bk3710 IDE controller support"
index 45a1c04..991eb72 100644 (file)
@@ -29,7 +29,6 @@ obj-$(CONFIG_BLK_DEV_4DRIVES)         += ide-4drives.o
 
 obj-$(CONFIG_BLK_DEV_GAYLE)            += gayle.o
 obj-$(CONFIG_BLK_DEV_FALCON_IDE)       += falconide.o
-obj-$(CONFIG_BLK_DEV_Q40IDE)           += q40ide.o
 obj-$(CONFIG_BLK_DEV_BUDDHA)           += buddha.o
 
 obj-$(CONFIG_BLK_DEV_AEC62XX)          += aec62xx.o
index bb86d84..a73a9dc 100644 (file)
 
 #define DRV_NAME "falconide"
 
-    /*
-     *  Offsets from base address
-     */
-
-#define ATA_HD_CONTROL 0x39
-
+#ifdef CONFIG_ATARI
     /*
      *  falconide_intr_lock is used to obtain access to the IDE interrupt,
      *  which is shared between several drivers.
@@ -55,6 +50,7 @@ static void falconide_get_lock(irq_handler_t handler, void *data)
                falconide_intr_lock = 1;
        }
 }
+#endif
 
 static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
                                 void *buf, unsigned int len)
@@ -98,8 +94,10 @@ static const struct ide_tp_ops falconide_tp_ops = {
 };
 
 static const struct ide_port_info falconide_port_info = {
+#ifdef CONFIG_ATARI
        .get_lock               = falconide_get_lock,
        .release_lock           = falconide_release_lock,
+#endif
        .tp_ops                 = &falconide_tp_ops,
        .host_flags             = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
                                  IDE_HFLAG_NO_DMA,
@@ -107,7 +105,8 @@ static const struct ide_port_info falconide_port_info = {
        .chipset                = ide_generic,
 };
 
-static void __init falconide_setup_ports(struct ide_hw *hw, unsigned long base)
+static void __init falconide_setup_ports(struct ide_hw *hw, unsigned long base,
+                                        unsigned long ctl, int irq)
 {
        int i;
 
@@ -118,9 +117,9 @@ static void __init falconide_setup_ports(struct ide_hw *hw, unsigned long base)
        for (i = 1; i < 8; i++)
                hw->io_ports_array[i] = base + 1 + i * 4;
 
-       hw->io_ports.ctl_addr = base + ATA_HD_CONTROL;
+       hw->io_ports.ctl_addr = ctl + 1;
 
-       hw->irq = IRQ_MFP_IDE;
+       hw->irq = irq;
 }
 
     /*
@@ -129,37 +128,69 @@ static void __init falconide_setup_ports(struct ide_hw *hw, unsigned long base)
 
 static int __init falconide_init(struct platform_device *pdev)
 {
-       struct resource *res;
+       struct resource *base_mem_res, *ctl_mem_res;
+       struct resource *base_res, *ctl_res, *irq_res;
        struct ide_host *host;
        struct ide_hw hw, *hws[] = { &hw };
-       unsigned long base;
        int rc;
+       int irq;
+
+       dev_info(&pdev->dev, "Atari Falcon and Q40/Q60 IDE controller\n");
+
+       base_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (base_res && !devm_request_region(&pdev->dev, base_res->start,
+                                          resource_size(base_res), DRV_NAME)) {
+               dev_err(&pdev->dev, "resources busy\n");
+               return -EBUSY;
+       }
 
-       dev_info(&pdev->dev, "Atari Falcon IDE controller\n");
+       ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (ctl_res && !devm_request_region(&pdev->dev, ctl_res->start,
+                                          resource_size(ctl_res), DRV_NAME)) {
+               dev_err(&pdev->dev, "resources busy\n");
+               return -EBUSY;
+       }
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
+       base_mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!base_mem_res)
                return -ENODEV;
 
-       if (!devm_request_mem_region(&pdev->dev, res->start,
-                                    resource_size(res), DRV_NAME)) {
+       if (!devm_request_mem_region(&pdev->dev, base_mem_res->start,
+                                    resource_size(base_mem_res), DRV_NAME)) {
                dev_err(&pdev->dev, "resources busy\n");
                return -EBUSY;
        }
 
-       base = (unsigned long)res->start;
+       ctl_mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!ctl_mem_res)
+               return -ENODEV;
+
+       if (MACH_IS_ATARI) {
+               irq = IRQ_MFP_IDE;
+       } else {
+               irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+               if (irq_res && irq_res->start > 0)
+                       irq = irq_res->start;
+               else
+                       return -ENODEV;
+       }
 
-       falconide_setup_ports(&hw, base);
+       falconide_setup_ports(&hw, base_mem_res->start, ctl_mem_res->start, irq);
 
        host = ide_host_alloc(&falconide_port_info, hws, 1);
-       if (host == NULL) {
-               rc = -ENOMEM;
-               goto err;
+       if (!host)
+               return -ENOMEM;
+
+       if (!MACH_IS_ATARI) {
+               host->get_lock = NULL;
+               host->release_lock = NULL;
        }
 
-       falconide_get_lock(NULL, NULL);
+       if (host->get_lock)
+               host->get_lock(NULL, NULL);
        rc = ide_host_register(host, &falconide_port_info, hws);
-       falconide_release_lock();
+       if (host->release_lock)
+               host->release_lock();
 
        if (rc)
                goto err_free;
@@ -168,8 +199,6 @@ static int __init falconide_init(struct platform_device *pdev)
        return 0;
 err_free:
        ide_host_free(host);
-err:
-       release_mem_region(res->start, resource_size(res));
        return rc;
 }
 
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
deleted file mode 100644 (file)
index ecd0a69..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- *  Q40 I/O port IDE Driver
- *
- *     (c) Richard Zidlicky
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- *
- *
- */
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/blkdev.h>
-#include <linux/ide.h>
-#include <linux/module.h>
-
-#include <asm/ide.h>
-
-    /*
-     *  Bases of the IDE interfaces
-     */
-
-#define Q40IDE_NUM_HWIFS       2
-
-#define PCIDE_BASE1    0x1f0
-#define PCIDE_BASE2    0x170
-#define PCIDE_BASE3    0x1e8
-#define PCIDE_BASE4    0x168
-#define PCIDE_BASE5    0x1e0
-#define PCIDE_BASE6    0x160
-
-static const unsigned long pcide_bases[Q40IDE_NUM_HWIFS] = {
-    PCIDE_BASE1, PCIDE_BASE2, /* PCIDE_BASE3, PCIDE_BASE4  , PCIDE_BASE5,
-    PCIDE_BASE6 */
-};
-
-static int q40ide_default_irq(unsigned long base)
-{
-           switch (base) {
-                   case 0x1f0: return 14;
-                   case 0x170: return 15;
-                   case 0x1e8: return 11;
-                   default:
-                       return 0;
-          }
-}
-
-
-/*
- * Addresses are pretranslated for Q40 ISA access.
- */
-static void q40_ide_setup_ports(struct ide_hw *hw, unsigned long base, int irq)
-{
-       memset(hw, 0, sizeof(*hw));
-       /* BIG FAT WARNING: 
-          assumption: only DATA port is ever used in 16 bit mode */
-       hw->io_ports.data_addr = Q40_ISA_IO_W(base);
-       hw->io_ports.error_addr = Q40_ISA_IO_B(base + 1);
-       hw->io_ports.nsect_addr = Q40_ISA_IO_B(base + 2);
-       hw->io_ports.lbal_addr = Q40_ISA_IO_B(base + 3);
-       hw->io_ports.lbam_addr = Q40_ISA_IO_B(base + 4);
-       hw->io_ports.lbah_addr = Q40_ISA_IO_B(base + 5);
-       hw->io_ports.device_addr = Q40_ISA_IO_B(base + 6);
-       hw->io_ports.status_addr = Q40_ISA_IO_B(base + 7);
-       hw->io_ports.ctl_addr = Q40_ISA_IO_B(base + 0x206);
-
-       hw->irq = irq;
-}
-
-static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
-                             void *buf, unsigned int len)
-{
-       unsigned long data_addr = drive->hwif->io_ports.data_addr;
-
-       if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
-               __ide_mm_insw(data_addr, buf, (len + 1) / 2);
-               return;
-       }
-
-       raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
-}
-
-static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
-                              void *buf, unsigned int len)
-{
-       unsigned long data_addr = drive->hwif->io_ports.data_addr;
-
-       if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
-               __ide_mm_outsw(data_addr, buf, (len + 1) / 2);
-               return;
-       }
-
-       raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
-}
-
-/* Q40 has a byte-swapped IDE interface */
-static const struct ide_tp_ops q40ide_tp_ops = {
-       .exec_command           = ide_exec_command,
-       .read_status            = ide_read_status,
-       .read_altstatus         = ide_read_altstatus,
-       .write_devctl           = ide_write_devctl,
-
-       .dev_select             = ide_dev_select,
-       .tf_load                = ide_tf_load,
-       .tf_read                = ide_tf_read,
-
-       .input_data             = q40ide_input_data,
-       .output_data            = q40ide_output_data,
-};
-
-static const struct ide_port_info q40ide_port_info = {
-       .tp_ops                 = &q40ide_tp_ops,
-       .host_flags             = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
-       .irq_flags              = IRQF_SHARED,
-       .chipset                = ide_generic,
-};
-
-/* 
- * the static array is needed to have the name reported in /proc/ioports,
- * hwif->name unfortunately isn't available yet
- */
-static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
-       "ide0", "ide1"
-};
-
-/*
- *  Probe for Q40 IDE interfaces
- */
-
-static int __init q40ide_init(void)
-{
-    int i;
-    struct ide_hw hw[Q40IDE_NUM_HWIFS], *hws[] = { NULL, NULL };
-
-    if (!MACH_IS_Q40)
-      return -ENODEV;
-
-    printk(KERN_INFO "ide: Q40 IDE controller\n");
-
-    for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
-       const char *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);
-               continue;
-       }
-       if (!request_region(pcide_bases[i]+0x206, 1, name)) {
-               printk("could not reserve port %lx for %s\n",
-                      pcide_bases[i]+0x206,name);
-               release_region(pcide_bases[i], 8);
-               continue;
-       }
-       q40_ide_setup_ports(&hw[i], pcide_bases[i],
-                       q40ide_default_irq(pcide_bases[i]));
-
-       hws[i] = &hw[i];
-    }
-
-    return ide_host_add(&q40ide_port_info, hws, Q40IDE_NUM_HWIFS, NULL);
-}
-
-module_init(q40ide_init);
-
-MODULE_LICENSE("GPL");