Example #1
0
static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
{
	int result = 0;
	struct mpc_i2c *i2c;

	if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
		return -ENOMEM;
	}
	memset(i2c, 0, sizeof(*i2c));

	i2c->irq = ocp->def->irq;
	i2c->flags = ((struct ocp_fs_i2c_data *)ocp->def->additions)->flags;
	init_waitqueue_head(&i2c->queue);

	if (!request_mem_region(ocp->def->paddr, MPC_I2C_REGION, "i2c-mpc")) {
		printk(KERN_ERR "i2c-mpc - resource unavailable\n");
		return -ENODEV;
	}

	i2c->base = ioremap(ocp->def->paddr, MPC_I2C_REGION);

	if (!i2c->base) {
		printk(KERN_ERR "i2c-mpc - failed to map controller\n");
		result = -ENOMEM;
		goto fail_map;
	}

	if (i2c->irq != OCP_IRQ_NA)
	{
		if ((result = request_irq(ocp->def->irq, mpc_i2c_isr,
					  0, "i2c-mpc", i2c)) < 0) {
			printk(KERN_ERR
			       "i2c-mpc - failed to attach interrupt\n");
			goto fail_irq;
		}
	} else
		i2c->irq = 0;

	i2c->adap = mpc_ops;
	i2c_set_adapdata(&i2c->adap, i2c);

	if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
		printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
		goto fail_add;
	}

	mpc_i2c_setclock(i2c);
	ocp_set_drvdata(ocp, i2c);
	return result;

      fail_add:
	if (ocp->def->irq != OCP_IRQ_NA)
		free_irq(ocp->def->irq, 0);
      fail_irq:
	iounmap(i2c->base);
      fail_map:
	release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
	kfree(i2c);
	return result;
}
Example #2
0
void __exit __tah_fini(struct ocp_device *ocpdev)
{
	struct tah_regs *p = ocp_get_drvdata(ocpdev);
	BUG_ON(!p);
	ocp_set_drvdata(ocpdev, NULL);
	iounmap((void *)p);
}
Example #3
0
static void __devexit mpc_i2c_remove(struct ocp_device *ocp)
{
	struct mpc_i2c *i2c = ocp_get_drvdata(ocp);
	ocp_set_drvdata(ocp, NULL);
	i2c_del_adapter(&i2c->adap);

	if (ocp->def->irq != OCP_IRQ_NA)
		free_irq(i2c->irq, i2c);
	iounmap(i2c->base);
	release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
	kfree(i2c);
}
Example #4
0
void __rgmii_fini(struct ocp_device *ocpdev, int input)
{
	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
	BUG_ON(!dev || dev->users == 0);

	RGMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);

	/* Disable this input */
	out_be32(&dev->base->fer,
		 in_be32(&dev->base->fer) & ~RGMII_FER_MASK(input));

	if (!--dev->users) {
		/* Free everything if this is the last user */
		ocp_set_drvdata(ocpdev, NULL);
		iounmap((void *)dev->base);
		kfree(dev);
	}
}
Example #5
0
static int __init rgmii_init(struct ocp_device *ocpdev, int input, int mode)
{
	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
	struct rgmii_regs *p;

	RGMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, mode);

	if (!dev) {
		dev = kmalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL);
		if (!dev) {
			printk(KERN_ERR
			       "rgmii%d: couldn't allocate device structure!\n",
			       ocpdev->def->index);
			return -ENOMEM;
		}
		memset(dev, 0, sizeof(struct ibm_ocp_rgmii));

		p = (struct rgmii_regs *)ioremap(ocpdev->def->paddr,
						 sizeof(struct rgmii_regs));
		if (!p) {
			printk(KERN_ERR
			       "rgmii%d: could not ioremap device registers!\n",
			       ocpdev->def->index);
			kfree(dev);
			return -ENOMEM;
		}

		dev->base = p;
		ocp_set_drvdata(ocpdev, dev);

		/* Disable all inputs by default */
		out_be32(&p->fer, 0);
	} else
		p = dev->base;

	/* Enable this input */
	out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input));

	printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n",
	       ocpdev->def->index, input, rgmii_mode_name(mode));

	++dev->users;
	return 0;
}
Example #6
0
static int __init tah_init(struct ocp_device *ocpdev)
{
	struct tah_regs *p;

	if (ocp_get_drvdata(ocpdev)) {
		printk(KERN_ERR "tah%d: already in use!\n", ocpdev->def->index);
		return -EBUSY;
	}

	/* Initialize TAH and enable IPv4 checksum verification, no TSO yet */
	p = (struct tah_regs *)ioremap(ocpdev->def->paddr, sizeof(*p));
	if (!p) {
		printk(KERN_ERR "tah%d: could not ioremap device registers!\n",
		       ocpdev->def->index);
		return -ENOMEM;
	}
	ocp_set_drvdata(ocpdev, p);
	__tah_reset(ocpdev);

	return 0;
}
Example #7
0
static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode)
{
	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
	struct zmii_regs __iomem *p;

	ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode);

	if (!dev) {
		dev = kzalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL);
		if (!dev) {
			printk(KERN_ERR
			       "zmii%d: couldn't allocate device structure!\n",
			       ocpdev->def->index);
			return -ENOMEM;
		}
		dev->mode = PHY_MODE_NA;

		p = ioremap(ocpdev->def->paddr, sizeof(struct zmii_regs));
		if (!p) {
			printk(KERN_ERR
			       "zmii%d: could not ioremap device registers!\n",
			       ocpdev->def->index);
			kfree(dev);
			return -ENOMEM;
		}
		dev->base = p;
		ocp_set_drvdata(ocpdev, dev);
		
		/* We may need FER value for autodetection later */
		dev->fer_save = in_be32(&p->fer);

		/* Disable all inputs by default */
		out_be32(&p->fer, 0);
	} else
		p = dev->base;

	if (!zmii_valid_mode(*mode)) {
		/* Probably an EMAC connected to RGMII, 
		 * but it still may need ZMII for MDIO 
		 */
		goto out;
	}

	/* Autodetect ZMII mode if not specified.
	 * This is only for backward compatibility with the old driver.
	 * Please, always specify PHY mode in your board port to avoid
	 * any surprises.
	 */
	if (dev->mode == PHY_MODE_NA) {
		if (*mode == PHY_MODE_NA) {
			u32 r = dev->fer_save;

			ZMII_DBG("%d: autodetecting mode, FER = 0x%08x" NL,
				 ocpdev->def->index, r);
			
			if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))
				dev->mode = PHY_MODE_MII;
			else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))
				dev->mode = PHY_MODE_RMII;
			else
				dev->mode = PHY_MODE_SMII;
		} else
			dev->mode = *mode;

		printk(KERN_NOTICE "zmii%d: bridge in %s mode\n",
		       ocpdev->def->index, zmii_mode_name(dev->mode));
	} else {
		/* All inputs must use the same mode */
		if (*mode != PHY_MODE_NA && *mode != dev->mode) {
			printk(KERN_ERR
			       "zmii%d: invalid mode %d specified for input %d\n",
			       ocpdev->def->index, *mode, input);
			return -EINVAL;
		}
	}

	/* Report back correct PHY mode, 
	 * it may be used during PHY initialization.
	 */
	*mode = dev->mode;

	/* Enable this input */
	out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input));
      out:
	++dev->users;
	return 0;
}