diff options
| author | Chris Metcalf <cmetcalf@tilera.com> | 2010-08-06 10:37:02 -0400 | 
|---|---|---|
| committer | Chris Metcalf <cmetcalf@tilera.com> | 2010-08-06 10:37:02 -0400 | 
| commit | ab11b487402f97975f3ac1eeea09c82f4431481e (patch) | |
| tree | 86337c5cbbd2b0c4bd07c0847a1dc7de3d898147 /drivers/i2c | |
| parent | 1c689cbcf2c2b7a35cd237abddd9206bb1b6fee1 (diff) | |
| parent | fc1caf6eafb30ea185720e29f7f5eccca61ecd60 (diff) | |
Merge branch 'master' into for-linus
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-cpm.c | 6 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 8 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ibm_iic.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-mpc.c | 71 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-sibyte.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core.c | 16 | 
6 files changed, 66 insertions, 43 deletions
| diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index b02b4533651..e591de1bc70 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -652,6 +652,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,  	cpm->adap = cpm_ops;  	i2c_set_adapdata(&cpm->adap, cpm);  	cpm->adap.dev.parent = &ofdev->dev; +	cpm->adap.dev.of_node = of_node_get(ofdev->dev.of_node);  	result = cpm_i2c_setup(cpm);  	if (result) { @@ -676,11 +677,6 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,  	dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",  		cpm->adap.name); -	/* -	 * register OF I2C devices -	 */ -	of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node); -  	return 0;  out_shut:  	cpm_i2c_shutdown(cpm); diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index f4b21f2bb8e..c60081169cc 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -655,7 +655,7 @@ static void __devinit dmi_check_onboard_device(u8 type, const char *name,  		/* & ~0x80, ignore enabled/disabled bit */  		if ((type & ~0x80) != dmi_devices[i].type)  			continue; -		if (strcmp(name, dmi_devices[i].name)) +		if (strcasecmp(name, dmi_devices[i].name))  			continue;  		memset(&info, 0, sizeof(struct i2c_board_info)); @@ -704,9 +704,6 @@ static int __devinit i801_probe(struct pci_dev *dev,  {  	unsigned char temp;  	int err, i; -#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE -	const char *vendor; -#endif  	I801_dev = dev;  	i801_features = 0; @@ -808,8 +805,7 @@ static int __devinit i801_probe(struct pci_dev *dev,  	}  #endif  #if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE -	vendor = dmi_get_system_info(DMI_BOARD_VENDOR); -	if (vendor && !strcmp(vendor, "FUJITSU SIEMENS")) +	if (dmi_name_in_vendors("FUJITSU"))  		dmi_walk(dmi_check_onboard_devices, &i801_adapter);  #endif diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index bf344135647..1168d61418c 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -745,6 +745,7 @@ static int __devinit iic_probe(struct of_device *ofdev,  	/* Register it with i2c layer */  	adap = &dev->adap;  	adap->dev.parent = &ofdev->dev; +	adap->dev.of_node = of_node_get(np);  	strlcpy(adap->name, "IBM IIC", sizeof(adap->name));  	i2c_set_adapdata(adap, dev);  	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; @@ -760,9 +761,6 @@ static int __devinit iic_probe(struct of_device *ofdev,  	dev_info(&ofdev->dev, "using %s mode\n",  		 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); -	/* Now register all the child nodes */ -	of_register_i2c_devices(adap, np); -  	return 0;  error_cleanup: diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index df00eb1f11f..6545d1c99b6 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -63,6 +63,7 @@ struct mpc_i2c {  	wait_queue_head_t queue;  	struct i2c_adapter adap;  	int irq; +	u32 real_clk;  };  struct mpc_i2c_divider { @@ -96,20 +97,23 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)  /* Sometimes 9th clock pulse isn't generated, and slave doesn't release   * the bus, because it wants to send ACK.   * Following sequence of enabling/disabling and sending start/stop generates - * the pulse, so it's all OK. + * the 9 pulses, so it's all OK.   */  static void mpc_i2c_fixup(struct mpc_i2c *i2c)  { -	writeccr(i2c, 0); -	udelay(30); -	writeccr(i2c, CCR_MEN); -	udelay(30); -	writeccr(i2c, CCR_MSTA | CCR_MTX); -	udelay(30); -	writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); -	udelay(30); -	writeccr(i2c, CCR_MEN); -	udelay(30); +	int k; +	u32 delay_val = 1000000 / i2c->real_clk + 1; + +	if (delay_val < 2) +		delay_val = 2; + +	for (k = 9; k; k--) { +		writeccr(i2c, 0); +		writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); +		udelay(delay_val); +		writeccr(i2c, CCR_MEN); +		udelay(delay_val << 1); +	}  }  static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) @@ -190,15 +194,18 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = {  };  static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, -					  int prescaler) +					  int prescaler, u32 *real_clk)  {  	const struct mpc_i2c_divider *div = NULL;  	unsigned int pvr = mfspr(SPRN_PVR);  	u32 divider;  	int i; -	if (clock == MPC_I2C_CLOCK_LEGACY) +	if (clock == MPC_I2C_CLOCK_LEGACY) { +		/* see below - default fdr = 0x3f -> div = 2048 */ +		*real_clk = mpc5xxx_get_bus_frequency(node) / 2048;  		return -EINVAL; +	}  	/* Determine divider value */  	divider = mpc5xxx_get_bus_frequency(node) / clock; @@ -216,7 +223,8 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,  			break;  	} -	return div ? (int)div->fdr : -EINVAL; +	*real_clk = mpc5xxx_get_bus_frequency(node) / div->divider; +	return (int)div->fdr;  }  static void __devinit mpc_i2c_setup_52xx(struct device_node *node, @@ -231,13 +239,14 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node,  		return;  	} -	ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler); +	ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, &i2c->real_clk);  	fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */  	writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);  	if (ret >= 0) -		dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); +		dev_info(i2c->dev, "clock %u Hz (fdr=%d)\n", i2c->real_clk, +			 fdr);  }  #else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */  static void __devinit mpc_i2c_setup_52xx(struct device_node *node, @@ -334,14 +343,17 @@ static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void)  }  static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, -					  u32 prescaler) +					  u32 prescaler, u32 *real_clk)  {  	const struct mpc_i2c_divider *div = NULL;  	u32 divider;  	int i; -	if (clock == MPC_I2C_CLOCK_LEGACY) +	if (clock == MPC_I2C_CLOCK_LEGACY) { +		/* see below - default fdr = 0x1031 -> div = 16 * 3072 */ +		*real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);  		return -EINVAL; +	}  	/* Determine proper divider value */  	if (of_device_is_compatible(node, "fsl,mpc8544-i2c")) @@ -364,6 +376,7 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,  			break;  	} +	*real_clk = fsl_get_sys_freq() / prescaler / div->divider;  	return div ? (int)div->fdr : -EINVAL;  } @@ -380,7 +393,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,  		return;  	} -	ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); +	ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler, &i2c->real_clk);  	fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */  	writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); @@ -388,7 +401,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,  	if (ret >= 0)  		dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n", -			 clock, fdr >> 8, fdr & 0xff); +			 i2c->real_clk, fdr >> 8, fdr & 0xff);  }  #else /* !CONFIG_FSL_SOC */ @@ -500,10 +513,14 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  			return -EINTR;  		}  		if (time_after(jiffies, orig_jiffies + HZ)) { +			u8 status = readb(i2c->base + MPC_I2C_SR); +  			dev_dbg(i2c->dev, "timeout\n"); -			if (readb(i2c->base + MPC_I2C_SR) == -			    (CSR_MCF | CSR_MBB | CSR_RXAK)) +			if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { +				writeb(status & ~CSR_MAL, +				       i2c->base + MPC_I2C_SR);  				mpc_i2c_fixup(i2c); +			}  			return -EIO;  		}  		schedule(); @@ -595,18 +612,26 @@ static int __devinit fsl_i2c_probe(struct of_device *op,  			mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0);  	} +	prop = of_get_property(op->dev.of_node, "fsl,timeout", &plen); +	if (prop && plen == sizeof(u32)) { +		mpc_ops.timeout = *prop * HZ / 1000000; +		if (mpc_ops.timeout < 5) +			mpc_ops.timeout = 5; +	} +	dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ); +  	dev_set_drvdata(&op->dev, i2c);  	i2c->adap = mpc_ops;  	i2c_set_adapdata(&i2c->adap, i2c);  	i2c->adap.dev.parent = &op->dev; +	i2c->adap.dev.of_node = of_node_get(op->dev.of_node);  	result = i2c_add_adapter(&i2c->adap);  	if (result < 0) {  		dev_err(i2c->dev, "failed to add adapter\n");  		goto fail_add;  	} -	of_register_i2c_devices(&i2c->adap, op->dev.of_node);  	return result; diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c index 3d76a188e42..0fe505d7abe 100644 --- a/drivers/i2c/busses/i2c-sibyte.c +++ b/drivers/i2c/busses/i2c-sibyte.c @@ -94,7 +94,7 @@ static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr,  		}  		break;  	default: -		return -1;      /* XXXKW better error code? */ +		return -EOPNOTSUPP;  	}  	while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY) @@ -104,7 +104,7 @@ static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr,  	if (error & M_SMB_ERROR) {  		/* Clear error bit by writing a 1 */  		csr_out32(M_SMB_ERROR, SMB_CSR(adap, R_SMB_STATUS)); -		return -1;      /* XXXKW better error code? */ +		return (error & M_SMB_ERROR_TYPE) ? -EIO : -ENXIO;  	}  	if (data_bytes == 1) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 1cca2631e5b..df937df845e 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -30,6 +30,8 @@  #include <linux/init.h>  #include <linux/idr.h>  #include <linux/mutex.h> +#include <linux/of_i2c.h> +#include <linux/of_device.h>  #include <linux/completion.h>  #include <linux/hardirq.h>  #include <linux/irqflags.h> @@ -70,6 +72,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)  	if (!client)  		return 0; +	/* Attempt an OF style match */ +	if (of_driver_match_device(dev, drv)) +		return 1; +  	driver = to_i2c_driver(drv);  	/* match on an id table if there is one */  	if (driver->id_table) @@ -790,6 +796,9 @@ static int i2c_register_adapter(struct i2c_adapter *adap)  	if (adap->nr < __i2c_first_dynamic_bus_num)  		i2c_scan_static_board_info(adap); +	/* Register devices from the device tree */ +	of_i2c_register_devices(adap); +  	/* Notify drivers */  	mutex_lock(&core_lock);  	dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, @@ -1428,13 +1437,12 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)  	if (!(adapter->class & driver->class))  		goto exit_free; -	/* Stop here if we can't use SMBUS_QUICK */ -	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) { +	/* Stop here if the bus doesn't support probing */ +	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE)) {  		if (address_list[0] == I2C_CLIENT_END)  			goto exit_free; -		dev_warn(&adapter->dev, "SMBus Quick command not supported, " -			 "can't probe for chips\n"); +		dev_warn(&adapter->dev, "Probing not supported\n");  		err = -EOPNOTSUPP;  		goto exit_free;  	} | 
