summaryrefslogtreecommitdiff
path: root/drivers/ata/pata_falcon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/pata_falcon.c')
-rw-r--r--drivers/ata/pata_falcon.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/drivers/ata/pata_falcon.c b/drivers/ata/pata_falcon.c
index 27b0952fde6b..9d0dd8f4c21c 100644
--- a/drivers/ata/pata_falcon.c
+++ b/drivers/ata/pata_falcon.c
@@ -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)