Blame view
drivers/ata/pata_platform.c
7.04 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 16 17 18 19 20 21 |
* * 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> #include <linux/init.h> #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... |
22 |
#include <linux/ata_platform.h> |
a20c9e820 [PATCH] ata: Gene... |
23 24 |
#define DRV_NAME "pata_platform" |
f7fc0ceb4 libata: pata_plat... |
25 |
#define DRV_VERSION "1.2" |
a20c9e820 [PATCH] ata: Gene... |
26 27 28 29 30 31 32 |
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... |
33 |
static int pata_platform_set_mode(struct ata_link *link, struct ata_device **unused) |
a20c9e820 [PATCH] ata: Gene... |
34 |
{ |
f58229f80 libata-link: impl... |
35 |
struct ata_device *dev; |
a20c9e820 [PATCH] ata: Gene... |
36 |
|
1eca4365b libata: beef up i... |
37 38 39 40 41 |
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_... |
42 43 |
ata_dev_info(dev, "configured for PIO "); |
a20c9e820 [PATCH] ata: Gene... |
44 |
} |
161c888b0 [PATCH] pata_plat... |
45 |
return 0; |
a20c9e820 [PATCH] ata: Gene... |
46 |
} |
a20c9e820 [PATCH] ata: Gene... |
47 |
static struct scsi_host_template pata_platform_sht = { |
68d1d07b5 libata: implement... |
48 |
ATA_PIO_SHT(DRV_NAME), |
a20c9e820 [PATCH] ata: Gene... |
49 50 51 |
}; static struct ata_port_operations pata_platform_port_ops = { |
029cfd6b7 libata: implement... |
52 |
.inherits = &ata_sff_port_ops, |
5682ed33a libata: rename SF... |
53 |
.sff_data_xfer = ata_sff_data_xfer_noirq, |
029cfd6b7 libata: implement... |
54 55 |
.cable_detect = ata_cable_unknown, .set_mode = pata_platform_set_mode, |
a20c9e820 [PATCH] ata: Gene... |
56 57 58 |
}; static void pata_platform_setup_port(struct ata_ioports *ioaddr, |
cf03613e9 libata: pata_plat... |
59 |
unsigned int shift) |
a20c9e820 [PATCH] ata: Gene... |
60 |
{ |
a20c9e820 [PATCH] ata: Gene... |
61 |
/* Fixup the port shift for platforms that need it */ |
a20c9e820 [PATCH] ata: Gene... |
62 63 64 65 66 67 68 69 70 71 72 73 74 |
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... |
75 76 77 78 79 80 81 |
* __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 |
a20c9e820 [PATCH] ata: Gene... |
82 83 84 85 |
* * Register a platform bus IDE interface. Such interfaces are PIO and we * assume do not support IRQ sharing. * |
f7fc0ceb4 libata: pata_plat... |
86 |
* Platform devices are expected to contain at least 2 resources per port: |
a20c9e820 [PATCH] ata: Gene... |
87 88 89 |
* * - I/O Base (IORESOURCE_IO or IORESOURCE_MEM) * - CTL Base (IORESOURCE_IO or IORESOURCE_MEM) |
f7fc0ceb4 libata: pata_plat... |
90 91 92 |
* * and optionally: * |
a20c9e820 [PATCH] ata: Gene... |
93 94 95 96 97 |
* - 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... |
98 99 |
* * If no IRQ resource is present, PIO polling mode is used instead. |
a20c9e820 [PATCH] ata: Gene... |
100 |
*/ |
cf03613e9 libata: pata_plat... |
101 102 103 104 105 106 |
int __devinit __pata_platform_probe(struct device *dev, struct resource *io_res, struct resource *ctl_res, struct resource *irq_res, unsigned int ioport_shift, int __pio_mask) |
a20c9e820 [PATCH] ata: Gene... |
107 |
{ |
5d728824e libata: convert t... |
108 109 |
struct ata_host *host; struct ata_port *ap; |
a20c9e820 [PATCH] ata: Gene... |
110 |
unsigned int mmio; |
cf03613e9 libata: pata_plat... |
111 112 |
int irq = 0; int irq_flags = 0; |
a20c9e820 [PATCH] ata: Gene... |
113 114 115 116 117 118 119 120 |
/* * Check for MMIO */ mmio = (( io_res->flags == IORESOURCE_MEM) && (ctl_res->flags == IORESOURCE_MEM)); /* |
f7fc0ceb4 libata: pata_plat... |
121 122 |
* And the IRQ */ |
cf03613e9 libata: pata_plat... |
123 124 125 126 |
if (irq_res && irq_res->start > 0) { irq = irq_res->start; irq_flags = irq_res->flags; } |
f7fc0ceb4 libata: pata_plat... |
127 128 |
/* |
a20c9e820 [PATCH] ata: Gene... |
129 130 |
* Now that that's out of the way, wire up the port.. */ |
cf03613e9 libata: pata_plat... |
131 |
host = ata_host_alloc(dev, 1); |
5d728824e libata: convert t... |
132 133 134 135 136 |
if (!host) return -ENOMEM; ap = host->ports[0]; ap->ops = &pata_platform_port_ops; |
cf03613e9 libata: pata_plat... |
137 |
ap->pio_mask = __pio_mask; |
5d728824e libata: convert t... |
138 |
ap->flags |= ATA_FLAG_SLAVE_POSS; |
a20c9e820 [PATCH] ata: Gene... |
139 140 |
/* |
f7fc0ceb4 libata: pata_plat... |
141 142 143 144 145 146 147 148 |
* 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... |
149 150 151 |
* Handle the MMIO case */ if (mmio) { |
cf03613e9 libata: pata_plat... |
152 |
ap->ioaddr.cmd_addr = devm_ioremap(dev, io_res->start, |
041b5eac2 drivers/ata: use ... |
153 |
resource_size(io_res)); |
cf03613e9 libata: pata_plat... |
154 |
ap->ioaddr.ctl_addr = devm_ioremap(dev, ctl_res->start, |
041b5eac2 drivers/ata: use ... |
155 |
resource_size(ctl_res)); |
a20c9e820 [PATCH] ata: Gene... |
156 |
} else { |
cf03613e9 libata: pata_plat... |
157 |
ap->ioaddr.cmd_addr = devm_ioport_map(dev, io_res->start, |
041b5eac2 drivers/ata: use ... |
158 |
resource_size(io_res)); |
cf03613e9 libata: pata_plat... |
159 |
ap->ioaddr.ctl_addr = devm_ioport_map(dev, ctl_res->start, |
041b5eac2 drivers/ata: use ... |
160 |
resource_size(ctl_res)); |
0d5ff5667 libata: convert t... |
161 |
} |
5d728824e libata: convert t... |
162 |
if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) { |
cf03613e9 libata: pata_plat... |
163 164 |
dev_err(dev, "failed to map IO/CTL base "); |
0d5ff5667 libata: convert t... |
165 |
return -ENOMEM; |
a20c9e820 [PATCH] ata: Gene... |
166 |
} |
5d728824e libata: convert t... |
167 |
ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; |
a20c9e820 [PATCH] ata: Gene... |
168 |
|
cf03613e9 libata: pata_plat... |
169 |
pata_platform_setup_port(&ap->ioaddr, ioport_shift); |
a20c9e820 [PATCH] ata: Gene... |
170 |
|
cbcdd8759 libata: implement... |
171 172 173 |
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... |
174 |
/* activate */ |
9363c3825 libata: rename SF... |
175 |
return ata_host_activate(host, irq, irq ? ata_sff_interrupt : NULL, |
cf03613e9 libata: pata_plat... |
176 |
irq_flags, &pata_platform_sht); |
a20c9e820 [PATCH] ata: Gene... |
177 |
} |
cf03613e9 libata: pata_plat... |
178 |
EXPORT_SYMBOL_GPL(__pata_platform_probe); |
a20c9e820 [PATCH] ata: Gene... |
179 180 |
/** |
cf03613e9 libata: pata_plat... |
181 182 |
* __pata_platform_remove - unplug a platform interface * @dev: device |
a20c9e820 [PATCH] ata: Gene... |
183 184 185 186 |
* * A platform bus ATA device has been unplugged. Perform the needed * cleanup. Also called on module unload for any active devices. */ |
78a7ba47f pata_platform: __... |
187 |
int __pata_platform_remove(struct device *dev) |
a20c9e820 [PATCH] ata: Gene... |
188 |
{ |
a20c9e820 [PATCH] ata: Gene... |
189 |
struct ata_host *host = dev_get_drvdata(dev); |
1a68ff13c pata_platform: fi... |
190 |
ata_host_detach(host); |
a20c9e820 [PATCH] ata: Gene... |
191 192 193 |
return 0; } |
cf03613e9 libata: pata_plat... |
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
EXPORT_SYMBOL_GPL(__pata_platform_remove); static int __devinit pata_platform_probe(struct platform_device *pdev) { struct resource *io_res; struct resource *ctl_res; struct resource *irq_res; struct pata_platform_info *pp_info = pdev->dev.platform_data; /* * 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); if (irq_res) irq_res->flags = pp_info ? pp_info->irq_flags : 0; return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res, pp_info ? pp_info->ioport_shift : 0, pio_mask); } static int __devexit pata_platform_remove(struct platform_device *pdev) { return __pata_platform_remove(&pdev->dev); } |
a20c9e820 [PATCH] ata: Gene... |
248 249 250 251 252 253 254 255 256 |
static struct platform_driver pata_platform_driver = { .probe = pata_platform_probe, .remove = __devexit_p(pata_platform_remove), .driver = { .name = DRV_NAME, .owner = THIS_MODULE, }, }; |
99c8ea3e5 SATA/PATA: conver... |
257 |
module_platform_driver(pata_platform_driver); |
a20c9e820 [PATCH] ata: Gene... |
258 259 260 261 262 263 264 |
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... |
265 |
MODULE_ALIAS("platform:" DRV_NAME); |