i2c: i801: Fix resume bug
authorVolker Rümelin <vr_qemu@t-online.de>
Tue, 1 Sep 2020 13:22:21 +0000 (15:22 +0200)
committerWolfram Sang <wsa@kernel.org>
Mon, 14 Sep 2020 07:02:52 +0000 (09:02 +0200)
On suspend the original host configuration gets restored. The
resume routine has to undo this, otherwise the SMBus master
may be left in disabled state or in i2c mode.

[JD: Rebased on v5.8, moved the write into i801_setup_hstcfg.]

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Cc: stable@vger.kernel.org
drivers/i2c/busses/i2c-i801.c

index e32ef3f..22597fa 100644 (file)
@@ -1709,6 +1709,16 @@ static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; }
 static inline void i801_acpi_remove(struct i801_priv *priv) { }
 #endif
 
+static unsigned char i801_setup_hstcfg(struct i801_priv *priv)
+{
+       unsigned char hstcfg = priv->original_hstcfg;
+
+       hstcfg &= ~SMBHSTCFG_I2C_EN;    /* SMBus timing */
+       hstcfg |= SMBHSTCFG_HST_EN;
+       pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hstcfg);
+       return hstcfg;
+}
+
 static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
        unsigned char temp;
@@ -1830,14 +1840,10 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
                return err;
        }
 
-       pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp);
-       priv->original_hstcfg = temp;
-       temp &= ~SMBHSTCFG_I2C_EN;      /* SMBus timing */
-       if (!(temp & SMBHSTCFG_HST_EN)) {
+       pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &priv->original_hstcfg);
+       temp = i801_setup_hstcfg(priv);
+       if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN))
                dev_info(&dev->dev, "Enabling SMBus device\n");
-               temp |= SMBHSTCFG_HST_EN;
-       }
-       pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp);
 
        if (temp & SMBHSTCFG_SMB_SMI_EN) {
                dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
@@ -1963,6 +1969,7 @@ static int i801_resume(struct device *dev)
 {
        struct i801_priv *priv = dev_get_drvdata(dev);
 
+       i801_setup_hstcfg(priv);
        i801_enable_host_notify(&priv->adapter);
 
        return 0;