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

Commit dae311b4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog:
  [WATCHDOG] make watchdog/hpwdt.c:asminline_call() static
  [WATCHDOG] Remove volatiles from watchdog device structures
  [WATCHDOG] replace remaining __FUNCTION__ occurrences
  [WATCHDOG] hpwdt: Use dmi_walk() instead of own copy
  [WATCHDOG] Fix return value warning in hpwdt
  [WATCHDOG] Fix declaration of struct smbios_entry_point in hpwdt
  [WATCHDOG] it8712f_wdt support for 16-bit timeout values, WDIOC_GETSTATUS
parents 99eeed47 8b1266f4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -59,9 +59,9 @@ static int ticks = 10000;

static struct {
	struct completion stop;
	volatile int running;
	int running;
	struct timer_list timer;
	volatile int queue;
	int queue;
	int default_ticks;
	unsigned long inuse;
} cpu5wdt_device;
+24 −190
Original line number Diff line number Diff line
@@ -58,41 +58,6 @@ struct bios32_service_dir {
	u8 reserved[5];
};

/*
 * smbios_entry_point     - defines SMBIOS entry point structure
 *
 * anchor[4]              - anchor string (_SM_)
 * checksum               - checksum of the entry point structure
 * length                 - length of the entry point structure
 * major_ver              - major version (02h for revision 2.1)
 * minor_ver              - minor version (01h for revision 2.1)
 * max_struct_size        - size of the largest SMBIOS structure
 * revision               - entry point structure revision implemented
 * formatted_area[5]      - reserved
 * intermediate_anchor[5] - intermediate anchor string (_DMI_)
 * intermediate_checksum  - intermediate checksum
 * table_length           - structure table length
 * table_address          - structure table address
 * table_num_structs      - number of SMBIOS structures present
 * bcd_revision           - BCD revision
 */
struct smbios_entry_point {
	u8 anchor[4];
	u8 checksum;
	u8 length;
	u8 major_ver;
	u8 minor_ver;
	u16 max_struct_size;
	u8 revision;
	u8 formatted_area[5];
	u8 intermediate_anchor[5];
	u8 intermediate_checksum;
	u16 table_length;
	u64 table_address;
	u16 table_num_structs;
	u8 bcd_revision;
};

/* type 212 */
struct smbios_cru64_info {
	u8 type;
@@ -175,30 +140,12 @@ static struct pci_device_id hpwdt_devices[] = {
};
MODULE_DEVICE_TABLE(pci, hpwdt_devices);

/*
 *	bios_checksum
 */
static int __devinit bios_checksum(const char __iomem *ptr, int len)
{
	char sum = 0;
	int i;

	/*
	 * calculate checksum of size bytes. This should add up
	 * to zero if we have a valid header.
	 */
	for (i = 0; i < len; i++)
		sum += ptr[i];

	return ((sum == 0) && (len > 0));
}

#ifndef CONFIG_X86_64
/* --32 Bit Bios------------------------------------------------------------ */

#define HPWDT_ARCH	32

asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
static void asminline_call(struct cmn_registers *pi86Regs,
			   unsigned long *pRomEntry)
{
	asm("pushl       %ebp               \n\t"
@@ -302,6 +249,24 @@ static int __devinit cru_detect(unsigned long map_entry,
	return retval;
}

/*
 *	bios_checksum
 */
static int __devinit bios_checksum(const char __iomem *ptr, int len)
{
	char sum = 0;
	int i;

	/*
	 * calculate checksum of size bytes. This should add up
	 * to zero if we have a valid header.
	 */
	for (i = 0; i < len; i++)
		sum += ptr[i];

	return ((sum == 0) && (len > 0));
}

/*
 *	bios32_present
 *
@@ -368,7 +333,7 @@ static int __devinit detect_cru_service(void)

#define HPWDT_ARCH	64

asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
static void asminline_call(struct cmn_registers *pi86Regs,
			   unsigned long *pRomEntry)
{
	asm("pushq      %rbp            \n\t"
@@ -410,12 +375,8 @@ asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
 *	dmi_find_cru
 *
 *	Routine Description:
 *	This function checks wether or not a SMBIOS/DMI record is
 *	This function checks whether or not a SMBIOS/DMI record is
 *	the 64bit CRU info or not
 *
 *	Return Value:
 *	0        :  SUCCESS - if record found
 *	<0       :  FAILURE - if record not found
 */
static void __devinit dmi_find_cru(const struct dmi_header *dm)
{
@@ -434,138 +395,11 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm)
	}
}

/*
 *	dmi_table
 *
 *	Routine Description:
 *	Decode the SMBIOS/DMI table and check if we have a 64bit CRU record
 *	or not.
 *
 *	We have to be cautious here. We have seen BIOSes with DMI pointers
 *	pointing to completely the wrong place for example
 */
static void __devinit dmi_table(u8 *buf, int len, int num,
		      void (*decode)(const struct dmi_header *))
{
	u8 *data = buf;
	int i = 0;

	/*
	 *	Stop when we see all the items the table claimed to have
	 *	OR we run off the end of the table (also happens)
	 */
	while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
		const struct dmi_header *dm = (const struct dmi_header *)data;

		/*
		 *  We want to know the total length (formated area and strings)
		 *  before decoding to make sure we won't run off the table in
		 *  dmi_decode or dmi_string
		 */
		data += dm->length;
		while ((data - buf < len - 1) && (data[0] || data[1]))
			data++;
		if (data - buf < len - 1)
			decode(dm);
		data += 2;
		i++;
	}
}

