Skip to content

Commit

Permalink
m68k/q40: Replace q40ide driver with pata_falcon and falconide
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
fthain authored and axboe committed Jun 10, 2021
1 parent cabd10b commit 44b1fbc
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 245 deletions.
12 changes: 2 additions & 10 deletions arch/m68k/atari/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion arch/m68k/configs/multi_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion arch/m68k/configs/q40_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 31 additions & 6 deletions arch/m68k/q40/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
6 changes: 3 additions & 3 deletions drivers/ata/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
62 changes: 45 additions & 17 deletions drivers/ata/pata_falcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -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)
Expand Down
18 changes: 5 additions & 13 deletions drivers/ide/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 0 additions & 1 deletion drivers/ide/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
79 changes: 54 additions & 25 deletions drivers/ide/falconide.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
Expand Down Expand Up @@ -98,16 +94,19 @@ 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,
.irq_flags = IRQF_SHARED,
.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;

Expand All @@ -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;
}

/*
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down

0 comments on commit 44b1fbc

Please sign in to comment.