Hi Jean: * Jean Delvare <khali at linux-fr.org> [2006-04-18 14:06:29 +0200]: > Fix for bug #6395: > Fail to resume on Tecra M2 with ADM1032 and Intel 82801DBM > > The BIOS of the Tecra M2 doesn't like it when it has to reboot or > resume after the i2c-i801 driver has left the SMBus in PEC mode. So we > need to add proper .suspend, .resume and .shutdown callbacks to that > driver, where we clear and restore the PEC mode bit appropriately. NACK: saved_auxctl is uninitialized in this patch (what happened to the patch I looked at last night?) Also, now that I look at it again... wouldn't it be much easier to just disable PEC again after every transfer? That's safer too: the call- backs might not be enough e.g. if the user hits the reset button after a PEC transfer. > Thanks to Daniele Gaffuri for the very good report and contribution. > > Signed-off-by: Jean Delvare <khali at linux-fr.org> > --- > drivers/i2c/busses/i2c-i801.c | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > --- linux-2.6.17-rc1.orig/drivers/i2c/busses/i2c-i801.c 2006-04-18 09:34:15.000000000 +0200 > +++ linux-2.6.17-rc1/drivers/i2c/busses/i2c-i801.c 2006-04-18 12:47:07.000000000 +0200 > @@ -110,6 +110,7 @@ > static struct pci_driver i801_driver; > static struct pci_dev *I801_dev; > static int isich4; > +static u8 saved_auxctl; > > static int i801_setup(struct pci_dev *dev) > { > @@ -551,17 +552,46 @@ > return i2c_add_adapter(&i801_adapter); > } > > +static void i801_shutdown(struct pci_dev *dev) > +{ > + if (isich4) { > + /* Disable PEC mode before leaving, else some BIOSes will > + fail to resume/reboot. */ > + outb_p(0, SMBAUXCTL); > + } > +} > + > static void __devexit i801_remove(struct pci_dev *dev) > { > i2c_del_adapter(&i801_adapter); > + i801_shutdown(dev); > release_region(i801_smba, (isich4 ? 16 : 8)); > } > > +static int i801_suspend(struct pci_dev *dev, pm_message_t state) > +{ > + i801_shutdown(dev); > + return pci_save_state(dev); > +} > + > +static int i801_resume(struct pci_dev *dev) > +{ > + pci_restore_state(dev); > + if (isich4) { > + /* Restore PEC mode */ > + outb_p(saved_auxctl, SMBAUXCTL); > + } > + return 0; > +} > + > static struct pci_driver i801_driver = { > .name = "i801_smbus", > .id_table = i801_ids, > .probe = i801_probe, > .remove = __devexit_p(i801_remove), > + .suspend = i801_suspend, > + .resume = i801_resume, > + .shutdown = i801_shutdown, > }; > > static int __init i2c_i801_init(void) > Regards, -- Mark M. Hoffman mhoffman at lightlink.com