summaryrefslogtreecommitdiff
path: root/drivers/ide
diff options
context:
space:
mode:
authorFinn Thain <fthain@linux-m68k.org>2021-06-10 11:15:06 +1000
committerJens Axboe <axboe@kernel.dk>2021-06-10 16:30:12 -0600
commit44b1fbc0f5f30e66a56d29575349f0b1ebe2b0ee (patch)
tree924d54b1cee2d72fc71c8c569a64164d2040df23 /drivers/ide
parentcabd10be0b9e4bf043dc828321875b937b2aa7ca (diff)
downloadlwn-44b1fbc0f5f30e66a56d29575349f0b1ebe2b0ee.tar.gz
lwn-44b1fbc0f5f30e66a56d29575349f0b1ebe2b0ee.zip
m68k/q40: Replace q40ide driver with pata_falcon and falconide
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>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Kconfig18
-rw-r--r--drivers/ide/Makefile1
-rw-r--r--drivers/ide/falconide.c79
-rw-r--r--drivers/ide/q40ide.c168
4 files changed, 59 insertions, 207 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 8ce4a5878d0c..8af1ac69e5f8 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -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"
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 45a1c0463bed..991eb72a786b 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -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
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index bb86d84558d9..a73a9dc17e4d 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -25,12 +25,7 @@
#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
index ecd0a69245f6..000000000000
--- a/drivers/ide/q40ide.c
+++ /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");