diff options
-rw-r--r-- | Documentation/i2c/busses/i2c-i801 | 8 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 21 |
2 files changed, 27 insertions, 2 deletions
diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index e1bb5b261693..e307914a3eda 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 | |||
@@ -27,7 +27,13 @@ Authors: | |||
27 | Module Parameters | 27 | Module Parameters |
28 | ----------------- | 28 | ----------------- |
29 | 29 | ||
30 | None. | 30 | * disable_features (bit vector) |
31 | Disable selected features normally supported by the device. This makes it | ||
32 | possible to work around possible driver or hardware bugs if the feature in | ||
33 | question doesn't work as intended for whatever reason. Bit values: | ||
34 | 1 disable SMBus PEC | ||
35 | 2 disable the block buffer | ||
36 | 8 disable the I2C block read functionality | ||
31 | 37 | ||
32 | 38 | ||
33 | Description | 39 | Description |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 299b918455a3..f0fef343e19b 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -138,6 +138,17 @@ static struct pci_dev *I801_dev; | |||
138 | #define FEATURE_I2C_BLOCK_READ (1 << 3) | 138 | #define FEATURE_I2C_BLOCK_READ (1 << 3) |
139 | static unsigned int i801_features; | 139 | static unsigned int i801_features; |
140 | 140 | ||
141 | static const char *i801_feature_names[] = { | ||
142 | "SMBus PEC", | ||
143 | "Block buffer", | ||
144 | "Block process call", | ||
145 | "I2C block read", | ||
146 | }; | ||
147 | |||
148 | static unsigned int disable_features; | ||
149 | module_param(disable_features, uint, S_IRUGO | S_IWUSR); | ||
150 | MODULE_PARM_DESC(disable_features, "Disable selected driver features"); | ||
151 | |||
141 | /* Make sure the SMBus host is ready to start transmitting. | 152 | /* Make sure the SMBus host is ready to start transmitting. |
142 | Return 0 if it is, -EBUSY if it is not. */ | 153 | Return 0 if it is, -EBUSY if it is not. */ |
143 | static int i801_check_pre(void) | 154 | static int i801_check_pre(void) |
@@ -692,7 +703,7 @@ static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm, | |||
692 | static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) | 703 | static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) |
693 | { | 704 | { |
694 | unsigned char temp; | 705 | unsigned char temp; |
695 | int err; | 706 | int err, i; |
696 | #if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE | 707 | #if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE |
697 | const char *vendor; | 708 | const char *vendor; |
698 | #endif | 709 | #endif |
@@ -720,6 +731,14 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
720 | break; | 731 | break; |
721 | } | 732 | } |
722 | 733 | ||
734 | /* Disable features on user request */ | ||
735 | for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) { | ||
736 | if (i801_features & disable_features & (1 << i)) | ||
737 | dev_notice(&dev->dev, "%s disabled by user\n", | ||
738 | i801_feature_names[i]); | ||
739 | } | ||
740 | i801_features &= ~disable_features; | ||
741 | |||
723 | err = pci_enable_device(dev); | 742 | err = pci_enable_device(dev); |
724 | if (err) { | 743 | if (err) { |
725 | dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", | 744 | dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", |