Blame view
drivers/ata/pata_platform.c
6.62 KB
a20c9e820 [PATCH] ata: Gene... |
1 2 3 |
/* * Generic platform device PATA driver * |
f7fc0ceb4 libata: pata_plat... |
4 |
* Copyright (C) 2006 - 2007 Paul Mundt |
a20c9e820 [PATCH] ata: Gene... |
5 6 7 |
* * Based on pata_pcmcia: * |
ab7716300 ata: Switch all m... |
8 |
* Copyright 2005-2006 Red Hat Inc, all rights reserved. |
a20c9e820 [PATCH] ata: Gene... |
9 10 11 12 13 14 15 |
* * 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/kernel.h> #include <linux/module.h> |
a20c9e820 [PATCH] ata: Gene... |
16 17 18 19 20 |
#include <linux/blkdev.h> #include <scsi/scsi_host.h> #include <linux/ata.h> #include <linux/libata.h> #include <linux/platform_device.h> |
0a87e3e92 Rename: linux/pat... |
21 |
#include <linux/ata_platform.h> |
a20c9e820 [PATCH] ata: Gene... |
22 23 |
#define DRV_NAME "pata_platform" |
f7fc0ceb4 libata: pata_plat... |
24 |
#define DRV_VERSION "1.2" |
a20c9e820 [PATCH] ata: Gene... |
25 26 27 28 29 30 31 |
static int pio_mask = 1; /* * Provide our own set_mode() as we don't want to change anything that has * already been configured.. */ |
0260731f0 libata-link: link... |
32 |
static int pata_platform_set_mode(struct ata_link *link, struct ata_device **unused) |
a20c9e820 [PATCH] ata: Gene... |
33 |
{ |
f58229f80 libata-link: impl... |
34 |
struct ata_device *dev; |
a20c9e820 [PATCH] ata: Gene... |
35 |
|
1eca4365b libata: beef up i... |
36 37 38 39 40 |
ata_for_each_dev(dev, link, ENABLED) { /* We don't really care */ dev->pio_mode = dev->xfer_mode = XFER_PIO_0; dev->xfer_shift = ATA_SHIFT_PIO; dev->flags |= ATA_DFLAG_PIO; |
a9a79dfec ata: Convert ata_... |
41 42 |
ata_dev_info(dev, "configured for PIO "); |
a20c9e820 [PATCH] ata: Gene... |
43 |
} |
161c888b0 [PATCH] pata_plat... |
44 |
return 0; |
a20c9e820 [PATCH] ata: Gene... |
45 |
} |
a20c9e820 [PATCH] ata: Gene... |
46 |
static struct scsi_host_template pata_platform_sht = { |
68d1d07b5 libata: implement... |
47 |
ATA_PIO_SHT(DRV_NAME), |
a20c9e820 [PATCH] ata: Gene... |
48 |
}; |
a20c9e820 [PATCH] ata: Gene... |
49 |
static void pata_platform_setup_port(struct ata_ioports *ioaddr, |
cf03613e9 libata: pata_plat... |
50 |
unsigned int shift) |
a20c9e820 [PATCH] ata: Gene... |
51 |
{ |
a20c9e820 [PATCH] ata: Gene... |
52 |
/* Fixup the port shift for platforms that need it */ |
a20c9e820 [PATCH] ata: Gene... |
53 54 55 56 57 58 59 60 61 62 63 64 65 |
ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift); ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift); ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift); ioaddr->nsect_addr = ioaddr->cmd_addr + (ATA_REG_NSECT << shift); ioaddr->lbal_addr = ioaddr->cmd_addr + (ATA_REG_LBAL << shift); ioaddr->lbam_addr = ioaddr->cmd_addr + (ATA_REG_LBAM << shift); ioaddr->lbah_addr = ioaddr->cmd_addr + (ATA_REG_LBAH << shift); ioaddr->device_addr = ioaddr->cmd_addr + (ATA_REG_DEVICE << shift); ioaddr->status_addr = ioaddr->cmd_addr + (ATA_REG_STATUS << shift); ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << shift); } /** |
cf03613e9 libata: pata_plat... |
66 67 68 69 70 71 72 |
* __pata_platform_probe - attach a platform interface * @dev: device * @io_res: Resource representing I/O base * @ctl_res: Resource representing CTL base * @irq_res: Resource representing IRQ and its flags * @ioport_shift: I/O port shift * @__pio_mask: PIO mask |
172639053 ata: pata_platfor... |
73 |
* @sht: scsi_host_template to use when registering |
f3d5e4f18 ata: pata_of_plat... |
74 |
* @use16bit: Flag to indicate 16-bit IO instead of 32-bit |
a20c9e820 [PATCH] ata: Gene... |
75 76 77 78 |
* * Register a platform bus IDE interface. Such interfaces are PIO and we * assume do not support IRQ sharing. * |
f7fc0ceb4 libata: pata_plat... |
79 |
* Platform devices are expected to contain at least 2 resources per port: |
a20c9e820 [PATCH] ata: Gene... |
80 81 82 |
* * - I/O Base (IORESOURCE_IO or IORESOURCE_MEM) * - CTL Base (IORESOURCE_IO or IORESOURCE_MEM) |
f7fc0ceb4 libata: pata_plat... |
83 84 85 |
* * and optionally: * |
a20c9e820 [PATCH] ata: Gene... |
86 87 88 89 90 |
* - IRQ (IORESOURCE_IRQ) * * If the base resources are both mem types, the ioremap() is handled * here. For IORESOURCE_IO, it's assumed that there's no remapping * necessary. |
f7fc0ceb4 libata: pata_plat... |
91 92 |
* * If no IRQ resource is present, PIO polling mode is used instead. |
a20c9e820 [PATCH] ata: Gene... |
93 |
*/ |
0ec249146 Drivers: ata: rem... |
94 95 |
int __pata_platform_probe(struct device *dev, struct resource *io_res, struct resource *ctl_res, struct resource *irq_res, |
172639053 ata: pata_platfor... |
96 |
unsigned int ioport_shift, int __pio_mask, |
f3d5e4f18 ata: pata_of_plat... |
97 |
struct scsi_host_template *sht, bool use16bit) |
a20c9e820 [PATCH] ata: Gene... |
98 |
{ |
5d728824e libata: convert t... |
99 100 |
struct ata_host *host; struct ata_port *ap; |
a20c9e820 [PATCH] ata: Gene... |
101 |
unsigned int mmio; |
cf03613e9 libata: pata_plat... |
102 103 |
int irq = 0; int irq_flags = 0; |
a20c9e820 [PATCH] ata: Gene... |
104 105 106 107 108 109 110 111 |
/* * Check for MMIO */ mmio = (( io_res->flags == IORESOURCE_MEM) && (ctl_res->flags == IORESOURCE_MEM)); /* |
f7fc0ceb4 libata: pata_plat... |
112 113 |
* And the IRQ */ |
cf03613e9 libata: pata_plat... |
114 115 |
if (irq_res && irq_res->start > 0) { irq = irq_res->start; |
baac9ce1f ata: pata_platfor... |
116 |
irq_flags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; |
cf03613e9 libata: pata_plat... |
117 |
} |
f7fc0ceb4 libata: pata_plat... |
118 119 |
/* |
a20c9e820 [PATCH] ata: Gene... |
120 121 |
* Now that that's out of the way, wire up the port.. */ |
cf03613e9 libata: pata_plat... |
122 |
host = ata_host_alloc(dev, 1); |
5d728824e libata: convert t... |
123 124 125 |
if (!host) return -ENOMEM; ap = host->ports[0]; |
f3d5e4f18 ata: pata_of_plat... |
126 127 128 129 130 131 132 133 |
ap->ops = devm_kzalloc(dev, sizeof(*ap->ops), GFP_KERNEL); ap->ops->inherits = &ata_sff_port_ops; ap->ops->cable_detect = ata_cable_unknown; ap->ops->set_mode = pata_platform_set_mode; if (use16bit) ap->ops->sff_data_xfer = ata_sff_data_xfer; else ap->ops->sff_data_xfer = ata_sff_data_xfer32; |
cf03613e9 libata: pata_plat... |
134 |
ap->pio_mask = __pio_mask; |
5d728824e libata: convert t... |
135 |
ap->flags |= ATA_FLAG_SLAVE_POSS; |
a20c9e820 [PATCH] ata: Gene... |
136 137 |
/* |
f7fc0ceb4 libata: pata_plat... |
138 139 140 141 142 143 144 145 |
* Use polling mode if there's no IRQ */ if (!irq) { ap->flags |= ATA_FLAG_PIO_POLLING; ata_port_desc(ap, "no IRQ, using PIO polling"); } /* |
a20c9e820 [PATCH] ata: Gene... |
146 147 148 |
* Handle the MMIO case */ if (mmio) { |
cf03613e9 libata: pata_plat... |
149 |
ap->ioaddr.cmd_addr = devm_ioremap(dev, io_res->start, |
041b5eac2 drivers/ata: use ... |
150 |
resource_size(io_res)); |
cf03613e9 libata: pata_plat... |
151 |
ap->ioaddr.ctl_addr = devm_ioremap(dev, ctl_res->start, |
041b5eac2 drivers/ata: use ... |
152 |
resource_size(ctl_res)); |
a20c9e820 [PATCH] ata: Gene... |
153 |
} else { |
cf03613e9 libata: pata_plat... |
154 |
ap->ioaddr.cmd_addr = devm_ioport_map(dev, io_res->start, |
041b5eac2 drivers/ata: use ... |
155 |
resource_size(io_res)); |
cf03613e9 libata: pata_plat... |
156 |
ap->ioaddr.ctl_addr = devm_ioport_map(dev, ctl_res->start, |
041b5eac2 drivers/ata: use ... |
157 |
resource_size(ctl_res)); |
0d5ff5667 libata: convert t... |
158 |
} |
5d728824e libata: convert t... |
159 |
if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) { |
cf03613e9 libata: pata_plat... |
160 161 |
dev_err(dev, "failed to map IO/CTL base "); |
0d5ff5667 libata: convert t... |
162 |
return -ENOMEM; |
a20c9e820 [PATCH] ata: Gene... |
163 |
} |
5d728824e libata: convert t... |
164 |
ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; |
a20c9e820 [PATCH] ata: Gene... |
165 |
|
cf03613e9 libata: pata_plat... |
166 |
pata_platform_setup_port(&ap->ioaddr, ioport_shift); |
a20c9e820 [PATCH] ata: Gene... |
167 |
|
cbcdd8759 libata: implement... |
168 169 170 |
ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport", (unsigned long long)io_res->start, (unsigned long long)ctl_res->start); |
5d728824e libata: convert t... |
171 |
/* activate */ |
9363c3825 libata: rename SF... |
172 |
return ata_host_activate(host, irq, irq ? ata_sff_interrupt : NULL, |
172639053 ata: pata_platfor... |
173 |
irq_flags, sht); |
a20c9e820 [PATCH] ata: Gene... |
174 |
} |
cf03613e9 libata: pata_plat... |
175 |
EXPORT_SYMBOL_GPL(__pata_platform_probe); |
a20c9e820 [PATCH] ata: Gene... |
176 |
|
0ec249146 Drivers: ata: rem... |
177 |
static int pata_platform_probe(struct platform_device *pdev) |
cf03613e9 libata: pata_plat... |
178 179 180 181 |
{ struct resource *io_res; struct resource *ctl_res; struct resource *irq_res; |
61b8c345a ata: use dev_get_... |
182 |
struct pata_platform_info *pp_info = dev_get_platdata(&pdev->dev); |
cf03613e9 libata: pata_plat... |
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
/* * Simple resource validation .. */ if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) { dev_err(&pdev->dev, "invalid number of resources "); return -EINVAL; } /* * Get the I/O base first */ io_res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (io_res == NULL) { io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(io_res == NULL)) return -EINVAL; } /* * Then the CTL base */ ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1); if (ctl_res == NULL) { ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (unlikely(ctl_res == NULL)) return -EINVAL; } /* * And the IRQ */ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
cf03613e9 libata: pata_plat... |
217 218 219 |
return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res, pp_info ? pp_info->ioport_shift : 0, |
f3d5e4f18 ata: pata_of_plat... |
220 |
pio_mask, &pata_platform_sht, false); |
cf03613e9 libata: pata_plat... |
221 |
} |
a20c9e820 [PATCH] ata: Gene... |
222 223 |
static struct platform_driver pata_platform_driver = { .probe = pata_platform_probe, |
ccd1196a9 pata_platform: ut... |
224 |
.remove = ata_platform_remove_one, |
a20c9e820 [PATCH] ata: Gene... |
225 226 |
.driver = { .name = DRV_NAME, |
a20c9e820 [PATCH] ata: Gene... |
227 228 |
}, }; |
99c8ea3e5 SATA/PATA: conver... |
229 |
module_platform_driver(pata_platform_driver); |
a20c9e820 [PATCH] ata: Gene... |
230 231 232 233 234 235 236 |
module_param(pio_mask, int, 0); MODULE_AUTHOR("Paul Mundt"); MODULE_DESCRIPTION("low-level driver for platform device ATA"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); |
458622fcd ATA/IDE: fix plat... |
237 |
MODULE_ALIAS("platform:" DRV_NAME); |