diff options
author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2017-03-15 09:39:11 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2017-03-16 17:10:52 -0400 |
commit | 3075b62d15df424b8e87447eb13e1604240293f2 (patch) | |
tree | 78307cc12ff3185b7dd2164cf843ce3d513584dc | |
parent | af27e01cfcfcdf7f45488e023b474eb6de5f732e (diff) |
pata: remove the at91 driver
This driver is orphan since commit b2026f708e09 ("ARM: at91: remove
at91sam9260/at91sam9g20 legacy board support"). Given that nobody cared
adding DT support to it, it probably means it's no longer used and is
thus a good candidate for removal.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Acked-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r-- | drivers/ata/Kconfig | 8 | ||||
-rw-r--r-- | drivers/ata/Makefile | 1 | ||||
-rw-r--r-- | drivers/ata/pata_at91.c | 503 |
3 files changed, 0 insertions, 512 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 7e0fc9888f96..19069feb196d 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -884,14 +884,6 @@ config PATA_AT32 | |||
884 | 884 | ||
885 | If unsure, say N. | 885 | If unsure, say N. |
886 | 886 | ||
887 | config PATA_AT91 | ||
888 | tristate "PATA support for AT91SAM9260" | ||
889 | depends on ARM && SOC_AT91SAM9 | ||
890 | help | ||
891 | This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. | ||
892 | |||
893 | If unsure, say N. | ||
894 | |||
895 | config PATA_CMD640_PCI | 887 | config PATA_CMD640_PCI |
896 | tristate "CMD640 PCI PATA support (Experimental)" | 888 | tristate "CMD640 PCI PATA support (Experimental)" |
897 | depends on PCI | 889 | depends on PCI |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 89a0a1915d36..e29feb16bda1 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -91,7 +91,6 @@ obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o | |||
91 | 91 | ||
92 | # SFF PIO only | 92 | # SFF PIO only |
93 | obj-$(CONFIG_PATA_AT32) += pata_at32.o | 93 | obj-$(CONFIG_PATA_AT32) += pata_at32.o |
94 | obj-$(CONFIG_PATA_AT91) += pata_at91.o | ||
95 | obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o | 94 | obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o |
96 | obj-$(CONFIG_PATA_FALCON) += pata_falcon.o | 95 | obj-$(CONFIG_PATA_FALCON) += pata_falcon.o |
97 | obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o | 96 | obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o |
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c deleted file mode 100644 index fd5b34f0d007..000000000000 --- a/drivers/ata/pata_at91.c +++ /dev/null | |||
@@ -1,503 +0,0 @@ | |||
1 | /* | ||
2 | * PATA driver for AT91SAM9260 Static Memory Controller | ||
3 | * with CompactFlash interface in True IDE mode | ||
4 | * | ||
5 | * Copyright (C) 2009 Matyukevich Sergey | ||
6 | * 2011 Igor Plyatov | ||
7 | * | ||
8 | * Based on: | ||
9 | * * generic platform driver by Paul Mundt: drivers/ata/pata_platform.c | ||
10 | * * pata_at32 driver by Kristoffer Nyborg Gregertsen | ||
11 | * * at91_ide driver by Stanislaw Gruszka | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License version 2 | ||
15 | * as published by the Free Software Foundation. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/blkdev.h> | ||
22 | #include <linux/gfp.h> | ||
23 | #include <scsi/scsi_host.h> | ||
24 | #include <linux/ata.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/libata.h> | ||
27 | #include <linux/mfd/syscon.h> | ||
28 | #include <linux/mfd/syscon/atmel-smc.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/ata_platform.h> | ||
31 | #include <linux/platform_data/atmel.h> | ||
32 | #include <linux/regmap.h> | ||
33 | #include <linux/gpio.h> | ||
34 | |||
35 | #define DRV_NAME "pata_at91" | ||
36 | #define DRV_VERSION "0.3" | ||
37 | |||
38 | #define CF_IDE_OFFSET 0x00c00000 | ||
39 | #define CF_ALT_IDE_OFFSET 0x00e00000 | ||
40 | #define CF_IDE_RES_SIZE 0x08 | ||
41 | #define CS_PULSE_MAXIMUM 319 | ||
42 | #define ER_SMC_CALC 1 | ||
43 | #define ER_SMC_RECALC 2 | ||
44 | |||
45 | struct at91_ide_info { | ||
46 | unsigned long mode; | ||
47 | unsigned int cs; | ||
48 | struct clk *mck; | ||
49 | void __iomem *ide_addr; | ||
50 | void __iomem *alt_addr; | ||
51 | }; | ||
52 | |||
53 | /** | ||
54 | * struct smc_range - range of valid values for SMC register. | ||
55 | */ | ||
56 | struct smc_range { | ||
57 | int min; | ||
58 | int max; | ||
59 | }; | ||
60 | |||
61 | struct regmap *smc; | ||
62 | |||
63 | struct at91sam9_smc_generic_fields { | ||
64 | struct regmap_field *setup; | ||
65 | struct regmap_field *pulse; | ||
66 | struct regmap_field *cycle; | ||
67 | struct regmap_field *mode; | ||
68 | } fields; | ||
69 | |||
70 | /** | ||
71 | * adjust_smc_value - adjust value for one of SMC registers. | ||
72 | * @value: adjusted value | ||
73 | * @range: array of SMC ranges with valid values | ||
74 | * @size: SMC ranges array size | ||
75 | * | ||
76 | * This returns the difference between input and output value or negative | ||
77 | * in case of invalid input value. | ||
78 | * If negative returned, then output value = maximal possible from ranges. | ||
79 | */ | ||
80 | static int adjust_smc_value(int *value, struct smc_range *range, int size) | ||
81 | { | ||
82 | int maximum = (range + size - 1)->max; | ||
83 | int remainder; | ||
84 | |||
85 | do { | ||
86 | if (*value < range->min) { | ||
87 | remainder = range->min - *value; | ||
88 | *value = range->min; /* nearest valid value */ | ||
89 | return remainder; | ||
90 | } else if ((range->min <= *value) && (*value <= range->max)) | ||
91 | return 0; | ||
92 | |||
93 | range++; | ||
94 | } while (--size); | ||
95 | *value = maximum; | ||
96 | |||
97 | return -1; /* invalid value */ | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * calc_smc_vals - calculate SMC register values | ||
102 | * @dev: ATA device | ||
103 | * @setup: SMC_SETUP register value | ||
104 | * @pulse: SMC_PULSE register value | ||
105 | * @cycle: SMC_CYCLE register value | ||
106 | * | ||
107 | * This returns negative in case of invalid values for SMC registers: | ||
108 | * -ER_SMC_RECALC - recalculation required for SMC values, | ||
109 | * -ER_SMC_CALC - calculation failed (invalid input values). | ||
110 | * | ||
111 | * SMC use special coding scheme, see "Coding and Range of Timing | ||
112 | * Parameters" table from AT91SAM9 datasheets. | ||
113 | * | ||
114 | * SMC_SETUP = 128*setup[5] + setup[4:0] | ||
115 | * SMC_PULSE = 256*pulse[6] + pulse[5:0] | ||
116 | * SMC_CYCLE = 256*cycle[8:7] + cycle[6:0] | ||
117 | */ | ||
118 | static int calc_smc_vals(struct device *dev, | ||
119 | int *setup, int *pulse, int *cycle, int *cs_pulse) | ||
120 | { | ||
121 | int ret_val; | ||
122 | int err = 0; | ||
123 | struct smc_range range_setup[] = { /* SMC_SETUP valid values */ | ||
124 | {.min = 0, .max = 31}, /* first range */ | ||
125 | {.min = 128, .max = 159} /* second range */ | ||
126 | }; | ||
127 | struct smc_range range_pulse[] = { /* SMC_PULSE valid values */ | ||
128 | {.min = 0, .max = 63}, /* first range */ | ||
129 | {.min = 256, .max = 319} /* second range */ | ||
130 | }; | ||
131 | struct smc_range range_cycle[] = { /* SMC_CYCLE valid values */ | ||
132 | {.min = 0, .max = 127}, /* first range */ | ||
133 | {.min = 256, .max = 383}, /* second range */ | ||
134 | {.min = 512, .max = 639}, /* third range */ | ||
135 | {.min = 768, .max = 895} /* fourth range */ | ||
136 | }; | ||
137 | |||
138 | ret_val = adjust_smc_value(setup, range_setup, ARRAY_SIZE(range_setup)); | ||
139 | if (ret_val < 0) | ||
140 | dev_warn(dev, "maximal SMC Setup value\n"); | ||
141 | else | ||
142 | *cycle += ret_val; | ||
143 | |||
144 | ret_val = adjust_smc_value(pulse, range_pulse, ARRAY_SIZE(range_pulse)); | ||
145 | if (ret_val < 0) | ||
146 | dev_warn(dev, "maximal SMC Pulse value\n"); | ||
147 | else | ||
148 | *cycle += ret_val; | ||
149 | |||
150 | ret_val = adjust_smc_value(cycle, range_cycle, ARRAY_SIZE(range_cycle)); | ||
151 | if (ret_val < 0) | ||
152 | dev_warn(dev, "maximal SMC Cycle value\n"); | ||
153 | |||
154 | *cs_pulse = *cycle; | ||
155 | if (*cs_pulse > CS_PULSE_MAXIMUM) { | ||
156 | dev_err(dev, "unable to calculate valid SMC settings\n"); | ||
157 | return -ER_SMC_CALC; | ||
158 | } | ||
159 | |||
160 | ret_val = adjust_smc_value(cs_pulse, range_pulse, | ||
161 | ARRAY_SIZE(range_pulse)); | ||
162 | if (ret_val < 0) { | ||
163 | dev_warn(dev, "maximal SMC CS Pulse value\n"); | ||
164 | } else if (ret_val != 0) { | ||
165 | *cycle = *cs_pulse; | ||
166 | dev_warn(dev, "SMC Cycle extended\n"); | ||
167 | err = -ER_SMC_RECALC; | ||
168 | } | ||
169 | |||
170 | return err; | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * to_smc_format - convert values into SMC format | ||
175 | * @setup: SETUP value of SMC Setup Register | ||
176 | * @pulse: PULSE value of SMC Pulse Register | ||
177 | * @cycle: CYCLE value of SMC Cycle Register | ||
178 | * @cs_pulse: NCS_PULSE value of SMC Pulse Register | ||
179 | */ | ||
180 | static void to_smc_format(int *setup, int *pulse, int *cycle, int *cs_pulse) | ||
181 | { | ||
182 | *setup = (*setup & 0x1f) | ((*setup & 0x80) >> 2); | ||
183 | *pulse = (*pulse & 0x3f) | ((*pulse & 0x100) >> 2); | ||
184 | *cycle = (*cycle & 0x7f) | ((*cycle & 0x300) >> 1); | ||
185 | *cs_pulse = (*cs_pulse & 0x3f) | ((*cs_pulse & 0x100) >> 2); | ||
186 | } | ||
187 | |||
188 | static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz) | ||
189 | { | ||
190 | unsigned long mul; | ||
191 | |||
192 | /* | ||
193 | * cycles = x [nsec] * f [Hz] / 10^9 [ns in sec] = | ||
194 | * x * (f / 1_000_000_000) = | ||
195 | * x * ((f * 65536) / 1_000_000_000) / 65536 = | ||
196 | * x * (((f / 10_000) * 65536) / 100_000) / 65536 = | ||
197 | */ | ||
198 | |||
199 | mul = (mck_hz / 10000) << 16; | ||
200 | mul /= 100000; | ||
201 | |||
202 | return (ns * mul + 65536) >> 16; /* rounding */ | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * set_smc_timing - SMC timings setup. | ||
207 | * @dev: device | ||
208 | * @info: AT91 IDE info | ||
209 | * @ata: ATA timings | ||
210 | * | ||
211 | * Its assumed that write timings are same as read timings, | ||
212 | * cs_setup = 0 and cs_pulse = cycle. | ||
213 | */ | ||
214 | static void set_smc_timing(struct device *dev, struct ata_device *adev, | ||
215 | struct at91_ide_info *info, const struct ata_timing *ata) | ||
216 | { | ||
217 | int ret = 0; | ||
218 | int use_iordy; | ||
219 | unsigned int t6z; /* data tristate time in ns */ | ||
220 | unsigned int cycle; /* SMC Cycle width in MCK ticks */ | ||
221 | unsigned int setup; /* SMC Setup width in MCK ticks */ | ||
222 | unsigned int pulse; /* CFIOR and CFIOW pulse width in MCK ticks */ | ||
223 | unsigned int cs_pulse; /* CS4 or CS5 pulse width in MCK ticks*/ | ||
224 | unsigned int tdf_cycles; /* SMC TDF MCK ticks */ | ||
225 | unsigned long mck_hz; /* MCK frequency in Hz */ | ||
226 | |||
227 | t6z = (ata->mode < XFER_PIO_5) ? 30 : 20; | ||
228 | mck_hz = clk_get_rate(info->mck); | ||
229 | cycle = calc_mck_cycles(ata->cyc8b, mck_hz); | ||
230 | setup = calc_mck_cycles(ata->setup, mck_hz); | ||
231 | pulse = calc_mck_cycles(ata->act8b, mck_hz); | ||
232 | tdf_cycles = calc_mck_cycles(t6z, mck_hz); | ||
233 | |||
234 | do { | ||
235 | ret = calc_smc_vals(dev, &setup, &pulse, &cycle, &cs_pulse); | ||
236 | } while (ret == -ER_SMC_RECALC); | ||
237 | |||
238 | if (ret == -ER_SMC_CALC) | ||
239 | dev_err(dev, "Interface may not operate correctly\n"); | ||
240 | |||
241 | dev_dbg(dev, "SMC Setup=%u, Pulse=%u, Cycle=%u, CS Pulse=%u\n", | ||
242 | setup, pulse, cycle, cs_pulse); | ||
243 | to_smc_format(&setup, &pulse, &cycle, &cs_pulse); | ||
244 | /* disable or enable waiting for IORDY signal */ | ||
245 | use_iordy = ata_pio_need_iordy(adev); | ||
246 | if (use_iordy) | ||
247 | info->mode |= AT91_SMC_EXNWMODE_READY; | ||
248 | |||
249 | if (tdf_cycles > 15) { | ||
250 | tdf_cycles = 15; | ||
251 | dev_warn(dev, "maximal SMC TDF Cycles value\n"); | ||
252 | } | ||
253 | |||
254 | dev_dbg(dev, "Use IORDY=%u, TDF Cycles=%u\n", use_iordy, tdf_cycles); | ||
255 | |||
256 | regmap_fields_write(fields.setup, info->cs, | ||
257 | AT91SAM9_SMC_NRDSETUP(setup) | | ||
258 | AT91SAM9_SMC_NWESETUP(setup) | | ||
259 | AT91SAM9_SMC_NCS_NRDSETUP(0) | | ||
260 | AT91SAM9_SMC_NCS_WRSETUP(0)); | ||
261 | regmap_fields_write(fields.pulse, info->cs, | ||
262 | AT91SAM9_SMC_NRDPULSE(pulse) | | ||
263 | AT91SAM9_SMC_NWEPULSE(pulse) | | ||
264 | AT91SAM9_SMC_NCS_NRDPULSE(cs_pulse) | | ||
265 | AT91SAM9_SMC_NCS_WRPULSE(cs_pulse)); | ||
266 | regmap_fields_write(fields.cycle, info->cs, | ||
267 | AT91SAM9_SMC_NRDCYCLE(cycle) | | ||
268 | AT91SAM9_SMC_NWECYCLE(cycle)); | ||
269 | regmap_fields_write(fields.mode, info->cs, info->mode | | ||
270 | AT91_SMC_TDF_(tdf_cycles)); | ||
271 | } | ||
272 | |||
273 | static void pata_at91_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
274 | { | ||
275 | struct at91_ide_info *info = ap->host->private_data; | ||
276 | struct ata_timing timing; | ||
277 | int ret; | ||
278 | |||
279 | /* Compute ATA timing and set it to SMC */ | ||
280 | ret = ata_timing_compute(adev, adev->pio_mode, &timing, 1000, 0); | ||
281 | if (ret) { | ||
282 | dev_warn(ap->dev, "Failed to compute ATA timing %d, " | ||
283 | "set PIO_0 timing\n", ret); | ||
284 | timing = *ata_timing_find_mode(XFER_PIO_0); | ||
285 | } | ||
286 | set_smc_timing(ap->dev, adev, info, &timing); | ||
287 | } | ||
288 | |||
289 | static unsigned int pata_at91_data_xfer_noirq(struct ata_queued_cmd *qc, | ||
290 | unsigned char *buf, unsigned int buflen, int rw) | ||
291 | { | ||
292 | struct at91_ide_info *info = qc->dev->link->ap->host->private_data; | ||
293 | unsigned int consumed; | ||
294 | unsigned int mode; | ||
295 | unsigned long flags; | ||
296 | |||
297 | local_irq_save(flags); | ||
298 | regmap_fields_read(fields.mode, info->cs, &mode); | ||
299 | |||
300 | /* set 16bit mode before writing data */ | ||
301 | regmap_fields_write(fields.mode, info->cs, (mode & ~AT91_SMC_DBW) | | ||
302 | AT91_SMC_DBW_16); | ||
303 | |||
304 | consumed = ata_sff_data_xfer(qc, buf, buflen, rw); | ||
305 | |||
306 | /* restore 8bit mode after data is written */ | ||
307 | regmap_fields_write(fields.mode, info->cs, (mode & ~AT91_SMC_DBW) | | ||
308 | AT91_SMC_DBW_8); | ||
309 | |||
310 | local_irq_restore(flags); | ||
311 | return consumed; | ||
312 | } | ||
313 | |||
314 | static struct scsi_host_template pata_at91_sht = { | ||
315 | ATA_PIO_SHT(DRV_NAME), | ||
316 | }; | ||
317 | |||
318 | static struct ata_port_operations pata_at91_port_ops = { | ||
319 | .inherits = &ata_sff_port_ops, | ||
320 | |||
321 | .sff_data_xfer = pata_at91_data_xfer_noirq, | ||
322 | .set_piomode = pata_at91_set_piomode, | ||
323 | .cable_detect = ata_cable_40wire, | ||
324 | }; | ||
325 | |||
326 | static int at91sam9_smc_fields_init(struct device *dev) | ||
327 | { | ||
328 | struct reg_field field = REG_FIELD(0, 0, 31); | ||
329 | |||
330 | field.id_size = 8; | ||
331 | field.id_offset = AT91SAM9_SMC_GENERIC_BLK_SZ; | ||
332 | |||
333 | field.reg = AT91SAM9_SMC_SETUP(AT91SAM9_SMC_GENERIC); | ||
334 | fields.setup = devm_regmap_field_alloc(dev, smc, field); | ||
335 | if (IS_ERR(fields.setup)) | ||
336 | return PTR_ERR(fields.setup); | ||
337 | |||
338 | field.reg = AT91SAM9_SMC_PULSE(AT91SAM9_SMC_GENERIC); | ||
339 | fields.pulse = devm_regmap_field_alloc(dev, smc, field); | ||
340 | if (IS_ERR(fields.pulse)) | ||
341 | return PTR_ERR(fields.pulse); | ||
342 | |||
343 | field.reg = AT91SAM9_SMC_CYCLE(AT91SAM9_SMC_GENERIC); | ||
344 | fields.cycle = devm_regmap_field_alloc(dev, smc, field); | ||
345 | if (IS_ERR(fields.cycle)) | ||
346 | return PTR_ERR(fields.cycle); | ||
347 | |||
348 | field.reg = AT91SAM9_SMC_MODE(AT91SAM9_SMC_GENERIC); | ||
349 | fields.mode = devm_regmap_field_alloc(dev, smc, field); | ||
350 | |||
351 | return PTR_ERR_OR_ZERO(fields.mode); | ||
352 | } | ||
353 | |||
354 | static int pata_at91_probe(struct platform_device *pdev) | ||
355 | { | ||
356 | struct at91_cf_data *board = dev_get_platdata(&pdev->dev); | ||
357 | struct device *dev = &pdev->dev; | ||
358 | struct at91_ide_info *info; | ||
359 | struct resource *mem_res; | ||
360 | struct ata_host *host; | ||
361 | struct ata_port *ap; | ||
362 | |||
363 | int irq_flags = 0; | ||
364 | int irq = 0; | ||
365 | int ret; | ||
366 | |||
367 | /* get platform resources: IO/CTL memories and irq/rst pins */ | ||
368 | |||
369 | if (pdev->num_resources != 1) { | ||
370 | dev_err(&pdev->dev, "invalid number of resources\n"); | ||
371 | return -EINVAL; | ||
372 | } | ||
373 | |||
374 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
375 | |||
376 | if (!mem_res) { | ||
377 | dev_err(dev, "failed to get mem resource\n"); | ||
378 | return -EINVAL; | ||
379 | } | ||
380 | |||
381 | irq = board->irq_pin; | ||
382 | |||
383 | smc = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "atmel,smc"); | ||
384 | if (IS_ERR(smc)) | ||
385 | return PTR_ERR(smc); | ||
386 | |||
387 | ret = at91sam9_smc_fields_init(dev); | ||
388 | if (ret < 0) | ||
389 | return ret; | ||
390 | |||
391 | /* init ata host */ | ||
392 | |||
393 | host = ata_host_alloc(dev, 1); | ||
394 | |||
395 | if (!host) | ||
396 | return -ENOMEM; | ||
397 | |||
398 | ap = host->ports[0]; | ||
399 | ap->ops = &pata_at91_port_ops; | ||
400 | ap->flags |= ATA_FLAG_SLAVE_POSS; | ||
401 | ap->pio_mask = ATA_PIO4; | ||
402 | |||
403 | if (!gpio_is_valid(irq)) { | ||
404 | ap->flags |= ATA_FLAG_PIO_POLLING; | ||
405 | ata_port_desc(ap, "no IRQ, using PIO polling"); | ||
406 | } | ||
407 | |||
408 | info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); | ||
409 | |||
410 | if (!info) { | ||
411 | dev_err(dev, "failed to allocate memory for private data\n"); | ||
412 | return -ENOMEM; | ||
413 | } | ||
414 | |||
415 | info->mck = clk_get(NULL, "mck"); | ||
416 | |||
417 | if (IS_ERR(info->mck)) { | ||
418 | dev_err(dev, "failed to get access to mck clock\n"); | ||
419 | return -ENODEV; | ||
420 | } | ||
421 | |||
422 | info->cs = board->chipselect; | ||
423 | info->mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | | ||
424 | AT91_SMC_EXNWMODE_READY | AT91_SMC_BAT_SELECT | | ||
425 | AT91_SMC_DBW_8 | AT91_SMC_TDF_(0); | ||
426 | |||
427 | info->ide_addr = devm_ioremap(dev, | ||
428 | mem_res->start + CF_IDE_OFFSET, CF_IDE_RES_SIZE); | ||
429 | |||
430 | if (!info->ide_addr) { | ||
431 | dev_err(dev, "failed to map IO base\n"); | ||
432 | ret = -ENOMEM; | ||
433 | goto err_put; | ||
434 | } | ||
435 | |||
436 | info->alt_addr = devm_ioremap(dev, | ||
437 | mem_res->start + CF_ALT_IDE_OFFSET, CF_IDE_RES_SIZE); | ||
438 | |||
439 | if (!info->alt_addr) { | ||
440 | dev_err(dev, "failed to map CTL base\n"); | ||
441 | ret = -ENOMEM; | ||
442 | goto err_put; | ||
443 | } | ||
444 | |||
445 | ap->ioaddr.cmd_addr = info->ide_addr; | ||
446 | ap->ioaddr.ctl_addr = info->alt_addr + 0x06; | ||
447 | ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; | ||
448 | |||
449 | ata_sff_std_ports(&ap->ioaddr); | ||
450 | |||
451 | ata_port_desc(ap, "mmio cmd 0x%llx ctl 0x%llx", | ||
452 | (unsigned long long)mem_res->start + CF_IDE_OFFSET, | ||
453 | (unsigned long long)mem_res->start + CF_ALT_IDE_OFFSET); | ||
454 | |||
455 | host->private_data = info; | ||
456 | |||
457 | ret = ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, | ||
458 | gpio_is_valid(irq) ? ata_sff_interrupt : NULL, | ||
459 | irq_flags, &pata_at91_sht); | ||
460 | if (ret) | ||
461 | goto err_put; | ||
462 | |||
463 | return 0; | ||
464 | |||
465 | err_put: | ||
466 | clk_put(info->mck); | ||
467 | return ret; | ||
468 | } | ||
469 | |||
470 | static int pata_at91_remove(struct platform_device *pdev) | ||
471 | { | ||
472 | struct ata_host *host = platform_get_drvdata(pdev); | ||
473 | struct at91_ide_info *info; | ||
474 | |||
475 | if (!host) | ||
476 | return 0; | ||
477 | info = host->private_data; | ||
478 | |||
479 | ata_host_detach(host); | ||
480 | |||
481 | if (!info) | ||
482 | return 0; | ||
483 | |||
484 | clk_put(info->mck); | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | static struct platform_driver pata_at91_driver = { | ||
490 | .probe = pata_at91_probe, | ||
491 | .remove = pata_at91_remove, | ||
492 | .driver = { | ||
493 | .name = DRV_NAME, | ||
494 | }, | ||
495 | }; | ||
496 | |||
497 | module_platform_driver(pata_at91_driver); | ||
498 | |||
499 | MODULE_LICENSE("GPL"); | ||
500 | MODULE_DESCRIPTION("Driver for CF in True IDE mode on AT91SAM9260 SoC"); | ||
501 | MODULE_AUTHOR("Matyukevich Sergey"); | ||
502 | MODULE_VERSION(DRV_VERSION); | ||
503 | |||