in pata_samsung_cf.c [492:592]
static int __init pata_s3c_probe(struct platform_device *pdev)
{
struct s3c_ide_platdata *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct s3c_ide_info *info;
struct resource *res;
struct ata_port *ap;
struct ata_host *host;
enum s3c_cpu_type cpu_type;
int ret;
cpu_type = platform_get_device_id(pdev)->driver_data;
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->irq = platform_get_irq(pdev, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
info->ide_addr = devm_ioremap_resource(dev, res);
if (IS_ERR(info->ide_addr))
return PTR_ERR(info->ide_addr);
info->clk = devm_clk_get(&pdev->dev, "cfcon");
if (IS_ERR(info->clk)) {
dev_err(dev, "failed to get access to cf controller clock\n");
ret = PTR_ERR(info->clk);
info->clk = NULL;
return ret;
}
clk_enable(info->clk);
/* init ata host */
host = ata_host_alloc(dev, 1);
if (!host) {
dev_err(dev, "failed to allocate ide host\n");
ret = -ENOMEM;
goto stop_clk;
}
ap = host->ports[0];
ap->pio_mask = ATA_PIO4;
if (cpu_type == TYPE_S3C64XX) {
ap->ops = &pata_s3c_port_ops;
info->sfr_addr = info->ide_addr + 0x1800;
info->ide_addr += 0x1900;
info->fifo_status_reg = 0x94;
} else {
ap->ops = &pata_s5p_port_ops;
info->fifo_status_reg = 0x84;
}
info->cpu_type = cpu_type;
if (info->irq <= 0) {
ap->flags |= ATA_FLAG_PIO_POLLING;
info->irq = 0;
ata_port_desc(ap, "no IRQ, using PIO polling\n");
}
ap->ioaddr.cmd_addr = info->ide_addr + S3C_ATA_CMD;
ap->ioaddr.data_addr = info->ide_addr + S3C_ATA_PIO_DTR;
ap->ioaddr.error_addr = info->ide_addr + S3C_ATA_PIO_FED;
ap->ioaddr.feature_addr = info->ide_addr + S3C_ATA_PIO_FED;
ap->ioaddr.nsect_addr = info->ide_addr + S3C_ATA_PIO_SCR;
ap->ioaddr.lbal_addr = info->ide_addr + S3C_ATA_PIO_LLR;
ap->ioaddr.lbam_addr = info->ide_addr + S3C_ATA_PIO_LMR;
ap->ioaddr.lbah_addr = info->ide_addr + S3C_ATA_PIO_LHR;
ap->ioaddr.device_addr = info->ide_addr + S3C_ATA_PIO_DVR;
ap->ioaddr.status_addr = info->ide_addr + S3C_ATA_PIO_CSD;
ap->ioaddr.command_addr = info->ide_addr + S3C_ATA_PIO_CSD;
ap->ioaddr.altstatus_addr = info->ide_addr + S3C_ATA_PIO_DAD;
ap->ioaddr.ctl_addr = info->ide_addr + S3C_ATA_PIO_DAD;
ata_port_desc(ap, "mmio cmd 0x%llx ",
(unsigned long long)res->start);
host->private_data = info;
if (pdata && pdata->setup_gpio)
pdata->setup_gpio();
/* Set endianness and enable the interface */
pata_s3c_hwinit(info, pdata);
ret = ata_host_activate(host, info->irq,
info->irq ? pata_s3c_irq : NULL,
0, &pata_s3c_sht);
if (ret)
goto stop_clk;
return 0;
stop_clk:
clk_disable(info->clk);
return ret;
}