Commit 606e1044 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6

into home.osdl.org:/home/torvalds/v2.5/linux
parents bed2f5d0 e47b5d29
...@@ -187,10 +187,6 @@ static struct irqchip clps7500_no_chip = { ...@@ -187,10 +187,6 @@ static struct irqchip clps7500_no_chip = {
.unmask = cl7500_no_action, .unmask = cl7500_no_action,
}; };
static void no_action(int cpl, void *dev_id, struct pt_regs *regs)
{
}
static struct irqaction irq_isa = { no_action, 0, 0, "isa", NULL, NULL }; static struct irqaction irq_isa = { no_action, 0, 0, "isa", NULL, NULL };
static void __init clps7500_init_irq(void) static void __init clps7500_init_irq(void)
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -90,3 +91,6 @@ int lm_device_register(struct lm_device *dev) ...@@ -90,3 +91,6 @@ int lm_device_register(struct lm_device *dev)
} }
return ret; return ret;
} }
EXPORT_SYMBOL(lm_driver_register);
EXPORT_SYMBOL(lm_driver_unregister);
...@@ -248,11 +248,11 @@ config I2C_SIS5595 ...@@ -248,11 +248,11 @@ config I2C_SIS5595
will be called i2c-sis5595. will be called i2c-sis5595.
config I2C_SIS630 config I2C_SIS630
tristate "SiS 630" tristate "SiS 630/730"
depends on I2C && PCI && EXPERIMENTAL depends on I2C && PCI && EXPERIMENTAL
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
SiS630 SMBus (a subset of I2C) interface. SiS630 and SiS730 SMBus (a subset of I2C) interface.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-sis630. will be called i2c-sis630.
......
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
Fixed the typo in sis630_access (Thanks to Mark M. Hoffman) Fixed the typo in sis630_access (Thanks to Mark M. Hoffman)
Changed sis630_transaction.(Thanks to Mark M. Hoffman) Changed sis630_transaction.(Thanks to Mark M. Hoffman)
18.09.2002 18.09.2002
Added SIS730 as supported Added SIS730 as supported.
21.09.2002 21.09.2002
Added high_clock module option.If this option is set Added high_clock module option.If this option is set
used Host Master Clock 56KHz (default 14KHz).For now we are save old Host used Host Master Clock 56KHz (default 14KHz).For now we save old Host
Master Clock and after transaction completed restore (otherwise Master Clock and after transaction completed restore (otherwise
it's confuse BIOS and hung Machine). it's confuse BIOS and hung Machine).
24.09.2002 24.09.2002
...@@ -95,12 +95,22 @@ ...@@ -95,12 +95,22 @@
/* insmod parameters */ /* insmod parameters */
static int high_clock = 0; static int high_clock = 0;
static int force = 0;
MODULE_PARM(high_clock, "i"); MODULE_PARM(high_clock, "i");
MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz)."); MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz).");
MODULE_PARM(force, "i");
MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!");
/* acpi base address */
static unsigned short acpi_base = 0; static unsigned short acpi_base = 0;
/* supported chips */
static int supported[] = {
PCI_DEVICE_ID_SI_630,
PCI_DEVICE_ID_SI_730,
0 /* terminates the list */
};
static inline u8 sis630_read(u8 reg) static inline u8 sis630_read(u8 reg)
{ {
return inb(acpi_base + reg); return inb(acpi_base + reg);
...@@ -277,6 +287,10 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat ...@@ -277,6 +287,10 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat
if (len == 0) if (len == 0)
data->block[0] = sis630_read(SMB_COUNT); data->block[0] = sis630_read(SMB_COUNT);
/* just to be sure */
if (data->block[0] > 32)
data->block[0] = 32;
dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]); dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]);
for (i=0; i < 8 && len < data->block[0]; i++,len++) { for (i=0; i < 8 && len < data->block[0]; i++,len++) {
...@@ -372,16 +386,26 @@ static u32 sis630_func(struct i2c_adapter *adapter) ...@@ -372,16 +386,26 @@ static u32 sis630_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_BLOCK_DATA; I2C_FUNC_SMBUS_BLOCK_DATA;
} }
static int sis630_setup(struct pci_dev *dummy) static int sis630_setup(struct pci_dev *sis630_dev)
{ {
unsigned char b; unsigned char b;
struct pci_dev *sis630_dev = NULL; struct pci_dev *dummy = NULL;
int retval = -ENODEV; int retval = -ENODEV, i;
/* check for supported SiS devices */
for (i=0; supported[i] > 0 ; i++) {
if ((dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy)))
break; /* found */
}
/* We need ISA bridge and not pci device passed in. */ if (dummy) {
sis630_dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis630_dev); pci_dev_put(dummy);
if (!sis630_dev) { }
dev_err(&dummy->dev, "Error: Can't detect 85C503/5513 ISA bridge!\n"); else if (force > 0) {
dev_err(&sis630_dev->dev, "WARNING: Can't detect SIS630 compatible device, but "
"loading because of force option enabled\n");
}
else {
return -ENODEV; return -ENODEV;
} }
...@@ -389,19 +413,19 @@ static int sis630_setup(struct pci_dev *dummy) ...@@ -389,19 +413,19 @@ static int sis630_setup(struct pci_dev *dummy)
Enable ACPI first , so we can accsess reg 74-75 Enable ACPI first , so we can accsess reg 74-75
in acpi io space and read acpi base addr in acpi io space and read acpi base addr
*/ */
if (!pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) { if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n"); dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
goto exit; goto exit;
} }
/* if ACPI already enabled , do nothing */ /* if ACPI already enabled , do nothing */
if (!(b & 0x80) && if (!(b & 0x80) &&
!pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) { pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n"); dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
goto exit; goto exit;
} }
/* Determine the ACPI base address */ /* Determine the ACPI base address */
if (!pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) { if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n"); dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
goto exit; goto exit;
} }
...@@ -418,7 +442,8 @@ static int sis630_setup(struct pci_dev *dummy) ...@@ -418,7 +442,8 @@ static int sis630_setup(struct pci_dev *dummy)
retval = 0; retval = 0;
exit: exit:
pci_dev_put(sis630_dev); if (retval)
acpi_base = 0;
return retval; return retval;
} }
...@@ -432,19 +457,18 @@ static struct i2c_algorithm smbus_algorithm = { ...@@ -432,19 +457,18 @@ static struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis630_adapter = { static struct i2c_adapter sis630_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.class = I2C_ADAP_CLASS_SMBUS,
.name = "unset", .name = "unset",
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
}; };
static struct pci_device_id sis630_ids[] __devinitdata = { static struct pci_device_id sis630_ids[] __devinitdata = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630) }, { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_730) },
{ 0, } { 0, }
}; };
static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id) static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
{ {
if (sis630_setup(dev)) { if (sis630_setup(dev)) {
dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n"); dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n");
return -ENODEV; return -ENODEV;
...@@ -461,7 +485,11 @@ static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_i ...@@ -461,7 +485,11 @@ static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_i
static void __devexit sis630_remove(struct pci_dev *dev) static void __devexit sis630_remove(struct pci_dev *dev)
{ {
i2c_del_adapter(&sis630_adapter); if (acpi_base) {
i2c_del_adapter(&sis630_adapter);
release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
acpi_base = 0;
}
} }
...@@ -481,7 +509,6 @@ static int __init i2c_sis630_init(void) ...@@ -481,7 +509,6 @@ static int __init i2c_sis630_init(void)
static void __exit i2c_sis630_exit(void) static void __exit i2c_sis630_exit(void)
{ {
pci_unregister_driver(&sis630_driver); pci_unregister_driver(&sis630_driver);
release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
} }
......
...@@ -15,7 +15,7 @@ config SENSORS_ADM1021 ...@@ -15,7 +15,7 @@ config SENSORS_ADM1021
help help
If you say yes here you get support for Analog Devices ADM1021 If you say yes here you get support for Analog Devices ADM1021
and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
Genesys Logic GL523SM, National Semi LM84, TI THMC10, Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10,
and the XEON processor built-in sensor. and the XEON processor built-in sensor.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
...@@ -34,30 +34,30 @@ config SENSORS_EEPROM ...@@ -34,30 +34,30 @@ config SENSORS_EEPROM
will be called eeprom. will be called eeprom.
config SENSORS_IT87 config SENSORS_IT87
tristate "National Semiconductors IT87 and compatibles" tristate "ITE IT87xx and compatibles"
depends on I2C && EXPERIMENTAL depends on I2C && EXPERIMENTAL
select I2C_SENSOR select I2C_SENSOR
help help
If you say yes here you get support for National Semiconductor IT87 If you say yes here you get support for ITE IT87xx sensor chips
sensor chips and clones: IT8705F, IT8712F and SiS960. and clones: SiS960.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called it87. will be called it87.
config SENSORS_LM75 config SENSORS_LM75
tristate "National Semiconductors LM75 and compatibles" tristate "National Semiconductor LM75 and compatibles"
depends on I2C && EXPERIMENTAL depends on I2C && EXPERIMENTAL
select I2C_SENSOR select I2C_SENSOR
help help
If you say yes here you get support for National Semiconductor LM75 If you say yes here you get support for National Semiconductor LM75
sensor chips and clones: Dallas Semi DS75 and DS1775, TelCon sensor chips and clones: Dallas Semi DS75 and DS1775, TelCon
TCN75, and National Semi LM77. TCN75, and National Semiconductor LM77.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called lm75. will be called lm75.
config SENSORS_LM78 config SENSORS_LM78
tristate "National Semiconductors LM78 and compatibles" tristate "National Semiconductor LM78 and compatibles"
depends on I2C && EXPERIMENTAL depends on I2C && EXPERIMENTAL
select I2C_SENSOR select I2C_SENSOR
help help
...@@ -69,7 +69,7 @@ config SENSORS_LM78 ...@@ -69,7 +69,7 @@ config SENSORS_LM78
will be called lm78. will be called lm78.
config SENSORS_LM85 config SENSORS_LM85
tristate "National Semiconductors LM85 and compatibles" tristate "National Semiconductor LM85 and compatibles"
depends on I2C && EXPERIMENTAL depends on I2C && EXPERIMENTAL
select I2C_SENSOR select I2C_SENSOR
help help
......
...@@ -322,6 +322,10 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -322,6 +322,10 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto error3; goto error3;
/* Initialize the ADM1021 chip */
adm1021_init_client(new_client);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_temp_max1); device_create_file(&new_client->dev, &dev_attr_temp_max1);
device_create_file(&new_client->dev, &dev_attr_temp_min1); device_create_file(&new_client->dev, &dev_attr_temp_min1);
device_create_file(&new_client->dev, &dev_attr_temp_input1); device_create_file(&new_client->dev, &dev_attr_temp_input1);
...@@ -332,8 +336,6 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -332,8 +336,6 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
if (data->type == adm1021) if (data->type == adm1021)
device_create_file(&new_client->dev, &dev_attr_die_code); device_create_file(&new_client->dev, &dev_attr_die_code);
/* Initialize the ADM1021 chip */
adm1021_init_client(new_client);
return 0; return 0;
error3: error3:
......
...@@ -701,7 +701,10 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -701,7 +701,10 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto ERROR1; goto ERROR1;
/* register sysfs hooks */ /* Initialize the IT87 chip */
it87_init_client(new_client, data);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_in_input0); device_create_file(&new_client->dev, &dev_attr_in_input0);
device_create_file(&new_client->dev, &dev_attr_in_input1); device_create_file(&new_client->dev, &dev_attr_in_input1);
device_create_file(&new_client->dev, &dev_attr_in_input2); device_create_file(&new_client->dev, &dev_attr_in_input2);
...@@ -750,8 +753,6 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -750,8 +753,6 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_fan_div3); device_create_file(&new_client->dev, &dev_attr_fan_div3);
device_create_file(&new_client->dev, &dev_attr_alarm); device_create_file(&new_client->dev, &dev_attr_alarm);
/* Initialize the IT87 chip */
it87_init_client(new_client, data);
return 0; return 0;
ERROR1: ERROR1:
......
...@@ -204,11 +204,14 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -204,11 +204,14 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto exit_free; goto exit_free;
/* Initialize the LM75 chip */
lm75_init_client(new_client);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_temp_max); device_create_file(&new_client->dev, &dev_attr_temp_max);
device_create_file(&new_client->dev, &dev_attr_temp_min); device_create_file(&new_client->dev, &dev_attr_temp_min);
device_create_file(&new_client->dev, &dev_attr_temp_input); device_create_file(&new_client->dev, &dev_attr_temp_input);
lm75_init_client(new_client);
return 0; return 0;
exit_free: exit_free:
......
...@@ -648,7 +648,10 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -648,7 +648,10 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto ERROR2; goto ERROR2;
/* register sysfs hooks */ /* Initialize the LM78 chip */
lm78_init_client(new_client);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_in_input0); device_create_file(&new_client->dev, &dev_attr_in_input0);
device_create_file(&new_client->dev, &dev_attr_in_min0); device_create_file(&new_client->dev, &dev_attr_in_min0);
device_create_file(&new_client->dev, &dev_attr_in_max0); device_create_file(&new_client->dev, &dev_attr_in_max0);
...@@ -685,8 +688,6 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -685,8 +688,6 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_alarms); device_create_file(&new_client->dev, &dev_attr_alarms);
device_create_file(&new_client->dev, &dev_attr_vid); device_create_file(&new_client->dev, &dev_attr_vid);
/* Initialize the LM78 chip */
lm78_init_client(new_client);
return 0; return 0;
ERROR2: ERROR2:
......
...@@ -888,6 +888,10 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -888,6 +888,10 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
/* Set the VRM version */ /* Set the VRM version */
data->vrm = LM85_INIT_VRM ; data->vrm = LM85_INIT_VRM ;
/* Initialize the LM85 chip */
lm85_init_client(new_client);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_fan_input1); device_create_file(&new_client->dev, &dev_attr_fan_input1);
device_create_file(&new_client->dev, &dev_attr_fan_input2); device_create_file(&new_client->dev, &dev_attr_fan_input2);
device_create_file(&new_client->dev, &dev_attr_fan_input3); device_create_file(&new_client->dev, &dev_attr_fan_input3);
...@@ -930,8 +934,6 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -930,8 +934,6 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
device_create_file(&new_client->dev, &dev_attr_vid); device_create_file(&new_client->dev, &dev_attr_vid);
device_create_file(&new_client->dev, &dev_attr_alarms); device_create_file(&new_client->dev, &dev_attr_alarms);
/* Initialize the LM85 chip */
lm85_init_client(new_client);
return 0; return 0;
/* Error out and cleanup code */ /* Error out and cleanup code */
......
...@@ -735,7 +735,10 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -735,7 +735,10 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto ERROR3; goto ERROR3;
/* register sysfs hooks */ /* Initialize the VIA686A chip */
via686a_init_client(new_client);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_in_input0); device_create_file(&new_client->dev, &dev_attr_in_input0);
device_create_file(&new_client->dev, &dev_attr_in_input1); device_create_file(&new_client->dev, &dev_attr_in_input1);
device_create_file(&new_client->dev, &dev_attr_in_input2); device_create_file(&new_client->dev, &dev_attr_in_input2);
...@@ -768,8 +771,6 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -768,8 +771,6 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_fan_div2); device_create_file(&new_client->dev, &dev_attr_fan_div2);
device_create_file(&new_client->dev, &dev_attr_alarm); device_create_file(&new_client->dev, &dev_attr_alarm);
/* Initialize the VIA686A chip */
via686a_init_client(new_client);
return 0; return 0;
ERROR3: ERROR3:
......
...@@ -1346,6 +1346,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1346,6 +1346,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
data->lm75[1] = NULL; data->lm75[1] = NULL;
} }
/* Initialize the chip */
w83781d_init_client(new_client);
/* Register sysfs hooks */
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
if (kind != w83783s && kind != w83697hf) if (kind != w83783s && kind != w83697hf)
device_create_file_in(new_client, 1); device_create_file_in(new_client, 1);
...@@ -1408,8 +1412,6 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1408,8 +1412,6 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
} }
#endif #endif
/* Initialize the chip */
w83781d_init_client(new_client);
return 0; return 0;
ERROR3: ERROR3:
......
...@@ -49,6 +49,7 @@ struct i2c_dev { ...@@ -49,6 +49,7 @@ struct i2c_dev {
int minor; int minor;
struct i2c_adapter *adap; struct i2c_adapter *adap;
struct class_device class_dev; struct class_device class_dev;
struct completion released; /* FIXME, we need a class_device_unregister() */
}; };
#define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev) #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev)
...@@ -112,7 +113,6 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev) ...@@ -112,7 +113,6 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)
spin_lock(&i2c_dev_array_lock); spin_lock(&i2c_dev_array_lock);
i2c_dev_array[i2c_dev->minor] = NULL; i2c_dev_array[i2c_dev->minor] = NULL;
spin_unlock(&i2c_dev_array_lock); spin_unlock(&i2c_dev_array_lock);
kfree(i2c_dev);
} }
static ssize_t show_dev(struct class_device *class_dev, char *buf) static ssize_t show_dev(struct class_device *class_dev, char *buf)
...@@ -421,8 +421,15 @@ static struct file_operations i2cdev_fops = { ...@@ -421,8 +421,15 @@ static struct file_operations i2cdev_fops = {
.release = i2cdev_release, .release = i2cdev_release,
}; };
static void release_i2c_dev(struct class_device *dev)
{
struct i2c_dev *i2c_dev = to_i2c_dev(dev);
complete(&i2c_dev->released);
}
static struct class i2c_dev_class = { static struct class i2c_dev_class = {
.name = "i2c-dev", .name = "i2c-dev",
.release = &release_i2c_dev,
}; };
static int i2cdev_attach_adapter(struct i2c_adapter *adap) static int i2cdev_attach_adapter(struct i2c_adapter *adap)
...@@ -453,6 +460,7 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) ...@@ -453,6 +460,7 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
return 0; return 0;
error: error:
return_i2c_dev(i2c_dev); return_i2c_dev(i2c_dev);
kfree(i2c_dev);
return retval; return retval;
} }
...@@ -464,9 +472,12 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) ...@@ -464,9 +472,12 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap)
if (!i2c_dev) if (!i2c_dev)
return -ENODEV; return -ENODEV;
class_device_unregister(&i2c_dev->class_dev); init_completion(&i2c_dev->released);
devfs_remove("i2c/%d", i2c_dev->minor); devfs_remove("i2c/%d", i2c_dev->minor);
return_i2c_dev(i2c_dev); return_i2c_dev(i2c_dev);
class_device_unregister(&i2c_dev->class_dev);
wait_for_completion(&i2c_dev->released);
kfree(i2c_dev);
dev_dbg(&adap->dev, "Adapter unregistered\n"); dev_dbg(&adap->dev, "Adapter unregistered\n");
return 0; return 0;
......
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