Commit bb476800 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c fixes from Wolfram Sang:
 "Here are two I2C driver regression fixes.  piix4 gets a larger
  overhaul fixing the latest refactoring and also an older known issue
  as well.  designware-pci gets a fix for a bad merge conflict
  resolution"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: piix4: don't regress on bus names
  i2c: designware-pci: use IRQF_COND_SUSPEND flag
  i2c: piix4: Fully initialize SB800 before it is registered
  i2c: piix4: Fix SB800 locking
parents ad0b40fa 52795f6f
...@@ -874,7 +874,8 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) ...@@ -874,7 +874,8 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
i2c_set_adapdata(adap, dev); i2c_set_adapdata(adap, dev);
i2c_dw_disable_int(dev); i2c_dw_disable_int(dev);
r = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, IRQF_SHARED, r = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr,
IRQF_SHARED | IRQF_COND_SUSPEND,
dev_name(dev->dev), dev); dev_name(dev->dev), dev);
if (r) { if (r) {
dev_err(dev->dev, "failure requesting irq %i: %d\n", dev_err(dev->dev, "failure requesting irq %i: %d\n",
......
...@@ -137,10 +137,11 @@ static const struct dmi_system_id piix4_dmi_ibm[] = { ...@@ -137,10 +137,11 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
}; };
/* SB800 globals */ /* SB800 globals */
static DEFINE_MUTEX(piix4_mutex_sb800);
static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = { static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = {
"SDA0", "SDA2", "SDA3", "SDA4" " port 0", " port 2", " port 3", " port 4"
}; };
static const char *piix4_aux_port_name_sb800 = "SDA1"; static const char *piix4_aux_port_name_sb800 = " port 1";
struct i2c_piix4_adapdata { struct i2c_piix4_adapdata {
unsigned short smba; unsigned short smba;
...@@ -148,7 +149,6 @@ struct i2c_piix4_adapdata { ...@@ -148,7 +149,6 @@ struct i2c_piix4_adapdata {
/* SB800 */ /* SB800 */
bool sb800_main; bool sb800_main;
unsigned short port; unsigned short port;
struct mutex *mutex;
}; };
static int piix4_setup(struct pci_dev *PIIX4_dev, static int piix4_setup(struct pci_dev *PIIX4_dev,
...@@ -275,10 +275,12 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, ...@@ -275,10 +275,12 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
else else
smb_en = (aux) ? 0x28 : 0x2c; smb_en = (aux) ? 0x28 : 0x2c;
mutex_lock(&piix4_mutex_sb800);
outb_p(smb_en, SB800_PIIX4_SMB_IDX); outb_p(smb_en, SB800_PIIX4_SMB_IDX);
smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX); outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX);
smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1); smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1);
mutex_unlock(&piix4_mutex_sb800);
if (!smb_en) { if (!smb_en) {
smb_en_status = smba_en_lo & 0x10; smb_en_status = smba_en_lo & 0x10;
...@@ -559,7 +561,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, ...@@ -559,7 +561,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
u8 port; u8 port;
int retval; int retval;
mutex_lock(adapdata->mutex); mutex_lock(&piix4_mutex_sb800);
outb_p(SB800_PIIX4_PORT_IDX, SB800_PIIX4_SMB_IDX); outb_p(SB800_PIIX4_PORT_IDX, SB800_PIIX4_SMB_IDX);
smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
...@@ -574,7 +576,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, ...@@ -574,7 +576,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1); outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1);
mutex_unlock(adapdata->mutex); mutex_unlock(&piix4_mutex_sb800);
return retval; return retval;
} }
...@@ -625,6 +627,7 @@ static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS]; ...@@ -625,6 +627,7 @@ static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
static struct i2c_adapter *piix4_aux_adapter; static struct i2c_adapter *piix4_aux_adapter;
static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
bool sb800_main, unsigned short port,
const char *name, struct i2c_adapter **padap) const char *name, struct i2c_adapter **padap)
{ {
struct i2c_adapter *adap; struct i2c_adapter *adap;
...@@ -639,7 +642,8 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, ...@@ -639,7 +642,8 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->algo = &smbus_algorithm; adap->algo = sb800_main ? &piix4_smbus_algorithm_sb800
: &smbus_algorithm;
adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL); adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL);
if (adapdata == NULL) { if (adapdata == NULL) {
...@@ -649,12 +653,14 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, ...@@ -649,12 +653,14 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
} }
adapdata->smba = smba; adapdata->smba = smba;
adapdata->sb800_main = sb800_main;
adapdata->port = port;
/* set up the sysfs linkage to our parent device */ /* set up the sysfs linkage to our parent device */
adap->dev.parent = &dev->dev; adap->dev.parent = &dev->dev;
snprintf(adap->name, sizeof(adap->name), snprintf(adap->name, sizeof(adap->name),
"SMBus PIIX4 adapter %s at %04x", name, smba); "SMBus PIIX4 adapter%s at %04x", name, smba);
i2c_set_adapdata(adap, adapdata); i2c_set_adapdata(adap, adapdata);
...@@ -673,30 +679,16 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, ...@@ -673,30 +679,16 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba) static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba)
{ {
struct mutex *mutex;
struct i2c_piix4_adapdata *adapdata; struct i2c_piix4_adapdata *adapdata;
int port; int port;
int retval; int retval;
mutex = kzalloc(sizeof(*mutex), GFP_KERNEL);
if (mutex == NULL)
return -ENOMEM;
mutex_init(mutex);
for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) { for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
retval = piix4_add_adapter(dev, smba, retval = piix4_add_adapter(dev, smba, true, port,
piix4_main_port_names_sb800[port], piix4_main_port_names_sb800[port],
&piix4_main_adapters[port]); &piix4_main_adapters[port]);
if (retval < 0) if (retval < 0)
goto error; goto error;
piix4_main_adapters[port]->algo = &piix4_smbus_algorithm_sb800;
adapdata = i2c_get_adapdata(piix4_main_adapters[port]);
adapdata->sb800_main = true;
adapdata->port = port;
adapdata->mutex = mutex;
} }
return retval; return retval;
...@@ -714,19 +706,20 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba) ...@@ -714,19 +706,20 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba)
} }
} }
kfree(mutex);
return retval; return retval;
} }
static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
{ {
int retval; int retval;
bool is_sb800 = false;
if ((dev->vendor == PCI_VENDOR_ID_ATI && if ((dev->vendor == PCI_VENDOR_ID_ATI &&
dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
dev->revision >= 0x40) || dev->revision >= 0x40) ||
dev->vendor == PCI_VENDOR_ID_AMD) { dev->vendor == PCI_VENDOR_ID_AMD) {
is_sb800 = true;
if (!request_region(SB800_PIIX4_SMB_IDX, 2, "smba_idx")) { if (!request_region(SB800_PIIX4_SMB_IDX, 2, "smba_idx")) {
dev_err(&dev->dev, dev_err(&dev->dev,
"SMBus base address index region 0x%x already in use!\n", "SMBus base address index region 0x%x already in use!\n",
...@@ -756,7 +749,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -756,7 +749,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
return retval; return retval;
/* Try to register main SMBus adapter, give up if we can't */ /* Try to register main SMBus adapter, give up if we can't */
retval = piix4_add_adapter(dev, retval, "main", retval = piix4_add_adapter(dev, retval, false, 0, "",
&piix4_main_adapters[0]); &piix4_main_adapters[0]);
if (retval < 0) if (retval < 0)
return retval; return retval;
...@@ -783,7 +776,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -783,7 +776,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (retval > 0) { if (retval > 0) {
/* Try to add the aux adapter if it exists, /* Try to add the aux adapter if it exists,
* piix4_add_adapter will clean up if this fails */ * piix4_add_adapter will clean up if this fails */
piix4_add_adapter(dev, retval, piix4_aux_port_name_sb800, piix4_add_adapter(dev, retval, false, 0,
is_sb800 ? piix4_aux_port_name_sb800 : "",
&piix4_aux_adapter); &piix4_aux_adapter);
} }
...@@ -798,11 +792,9 @@ static void piix4_adap_remove(struct i2c_adapter *adap) ...@@ -798,11 +792,9 @@ static void piix4_adap_remove(struct i2c_adapter *adap)
i2c_del_adapter(adap); i2c_del_adapter(adap);
if (adapdata->port == 0) { if (adapdata->port == 0) {
release_region(adapdata->smba, SMBIOSIZE); release_region(adapdata->smba, SMBIOSIZE);
if (adapdata->sb800_main) { if (adapdata->sb800_main)
kfree(adapdata->mutex);
release_region(SB800_PIIX4_SMB_IDX, 2); release_region(SB800_PIIX4_SMB_IDX, 2);
} }
}
kfree(adapdata); kfree(adapdata);
kfree(adap); kfree(adap);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment