18 #include <linux/kernel.h>
19 #include <linux/module.h>
24 #include <linux/slab.h>
29 #define DRV_NAME "pata_samsung_cf"
30 #define DRV_VERSION "0.1"
56 static void pata_s3c_set_endian(
void __iomem *s3c_ide_regbase,
u8 mode)
63 static void pata_s3c_cfg_mode(
void __iomem *s3c_ide_sfrbase)
78 piotime = ((t2i & 0xff) << 12) | ((t2 & 0xff) << 4) | (t1 & 0xf);
100 cycle_time * 1000, 0);
102 piotime = pata_s3c_setup_timing(info, &
timing);
112 static int wait_for_host_ready(
struct s3c_ide_info *info)
120 if ((
readl(fifo_reg) >> 28) == 0)
133 wait_for_host_ready(info);
145 wait_for_host_ready(info);
147 wait_for_host_ready(info);
155 static void pata_s3c_tf_load(
struct ata_port *ap,
158 struct ata_ioports *ioaddr = &ap->ioaddr;
161 if (tf->
ctl != ap->last_ctl) {
162 ata_outb(ap->
host, tf->
ctl, ioaddr->ctl_addr);
163 ap->last_ctl = tf->
ctl;
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);
184 ata_outb(ap->
host, tf->
device, ioaddr->device_addr);
194 struct ata_ioports *ioaddr = &ap->ioaddr;
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);
210 ata_outb(ap->
host, tf->
ctl, ioaddr->ctl_addr);
211 ap->last_ctl = tf->
ctl;
218 static void pata_s3c_exec_command(
struct ata_port *ap,
221 ata_outb(ap->
host, tf->
command, ap->ioaddr.command_addr);
228 static u8 pata_s3c_check_status(
struct ata_port *ap)
230 return ata_inb(ap->
host, ap->ioaddr.status_addr);
236 static u8 pata_s3c_check_altstatus(
struct ata_port *ap)
238 return ata_inb(ap->
host, ap->ioaddr.altstatus_addr);
250 unsigned int words = buflen >> 1,
i;
251 u16 *data_ptr = (
u16 *)buf;
255 for (i = 0; i < words; i++, data_ptr++) {
256 wait_for_host_ready(info);
258 wait_for_host_ready(info);
263 for (i = 0; i < words; i++, data_ptr++) {
264 wait_for_host_ready(info);
265 writew(*data_ptr, data_addr);
269 dev_err(ap->
dev,
"unexpected trailing data\n");
277 static void pata_s3c_dev_select(
struct ata_port *ap,
unsigned int device)
284 ata_outb(ap->
host, tmp, ap->ioaddr.device_addr);
291 static unsigned int pata_s3c_devchk(
struct ata_port *ap,
294 struct ata_ioports *ioaddr = &ap->ioaddr;
297 pata_s3c_dev_select(ap, device);
299 ata_outb(ap->
host, 0x55, ioaddr->nsect_addr);
300 ata_outb(ap->
host, 0xaa, ioaddr->lbal_addr);
302 ata_outb(ap->
host, 0xaa, ioaddr->nsect_addr);
303 ata_outb(ap->
host, 0x55, ioaddr->lbal_addr);
305 ata_outb(ap->
host, 0x55, ioaddr->nsect_addr);
306 ata_outb(ap->
host, 0xaa, ioaddr->lbal_addr);
308 nsect = ata_inb(ap->
host, ioaddr->nsect_addr);
309 lbal = ata_inb(ap->
host, ioaddr->lbal_addr);
311 if ((nsect == 0x55) && (lbal == 0xaa))
320 static int pata_s3c_wait_after_reset(
struct ata_link *
link,
321 unsigned long deadline)
341 static unsigned int pata_s3c_bus_softreset(
struct ata_port *ap,
342 unsigned long deadline)
344 struct ata_ioports *ioaddr = &ap->ioaddr;
347 ata_outb(ap->
host, ap->ctl, ioaddr->ctl_addr);
349 ata_outb(ap->
host, ap->ctl |
ATA_SRST, ioaddr->ctl_addr);
351 ata_outb(ap->
host, ap->ctl, ioaddr->ctl_addr);
352 ap->last_ctl = ap->ctl;
354 return pata_s3c_wait_after_reset(&ap->
link, deadline);
360 static int pata_s3c_softreset(
struct ata_link *link,
unsigned int *classes,
361 unsigned long deadline)
364 unsigned int devmask = 0;
369 if (pata_s3c_devchk(ap, 0))
373 pata_s3c_dev_select(ap, 0);
376 rc = pata_s3c_bus_softreset(ap, deadline);
378 if (rc && rc != -
ENODEV) {
385 devmask & (1 << 0), &err);
395 ata_outb(ap->
host, ctl, ap->ioaddr.ctl_addr);
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,
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,
418 .set_piomode = pata_s3c_set_piomode,
421 static void pata_s3c_enable(
void *s3c_ide_regbase,
bool state)
424 temp = state ? (temp | 1) : (temp & ~1);
428 static irqreturn_t pata_s3c_irq(
int irq,
void *dev_instance)
430 struct ata_host *host = dev_instance;
447 pata_s3c_set_endian(info->
ide_addr, 1);
448 pata_s3c_enable(info->
ide_addr,
true);
462 pata_s3c_set_endian(info->
ide_addr, 0);
463 pata_s3c_enable(info->
ide_addr,
true);
479 struct device *
dev = &pdev->
dev;
491 dev_err(dev,
"failed to allocate memory for device data\n");
499 dev_err(dev,
"failed to get mem resource\n");
505 dev_err(dev,
"error requesting register region\n");
511 dev_err(dev,
"failed to map IO base address\n");
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);
528 dev_err(dev,
"failed to allocate ide host\n");
537 ap->
ops = &pata_s3c_port_ops;
542 ap->
ops = &pata_s5p_port_ops;
547 ap->
ops = &pata_s5p_port_ops;
553 if (info->
irq <= 0) {
574 (
unsigned long long)res->
start);
582 pata_s3c_hwinit(info, pdata);
584 platform_set_drvdata(pdev, host);
587 info->
irq ? pata_s3c_irq :
NULL,
598 struct ata_host *host = platform_get_drvdata(pdev);
610 static int pata_s3c_suspend(
struct device *dev)
613 struct ata_host *host = platform_get_drvdata(pdev);
618 static int pata_s3c_resume(
struct device *dev)
621 struct ata_host *host = platform_get_drvdata(pdev);
625 pata_s3c_hwinit(info, pdata);
626 ata_host_resume(host);
631 static const struct dev_pm_ops pata_s3c_pm_ops = {
633 .resume = pata_s3c_resume,
640 .name =
"s3c64xx-pata",
643 .name =
"s5pc100-pata",
646 .name =
"s5pv210-pata",
655 .remove =
__exit_p(pata_s3c_remove),
656 .id_table = pata_s3c_driver_ids,
661 .pm = &pata_s3c_pm_ops,
666 static int __init pata_s3c_init(
void)
671 static void __exit pata_s3c_exit(
void)