Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2f7c354 authored by Jaya Kumar's avatar Jaya Kumar Committed by Linus Torvalds
Browse files

[PATCH] x86 reboot: Add reboot fixup for gx1/cs5530a



This patch by Jaya Kumar introduces a generic infrastructure to deal with
x86 chipsets with nonstandard reset sequences, and adds support for the
Geode gx1/cs5530a chipset.

Signed-off-by: default avatarJaya Kumar <jayalk@intworks.biz>
Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 67701ae9
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -653,6 +653,24 @@ config I8K
	  Say Y if you intend to run this kernel on a Dell Inspiron 8000.
	  Say N otherwise.

config X86_REBOOTFIXUPS
	bool "Enable X86 board specific fixups for reboot"
	depends on X86
	default n
	---help---
	  This enables chipset and/or board specific fixups to be done
	  in order to get reboot to work correctly. This is only needed on
	  some combinations of hardware and BIOS. The symptom, for which
	  this config is intended, is when reboot ends with a stalled/hung
	  system.

	  Currently, the only fixup is for the Geode GX1/CS5530A/TROM2.1.
	  combination.

	  Say Y if you want to enable the fixup. Currently, it's safe to
	  enable this option even if you don't need it.
	  Say N otherwise.

config MICROCODE
	tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
	---help---
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
obj-$(CONFIG_X86_MPPARSE)	+= mpparse.o
obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
obj-$(CONFIG_X86_REBOOTFIXUPS)	+= reboot_fixups.o
obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit.o
obj-$(CONFIG_KPROBES)		+= kprobes.o
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <asm/uaccess.h>
#include <asm/apic.h>
#include "mach_reboot.h"
#include <linux/reboot_fixups.h>

/*
 * Power off function, if any
@@ -348,6 +349,7 @@ void machine_restart(char * __unused)
		/* rebooting needs to touch the page at absolute addr 0 */
		*((unsigned short *)__va(0x472)) = reboot_mode;
		for (;;) {
			mach_reboot_fixups(); /* for board specific fixups */
			mach_reboot();
			/* That didn't work - force a triple fault.. */
			__asm__ __volatile__("lidt %0": :"m" (no_idt));
+56 −0
Original line number Diff line number Diff line
/*
 * linux/arch/i386/kernel/reboot_fixups.c
 *
 * This is a good place to put board specific reboot fixups.
 *
 * List of supported fixups:
 * geode-gx1/cs5530a - Jaya Kumar <jayalk@intworks.biz>
 *
 */

#include <asm/delay.h>
#include <linux/pci.h>

static void cs5530a_warm_reset(struct pci_dev *dev)
{
	/* writing 1 to the reset control register, 0x44 causes the
	cs5530a to perform a system warm reset */
	pci_write_config_byte(dev, 0x44, 0x1);
	udelay(50); /* shouldn't get here but be safe and spin-a-while */
	return;
}

struct device_fixup {
	unsigned int vendor;
	unsigned int device;
	void (*reboot_fixup)(struct pci_dev *);
};

static struct device_fixup fixups_table[] = {
{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset },
};

/*
 * we see if any fixup is available for our current hardware. if there
 * is a fixup, we call it and we expect to never return from it. if we
 * do return, we keep looking and then eventually fall back to the
 * standard mach_reboot on return.
 */
void mach_reboot_fixups(void)
{
	struct device_fixup *cur;
	struct pci_dev *dev;
	int i;

	for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
		cur = &(fixups_table[i]);
		dev = pci_get_device(cur->vendor, cur->device, 0);
		if (!dev)
			continue;

		cur->reboot_fixup(dev);
	}

	printk(KERN_WARNING "No reboot fixup found for your hardware\n");
}
+10 −0
Original line number Diff line number Diff line
#ifndef _LINUX_REBOOT_FIXUPS_H
#define _LINUX_REBOOT_FIXUPS_H

#ifdef CONFIG_X86_REBOOTFIXUPS
extern void mach_reboot_fixups(void);
#else
#define mach_reboot_fixups() ((void)(0))
#endif

#endif /* _LINUX_REBOOT_FIXUPS_H */