diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2008-04-28 07:41:36 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-29 02:16:25 -0400 |
commit | 3dd654bfdf8905d0acb6f6231b5e736d2b0d4bc6 (patch) | |
tree | 5d5cf68ed77f2dd57b04d0dd672ff633750ba43f /drivers/ata/pata_rb532_cf.c | |
parent | a01e035ebb552223c03f2d9138ffc73f2d4d3965 (diff) |
[MIPS] ATA: Rename routerboard 500 to 532
The platform is actually named routerboard 532 so let's call it this. This
patch only rename files, Kconfig and C symbols; no functional changes.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/pata_rb532_cf.c')
-rw-r--r-- | drivers/ata/pata_rb532_cf.c | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c new file mode 100644 index 000000000000..a108d259f19d --- /dev/null +++ b/drivers/ata/pata_rb532_cf.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | * A low-level PATA driver to handle a Compact Flash connected on the | ||
3 | * Mikrotik's RouterBoard 532 board. | ||
4 | * | ||
5 | * Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org> | ||
6 | * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> | ||
7 | * | ||
8 | * This file was based on: drivers/ata/pata_ixp4xx_cf.c | ||
9 | * Copyright (C) 2006-07 Tower Technologies | ||
10 | * Author: Alessandro Zummo <a.zummo@towertech.it> | ||
11 | * | ||
12 | * Also was based on the driver for Linux 2.4.xx published by Mikrotik for | ||
13 | * their RouterBoard 1xx and 5xx series devices. The original Mikrotik code | ||
14 | * seems not to have a license. | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License version 2 as | ||
18 | * published by the Free Software Foundation. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | |||
26 | #include <linux/io.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/irq.h> | ||
29 | |||
30 | #include <linux/libata.h> | ||
31 | #include <scsi/scsi_host.h> | ||
32 | |||
33 | #include <asm/gpio.h> | ||
34 | |||
35 | #define DRV_NAME "pata-rb532-cf" | ||
36 | #define DRV_VERSION "0.1.0" | ||
37 | #define DRV_DESC "PATA driver for RouterBOARD 532 Compact Flash" | ||
38 | |||
39 | #define RB500_CF_MAXPORTS 1 | ||
40 | #define RB500_CF_IO_DELAY 400 | ||
41 | |||
42 | #define RB500_CF_REG_CMD 0x0800 | ||
43 | #define RB500_CF_REG_CTRL 0x080E | ||
44 | #define RB500_CF_REG_DATA 0x0C00 | ||
45 | |||
46 | struct rb532_cf_info { | ||
47 | void __iomem *iobase; | ||
48 | unsigned int gpio_line; | ||
49 | int frozen; | ||
50 | unsigned int irq; | ||
51 | }; | ||
52 | |||
53 | /* ------------------------------------------------------------------------ */ | ||
54 | |||
55 | static inline void rb532_pata_finish_io(struct ata_port *ap) | ||
56 | { | ||
57 | struct ata_host *ah = ap->host; | ||
58 | struct rb532_cf_info *info = ah->private_data; | ||
59 | |||
60 | ata_sff_altstatus(ap); | ||
61 | ndelay(RB500_CF_IO_DELAY); | ||
62 | |||
63 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); | ||
64 | } | ||
65 | |||
66 | static void rb532_pata_exec_command(struct ata_port *ap, | ||
67 | const struct ata_taskfile *tf) | ||
68 | { | ||
69 | writeb(tf->command, ap->ioaddr.command_addr); | ||
70 | rb532_pata_finish_io(ap); | ||
71 | } | ||
72 | |||
73 | static void rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf, | ||
74 | unsigned int buflen, int write_data) | ||
75 | { | ||
76 | struct ata_port *ap = adev->link->ap; | ||
77 | void __iomem *ioaddr = ap->ioaddr.data_addr; | ||
78 | |||
79 | if (write_data) { | ||
80 | for (; buflen > 0; buflen--, buf++) | ||
81 | writeb(*buf, ioaddr); | ||
82 | } else { | ||
83 | for (; buflen > 0; buflen--, buf++) | ||
84 | *buf = readb(ioaddr); | ||
85 | } | ||
86 | |||
87 | rb532_pata_finish_io(adev->link->ap); | ||
88 | } | ||
89 | |||
90 | static void rb532_pata_freeze(struct ata_port *ap) | ||
91 | { | ||
92 | struct rb532_cf_info *info = ap->host->private_data; | ||
93 | |||
94 | info->frozen = 1; | ||
95 | } | ||
96 | |||
97 | static void rb532_pata_thaw(struct ata_port *ap) | ||
98 | { | ||
99 | struct rb532_cf_info *info = ap->host->private_data; | ||
100 | |||
101 | info->frozen = 0; | ||
102 | } | ||
103 | |||
104 | static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance) | ||
105 | { | ||
106 | struct ata_host *ah = dev_instance; | ||
107 | struct rb532_cf_info *info = ah->private_data; | ||
108 | |||
109 | if (gpio_get_value(info->gpio_line)) { | ||
110 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW); | ||
111 | if (!info->frozen) | ||
112 | ata_sff_interrupt(info->irq, dev_instance); | ||
113 | } else { | ||
114 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); | ||
115 | } | ||
116 | |||
117 | return IRQ_HANDLED; | ||
118 | } | ||
119 | |||
120 | static struct ata_port_operations rb532_pata_port_ops = { | ||
121 | .inherits = &ata_sff_port_ops, | ||
122 | .sff_exec_command = rb532_pata_exec_command, | ||
123 | .sff_data_xfer = rb532_pata_data_xfer, | ||
124 | .freeze = rb532_pata_freeze, | ||
125 | .thaw = rb532_pata_thaw, | ||
126 | }; | ||
127 | |||
128 | /* ------------------------------------------------------------------------ */ | ||
129 | |||
130 | static struct scsi_host_template rb532_pata_sht = { | ||
131 | ATA_PIO_SHT(DRV_NAME), | ||
132 | }; | ||
133 | |||
134 | /* ------------------------------------------------------------------------ */ | ||
135 | |||
136 | static void rb532_pata_setup_ports(struct ata_host *ah) | ||
137 | { | ||
138 | struct rb532_cf_info *info = ah->private_data; | ||
139 | struct ata_port *ap; | ||
140 | |||
141 | ap = ah->ports[0]; | ||
142 | |||
143 | ap->ops = &rb532_pata_port_ops; | ||
144 | ap->pio_mask = 0x1f; /* PIO4 */ | ||
145 | ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; | ||
146 | |||
147 | ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_CMD; | ||
148 | ap->ioaddr.ctl_addr = info->iobase + RB500_CF_REG_CTRL; | ||
149 | ap->ioaddr.altstatus_addr = info->iobase + RB500_CF_REG_CTRL; | ||
150 | |||
151 | ata_sff_std_ports(&ap->ioaddr); | ||
152 | |||
153 | ap->ioaddr.data_addr = info->iobase + RB500_CF_REG_DATA; | ||
154 | } | ||
155 | |||
156 | static __devinit int rb532_pata_driver_probe(struct platform_device *pdev) | ||
157 | { | ||
158 | unsigned int irq; | ||
159 | int gpio; | ||
160 | struct resource *res; | ||
161 | struct ata_host *ah; | ||
162 | struct rb532_cf_info *info; | ||
163 | int ret; | ||
164 | |||
165 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
166 | if (!res) { | ||
167 | dev_err(&pdev->dev, "no IOMEM resource found\n"); | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | irq = platform_get_irq(pdev, 0); | ||
172 | if (irq <= 0) { | ||
173 | dev_err(&pdev->dev, "no IRQ resource found\n"); | ||
174 | return -ENOENT; | ||
175 | } | ||
176 | |||
177 | gpio = irq_to_gpio(irq); | ||
178 | if (gpio < 0) { | ||
179 | dev_err(&pdev->dev, "no GPIO found for irq%d\n", irq); | ||
180 | return -ENOENT; | ||
181 | } | ||
182 | |||
183 | ret = gpio_request(gpio, DRV_NAME); | ||
184 | if (ret) { | ||
185 | dev_err(&pdev->dev, "GPIO request failed\n"); | ||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | /* allocate host */ | ||
190 | ah = ata_host_alloc(&pdev->dev, RB500_CF_MAXPORTS); | ||
191 | if (!ah) | ||
192 | return -ENOMEM; | ||
193 | |||
194 | platform_set_drvdata(pdev, ah); | ||
195 | |||
196 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
197 | if (!info) | ||
198 | return -ENOMEM; | ||
199 | |||
200 | ah->private_data = info; | ||
201 | info->gpio_line = gpio; | ||
202 | info->irq = irq; | ||
203 | |||
204 | info->iobase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
205 | res->end - res->start + 1); | ||
206 | if (!info->iobase) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | ret = gpio_direction_input(gpio); | ||
210 | if (ret) { | ||
211 | dev_err(&pdev->dev, "unable to set GPIO direction, err=%d\n", | ||
212 | ret); | ||
213 | goto err_free_gpio; | ||
214 | } | ||
215 | |||
216 | rb532_pata_setup_ports(ah); | ||
217 | |||
218 | ret = ata_host_activate(ah, irq, rb532_pata_irq_handler, | ||
219 | IRQF_TRIGGER_LOW, &rb532_pata_sht); | ||
220 | if (ret) | ||
221 | goto err_free_gpio; | ||
222 | |||
223 | return 0; | ||
224 | |||
225 | err_free_gpio: | ||
226 | gpio_free(gpio); | ||
227 | |||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | static __devexit int rb532_pata_driver_remove(struct platform_device *pdev) | ||
232 | { | ||
233 | struct ata_host *ah = platform_get_drvdata(pdev); | ||
234 | struct rb532_cf_info *info = ah->private_data; | ||
235 | |||
236 | ata_host_detach(ah); | ||
237 | gpio_free(info->gpio_line); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | /* work with hotplug and coldplug */ | ||
243 | MODULE_ALIAS("platform:" DRV_NAME); | ||
244 | |||
245 | static struct platform_driver rb532_pata_platform_driver = { | ||
246 | .probe = rb532_pata_driver_probe, | ||
247 | .remove = __devexit_p(rb532_pata_driver_remove), | ||
248 | .driver = { | ||
249 | .name = DRV_NAME, | ||
250 | .owner = THIS_MODULE, | ||
251 | }, | ||
252 | }; | ||
253 | |||
254 | /* ------------------------------------------------------------------------ */ | ||
255 | |||
256 | #define DRV_INFO DRV_DESC " version " DRV_VERSION | ||
257 | |||
258 | static int __init rb532_pata_module_init(void) | ||
259 | { | ||
260 | printk(KERN_INFO DRV_INFO "\n"); | ||
261 | |||
262 | return platform_driver_register(&rb532_pata_platform_driver); | ||
263 | } | ||
264 | |||
265 | static void __exit rb532_pata_module_exit(void) | ||
266 | { | ||
267 | platform_driver_unregister(&rb532_pata_platform_driver); | ||
268 | } | ||
269 | |||
270 | MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>"); | ||
271 | MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); | ||
272 | MODULE_DESCRIPTION(DRV_DESC); | ||
273 | MODULE_VERSION(DRV_VERSION); | ||
274 | MODULE_LICENSE("GPL"); | ||
275 | |||
276 | module_init(rb532_pata_module_init); | ||
277 | module_exit(rb532_pata_module_exit); | ||