mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
parport_pc: after superio probing restore original register values
CONFIG_PARPORT_PC_SUPERIO probes for various superio chips by writing byte sequences to a set of different potential I/O ranges. But the probed ranges are not exclusive to parallel ports. Some of our boards just happen to have a watchdog in one of them. Took us almost a week to figure out why some distros reboot without warning after running flawlessly for 3 hours. For exactly 170 = 0xAA minutes, that is ... Fixed by restoring original values after probing. Also fixed too small request_region() in detect_and_report_it87(). Signed-off-by: Jens Rottmann <JRottmann@LiPPERTEmbedded.de> Signed-off-by: Alan Cox <alan@linux.intel.com> Cc: <stable@kernel.org> Acked-by: Jeff Garzik <jgarzik@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
752a478751
commit
e2434dc1c1
1 changed files with 25 additions and 6 deletions
|
@ -1471,11 +1471,13 @@ static void __devinit decode_smsc(int efer, int key, int devid, int devrev)
|
|||
|
||||
static void __devinit winbond_check(int io, int key)
|
||||
{
|
||||
int devid, devrev, oldid, x_devid, x_devrev, x_oldid;
|
||||
int origval, devid, devrev, oldid, x_devid, x_devrev, x_oldid;
|
||||
|
||||
if (!request_region(io, 3, __func__))
|
||||
return;
|
||||
|
||||
origval = inb(io); /* Save original value */
|
||||
|
||||
/* First probe without key */
|
||||
outb(0x20, io);
|
||||
x_devid = inb(io + 1);
|
||||
|
@ -1495,6 +1497,8 @@ static void __devinit winbond_check(int io, int key)
|
|||
oldid = inb(io + 1);
|
||||
outb(0xaa, io); /* Magic Seal */
|
||||
|
||||
outb(origval, io); /* in case we poked some entirely different hardware */
|
||||
|
||||
if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
|
||||
goto out; /* protection against false positives */
|
||||
|
||||
|
@ -1505,11 +1509,15 @@ out:
|
|||
|
||||
static void __devinit winbond_check2(int io, int key)
|
||||
{
|
||||
int devid, devrev, oldid, x_devid, x_devrev, x_oldid;
|
||||
int origval[3], devid, devrev, oldid, x_devid, x_devrev, x_oldid;
|
||||
|
||||
if (!request_region(io, 3, __func__))
|
||||
return;
|
||||
|
||||
origval[0] = inb(io); /* Save original values */
|
||||
origval[1] = inb(io + 1);
|
||||
origval[2] = inb(io + 2);
|
||||
|
||||
/* First probe without the key */
|
||||
outb(0x20, io + 2);
|
||||
x_devid = inb(io + 2);
|
||||
|
@ -1528,6 +1536,10 @@ static void __devinit winbond_check2(int io, int key)
|
|||
oldid = inb(io + 2);
|
||||
outb(0xaa, io); /* Magic Seal */
|
||||
|
||||
outb(origval[0], io); /* in case we poked some entirely different hardware */
|
||||
outb(origval[1], io + 1);
|
||||
outb(origval[2], io + 2);
|
||||
|
||||
if (x_devid == devid && x_devrev == devrev && x_oldid == oldid)
|
||||
goto out; /* protection against false positives */
|
||||
|
||||
|
@ -1538,11 +1550,13 @@ out:
|
|||
|
||||
static void __devinit smsc_check(int io, int key)
|
||||
{
|
||||
int id, rev, oldid, oldrev, x_id, x_rev, x_oldid, x_oldrev;
|
||||
int origval, id, rev, oldid, oldrev, x_id, x_rev, x_oldid, x_oldrev;
|
||||
|
||||
if (!request_region(io, 3, __func__))
|
||||
return;
|
||||
|
||||
origval = inb(io); /* Save original value */
|
||||
|
||||
/* First probe without the key */
|
||||
outb(0x0d, io);
|
||||
x_oldid = inb(io + 1);
|
||||
|
@ -1566,6 +1580,8 @@ static void __devinit smsc_check(int io, int key)
|
|||
rev = inb(io + 1);
|
||||
outb(0xaa, io); /* Magic Seal */
|
||||
|
||||
outb(origval, io); /* in case we poked some entirely different hardware */
|
||||
|
||||
if (x_id == id && x_oldrev == oldrev &&
|
||||
x_oldid == oldid && x_rev == rev)
|
||||
goto out; /* protection against false positives */
|
||||
|
@ -1602,11 +1618,12 @@ static void __devinit detect_and_report_smsc(void)
|
|||
static void __devinit detect_and_report_it87(void)
|
||||
{
|
||||
u16 dev;
|
||||
u8 r;
|
||||
u8 origval, r;
|
||||
if (verbose_probing)
|
||||
printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
|
||||
if (!request_region(0x2e, 1, __func__))
|
||||
if (!request_region(0x2e, 2, __func__))
|
||||
return;
|
||||
origval = inb(0x2e); /* Save original value */
|
||||
outb(0x87, 0x2e);
|
||||
outb(0x01, 0x2e);
|
||||
outb(0x55, 0x2e);
|
||||
|
@ -1626,8 +1643,10 @@ static void __devinit detect_and_report_it87(void)
|
|||
outb(r | 8, 0x2F);
|
||||
outb(0x02, 0x2E); /* Lock */
|
||||
outb(0x02, 0x2F);
|
||||
} else {
|
||||
outb(origval, 0x2e); /* Oops, sorry to disturb */
|
||||
}
|
||||
release_region(0x2e, 1);
|
||||
release_region(0x2e, 2);
|
||||
}
|
||||
#endif /* CONFIG_PARPORT_PC_SUPERIO */
|
||||
|
||||
|
|
Loading…
Reference in a new issue