Ejemplo n.º 1
0
static struct bbc_i2c_bus * __init attach_one_i2c(struct of_device *op, int index)
{
	struct bbc_i2c_bus *bp;
	struct device_node *dp;
	int entry;

	bp = kzalloc(sizeof(*bp), GFP_KERNEL);
	if (!bp)
		return NULL;

	bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs");
	if (!bp->i2c_control_regs)
		goto fail;

	bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel");
	if (!bp->i2c_bussel_reg)
		goto fail;

	bp->waiting = 0;
	init_waitqueue_head(&bp->wq);
	if (request_irq(op->irqs[0], bbc_i2c_interrupt,
			IRQF_SHARED, "bbc_i2c", bp))
		goto fail;

	bp->index = index;
	bp->op = op;

	spin_lock_init(&bp->lock);

	entry = 0;
	for (dp = op->node->child;
	     dp && entry < 8;
	     dp = dp->sibling, entry++) {
		struct of_device *child_op;

		child_op = of_find_device_by_node(dp);
		bp->devs[entry].device = child_op;
		bp->devs[entry].client_claimed = 0;
	}

	writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0);
	bp->own = readb(bp->i2c_control_regs + 0x01);
	writeb(I2C_PCF_PIN | I2C_PCF_ES1, bp->i2c_control_regs + 0x0);
	bp->clock = readb(bp->i2c_control_regs + 0x01);

	printk(KERN_INFO "i2c-%d: Regs at %p, %d devices, own %02x, clock %02x.\n",
	       bp->index, bp->i2c_control_regs, entry, bp->own, bp->clock);

	reset_one_i2c(bp);

	return bp;

fail:
	if (bp->i2c_bussel_reg)
		of_iounmap(&op->resource[1], bp->i2c_bussel_reg, 1);
	if (bp->i2c_control_regs)
		of_iounmap(&op->resource[0], bp->i2c_control_regs, 2);
	kfree(bp);
	return NULL;
}
Ejemplo n.º 2
0
static int __init attach_one_i2c(struct linux_ebus_device *edev, int index)
{
	struct bbc_i2c_bus *bp = kmalloc(sizeof(*bp), GFP_KERNEL);
	struct linux_ebus_child *echild;
	int entry;

	if (!bp)
		return -ENOMEM;
	memset(bp, 0, sizeof(*bp));

	bp->i2c_control_regs = ioremap(edev->resource[0].start, 0x2);
	if (!bp->i2c_control_regs)
		goto fail;

	if (edev->num_addrs == 2) {
		bp->i2c_bussel_reg = ioremap(edev->resource[1].start, 0x1);
		if (!bp->i2c_bussel_reg)
			goto fail;
	}

	bp->waiting = 0;
	init_waitqueue_head(&bp->wq);
	if (request_irq(edev->irqs[0], bbc_i2c_interrupt,
			SA_SHIRQ, "bbc_i2c", bp))
		goto fail;

	bp->index = index;
	bp->bus_edev = edev;

	spin_lock_init(&bp->lock);
	bp->next = all_bbc_i2c;
	all_bbc_i2c = bp;

	entry = 0;
	for (echild = edev->children;
	     echild && entry < 8;
	     echild = echild->next, entry++) {
		bp->devs[entry].device = echild;
		bp->devs[entry].client_claimed = 0;
	}

	writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0);
	bp->own = readb(bp->i2c_control_regs + 0x01);
	writeb(I2C_PCF_PIN | I2C_PCF_ES1, bp->i2c_control_regs + 0x0);
	bp->clock = readb(bp->i2c_control_regs + 0x01);

	printk(KERN_INFO "i2c-%d: Regs at %p, %d devices, own %02x, clock %02x.\n",
	       bp->index, bp->i2c_control_regs, entry, bp->own, bp->clock);

	reset_one_i2c(bp);

	return 0;

fail:
	if (bp->i2c_bussel_reg)
		iounmap(bp->i2c_bussel_reg);
	if (bp->i2c_control_regs)
		iounmap(bp->i2c_control_regs);
	kfree(bp);
	return -EINVAL;
}