diff -ru linux-2.2.14/CREDITS linux-2.2.14-SOYO_Workaround/CREDITS --- linux-2.2.14/CREDITS Tue Jan 4 19:12:10 2000 +++ linux-2.2.14-SOYO_Workaround/CREDITS Thu Jan 20 10:00:52 2000 @@ -1892,6 +1892,14 @@ S: Cliffwood, New Jersey 07721 S: USA +N: Rogier Stam +E: linux@soyo.nl +W: http://www.soyo.nl +D: APM Workaround for shutdown problem for SY-5EMA and SY-5EH mainboards. +S: Signaalrood 19 +S: 2718SH Zoetermeer +S: The Netherlands + N: Henrik Storner E: storner@image.dk W: http://www.image.dk/~storner/ diff -ru linux-2.2.14/Documentation/Configure.help linux-2.2.14-SOYO_Workaround/Documentation/Configure.help --- linux-2.2.14/Documentation/Configure.help Tue Jan 4 19:12:10 2000 +++ linux-2.2.14-SOYO_Workaround/Documentation/Configure.help Wed Jan 19 17:33:56 2000 @@ -9124,6 +9124,23 @@ other APM options, this option may not work reliably with some APM BIOS implementations. +Use SOYO VIA VT82C586B/ETEQ EQ82C6629 shutdown workaround +CONFIG_APM_SOYO_SHUTDOWN_WORKAROUND + Use workaround to be able to switch off the computer by software. + This patch is necessary for the SOYO SY-5EMA and SY-5EH systems. For + systems that do not have this chipset, this patch will have no + effect except enlarging the kernel by about 150 bytes. This + workaround should also work on other systems which have the same + chipset (south bridge) as these mainboards, but does not have to be + necessary (since other mainboards do not necessarily have the same + problem). + + Say Y if you have one of these SOYO mainboards, or N if not. + + If you have problems with this workaround please email linux@soyo.nl + Newest versions of this patch can be found on + ftp://ftp.soyo.nl/Patches/Linux-2.2 + Ignore multiple suspend/standby events CONFIG_APM_IGNORE_MULTIPLE_SUSPEND This option is necessary on the IBM Thinkpad 560, but should work on diff -ru linux-2.2.14/arch/i386/config.in linux-2.2.14-SOYO_Workaround/arch/i386/config.in --- linux-2.2.14/arch/i386/config.in Tue Jan 4 19:12:11 2000 +++ linux-2.2.14-SOYO_Workaround/arch/i386/config.in Wed Jan 19 17:35:49 2000 @@ -110,6 +110,9 @@ bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK bool ' Power off on shutdown' CONFIG_APM_POWER_OFF + if [ "$CONFIG_APM_POWER_OFF" = "y" ]; then + bool ' Use SOYO VIA VT82C586B/ETEQ EQ82C6629 shutdown workaround' CONFIG_APM_SOYO_SHUTDOWN_WORKAROUND + fi bool ' Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT diff -ru linux-2.2.14/arch/i386/kernel/apm.c linux-2.2.14-SOYO_Workaround/arch/i386/kernel/apm.c --- linux-2.2.14/arch/i386/kernel/apm.c Tue Jan 4 19:12:11 2000 +++ linux-2.2.14-SOYO_Workaround/arch/i386/kernel/apm.c Thu Jan 20 11:13:23 2000 @@ -90,6 +90,10 @@ * Use CONFIG_SMP instead of __SMP__ * Ignore BOUNCES for three seconds. * Stephen Rothwell + * 1.9a: Add workaround for SOYO SY-5EMA/SY-5EH mainboards to be able + * to shutdown these systems by software. Supplied by SOYO + * Europe BV (Rogier Stam ). Workaround has been + * added to the apm_power_off procedure. * * APM 1.1 Reference: * @@ -128,7 +132,9 @@ #include #include #include +#include +#include #include #include #include @@ -555,7 +561,88 @@ * kernel option. */ if (apm_enabled || (smp_hack == 2)) - (void) apm_set_power_state(APM_STATE_OFF); +#ifndef CONFIG_APM_SOYO_SHUTDOWN_WORKAROUND + (void) apm_set_power_state(APM_STATE_OFF); +#else + { + /* Patch to allow the SY-5EH and SY-5EMA systems to shutdown */ + /* by software without crashing. In essence we write directly*/ + /* to the chipset registers to shutdown the system, instead */ + /* calling the APM functions in the BIOS and letting the BIOS*/ + /* shutdown the system for us. */ + + /* First check if we have a PCI BIOS. If not, we can forget */ + /* about the whole thing. */ + if ( pcibios_present( ) ) + { + unsigned char Bus; /* Bus on which device is found */ + unsigned char FunctionNr; /* Function number of the device */ + unsigned short Data; /* Data to be read or written */ + + /* If we reach this point, we have a PCI BIOS */ + if ( pcibios_find_device( 0x1106, 0x3040, 0x0000, &Bus, + &FunctionNr ) != PCIBIOS_SUCCESSFUL ) + { + /* If we can't find the VT82C586B Southbridge Power */ + /* Management registers, try it the old way. */ + (void) apm_set_power_state(APM_STATE_OFF); + } + + /* Now test which version of the chip we are talking about. */ + /* according to Revision 1.0 of the VT82C586B Data sheet */ + /* there are 2 different ways of accessing the IO Register */ + /* Base Address register. For Revision 3040E or earlier we */ + /* can read this information from offset 20-23 bit 15:8. For*/ + /* Revision 3040F and later we can read this from offset */ + /* 48-4B bit 15:8. At offset 0x08 we can find which */ + /* Revision the current chip is. */ + if( pcibios_read_config_word( Bus, FunctionNr, 0x08, &Data ) != + PCIBIOS_SUCCESSFUL ) + { + /* If we can't find the VT82C586B Southbridge Power */ + /* Management registers, try it the old way. */ + (void) apm_set_power_state(APM_STATE_OFF); + } + /* Clear all but the low byte which contains the Revision ID. */ + Data&=0x00FF; + if( Data == 0x0000 ) + { + /* This is a revision 3040E chip */ + if( pcibios_read_config_word( Bus, FunctionNr, 0x20, &Data ) + != PCIBIOS_SUCCESSFUL ) + { + /* If we can't find the VT82C586B Southbridge Power */ + /* Management registers, try it the old way. */ + (void) apm_set_power_state(APM_STATE_OFF); + } + } + else + { + /* This is a revision 3040F or later chip */ + if( pcibios_read_config_word( Bus, FunctionNr, 0x48, &Data ) + != PCIBIOS_SUCCESSFUL ) + { + /* If we can't find the VT82C586B Southbridge Power */ + /* Management registers, try it the old way. */ + (void) apm_set_power_state(APM_STATE_OFF); + } + } + + /* We now have the port in Data. Since the port is stored */ + /* in the lower 16 bits we do not have to fetch the upper */ + /* 16 bits. Note that bit 7:0 are invalid and should be */ + /* cleared. We should write 0x2000 to offset 4 of the port*/ + /* specified in Data to shutdown the system. */ + Data&=0xFF00; + Data+=0x0004; + outw_p( 0x2000, Data ); + } + /* If after writing to the port in Data we still have not */ + /* shutdown try the old fashioned way. We will also try */ + /* the old way if no PCI BIOS can be found. */ + (void) apm_set_power_state(APM_STATE_OFF); + } +#endif } #ifdef CONFIG_APM_DISPLAY_BLANK