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

Commit 5efc7a62 authored by Thomas Mingarelli's avatar Thomas Mingarelli Committed by Wim Van Sebroeck
Browse files

watchdog: hpwdt: add next gen HP servers



This patch is required to enable hpwdt to work on next generation HP servers
with iLO.

Signed-off-by: default avatarThomas Mingarelli <thomas.mingarelli@hp.com>
Signed-off-by: default avatarWim Van Sebroeck <wim@iguana.be>
parent 22602868
Loading
Loading
Loading
Loading
+77 −27
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@
#include <asm/cacheflush.h>
#endif /* CONFIG_HPWDT_NMI_DECODING */

#define HPWDT_VERSION			"1.2.0"
#define HPWDT_VERSION			"1.3.0"
#define SECS_TO_TICKS(secs)		((secs) * 1000 / 128)
#define TICKS_TO_SECS(ticks)		((ticks) * 128 / 1000)
#define HPWDT_MAX_TIMER			TICKS_TO_SECS(65535)
@@ -87,6 +87,19 @@ struct smbios_cru64_info {
};
#define SMBIOS_CRU64_INFORMATION	212

/* type 219 */
struct smbios_proliant_info {
	u8 type;
	u8 byte_length;
	u16 handle;
	u32 power_features;
	u32 omega_features;
	u32 reserved;
	u32 misc_features;
};
#define SMBIOS_ICRU_INFORMATION		219


struct cmn_registers {
	union {
		struct {
@@ -132,6 +145,7 @@ struct cmn_registers {
static unsigned int hpwdt_nmi_decoding;
static unsigned int allow_kdump;
static unsigned int priority;		/* hpwdt at end of die_notify list */
static unsigned int is_icru;
static DEFINE_SPINLOCK(rom_lock);
static void *cru_rom_addr;
static struct cmn_registers cmn_regs;
@@ -476,19 +490,22 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
		goto out;

	spin_lock_irqsave(&rom_lock, rom_pl);
	if (!die_nmi_called)
	if (!die_nmi_called && !is_icru)
		asminline_call(&cmn_regs, cru_rom_addr);
	die_nmi_called = 1;
	spin_unlock_irqrestore(&rom_lock, rom_pl);
	if (!is_icru) {
		if (cmn_regs.u1.ral == 0) {
			printk(KERN_WARNING "hpwdt: An NMI occurred, "
				"but unable to determine source.\n");
	} else {
		}
	}

	if (allow_kdump)
		hpwdt_stop();
	panic("An NMI occurred, please see the Integrated "
		"Management Log for details.\n");
	}

out:
	return NOTIFY_OK;
}
@@ -659,10 +676,42 @@ static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev)
}
#endif /* CONFIG_X86_LOCAL_APIC */

/*
 *	dmi_find_icru
 *
 *	Routine Description:
 *	This function checks whether or not we are on an iCRU-based server.
 *	This check is independent of architecture and needs to be made for
 *	any ProLiant system.
 */
static void __devinit dmi_find_icru(const struct dmi_header *dm, void *dummy)
{
	struct smbios_proliant_info *smbios_proliant_ptr;

	if (dm->type == SMBIOS_ICRU_INFORMATION) {
		smbios_proliant_ptr = (struct smbios_proliant_info *) dm;
		if (smbios_proliant_ptr->misc_features & 0x01)
			is_icru = 1;
	}
}

static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
{
	int retval;

	/*
	 * On typical CRU-based systems we need to map that service in
	 * the BIOS. For 32 bit Operating Systems we need to go through
	 * the 32 Bit BIOS Service Directory. For 64 bit Operating
	 * Systems we get that service through SMBIOS.
	 *
	 * On systems that support the new iCRU service all we need to
	 * do is call dmi_walk to get the supported flag value and skip
	 * the old cru detect code.
	 */
	dmi_walk(dmi_find_icru, NULL);
	if (!is_icru) {

		/*
		* We need to map the ROM to get the CRU service.
		* For 32 bit Operating Systems we need to go through the 32 Bit
@@ -683,6 +732,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
		*/
		cmn_regs.u1.rah = 0x0D;
		cmn_regs.u1.ral = 0x02;
	}

	/*
	 * If the priority is set to 1, then we will be put first on the