aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/rtmutex.h
diff options
context:
space:
mode:
authorKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>2010-03-16 20:36:58 -0400
committerIngo Molnar <mingo@elte.hu>2010-03-17 05:48:49 -0400
commit8bc037fb89bb3104b9ae290d18c877624cd7d9cc (patch)
tree33a95e7bf529ea6bdb28d1dda86f49450f9dc883 /include/linux/rtmutex.h
parentc890692bf37671b5b78a1870d55d6d87e1c8a509 (diff)
sched: Use proper type in sched_getaffinity()
Using the proper type fixes the following compiler warning: kernel/sched.c:4850: warning: comparison of distinct pointer types lacks a cast Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: torvalds@linux-foundation.org Cc: travis@sgi.com Cc: peterz@infradead.org Cc: drepper@redhat.com Cc: rja@sgi.com Cc: sharyath@in.ibm.com Cc: steiner@sgi.com LKML-Reference: <20100317090046.4C79.A69D9226@jp.fujitsu.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/rtmutex.h')
0 files changed, 0 insertions, 0 deletions
a id='n292' href='#n292'>292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
/*
 *	w83697hf/hg WDT driver
 *
 *	(c) Copyright 2006 Samuel Tardieu <sam@rfc1149.net>
 *	(c) Copyright 2006 Marcus Junker <junker@anduras.de>
 *
 *	Based on w83627hf_wdt.c which is based on advantechwdt.c
 *	which is based on wdt.c.
 *	Original copyright messages:
 *
 *	(c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
 *
 *	(c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
 *
 *	(c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
 *						All Rights Reserved.
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 *
 *	Neither Marcus Junker nor ANDURAS AG admit liability nor provide
 *	warranty for any of this software. This material is provided
 *	"AS-IS" and at no charge.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/uaccess.h>


#define WATCHDOG_NAME "w83697hf/hg WDT"
#define WATCHDOG_TIMEOUT 60		/* 60 sec default timeout */
#define WATCHDOG_EARLY_DISABLE 1	/* Disable until userland kicks in */

static unsigned long wdt_is_open;
static char expect_close;
static DEFINE_SPINLOCK(io_lock);

/* You must set this - there is no sane way to probe for this board. */
static int wdt_io = 0x2e;
module_param(wdt_io, int, 0);
MODULE_PARM_DESC(wdt_io,
		"w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)");

static int timeout = WATCHDOG_TIMEOUT;	/* in seconds */
module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout,
	"Watchdog timeout in seconds. 1<= timeout <=255 (default="
				__MODULE_STRING(WATCHDOG_TIMEOUT) ")");

static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout,
	"Watchdog cannot be stopped once started (default="
				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

static int early_disable = WATCHDOG_EARLY_DISABLE;
module_param(early_disable, int, 0);
MODULE_PARM_DESC(early_disable,
	"Watchdog gets disabled at boot time (default="
				__MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")");

/*
 *	Kernel methods.
 */

#define W83697HF_EFER (wdt_io + 0)  /* Extended Function Enable Register */
#define W83697HF_EFIR (wdt_io + 0)  /* Extended Function Index Register
							(same as EFER) */
#define W83697HF_EFDR (wdt_io + 1)  /* Extended Function Data Register */

static inline void w83697hf_unlock(void)
{
	outb_p(0x87, W83697HF_EFER);	/* Enter extended function mode */
	outb_p(0x87, W83697HF_EFER);	/* Again according to manual */
}

static inline void w83697hf_lock(void)
{
	outb_p(0xAA, W83697HF_EFER);	/* Leave extended function mode */
}

/*
 *	The three functions w83697hf_get_reg(), w83697hf_set_reg() and
 *	w83697hf_write_timeout() must be called with the device unlocked.
 */

static unsigned char w83697hf_get_reg(unsigned char reg)
{
	outb_p(reg, W83697HF_EFIR);
	return inb_p(W83697HF_EFDR);
}

static void w83697hf_set_reg(unsigned char reg, unsigned char data)
{
	outb_p(reg, W83697HF_EFIR);
	outb_p(data, W83697HF_EFDR);
}

static void w83697hf_write_timeout(int timeout)
{
	/* Write Timeout counter to CRF4 */
	w83697hf_set_reg(0xF4, timeout);
}

static void w83697hf_select_wdt(void)
{
	w83697hf_unlock();
	w83697hf_set_reg(0x07, 0x08);	/* Switch to logic device 8 (GPIO2) */
}