/*
 *	smbios_present
 *
 *	Routine Description:
 *	This function parses the SMBIOS entry point table to retrieve
 *	the 64 bit CRU Service.
 *
 *	Return Value:
 *	0        :  SUCCESS
 *	<0       :  FAILURE
 */
static int __devinit smbios_present(const char __iomem *p)
{
	struct smbios_entry_point *eps =
		(struct smbios_entry_point *) p;
	int length;
	u8 *buf;

	/* check if we have indeed the SMBIOS table entry point */
	if ((strncmp((char *)eps->anchor, "_SM_",
			     sizeof(eps->anchor))) == 0) {
		length = eps->length;

		/* SMBIOS v2.1 implementation might use 0x1e */
		if ((length == 0x1e) &&
		    (eps->major_ver == 2) &&
		    (eps->minor_ver == 1))
			length = 0x1f;

		/*
		 * Now we will check:
		 * - SMBIOS checksum must be 0
		 * - intermediate anchor should be _DMI_
		 * - intermediate checksum should be 0
		 */
		if ((bios_checksum(p, length)) &&
		    (strncmp((char *)eps->intermediate_anchor, "_DMI_",
		             sizeof(eps->intermediate_anchor)) == 0) &&
		    (bios_checksum(p+0x10, 15))) {
			buf = ioremap(eps->table_address, eps->table_length);
			if (buf == NULL)
				return -ENODEV;


			/* Scan the DMI table for the 64 bit CRU service */
			dmi_table(buf, eps->table_length,
			          eps->table_num_structs, dmi_find_cru);

			iounmap(buf);
			return 0;
		}
	}

	return -ENODEV;
}

static int __devinit smbios_scan_machine(void)
{
	char __iomem *p, *q;
	int rc;

	if (efi_enabled) {
		if (efi.smbios == EFI_INVALID_TABLE_ADDR)
			return -ENODEV;

		p = ioremap(efi.smbios, 32);
		if (p == NULL)
			return -ENOMEM;

		rc = smbios_present(p);
		iounmap(p);
	} else {
		/*
		 * Search from 0x0f0000 through 0x0fffff, inclusive.
		 */
		p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
		if (p == NULL)
			return -ENOMEM;

		for (q = p; q < p + ROM_SIZE; q += 16) {
			rc = smbios_present(q);
			if (!rc) {
				break;
			}
		}
		iounmap(p);
	}
}

