diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-mpc.c | 16 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 47 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-sibyte.c | 6 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core.c | 14 | 
4 files changed, 60 insertions, 23 deletions
| diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 18beb0ad7bf..a076129de7e 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -99,7 +99,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)  	u32 x;  	int result = 0; -	if (i2c->irq == 0) +	if (i2c->irq == NO_IRQ)  	{  		while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {  			schedule(); @@ -329,10 +329,9 @@ static int fsl_i2c_probe(struct platform_device *pdev)  		return -ENOMEM;  	i2c->irq = platform_get_irq(pdev, 0); -	if (i2c->irq < 0) { -		result = -ENXIO; -		goto fail_get_irq; -	} +	if (i2c->irq < 0) +		i2c->irq = NO_IRQ; /* Use polling */ +  	i2c->flags = pdata->device_flags;  	init_waitqueue_head(&i2c->queue); @@ -344,7 +343,7 @@ static int fsl_i2c_probe(struct platform_device *pdev)  		goto fail_map;  	} -	if (i2c->irq != 0) +	if (i2c->irq != NO_IRQ)  		if ((result = request_irq(i2c->irq, mpc_i2c_isr,  					  IRQF_SHARED, "i2c-mpc", i2c)) < 0) {  			printk(KERN_ERR @@ -367,12 +366,11 @@ static int fsl_i2c_probe(struct platform_device *pdev)  	return result;        fail_add: -	if (i2c->irq != 0) +	if (i2c->irq != NO_IRQ)  		free_irq(i2c->irq, i2c);        fail_irq:  	iounmap(i2c->base);        fail_map: -      fail_get_irq:  	kfree(i2c);  	return result;  }; @@ -384,7 +382,7 @@ static int fsl_i2c_remove(struct platform_device *pdev)  	i2c_del_adapter(&i2c->adap);  	platform_set_drvdata(pdev, NULL); -	if (i2c->irq != 0) +	if (i2c->irq != NO_IRQ)  		free_irq(i2c->irq, i2c);  	iounmap(i2c->base); diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index fdc9ad805e3..ac916596858 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -104,10 +104,31 @@ MODULE_PARM_DESC(force_addr,  static int piix4_transaction(void);  static unsigned short piix4_smba; +static int srvrworks_csb5_delay;  static struct pci_driver piix4_driver;  static struct i2c_adapter piix4_adapter; -static struct dmi_system_id __devinitdata piix4_dmi_table[] = { +static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = { +	{ +		.ident = "Sapphire AM2RD790", +		.matches = { +			DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."), +			DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"), +		}, +	}, +	{ +		.ident = "DFI Lanparty UT 790FX", +		.matches = { +			DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."), +			DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"), +		}, +	}, +	{ } +}; + +/* The IBM entry is in a separate table because we only check it +   on Intel-based systems */ +static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = {  	{  		.ident = "IBM",  		.matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, @@ -122,8 +143,20 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,  	dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); +	if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) && +	    (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5)) +		srvrworks_csb5_delay = 1; + +	/* On some motherboards, it was reported that accessing the SMBus +	   caused severe hardware problems */ +	if (dmi_check_system(piix4_dmi_blacklist)) { +		dev_err(&PIIX4_dev->dev, +			"Accessing the SMBus on this system is unsafe!\n"); +		return -EPERM; +	} +  	/* Don't access SMBus on IBM systems which get corrupted eeproms */ -	if (dmi_check_system(piix4_dmi_table) && +	if (dmi_check_system(piix4_dmi_ibm) &&  			PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {  		dev_err(&PIIX4_dev->dev, "IBM system detected; this module "  			"may corrupt your serial eeprom! Refusing to load " @@ -230,10 +263,14 @@ static int piix4_transaction(void)  	outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);  	/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */ -	do { +	if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */ +		msleep(2); +	else +		msleep(1); + +	while ((timeout++ < MAX_TIMEOUT) && +	       ((temp = inb_p(SMBHSTSTS)) & 0x01))  		msleep(1); -		temp = inb_p(SMBHSTSTS); -	} while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));  	/* If the SMBus is still busy, we give up */  	if (timeout >= MAX_TIMEOUT) { diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c index 8fbbdb4c2f3..114634da6c6 100644 --- a/drivers/i2c/busses/i2c-sibyte.c +++ b/drivers/i2c/busses/i2c-sibyte.c @@ -132,14 +132,14 @@ static const struct i2c_algorithm i2c_sibyte_algo = {  /*   * registering functions to load algorithms at runtime   */ -int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) +static int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)  {  	struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; -	/* register new adapter to i2c module... */ +	/* Register new adapter to i2c module... */  	i2c_adap->algo = &i2c_sibyte_algo; -	/* Set the frequency to 100 kHz */ +	/* Set the requested frequency. */  	csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));  	csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL)); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 26384daccb9..c99ebeadb55 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -327,6 +327,11 @@ void i2c_unregister_device(struct i2c_client *client)  EXPORT_SYMBOL_GPL(i2c_unregister_device); +static const struct i2c_device_id dummy_id[] = { +	{ "dummy", 0 }, +	{ }, +}; +  static int dummy_probe(struct i2c_client *client,  		       const struct i2c_device_id *id)  { @@ -342,13 +347,13 @@ static struct i2c_driver dummy_driver = {  	.driver.name	= "dummy",  	.probe		= dummy_probe,  	.remove		= dummy_remove, +	.id_table	= dummy_id,  };  /**   * i2c_new_dummy - return a new i2c device bound to a dummy driver   * @adapter: the adapter managing the device   * @address: seven bit address to be used - * @type: optional label used for i2c_client.name   * Context: can sleep   *   * This returns an I2C client bound to the "dummy" driver, intended for use @@ -364,15 +369,12 @@ static struct i2c_driver dummy_driver = {   * i2c_unregister_device(); or NULL to indicate an error.   */  struct i2c_client * -i2c_new_dummy(struct i2c_adapter *adapter, u16 address, const char *type) +i2c_new_dummy(struct i2c_adapter *adapter, u16 address)  {  	struct i2c_board_info info = { -		.driver_name	= "dummy", -		.addr		= address, +		I2C_BOARD_INFO("dummy", address),  	}; -	if (type) -		strlcpy(info.type, type, sizeof info.type);  	return i2c_new_device(adapter, &info);  }  EXPORT_SYMBOL_GPL(i2c_new_dummy); | 
