static int vlynq_probe()

in vlynq.c [653:742]


static int vlynq_probe(struct platform_device *pdev)
{
	struct vlynq_device *dev;
	struct resource *regs_res, *mem_res, *irq_res;
	int len, result;

	regs_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
	if (!regs_res)
		return -ENODEV;

	mem_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
	if (!mem_res)
		return -ENODEV;

	irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "devirq");
	if (!irq_res)
		return -ENODEV;

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		printk(KERN_ERR
		       "vlynq: failed to allocate device structure\n");
		return -ENOMEM;
	}

	dev->id = pdev->id;
	dev->dev.bus = &vlynq_bus_type;
	dev->dev.parent = &pdev->dev;
	dev_set_name(&dev->dev, "vlynq%d", dev->id);
	dev->dev.platform_data = pdev->dev.platform_data;
	dev->dev.release = vlynq_device_release;

	dev->regs_start = regs_res->start;
	dev->regs_end = regs_res->end;
	dev->mem_start = mem_res->start;
	dev->mem_end = mem_res->end;

	len = resource_size(regs_res);
	if (!request_mem_region(regs_res->start, len, dev_name(&dev->dev))) {
		printk(KERN_ERR "%s: Can't request vlynq registers\n",
		       dev_name(&dev->dev));
		result = -ENXIO;
		goto fail_request;
	}

	dev->local = ioremap(regs_res->start, len);
	if (!dev->local) {
		printk(KERN_ERR "%s: Can't remap vlynq registers\n",
		       dev_name(&dev->dev));
		result = -ENXIO;
		goto fail_remap;
	}

	dev->remote = (struct vlynq_regs *)((void *)dev->local +
					    VLYNQ_REMOTE_OFFSET);

	dev->irq = platform_get_irq_byname(pdev, "irq");
	dev->irq_start = irq_res->start;
	dev->irq_end = irq_res->end;
	dev->local_irq = dev->irq_end - dev->irq_start;
	dev->remote_irq = dev->local_irq - 1;

	if (device_register(&dev->dev))
		goto fail_register;
	platform_set_drvdata(pdev, dev);

	printk(KERN_INFO "%s: regs 0x%p, irq %d, mem 0x%p\n",
	       dev_name(&dev->dev), (void *)dev->regs_start, dev->irq,
	       (void *)dev->mem_start);

	dev->dev_id = 0;
	dev->divisor = vlynq_div_auto;
	result = __vlynq_enable_device(dev);
	if (result == 0) {
		dev->dev_id = readl(&dev->remote->chip);
		((struct plat_vlynq_ops *)(dev->dev.platform_data))->off(dev);
	}
	if (dev->dev_id)
		printk(KERN_INFO "Found a VLYNQ device: %08x\n", dev->dev_id);

	return 0;

fail_register:
	iounmap(dev->local);
fail_remap:
fail_request:
	release_mem_region(regs_res->start, len);
	kfree(dev);
	return result;
}