static int __devinit detect_cru_service(void)
{
	cru_rom_addr = NULL;

	smbios_scan_machine();	/* will become dmi_walk(dmi_find_cru); */
	dmi_walk(dmi_find_cru);

	/* if cru_rom_addr has been set then we found a CRU service */
	return ((cru_rom_addr != NULL)? 0: -ENODEV);
+64 −14
Original line number Diff line number Diff line
@@ -7,7 +7,8 @@
 *
 *	drivers/char/watchdog/scx200_wdt.c
 *	drivers/hwmon/it87.c
 *	IT8712F EC-LPC I/O Preliminary Specification 0.9.2.pdf
 *	IT8712F EC-LPC I/O Preliminary Specification 0.8.2
 *	IT8712F EC-LPC I/O Preliminary Specification 0.9.3
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License as
@@ -40,6 +41,7 @@ MODULE_DESCRIPTION("IT8712F Watchdog Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

static int max_units = 255;
static int margin = 60;		/* in seconds */
module_param(margin, int, 0);
MODULE_PARM_DESC(margin, "Watchdog margin in seconds");
@@ -51,6 +53,7 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
static struct semaphore it8712f_wdt_sem;
static unsigned expect_close;
static spinlock_t io_lock;
static unsigned char revision;

/* Dog Food address - We use the game port address */
static unsigned short address;
@@ -108,6 +111,15 @@ superio_inw(int reg)
	return val;
}

static void
superio_outw(int val, int reg)
{
	outb(reg++, REG);
	outb((val >> 8) & 0xff, VAL);
	outb(reg, REG);
	outb(val & 0xff, VAL);
}

static inline void
superio_select(int ldn)
{
@@ -143,15 +155,33 @@ static void
it8712f_wdt_update_margin(void)
{
	int config = WDT_OUT_KRST | WDT_OUT_PWROK;
	int units = margin;

	printk(KERN_INFO NAME ": timer margin %d seconds\n", margin);

	/* The timeout register only has 8bits wide */
	if (margin < 256)
		config |= WDT_UNIT_SEC;	/* else UNIT are MINUTES */
	/* Switch to minutes precision if the configured margin
	 * value does not fit within the register width.
	 */
	if (units <= max_units) {
		config |= WDT_UNIT_SEC; /* else UNIT is MINUTES */
		printk(KERN_INFO NAME ": timer margin %d seconds\n", units);
	} else {
		units /= 60;
		printk(KERN_INFO NAME ": timer margin %d minutes\n", units);
	}
	superio_outb(config, WDT_CONFIG);

	superio_outb((margin > 255) ? (margin / 60) : margin, WDT_TIMEOUT);
	if (revision >= 0x08)
		superio_outw(units, WDT_TIMEOUT);
	else
		superio_outb(units, WDT_TIMEOUT);
}

static int
it8712f_wdt_get_status(void)
{
	if (superio_inb(WDT_CONTROL) & 0x01)
		return WDIOF_CARDRESET;
	else
		return 0;
}

static void
@@ -234,7 +264,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file,
		.firmware_version = 1,
		.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
	};
	int new_margin;
	int value;

	switch (cmd) {
	default:
@@ -244,17 +274,27 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file,
			return -EFAULT;
		return 0;
	case WDIOC_GETSTATUS:
		superio_enter();
		superio_select(LDN_GPIO);

		value = it8712f_wdt_get_status();

		superio_exit();

		return put_user(value, p);
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);
	case WDIOC_KEEPALIVE:
		it8712f_wdt_ping();
		return 0;
	case WDIOC_SETTIMEOUT:
		if (get_user(new_margin, p))
		if (get_user(value, p))
			return -EFAULT;
		if (new_margin < 1)
		if (value < 1)
			return -EINVAL;
		if (value > (max_units * 60))
			return -EINVAL;
		margin = new_margin;
		margin = value;
		superio_enter();
		superio_select(LDN_GPIO);

@@ -262,6 +302,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file,

		superio_exit();
		it8712f_wdt_ping();
		/* Fall through */
	case WDIOC_GETTIMEOUT:
		if (put_user(margin, p))
			return -EFAULT;
@@ -336,9 +377,18 @@ it8712f_wdt_find(unsigned short *address)
	}

	err = 0;
	printk(KERN_DEBUG NAME ": Found IT%04xF chip revision %d - "
	revision = superio_inb(DEVREV) & 0x0f;

	/* Later revisions have 16-bit values per datasheet 0.9.1 */
	if (revision >= 0x08)
		max_units = 65535;

	if (margin > (max_units * 60))
		margin = (max_units * 60);

	printk(KERN_INFO NAME ": Found IT%04xF chip revision %d - "
		"using DogFood address 0x%x\n",
		chip_type, superio_inb(DEVREV) & 0x0f, *address);
		chip_type, revision, *address);

exit:
	superio_exit();
+1 −1
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ static unsigned long next_heartbeat = 0;
#ifndef ZF_DEBUG
#	define dprintk(format, args...)
#else
#	define dprintk(format, args...) printk(KERN_DEBUG PFX ":%s:%d: " format, __FUNCTION__, __LINE__ , ## args)
#	define dprintk(format, args...) printk(KERN_DEBUG PFX ":%s:%d: " format, __func__, __LINE__ , ## args)
#endif


+2 −2
Original line number Diff line number Diff line
@@ -59,9 +59,9 @@ static int ticks = 100 * HZ;

static struct {
	struct completion stop;
	volatile int running;
	int running;
	struct timer_list timer;
	volatile int queue;
	int queue;
	int default_ticks;
	unsigned long inuse;
	unsigned gpio;
Loading