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