diff -Nur linux/arch/i386/kernel/process.c linux-geode.reset/arch/i386/kernel/process.c --- linux/arch/i386/kernel/process.c Fri Oct 5 09:42:54 2001 +++ linux-geode.reset/arch/i386/kernel/process.c Fri Jul 19 15:17:49 2002 @@ -49,6 +49,153 @@ #include +#define CONFIG_LINUXBIOS_PM +#ifdef CONFIG_LINUXBIOS_PM +#include +void +cs5530_reset(struct pci_dev *dev) +{ + struct pci_dev *dev; + + printk(KERN_ERR __FUNCTION__ ": starting reset operation. \n"); + + dev = pci_find_device(PCI_VENDOR_ID_CYRIX, \ + PCI_DEVICE_ID_CYRIX_5530_LEGACY, 0); + + if (dev == NULL) { + printk(KERN_ERR __FUNCTION__ ": can't find device!!!\n"); + } + + /* Execute system wide reset by doing X-Bus Warm Start*/ + pci_write_config_byte(dev, 0x44, 0x1); + + printk(KERN_ERR __FUNCTION__ ": We should reset soon. \n"); +} + +void +sis503_reset(struct pci_dev *dev) +{ + unsigned char b; + unsigned short acpi_base; + + printk(KERN_ERR __FUNCTION__ ": starting reset operation. \n"); + + /* Enable ACPI by set B7 on Reg 0x40, LPC */ + pci_read_config_byte(dev, 0x40, &b); + pci_write_config_byte(dev, 0x40, b | 0x80); + printk(KERN_ERR __FUNCTION__ ": enabled ACPI. \n"); + + /* get the ACPI base address for register 0x74,0x75 of LPC */ + pci_read_config_word(dev, 0x74, &acpi_base); + printk(KERN_ERR __FUNCTION__ ":acpi base: %x\n", acpi_base); + + /* Set software watchdog timer init value */ + outb(0x03, 0x4a + acpi_base); + printk(KERN_ERR __FUNCTION__ ": set the dog. \n"); + + printk(KERN_ERR __FUNCTION__ ": enabling dog. \n"); + /* Software watchdog enable, issue PCIRST# when time expire */ + outb(0x8f, 0x4b + acpi_base); + + printk(KERN_ERR __FUNCTION__ ": We should reset soon. \n"); +} + +void +sis503_off(struct pci_dev *dev) +{ + unsigned char b; + unsigned short acpi_base; + + printk(KERN_ERR __FUNCTION__ ": starting reset operation. \n"); + /* Enable ACPI by set B7 on Reg 0x40, LPC */ + pci_read_config_byte(dev, 0x40, &b); + pci_write_config_byte(dev, 0x40, b | 0x80); + printk(KERN_ERR __FUNCTION__ ": enabled ACPI. \n"); + + /* get the ACPI base address for register 0x74,0x75 of LPC */ + pci_read_config_word(dev, 0x74, &acpi_base); + printk (KERN_ERR __FUNCTION__ ":acpi base: %x\n", acpi_base); + + /* ACPI Register 5, Bit 10-12, Sleeping Type, + set to 101 -> S5, soft_off */ + outb(0x14, 0x05 + acpi_base); + printk(KERN_ERR __FUNCTION__ ": DONE setting sleep type. \n"); + + /* ACPI Register 5, Bit 13, Sleep Enable */ + outb(0x20 | 0x14, 0x05 + acpi_base); + printk(KERN_ERR __FUNCTION__ ": DONE sleep enable. \n"); +} + +struct pci_dev * pci_find_device(unsigned int vendor, unsigned int device, + const struct pci_dev *from); + +struct linuxbios_control { + u_short vendor, device; + void (*poweroff)(struct pci_dev *); + void (*reset)(struct pci_dev *); +}; + +struct linuxbios_control controls[] = { + {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis503_off, sis503_reset}, + {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, NULL, cs5530_reset} +}; + +struct linuxbios_control *findcontrol(struct pci_dev **d) +{ + struct linuxbios_control *lb = controls, *retval = 0; + int i; + + printk(KERN_ERR __FUNCTION__ ": Find vendor 0x%x device 0x%x\n", + lb->vendor, lb->device); + for(lb = controls, i = 0; + (i < sizeof(controls)/sizeof(controls[0])) && (! retval); + i++, lb++) + { + *d = pci_find_device(lb->vendor, lb->device, 0); + if (*d) + retval = lb; + } + + printk(KERN_ERR __FUNCTION__ ": result of find is %p\n", retval); + return retval; +} + +void +linuxbios_poweroff(void) +{ + struct linuxbios_control *lb = 0; + struct pci_dev *dev; + + printk(KERN_ERR __FUNCTION__ ": find an lb\n"); + lb = findcontrol(&dev); + + printk(KERN_ERR __FUNCTION__ ": found lb %p, call %p\n", + lb, lb ? lb->poweroff : 0); + if (lb && (lb->poweroff)) + lb->poweroff(dev); + printk(KERN_ERR __FUNCTION__ ": Returning? Can't happen, I thought?\n"); +} + +void +linuxbios_reset(void) +{ + struct linuxbios_control *lb = 0; + struct pci_dev *dev; + + printk(KERN_ERR __FUNCTION__ ": find an lb\n"); + lb = findcontrol(&dev); + + printk(KERN_ERR __FUNCTION__ ": found lb %p, call %p\n", + lb, lb ? lb->reset : 0); + if (lb && (lb->reset)) + lb->reset(dev); + + printk(KERN_ERR __FUNCTION__ ": Returning? Can't happen, I thought?\n"); +} + +#endif + + asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); int hlt_counter; @@ -399,6 +546,9 @@ */ smp_send_stop(); disable_IO_APIC(); +#endif +#ifdef CONFIG_LINUXBIOS_PM + linuxbios_reset(); #endif if(!reboot_thru_bios) {