blob: 7d2142fbcbb77c122776678969cc2d86ce71d14f [file] [log] [blame]
Abhilash Kesavan155bf482010-07-13 13:23:05 +09001/*
2 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * PATA driver for Samsung SoCs.
6 * Supports CF Interface in True IDE mode. Currently only PIO mode has been
7 * implemented; UDMA support has to be added.
8 *
9 * Based on:
10 * PATA driver for AT91SAM9260 Static Memory Controller
11 * PATA driver for Toshiba SCC controller
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#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/clk.h>
22#include <linux/libata.h>
23#include <linux/platform_device.h>
24#include <linux/slab.h>
25
Arnd Bergmann436d42c2012-08-24 15:22:12 +020026#include <linux/platform_data/ata-samsung_cf.h>
Abhilash Kesavan155bf482010-07-13 13:23:05 +090027
28#define DRV_NAME "pata_samsung_cf"
29#define DRV_VERSION "0.1"
30
Sachin Kamat15e53182014-01-02 08:39:31 +053031#define S3C_CFATA_REG(x) (x)
32#define S3C_CFATA_MUX S3C_CFATA_REG(0x0)
33#define S3C_ATA_CTRL S3C_CFATA_REG(0x0)
34#define S3C_ATA_STATUS S3C_CFATA_REG(0x4)
35#define S3C_ATA_CMD S3C_CFATA_REG(0x8)
36#define S3C_ATA_SWRST S3C_CFATA_REG(0xc)
37#define S3C_ATA_IRQ S3C_CFATA_REG(0x10)
38#define S3C_ATA_IRQ_MSK S3C_CFATA_REG(0x14)
39#define S3C_ATA_CFG S3C_CFATA_REG(0x18)
40
41#define S3C_ATA_MDMA_TIME S3C_CFATA_REG(0x28)
42#define S3C_ATA_PIO_TIME S3C_CFATA_REG(0x2c)
43#define S3C_ATA_UDMA_TIME S3C_CFATA_REG(0x30)
44#define S3C_ATA_XFR_NUM S3C_CFATA_REG(0x34)
45#define S3C_ATA_XFR_CNT S3C_CFATA_REG(0x38)
46#define S3C_ATA_TBUF_START S3C_CFATA_REG(0x3c)
47#define S3C_ATA_TBUF_SIZE S3C_CFATA_REG(0x40)
48#define S3C_ATA_SBUF_START S3C_CFATA_REG(0x44)
49#define S3C_ATA_SBUF_SIZE S3C_CFATA_REG(0x48)
50#define S3C_ATA_CADR_TBUF S3C_CFATA_REG(0x4c)
51#define S3C_ATA_CADR_SBUF S3C_CFATA_REG(0x50)
52#define S3C_ATA_PIO_DTR S3C_CFATA_REG(0x54)
53#define S3C_ATA_PIO_FED S3C_CFATA_REG(0x58)
54#define S3C_ATA_PIO_SCR S3C_CFATA_REG(0x5c)
55#define S3C_ATA_PIO_LLR S3C_CFATA_REG(0x60)
56#define S3C_ATA_PIO_LMR S3C_CFATA_REG(0x64)
57#define S3C_ATA_PIO_LHR S3C_CFATA_REG(0x68)
58#define S3C_ATA_PIO_DVR S3C_CFATA_REG(0x6c)
59#define S3C_ATA_PIO_CSD S3C_CFATA_REG(0x70)
60#define S3C_ATA_PIO_DAD S3C_CFATA_REG(0x74)
61#define S3C_ATA_PIO_READY S3C_CFATA_REG(0x78)
62#define S3C_ATA_PIO_RDATA S3C_CFATA_REG(0x7c)
63
64#define S3C_CFATA_MUX_TRUEIDE 0x01
65#define S3C_ATA_CFG_SWAP 0x40
66#define S3C_ATA_CFG_IORDYEN 0x02
67
Abhilash Kesavan155bf482010-07-13 13:23:05 +090068enum s3c_cpu_type {
69 TYPE_S3C64XX,
70 TYPE_S5PC100,
71 TYPE_S5PV210,
72};
73
74/*
75 * struct s3c_ide_info - S3C PATA instance.
76 * @clk: The clock resource for this controller.
77 * @ide_addr: The area mapped for the hardware registers.
78 * @sfr_addr: The area mapped for the special function registers.
79 * @irq: The IRQ number we are using.
80 * @cpu_type: The exact type of this controller.
81 * @fifo_status_reg: The ATA_FIFO_STATUS register offset.
82 */
83struct s3c_ide_info {
84 struct clk *clk;
85 void __iomem *ide_addr;
86 void __iomem *sfr_addr;
87 unsigned int irq;
88 enum s3c_cpu_type cpu_type;
89 unsigned int fifo_status_reg;
90};
91
92static void pata_s3c_set_endian(void __iomem *s3c_ide_regbase, u8 mode)
93{
94 u32 reg = readl(s3c_ide_regbase + S3C_ATA_CFG);
95 reg = mode ? (reg & ~S3C_ATA_CFG_SWAP) : (reg | S3C_ATA_CFG_SWAP);
96 writel(reg, s3c_ide_regbase + S3C_ATA_CFG);
97}
98
99static void pata_s3c_cfg_mode(void __iomem *s3c_ide_sfrbase)
100{
101 /* Select true-ide as the internal operating mode */
102 writel(readl(s3c_ide_sfrbase + S3C_CFATA_MUX) | S3C_CFATA_MUX_TRUEIDE,
103 s3c_ide_sfrbase + S3C_CFATA_MUX);
104}
105
106static unsigned long
107pata_s3c_setup_timing(struct s3c_ide_info *info, const struct ata_timing *ata)
108{
109 int t1 = ata->setup;
110 int t2 = ata->act8b;
111 int t2i = ata->rec8b;
112 ulong piotime;
113
114 piotime = ((t2i & 0xff) << 12) | ((t2 & 0xff) << 4) | (t1 & 0xf);
115
116 return piotime;
117}
118
119static void pata_s3c_set_piomode(struct ata_port *ap, struct ata_device *adev)
120{
121 struct s3c_ide_info *info = ap->host->private_data;
122 struct ata_timing timing;
123 int cycle_time;
124 ulong ata_cfg = readl(info->ide_addr + S3C_ATA_CFG);
125 ulong piotime;
126
127 /* Enables IORDY if mode requires it */
128 if (ata_pio_need_iordy(adev))
129 ata_cfg |= S3C_ATA_CFG_IORDYEN;
130 else
131 ata_cfg &= ~S3C_ATA_CFG_IORDYEN;
132
133 cycle_time = (int)(1000000000UL / clk_get_rate(info->clk));
134
135 ata_timing_compute(adev, adev->pio_mode, &timing,
136 cycle_time * 1000, 0);
137
138 piotime = pata_s3c_setup_timing(info, &timing);
139
140 writel(ata_cfg, info->ide_addr + S3C_ATA_CFG);
141 writel(piotime, info->ide_addr + S3C_ATA_PIO_TIME);
142}
143
144/*
145 * Waits until the IDE controller is able to perform next read/write
146 * operation to the disk. Needed for 64XX series boards only.
147 */
148static int wait_for_host_ready(struct s3c_ide_info *info)
149{
150 ulong timeout;
151 void __iomem *fifo_reg = info->ide_addr + info->fifo_status_reg;
152
153 /* wait for maximum of 20 msec */
154 timeout = jiffies + msecs_to_jiffies(20);
155 while (time_before(jiffies, timeout)) {
156 if ((readl(fifo_reg) >> 28) == 0)
157 return 0;
158 }
159 return -EBUSY;
160}
161
162/*
163 * Writes to one of the task file registers.
164 */
165static void ata_outb(struct ata_host *host, u8 addr, void __iomem *reg)
166{
167 struct s3c_ide_info *info = host->private_data;
168
169 wait_for_host_ready(info);
170 writeb(addr, reg);
171}
172
173/*
174 * Reads from one of the task file registers.
175 */
176static u8 ata_inb(struct ata_host *host, void __iomem *reg)
177{
178 struct s3c_ide_info *info = host->private_data;
179 u8 temp;
180
181 wait_for_host_ready(info);
182 (void) readb(reg);
183 wait_for_host_ready(info);
184 temp = readb(info->ide_addr + S3C_ATA_PIO_RDATA);
185 return temp;
186}
187
188/*
189 * pata_s3c_tf_load - send taskfile registers to host controller
190 */
191static void pata_s3c_tf_load(struct ata_port *ap,
192 const struct ata_taskfile *tf)
193{
194 struct ata_ioports *ioaddr = &ap->ioaddr;
195 unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
196
197 if (tf->ctl != ap->last_ctl) {
198 ata_outb(ap->host, tf->ctl, ioaddr->ctl_addr);
199 ap->last_ctl = tf->ctl;
200 ata_wait_idle(ap);
201 }
202
203 if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
204 ata_outb(ap->host, tf->hob_feature, ioaddr->feature_addr);
205 ata_outb(ap->host, tf->hob_nsect, ioaddr->nsect_addr);
206 ata_outb(ap->host, tf->hob_lbal, ioaddr->lbal_addr);
207 ata_outb(ap->host, tf->hob_lbam, ioaddr->lbam_addr);
208 ata_outb(ap->host, tf->hob_lbah, ioaddr->lbah_addr);
209 }
210
211 if (is_addr) {
212 ata_outb(ap->host, tf->feature, ioaddr->feature_addr);
213 ata_outb(ap->host, tf->nsect, ioaddr->nsect_addr);
214 ata_outb(ap->host, tf->lbal, ioaddr->lbal_addr);
215 ata_outb(ap->host, tf->lbam, ioaddr->lbam_addr);
216 ata_outb(ap->host, tf->lbah, ioaddr->lbah_addr);
217 }
218
219 if (tf->flags & ATA_TFLAG_DEVICE)
220 ata_outb(ap->host, tf->device, ioaddr->device_addr);
221
222 ata_wait_idle(ap);
223}
224
225/*
226 * pata_s3c_tf_read - input device's ATA taskfile shadow registers
227 */
228static void pata_s3c_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
229{
230 struct ata_ioports *ioaddr = &ap->ioaddr;
231
232 tf->feature = ata_inb(ap->host, ioaddr->error_addr);
233 tf->nsect = ata_inb(ap->host, ioaddr->nsect_addr);
234 tf->lbal = ata_inb(ap->host, ioaddr->lbal_addr);
235 tf->lbam = ata_inb(ap->host, ioaddr->lbam_addr);
236 tf->lbah = ata_inb(ap->host, ioaddr->lbah_addr);
237 tf->device = ata_inb(ap->host, ioaddr->device_addr);
238
239 if (tf->flags & ATA_TFLAG_LBA48) {
240 ata_outb(ap->host, tf->ctl | ATA_HOB, ioaddr->ctl_addr);
241 tf->hob_feature = ata_inb(ap->host, ioaddr->error_addr);
242 tf->hob_nsect = ata_inb(ap->host, ioaddr->nsect_addr);
243 tf->hob_lbal = ata_inb(ap->host, ioaddr->lbal_addr);
244 tf->hob_lbam = ata_inb(ap->host, ioaddr->lbam_addr);
245 tf->hob_lbah = ata_inb(ap->host, ioaddr->lbah_addr);
246 ata_outb(ap->host, tf->ctl, ioaddr->ctl_addr);
247 ap->last_ctl = tf->ctl;
248 }
249}
250
251/*
252 * pata_s3c_exec_command - issue ATA command to host controller
253 */
254static void pata_s3c_exec_command(struct ata_port *ap,
255 const struct ata_taskfile *tf)
256{
257 ata_outb(ap->host, tf->command, ap->ioaddr.command_addr);
258 ata_sff_pause(ap);
259}
260
261/*
262 * pata_s3c_check_status - Read device status register
263 */
264static u8 pata_s3c_check_status(struct ata_port *ap)
265{
266 return ata_inb(ap->host, ap->ioaddr.status_addr);
267}
268
269/*
270 * pata_s3c_check_altstatus - Read alternate device status register
271 */
272static u8 pata_s3c_check_altstatus(struct ata_port *ap)
273{
274 return ata_inb(ap->host, ap->ioaddr.altstatus_addr);
275}
276
277/*
278 * pata_s3c_data_xfer - Transfer data by PIO
279 */
Jingoo Han3d70a362013-08-09 14:24:35 +0900280static unsigned int pata_s3c_data_xfer(struct ata_device *dev,
281 unsigned char *buf, unsigned int buflen, int rw)
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900282{
283 struct ata_port *ap = dev->link->ap;
284 struct s3c_ide_info *info = ap->host->private_data;
285 void __iomem *data_addr = ap->ioaddr.data_addr;
286 unsigned int words = buflen >> 1, i;
287 u16 *data_ptr = (u16 *)buf;
288
289 /* Requires wait same as in ata_inb/ata_outb */
290 if (rw == READ)
291 for (i = 0; i < words; i++, data_ptr++) {
292 wait_for_host_ready(info);
293 (void) readw(data_addr);
294 wait_for_host_ready(info);
295 *data_ptr = readw(info->ide_addr
296 + S3C_ATA_PIO_RDATA);
297 }
298 else
299 for (i = 0; i < words; i++, data_ptr++) {
300 wait_for_host_ready(info);
301 writew(*data_ptr, data_addr);
302 }
303
304 if (buflen & 0x01)
305 dev_err(ap->dev, "unexpected trailing data\n");
306
307 return words << 1;
308}
309
310/*
311 * pata_s3c_dev_select - Select device on ATA bus
312 */
313static void pata_s3c_dev_select(struct ata_port *ap, unsigned int device)
314{
315 u8 tmp = ATA_DEVICE_OBS;
316
317 if (device != 0)
318 tmp |= ATA_DEV1;
319
320 ata_outb(ap->host, tmp, ap->ioaddr.device_addr);
321 ata_sff_pause(ap);
322}
323
324/*
325 * pata_s3c_devchk - PATA device presence detection
326 */
327static unsigned int pata_s3c_devchk(struct ata_port *ap,
328 unsigned int device)
329{
330 struct ata_ioports *ioaddr = &ap->ioaddr;
331 u8 nsect, lbal;
332
333 pata_s3c_dev_select(ap, device);
334
335 ata_outb(ap->host, 0x55, ioaddr->nsect_addr);
336 ata_outb(ap->host, 0xaa, ioaddr->lbal_addr);
337
338 ata_outb(ap->host, 0xaa, ioaddr->nsect_addr);
339 ata_outb(ap->host, 0x55, ioaddr->lbal_addr);
340
341 ata_outb(ap->host, 0x55, ioaddr->nsect_addr);
342 ata_outb(ap->host, 0xaa, ioaddr->lbal_addr);
343
344 nsect = ata_inb(ap->host, ioaddr->nsect_addr);
345 lbal = ata_inb(ap->host, ioaddr->lbal_addr);
346
347 if ((nsect == 0x55) && (lbal == 0xaa))
348 return 1; /* we found a device */
349
350 return 0; /* nothing found */
351}
352
353/*
354 * pata_s3c_wait_after_reset - wait for devices to become ready after reset
355 */
356static int pata_s3c_wait_after_reset(struct ata_link *link,
357 unsigned long deadline)
358{
359 int rc;
360
Tejun Heo97750ce2010-09-06 17:56:29 +0200361 ata_msleep(link->ap, ATA_WAIT_AFTER_RESET);
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900362
363 /* always check readiness of the master device */
364 rc = ata_sff_wait_ready(link, deadline);
365 /* -ENODEV means the odd clown forgot the D7 pulldown resistor
366 * and TF status is 0xff, bail out on it too.
367 */
368 if (rc)
369 return rc;
370
371 return 0;
372}
373
374/*
375 * pata_s3c_bus_softreset - PATA device software reset
376 */
377static unsigned int pata_s3c_bus_softreset(struct ata_port *ap,
378 unsigned long deadline)
379{
380 struct ata_ioports *ioaddr = &ap->ioaddr;
381
382 /* software reset. causes dev0 to be selected */
383 ata_outb(ap->host, ap->ctl, ioaddr->ctl_addr);
384 udelay(20);
385 ata_outb(ap->host, ap->ctl | ATA_SRST, ioaddr->ctl_addr);
386 udelay(20);
387 ata_outb(ap->host, ap->ctl, ioaddr->ctl_addr);
388 ap->last_ctl = ap->ctl;
389
390 return pata_s3c_wait_after_reset(&ap->link, deadline);
391}
392
393/*
394 * pata_s3c_softreset - reset host port via ATA SRST
395 */
396static int pata_s3c_softreset(struct ata_link *link, unsigned int *classes,
397 unsigned long deadline)
398{
399 struct ata_port *ap = link->ap;
400 unsigned int devmask = 0;
401 int rc;
402 u8 err;
403
404 /* determine if device 0 is present */
405 if (pata_s3c_devchk(ap, 0))
406 devmask |= (1 << 0);
407
408 /* select device 0 again */
409 pata_s3c_dev_select(ap, 0);
410
411 /* issue bus reset */
412 rc = pata_s3c_bus_softreset(ap, deadline);
413 /* if link is occupied, -ENODEV too is an error */
414 if (rc && rc != -ENODEV) {
Joe Perchesa9a79df2011-04-15 15:51:59 -0700415 ata_link_err(link, "SRST failed (errno=%d)\n", rc);
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900416 return rc;
417 }
418
419 /* determine by signature whether we have ATA or ATAPI devices */
420 classes[0] = ata_sff_dev_classify(&ap->link.device[0],
421 devmask & (1 << 0), &err);
422
423 return 0;
424}
425
426/*
427 * pata_s3c_set_devctl - Write device control register
428 */
429static void pata_s3c_set_devctl(struct ata_port *ap, u8 ctl)
430{
431 ata_outb(ap->host, ctl, ap->ioaddr.ctl_addr);
432}
433
434static struct scsi_host_template pata_s3c_sht = {
435 ATA_PIO_SHT(DRV_NAME),
436};
437
438static struct ata_port_operations pata_s3c_port_ops = {
439 .inherits = &ata_sff_port_ops,
440 .sff_check_status = pata_s3c_check_status,
441 .sff_check_altstatus = pata_s3c_check_altstatus,
442 .sff_tf_load = pata_s3c_tf_load,
443 .sff_tf_read = pata_s3c_tf_read,
444 .sff_data_xfer = pata_s3c_data_xfer,
445 .sff_exec_command = pata_s3c_exec_command,
446 .sff_dev_select = pata_s3c_dev_select,
447 .sff_set_devctl = pata_s3c_set_devctl,
448 .softreset = pata_s3c_softreset,
449 .set_piomode = pata_s3c_set_piomode,
450};
451
452static struct ata_port_operations pata_s5p_port_ops = {
453 .inherits = &ata_sff_port_ops,
454 .set_piomode = pata_s3c_set_piomode,
455};
456
Jingoo Han3d70a362013-08-09 14:24:35 +0900457static void pata_s3c_enable(void __iomem *s3c_ide_regbase, bool state)
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900458{
459 u32 temp = readl(s3c_ide_regbase + S3C_ATA_CTRL);
460 temp = state ? (temp | 1) : (temp & ~1);
461 writel(temp, s3c_ide_regbase + S3C_ATA_CTRL);
462}
463
464static irqreturn_t pata_s3c_irq(int irq, void *dev_instance)
465{
466 struct ata_host *host = dev_instance;
467 struct s3c_ide_info *info = host->private_data;
468 u32 reg;
469
470 reg = readl(info->ide_addr + S3C_ATA_IRQ);
471 writel(reg, info->ide_addr + S3C_ATA_IRQ);
472
473 return ata_sff_interrupt(irq, dev_instance);
474}
475
476static void pata_s3c_hwinit(struct s3c_ide_info *info,
477 struct s3c_ide_platdata *pdata)
478{
479 switch (info->cpu_type) {
480 case TYPE_S3C64XX:
481 /* Configure as big endian */
482 pata_s3c_cfg_mode(info->sfr_addr);
483 pata_s3c_set_endian(info->ide_addr, 1);
484 pata_s3c_enable(info->ide_addr, true);
485 msleep(100);
486
487 /* Remove IRQ Status */
488 writel(0x1f, info->ide_addr + S3C_ATA_IRQ);
489 writel(0x1b, info->ide_addr + S3C_ATA_IRQ_MSK);
490 break;
491
492 case TYPE_S5PC100:
493 pata_s3c_cfg_mode(info->sfr_addr);
494 /* FALLTHROUGH */
495
496 case TYPE_S5PV210:
497 /* Configure as little endian */
498 pata_s3c_set_endian(info->ide_addr, 0);
499 pata_s3c_enable(info->ide_addr, true);
500 msleep(100);
501
502 /* Remove IRQ Status */
503 writel(0x3f, info->ide_addr + S3C_ATA_IRQ);
504 writel(0x3f, info->ide_addr + S3C_ATA_IRQ_MSK);
505 break;
506
507 default:
508 BUG();
509 }
510}
511
512static int __init pata_s3c_probe(struct platform_device *pdev)
513{
Jingoo Han61b8c342013-07-30 17:16:05 +0900514 struct s3c_ide_platdata *pdata = dev_get_platdata(&pdev->dev);
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900515 struct device *dev = &pdev->dev;
516 struct s3c_ide_info *info;
517 struct resource *res;
518 struct ata_port *ap;
519 struct ata_host *host;
520 enum s3c_cpu_type cpu_type;
521 int ret;
522
523 cpu_type = platform_get_device_id(pdev)->driver_data;
524
525 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
526 if (!info) {
527 dev_err(dev, "failed to allocate memory for device data\n");
528 return -ENOMEM;
529 }
530
531 info->irq = platform_get_irq(pdev, 0);
532
533 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900534
Jingoo Han3e692a92014-01-02 17:24:03 +0900535 info->ide_addr = devm_ioremap_resource(dev, res);
536 if (IS_ERR(info->ide_addr))
537 return PTR_ERR(info->ide_addr);
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900538
Jingoo Han25effc32013-01-10 11:05:06 +0900539 info->clk = devm_clk_get(&pdev->dev, "cfcon");
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900540 if (IS_ERR(info->clk)) {
541 dev_err(dev, "failed to get access to cf controller clock\n");
542 ret = PTR_ERR(info->clk);
543 info->clk = NULL;
544 return ret;
545 }
546
547 clk_enable(info->clk);
548
549 /* init ata host */
550 host = ata_host_alloc(dev, 1);
551 if (!host) {
552 dev_err(dev, "failed to allocate ide host\n");
553 ret = -ENOMEM;
554 goto stop_clk;
555 }
556
557 ap = host->ports[0];
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900558 ap->pio_mask = ATA_PIO4;
559
560 if (cpu_type == TYPE_S3C64XX) {
561 ap->ops = &pata_s3c_port_ops;
562 info->sfr_addr = info->ide_addr + 0x1800;
563 info->ide_addr += 0x1900;
564 info->fifo_status_reg = 0x94;
565 } else if (cpu_type == TYPE_S5PC100) {
566 ap->ops = &pata_s5p_port_ops;
567 info->sfr_addr = info->ide_addr + 0x1800;
568 info->ide_addr += 0x1900;
569 info->fifo_status_reg = 0x84;
570 } else {
571 ap->ops = &pata_s5p_port_ops;
572 info->fifo_status_reg = 0x84;
573 }
574
575 info->cpu_type = cpu_type;
576
577 if (info->irq <= 0) {
578 ap->flags |= ATA_FLAG_PIO_POLLING;
579 info->irq = 0;
580 ata_port_desc(ap, "no IRQ, using PIO polling\n");
581 }
582
583 ap->ioaddr.cmd_addr = info->ide_addr + S3C_ATA_CMD;
584 ap->ioaddr.data_addr = info->ide_addr + S3C_ATA_PIO_DTR;
585 ap->ioaddr.error_addr = info->ide_addr + S3C_ATA_PIO_FED;
586 ap->ioaddr.feature_addr = info->ide_addr + S3C_ATA_PIO_FED;
587 ap->ioaddr.nsect_addr = info->ide_addr + S3C_ATA_PIO_SCR;
588 ap->ioaddr.lbal_addr = info->ide_addr + S3C_ATA_PIO_LLR;
589 ap->ioaddr.lbam_addr = info->ide_addr + S3C_ATA_PIO_LMR;
590 ap->ioaddr.lbah_addr = info->ide_addr + S3C_ATA_PIO_LHR;
591 ap->ioaddr.device_addr = info->ide_addr + S3C_ATA_PIO_DVR;
592 ap->ioaddr.status_addr = info->ide_addr + S3C_ATA_PIO_CSD;
593 ap->ioaddr.command_addr = info->ide_addr + S3C_ATA_PIO_CSD;
594 ap->ioaddr.altstatus_addr = info->ide_addr + S3C_ATA_PIO_DAD;
595 ap->ioaddr.ctl_addr = info->ide_addr + S3C_ATA_PIO_DAD;
596
597 ata_port_desc(ap, "mmio cmd 0x%llx ",
598 (unsigned long long)res->start);
599
600 host->private_data = info;
601
602 if (pdata && pdata->setup_gpio)
603 pdata->setup_gpio();
604
605 /* Set endianness and enable the interface */
606 pata_s3c_hwinit(info, pdata);
607
608 platform_set_drvdata(pdev, host);
609
610 return ata_host_activate(host, info->irq,
611 info->irq ? pata_s3c_irq : NULL,
612 0, &pata_s3c_sht);
613
614stop_clk:
615 clk_disable(info->clk);
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900616 return ret;
617}
618
619static int __exit pata_s3c_remove(struct platform_device *pdev)
620{
621 struct ata_host *host = platform_get_drvdata(pdev);
622 struct s3c_ide_info *info = host->private_data;
623
624 ata_host_detach(host);
625
626 clk_disable(info->clk);
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900627
628 return 0;
629}
630
631#ifdef CONFIG_PM
632static int pata_s3c_suspend(struct device *dev)
633{
634 struct platform_device *pdev = to_platform_device(dev);
635 struct ata_host *host = platform_get_drvdata(pdev);
636
637 return ata_host_suspend(host, PMSG_SUSPEND);
638}
639
640static int pata_s3c_resume(struct device *dev)
641{
642 struct platform_device *pdev = to_platform_device(dev);
643 struct ata_host *host = platform_get_drvdata(pdev);
Jingoo Han61b8c342013-07-30 17:16:05 +0900644 struct s3c_ide_platdata *pdata = dev_get_platdata(&pdev->dev);
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900645 struct s3c_ide_info *info = host->private_data;
646
647 pata_s3c_hwinit(info, pdata);
648 ata_host_resume(host);
649
650 return 0;
651}
652
653static const struct dev_pm_ops pata_s3c_pm_ops = {
654 .suspend = pata_s3c_suspend,
655 .resume = pata_s3c_resume,
656};
657#endif
658
659/* driver device registration */
660static struct platform_device_id pata_s3c_driver_ids[] = {
661 {
662 .name = "s3c64xx-pata",
663 .driver_data = TYPE_S3C64XX,
664 }, {
665 .name = "s5pc100-pata",
666 .driver_data = TYPE_S5PC100,
667 }, {
668 .name = "s5pv210-pata",
669 .driver_data = TYPE_S5PV210,
670 },
671 { }
672};
673
674MODULE_DEVICE_TABLE(platform, pata_s3c_driver_ids);
675
676static struct platform_driver pata_s3c_driver = {
677 .remove = __exit_p(pata_s3c_remove),
678 .id_table = pata_s3c_driver_ids,
679 .driver = {
680 .name = DRV_NAME,
681 .owner = THIS_MODULE,
682#ifdef CONFIG_PM
683 .pm = &pata_s3c_pm_ops,
684#endif
685 },
686};
687
Jingoo Hanb186aff2013-03-04 17:34:42 +0900688module_platform_driver_probe(pata_s3c_driver, pata_s3c_probe);
Abhilash Kesavan155bf482010-07-13 13:23:05 +0900689
690MODULE_AUTHOR("Abhilash Kesavan, <a.kesavan@samsung.com>");
691MODULE_DESCRIPTION("low-level driver for Samsung PATA controller");
692MODULE_LICENSE("GPL");
693MODULE_VERSION(DRV_VERSION);