static int __init pata_s3c_probe()

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;
}