static inline void w83697hf_deselect_wdt(void)
{
	w83697hf_lock();
}

static void w83697hf_init(void)
{
	unsigned char bbuf;

	w83697hf_select_wdt();

	bbuf = w83697hf_get_reg(0x29);
	bbuf &= ~0x60;
	bbuf |= 0x20;

	/* Set pin 119 to WDTO# mode (= CR29, WDT0) */
	w83697hf_set_reg(0x29, bbuf);

	bbuf = w83697hf_get_reg(0xF3);
	bbuf &= ~0x04;
	w83697hf_set_reg(0xF3, bbuf);	/* Count mode is seconds */

	w83697hf_deselect_wdt();
}

static void wdt_ping(void)
{
	spin_lock(&io_lock);
	w83697hf_select_wdt();

	w83697hf_write_timeout(timeout);

	w83697hf_deselect_wdt();
	spin_unlock(&io_lock);
}

static void wdt_enable(void)
{
	spin_lock(&io_lock);
	w83697hf_select_wdt();

	w83697hf_write_timeout(timeout);
	w83697hf_set_reg(0x30, 1);	/* Enable timer */

	w83697hf_deselect_wdt();
	spin_unlock(&io_lock);
}

static void wdt_disable(void)
{
	spin_lock(&io_lock);
	w83697hf_select_wdt();

	w83697hf_set_reg(0x30, 0);	/* Disable timer */
	w83697hf_write_timeout(0);

	w83697hf_deselect_wdt();
	spin_unlock(&io_lock);
}

static unsigned char wdt_running(void)
{
	unsigned char t;

	spin_lock(&io_lock);
	w83697hf_select_wdt();

	t = w83697hf_get_reg(0xF4);	/* Read timer */

	w83697hf_deselect_wdt();
	spin_unlock(&io_lock);

	return t;
}

static int wdt_set_heartbeat(int t)
{
	if (t < 1 || t > 255)
		return -EINVAL;

	timeout = t;
	return 0;
}

static ssize_t wdt_write(struct file *file, const char __user *buf,
						size_t count, loff_t *ppos)
{
	if (count) {
		if (!nowayout) {
			size_t i;

			expect_close = 0;

			for (i = 0; i != count; i++) {
				char c;
				if (get_user(c, buf + i))
					return -EFAULT;
				if (c == 'V')
					expect_close = 42;
			}
		}
		wdt_ping();
	}
	return count;
}

static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	int new_timeout;
	static const struct watchdog_info ident = {
		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
							| WDIOF_MAGICCLOSE,
		.firmware_version = 1,
		.identity = "W83697HF WDT",
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		if (copy_to_user(argp, &ident, sizeof(ident)))
			return -EFAULT;
		break;

	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);

	case WDIOC_SETOPTIONS:
	{
		int options, retval = -EINVAL;

		if (get_user(options, p))
			return -EFAULT;

		if (options & WDIOS_DISABLECARD) {
			wdt_disable();
			retval = 0;
		}

		if (options & WDIOS_ENABLECARD) {
			wdt_enable();
			retval = 0;
		}

		return retval;
	}

	case WDIOC_KEEPALIVE:
		wdt_ping();
		break;

	case WDIOC_SETTIMEOUT:
		if (get_user(new_timeout, p))
			return -EFAULT;
		if (wdt_set_heartbeat(new_timeout))
			return -EINVAL;
		wdt_ping();
		/* Fall */

	case WDIOC_GETTIMEOUT:
		return put_user(timeout, p);

	default:
		return -ENOTTY;
	}
	return 0;
}

static int wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(0, &wdt_is_open))
		return -EBUSY;
	/*
	 *	Activate
	 */

	wdt_enable();
	return nonseekable_open(inode, file);
}

static int wdt_close(struct inode *inode, struct file *file)
{
	if (expect_close == 42)
		wdt_disable();
	else {
		pr_crit("Unexpected close, not stopping watchdog!\n");
		wdt_ping();
	}
	expect_close = 0;
	clear_bit(0, &wdt_is_open);
	return 0;
}

/*
 *	Notifier for system down
 */

static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
	void *unused)
{
	if (code == SYS_DOWN || code == SYS_HALT)
		wdt_disable();	/* Turn the WDT off */

	return NOTIFY_DONE;
}

/*
 *	Kernel Interfaces
 */

static const struct file_operations wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= wdt_write,
	.unlocked_ioctl	= wdt_ioctl,
	.open		= wdt_open,
	.release	= wdt_close,
};

static struct miscdevice wdt_miscdev = {