diff options
author | Jean Delvare <jdelvare@suse.de> | 2016-01-25 06:17:07 -0500 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2016-01-26 00:46:33 -0500 |
commit | 83c60158ebf16417af28b338bc0380cf17f2b9f9 (patch) | |
tree | b423fce0514240f58a7aae94ee0b7b7287ac4b36 | |
parent | a28e35171cb1ff84197e8d271b65aaeb8c404827 (diff) |
i2c: piix4: Fully initialize SB800 before it is registered
This closes a race window where I2C device drivers attempt to access
I2C buses which aren't fully initialized yet.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Tested-by: Christian Fetzer <fetzer.ch@gmail.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 5fd7505b9018..f79a84ef1aa4 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
@@ -627,6 +627,7 @@ static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS]; | |||
627 | static struct i2c_adapter *piix4_aux_adapter; | 627 | static struct i2c_adapter *piix4_aux_adapter; |
628 | 628 | ||
629 | static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, | 629 | static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, |
630 | bool sb800_main, unsigned short port, | ||
630 | const char *name, struct i2c_adapter **padap) | 631 | const char *name, struct i2c_adapter **padap) |
631 | { | 632 | { |
632 | struct i2c_adapter *adap; | 633 | struct i2c_adapter *adap; |
@@ -641,7 +642,8 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, | |||
641 | 642 | ||
642 | adap->owner = THIS_MODULE; | 643 | adap->owner = THIS_MODULE; |
643 | adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; | 644 | adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; |
644 | adap->algo = &smbus_algorithm; | 645 | adap->algo = sb800_main ? &piix4_smbus_algorithm_sb800 |
646 | : &smbus_algorithm; | ||
645 | 647 | ||
646 | adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL); | 648 | adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL); |
647 | if (adapdata == NULL) { | 649 | if (adapdata == NULL) { |
@@ -651,6 +653,8 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, | |||
651 | } | 653 | } |
652 | 654 | ||
653 | adapdata->smba = smba; | 655 | adapdata->smba = smba; |
656 | adapdata->sb800_main = sb800_main; | ||
657 | adapdata->port = port; | ||
654 | 658 | ||
655 | /* set up the sysfs linkage to our parent device */ | 659 | /* set up the sysfs linkage to our parent device */ |
656 | adap->dev.parent = &dev->dev; | 660 | adap->dev.parent = &dev->dev; |
@@ -680,17 +684,11 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba) | |||
680 | int retval; | 684 | int retval; |
681 | 685 | ||
682 | for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) { | 686 | for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) { |
683 | retval = piix4_add_adapter(dev, smba, | 687 | retval = piix4_add_adapter(dev, smba, true, port, |
684 | piix4_main_port_names_sb800[port], | 688 | piix4_main_port_names_sb800[port], |
685 | &piix4_main_adapters[port]); | 689 | &piix4_main_adapters[port]); |
686 | if (retval < 0) | 690 | if (retval < 0) |
687 | goto error; | 691 | goto error; |
688 | |||
689 | piix4_main_adapters[port]->algo = &piix4_smbus_algorithm_sb800; | ||
690 | |||
691 | adapdata = i2c_get_adapdata(piix4_main_adapters[port]); | ||
692 | adapdata->sb800_main = true; | ||
693 | adapdata->port = port; | ||
694 | } | 692 | } |
695 | 693 | ||
696 | return retval; | 694 | return retval; |
@@ -748,7 +746,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
748 | return retval; | 746 | return retval; |
749 | 747 | ||
750 | /* Try to register main SMBus adapter, give up if we can't */ | 748 | /* Try to register main SMBus adapter, give up if we can't */ |
751 | retval = piix4_add_adapter(dev, retval, "main", | 749 | retval = piix4_add_adapter(dev, retval, false, 0, "main", |
752 | &piix4_main_adapters[0]); | 750 | &piix4_main_adapters[0]); |
753 | if (retval < 0) | 751 | if (retval < 0) |
754 | return retval; | 752 | return retval; |
@@ -775,7 +773,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
775 | if (retval > 0) { | 773 | if (retval > 0) { |
776 | /* Try to add the aux adapter if it exists, | 774 | /* Try to add the aux adapter if it exists, |
777 | * piix4_add_adapter will clean up if this fails */ | 775 | * piix4_add_adapter will clean up if this fails */ |
778 | piix4_add_adapter(dev, retval, piix4_aux_port_name_sb800, | 776 | piix4_add_adapter(dev, retval, false, 0, |
777 | piix4_aux_port_name_sb800, | ||
779 | &piix4_aux_adapter); | 778 | &piix4_aux_adapter); |
780 | } | 779 | } |
781 | 780 | ||