aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-10-06 05:51:07 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-10-06 05:51:07 -0400
commit012e060c95e547eceea4a12c6f58592473bf4011 (patch)
treeb57d3eafb50ce517577d2cf366c9ef0b4b286589 /drivers/char
parent923f122573851d18a3832ca808269fa2d5046fb1 (diff)
parented39f731ab2e77e58122232f6e27333331d7793d (diff)
Merge branch 'master'
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/hp-agp.c2
-rw-r--r--drivers/char/amiserial.c4
-rw-r--r--drivers/char/drm/drm_drv.c2
-rw-r--r--drivers/char/drm/drm_proc.c2
-rw-r--r--drivers/char/epca.c84
-rw-r--r--drivers/char/epca.h12
-rw-r--r--drivers/char/hpet.c1
-rw-r--r--drivers/char/hvc_console.c6
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c6
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c2
-rw-r--r--drivers/char/n_r3964.c84
-rw-r--r--drivers/char/vt.c5
-rw-r--r--drivers/char/watchdog/Kconfig93
-rw-r--r--drivers/char/watchdog/Makefile7
-rw-r--r--drivers/char/watchdog/i6300esb.c527
-rw-r--r--drivers/char/watchdog/ibmasr.c405
-rw-r--r--drivers/char/watchdog/mpcore_wdt.c2
-rw-r--r--drivers/char/watchdog/mv64x60_wdt.c252
-rw-r--r--drivers/char/watchdog/pcwd_pci.c44
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c2
-rw-r--r--drivers/char/watchdog/sbc8360.c414
-rw-r--r--drivers/char/watchdog/w83977f_wdt.c543
22 files changed, 2351 insertions, 148 deletions
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 99762b6c19ae..de5d6d212674 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -252,7 +252,7 @@ hp_zx1_configure (void)
252 readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); 252 readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
253 writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); 253 writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
254 readl(hp->ioc_regs+HP_ZX1_TCNFG); 254 readl(hp->ioc_regs+HP_ZX1_TCNFG);
255 writel(~(HP_ZX1_IOVA_SIZE-1), hp->ioc_regs+HP_ZX1_IMASK); 255 writel((unsigned int)(~(HP_ZX1_IOVA_SIZE-1)), hp->ioc_regs+HP_ZX1_IMASK);
256 readl(hp->ioc_regs+HP_ZX1_IMASK); 256 readl(hp->ioc_regs+HP_ZX1_IMASK);
257 writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE); 257 writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE);
258 readl(hp->ioc_regs+HP_ZX1_IBASE); 258 readl(hp->ioc_regs+HP_ZX1_IBASE);
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 2a36561eec68..a124f8c5d062 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -2053,10 +2053,6 @@ static int __init rs_init(void)
2053 state->icount.rx = state->icount.tx = 0; 2053 state->icount.rx = state->icount.tx = 0;
2054 state->icount.frame = state->icount.parity = 0; 2054 state->icount.frame = state->icount.parity = 0;
2055 state->icount.overrun = state->icount.brk = 0; 2055 state->icount.overrun = state->icount.brk = 0;
2056 /*
2057 if(state->port && check_region(state->port,REGION_LENGTH(state)))
2058 continue;
2059 */
2060 2056
2061 printk(KERN_INFO "ttyS%d is the amiga builtin serial port\n", 2057 printk(KERN_INFO "ttyS%d is the amiga builtin serial port\n",
2062 state->line); 2058 state->line);
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 6ba48f346fcf..041bb47b5c39 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -376,7 +376,7 @@ static int __init drm_core_init(void)
376 goto err_p2; 376 goto err_p2;
377 } 377 }
378 378
379 drm_proc_root = create_proc_entry("dri", S_IFDIR, NULL); 379 drm_proc_root = proc_mkdir("dri", NULL);
380 if (!drm_proc_root) { 380 if (!drm_proc_root) {
381 DRM_ERROR("Cannot create /proc/dri\n"); 381 DRM_ERROR("Cannot create /proc/dri\n");
382 ret = -1; 382 ret = -1;
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 32d2bb99462c..977961002488 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -95,7 +95,7 @@ int drm_proc_init(drm_device_t *dev, int minor,
95 char name[64]; 95 char name[64];
96 96
97 sprintf(name, "%d", minor); 97 sprintf(name, "%d", minor);
98 *dev_root = create_proc_entry(name, S_IFDIR, root); 98 *dev_root = proc_mkdir(name, root);
99 if (!*dev_root) { 99 if (!*dev_root) {
100 DRM_ERROR("Cannot create /proc/dri/%s\n", name); 100 DRM_ERROR("Cannot create /proc/dri/%s\n", name);
101 return -1; 101 return -1;
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 58d3738a2b7f..407708a001e4 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -534,7 +534,7 @@ static void shutdown(struct channel *ch)
534 534
535 unsigned long flags; 535 unsigned long flags;
536 struct tty_struct *tty; 536 struct tty_struct *tty;
537 struct board_chan *bc; 537 struct board_chan __iomem *bc;
538 538
539 if (!(ch->asyncflags & ASYNC_INITIALIZED)) 539 if (!(ch->asyncflags & ASYNC_INITIALIZED))
540 return; 540 return;
@@ -618,7 +618,7 @@ static int pc_write(struct tty_struct * tty,
618 struct channel *ch; 618 struct channel *ch;
619 unsigned long flags; 619 unsigned long flags;
620 int remain; 620 int remain;
621 struct board_chan *bc; 621 struct board_chan __iomem *bc;
622 622
623 /* ---------------------------------------------------------------- 623 /* ----------------------------------------------------------------
624 pc_write is primarily called directly by the kernel routine 624 pc_write is primarily called directly by the kernel routine
@@ -685,7 +685,7 @@ static int pc_write(struct tty_struct * tty,
685 ------------------------------------------------------------------- */ 685 ------------------------------------------------------------------- */
686 686
687 dataLen = min(bytesAvailable, dataLen); 687 dataLen = min(bytesAvailable, dataLen);
688 memcpy(ch->txptr + head, buf, dataLen); 688 memcpy_toio(ch->txptr + head, buf, dataLen);
689 buf += dataLen; 689 buf += dataLen;
690 head += dataLen; 690 head += dataLen;
691 amountCopied += dataLen; 691 amountCopied += dataLen;
@@ -726,7 +726,7 @@ static int pc_write_room(struct tty_struct *tty)
726 struct channel *ch; 726 struct channel *ch;
727 unsigned long flags; 727 unsigned long flags;
728 unsigned int head, tail; 728 unsigned int head, tail;
729 struct board_chan *bc; 729 struct board_chan __iomem *bc;
730 730
731 remain = 0; 731 remain = 0;
732 732
@@ -773,7 +773,7 @@ static int pc_chars_in_buffer(struct tty_struct *tty)
773 int remain; 773 int remain;
774 unsigned long flags; 774 unsigned long flags;
775 struct channel *ch; 775 struct channel *ch;
776 struct board_chan *bc; 776 struct board_chan __iomem *bc;
777 777
778 /* --------------------------------------------------------- 778 /* ---------------------------------------------------------
779 verifyChannel returns the channel from the tty struct 779 verifyChannel returns the channel from the tty struct
@@ -830,7 +830,7 @@ static void pc_flush_buffer(struct tty_struct *tty)
830 unsigned int tail; 830 unsigned int tail;
831 unsigned long flags; 831 unsigned long flags;
832 struct channel *ch; 832 struct channel *ch;
833 struct board_chan *bc; 833 struct board_chan __iomem *bc;
834 /* --------------------------------------------------------- 834 /* ---------------------------------------------------------
835 verifyChannel returns the channel from the tty struct 835 verifyChannel returns the channel from the tty struct
836 if it is valid. This serves as a sanity check. 836 if it is valid. This serves as a sanity check.
@@ -976,7 +976,7 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
976 struct channel *ch; 976 struct channel *ch;
977 unsigned long flags; 977 unsigned long flags;
978 int line, retval, boardnum; 978 int line, retval, boardnum;
979 struct board_chan *bc; 979 struct board_chan __iomem *bc;
980 unsigned int head; 980 unsigned int head;
981 981
982 line = tty->index; 982 line = tty->index;
@@ -1041,7 +1041,7 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
1041 ch->statusflags = 0; 1041 ch->statusflags = 0;
1042 1042
1043 /* Save boards current modem status */ 1043 /* Save boards current modem status */
1044 ch->imodem = bc->mstat; 1044 ch->imodem = readb(&bc->mstat);
1045 1045
1046 /* ---------------------------------------------------------------- 1046 /* ----------------------------------------------------------------
1047 Set receive head and tail ptrs to each other. This indicates 1047 Set receive head and tail ptrs to each other. This indicates
@@ -1399,10 +1399,10 @@ static void post_fep_init(unsigned int crd)
1399{ /* Begin post_fep_init */ 1399{ /* Begin post_fep_init */
1400 1400
1401 int i; 1401 int i;
1402 unsigned char *memaddr; 1402 void __iomem *memaddr;
1403 struct global_data *gd; 1403 struct global_data __iomem *gd;
1404 struct board_info *bd; 1404 struct board_info *bd;
1405 struct board_chan *bc; 1405 struct board_chan __iomem *bc;
1406 struct channel *ch; 1406 struct channel *ch;
1407 int shrinkmem = 0, lowwater ; 1407 int shrinkmem = 0, lowwater ;
1408 1408
@@ -1461,7 +1461,7 @@ static void post_fep_init(unsigned int crd)
1461 8 and 64 of these structures. 1461 8 and 64 of these structures.
1462 -------------------------------------------------------------------- */ 1462 -------------------------------------------------------------------- */
1463 1463
1464 bc = (struct board_chan *)(memaddr + CHANSTRUCT); 1464 bc = memaddr + CHANSTRUCT;
1465 1465
1466 /* ------------------------------------------------------------------- 1466 /* -------------------------------------------------------------------
1467 The below assignment will set gd to point at the BEGINING of 1467 The below assignment will set gd to point at the BEGINING of
@@ -1470,7 +1470,7 @@ static void post_fep_init(unsigned int crd)
1470 pointer begins at 0xd10. 1470 pointer begins at 0xd10.
1471 ---------------------------------------------------------------------- */ 1471 ---------------------------------------------------------------------- */
1472 1472
1473 gd = (struct global_data *)(memaddr + GLOBAL); 1473 gd = memaddr + GLOBAL;
1474 1474
1475 /* -------------------------------------------------------------------- 1475 /* --------------------------------------------------------------------
1476 XEPORTS (address 0xc22) points at the number of channels the 1476 XEPORTS (address 0xc22) points at the number of channels the
@@ -1493,6 +1493,7 @@ static void post_fep_init(unsigned int crd)
1493 1493
1494 for (i = 0; i < bd->numports; i++, ch++, bc++) { /* Begin for each port */ 1494 for (i = 0; i < bd->numports; i++, ch++, bc++) { /* Begin for each port */
1495 unsigned long flags; 1495 unsigned long flags;
1496 u16 tseg, rseg;
1496 1497
1497 ch->brdchan = bc; 1498 ch->brdchan = bc;
1498 ch->mailbox = gd; 1499 ch->mailbox = gd;
@@ -1553,50 +1554,53 @@ static void post_fep_init(unsigned int crd)
1553 shrinkmem = 0; 1554 shrinkmem = 0;
1554 } 1555 }
1555 1556
1557 tseg = readw(&bc->tseg);
1558 rseg = readw(&bc->rseg);
1559
1556 switch (bd->type) { 1560 switch (bd->type) {
1557 1561
1558 case PCIXEM: 1562 case PCIXEM:
1559 case PCIXRJ: 1563 case PCIXRJ:
1560 case PCIXR: 1564 case PCIXR:
1561 /* Cover all the 2MEG cards */ 1565 /* Cover all the 2MEG cards */
1562 ch->txptr = memaddr + (((bc->tseg) << 4) & 0x1fffff); 1566 ch->txptr = memaddr + ((tseg << 4) & 0x1fffff);
1563 ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x1fffff); 1567 ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff);
1564 ch->txwin = FEPWIN | ((bc->tseg) >> 11); 1568 ch->txwin = FEPWIN | (tseg >> 11);
1565 ch->rxwin = FEPWIN | ((bc->rseg) >> 11); 1569 ch->rxwin = FEPWIN | (rseg >> 11);
1566 break; 1570 break;
1567 1571
1568 case PCXEM: 1572 case PCXEM:
1569 case EISAXEM: 1573 case EISAXEM:
1570 /* Cover all the 32K windowed cards */ 1574 /* Cover all the 32K windowed cards */
1571 /* Mask equal to window size - 1 */ 1575 /* Mask equal to window size - 1 */
1572 ch->txptr = memaddr + (((bc->tseg) << 4) & 0x7fff); 1576 ch->txptr = memaddr + ((tseg << 4) & 0x7fff);
1573 ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x7fff); 1577 ch->rxptr = memaddr + ((rseg << 4) & 0x7fff);
1574 ch->txwin = FEPWIN | ((bc->tseg) >> 11); 1578 ch->txwin = FEPWIN | (tseg >> 11);
1575 ch->rxwin = FEPWIN | ((bc->rseg) >> 11); 1579 ch->rxwin = FEPWIN | (rseg >> 11);
1576 break; 1580 break;
1577 1581
1578 case PCXEVE: 1582 case PCXEVE:
1579 case PCXE: 1583 case PCXE:
1580 ch->txptr = memaddr + (((bc->tseg - bd->memory_seg) << 4) & 0x1fff); 1584 ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff);
1581 ch->txwin = FEPWIN | ((bc->tseg - bd->memory_seg) >> 9); 1585 ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9);
1582 ch->rxptr = memaddr + (((bc->rseg - bd->memory_seg) << 4) & 0x1fff); 1586 ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff);
1583 ch->rxwin = FEPWIN | ((bc->rseg - bd->memory_seg) >>9 ); 1587 ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 );
1584 break; 1588 break;
1585 1589
1586 case PCXI: 1590 case PCXI:
1587 case PC64XE: 1591 case PC64XE:
1588 ch->txptr = memaddr + ((bc->tseg - bd->memory_seg) << 4); 1592 ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4);
1589 ch->rxptr = memaddr + ((bc->rseg - bd->memory_seg) << 4); 1593 ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4);
1590 ch->txwin = ch->rxwin = 0; 1594 ch->txwin = ch->rxwin = 0;
1591 break; 1595 break;
1592 1596
1593 } /* End switch bd->type */ 1597 } /* End switch bd->type */
1594 1598
1595 ch->txbufhead = 0; 1599 ch->txbufhead = 0;
1596 ch->txbufsize = bc->tmax + 1; 1600 ch->txbufsize = readw(&bc->tmax) + 1;
1597 1601
1598 ch->rxbufhead = 0; 1602 ch->rxbufhead = 0;
1599 ch->rxbufsize = bc->rmax + 1; 1603 ch->rxbufsize = readw(&bc->rmax) + 1;
1600 1604
1601 lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2); 1605 lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2);
1602 1606
@@ -1718,11 +1722,11 @@ static void epcapoll(unsigned long ignored)
1718static void doevent(int crd) 1722static void doevent(int crd)
1719{ /* Begin doevent */ 1723{ /* Begin doevent */
1720 1724
1721 void *eventbuf; 1725 void __iomem *eventbuf;
1722 struct channel *ch, *chan0; 1726 struct channel *ch, *chan0;
1723 static struct tty_struct *tty; 1727 static struct tty_struct *tty;
1724 struct board_info *bd; 1728 struct board_info *bd;
1725 struct board_chan *bc; 1729 struct board_chan __iomem *bc;
1726 unsigned int tail, head; 1730 unsigned int tail, head;
1727 int event, channel; 1731 int event, channel;
1728 int mstat, lstat; 1732 int mstat, lstat;
@@ -1817,7 +1821,7 @@ static void doevent(int crd)
1817static void fepcmd(struct channel *ch, int cmd, int word_or_byte, 1821static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
1818 int byte2, int ncmds, int bytecmd) 1822 int byte2, int ncmds, int bytecmd)
1819{ /* Begin fepcmd */ 1823{ /* Begin fepcmd */
1820 unchar *memaddr; 1824 unchar __iomem *memaddr;
1821 unsigned int head, cmdTail, cmdStart, cmdMax; 1825 unsigned int head, cmdTail, cmdStart, cmdMax;
1822 long count; 1826 long count;
1823 int n; 1827 int n;
@@ -2000,7 +2004,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
2000 2004
2001 unsigned int cmdHead; 2005 unsigned int cmdHead;
2002 struct termios *ts; 2006 struct termios *ts;
2003 struct board_chan *bc; 2007 struct board_chan __iomem *bc;
2004 unsigned mval, hflow, cflag, iflag; 2008 unsigned mval, hflow, cflag, iflag;
2005 2009
2006 bc = ch->brdchan; 2010 bc = ch->brdchan;
@@ -2010,7 +2014,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
2010 ts = tty->termios; 2014 ts = tty->termios;
2011 if ((ts->c_cflag & CBAUD) == 0) { /* Begin CBAUD detected */ 2015 if ((ts->c_cflag & CBAUD) == 0) { /* Begin CBAUD detected */
2012 cmdHead = readw(&bc->rin); 2016 cmdHead = readw(&bc->rin);
2013 bc->rout = cmdHead; 2017 writew(cmdHead, &bc->rout);
2014 cmdHead = readw(&bc->tin); 2018 cmdHead = readw(&bc->tin);
2015 /* Changing baud in mid-stream transmission can be wonderful */ 2019 /* Changing baud in mid-stream transmission can be wonderful */
2016 /* --------------------------------------------------------------- 2020 /* ---------------------------------------------------------------
@@ -2116,7 +2120,7 @@ static void receive_data(struct channel *ch)
2116 unchar *rptr; 2120 unchar *rptr;
2117 struct termios *ts = NULL; 2121 struct termios *ts = NULL;
2118 struct tty_struct *tty; 2122 struct tty_struct *tty;
2119 struct board_chan *bc; 2123 struct board_chan __iomem *bc;
2120 int dataToRead, wrapgap, bytesAvailable; 2124 int dataToRead, wrapgap, bytesAvailable;
2121 unsigned int tail, head; 2125 unsigned int tail, head;
2122 unsigned int wrapmask; 2126 unsigned int wrapmask;
@@ -2154,7 +2158,7 @@ static void receive_data(struct channel *ch)
2154 --------------------------------------------------------------------- */ 2158 --------------------------------------------------------------------- */
2155 2159
2156 if (!tty || !ts || !(ts->c_cflag & CREAD)) { 2160 if (!tty || !ts || !(ts->c_cflag & CREAD)) {
2157 bc->rout = head; 2161 writew(head, &bc->rout);
2158 return; 2162 return;
2159 } 2163 }
2160 2164
@@ -2270,7 +2274,7 @@ static int info_ioctl(struct tty_struct *tty, struct file * file,
2270static int pc_tiocmget(struct tty_struct *tty, struct file *file) 2274static int pc_tiocmget(struct tty_struct *tty, struct file *file)
2271{ 2275{
2272 struct channel *ch = (struct channel *) tty->driver_data; 2276 struct channel *ch = (struct channel *) tty->driver_data;
2273 struct board_chan *bc; 2277 struct board_chan __iomem *bc;
2274 unsigned int mstat, mflag = 0; 2278 unsigned int mstat, mflag = 0;
2275 unsigned long flags; 2279 unsigned long flags;
2276 2280
@@ -2351,7 +2355,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
2351 unsigned long flags; 2355 unsigned long flags;
2352 unsigned int mflag, mstat; 2356 unsigned int mflag, mstat;
2353 unsigned char startc, stopc; 2357 unsigned char startc, stopc;
2354 struct board_chan *bc; 2358 struct board_chan __iomem *bc;
2355 struct channel *ch = (struct channel *) tty->driver_data; 2359 struct channel *ch = (struct channel *) tty->driver_data;
2356 void __user *argp = (void __user *)arg; 2360 void __user *argp = (void __user *)arg;
2357 2361
@@ -2633,7 +2637,7 @@ static void pc_start(struct tty_struct *tty)
2633 spin_lock_irqsave(&epca_lock, flags); 2637 spin_lock_irqsave(&epca_lock, flags);
2634 /* Just in case output was resumed because of a change in Digi-flow */ 2638 /* Just in case output was resumed because of a change in Digi-flow */
2635 if (ch->statusflags & TXSTOPPED) { /* Begin transmit resume requested */ 2639 if (ch->statusflags & TXSTOPPED) { /* Begin transmit resume requested */
2636 struct board_chan *bc; 2640 struct board_chan __iomem *bc;
2637 globalwinon(ch); 2641 globalwinon(ch);
2638 bc = ch->brdchan; 2642 bc = ch->brdchan;
2639 if (ch->statusflags & LOWWAIT) 2643 if (ch->statusflags & LOWWAIT)
@@ -2727,7 +2731,7 @@ void digi_send_break(struct channel *ch, int msec)
2727static void setup_empty_event(struct tty_struct *tty, struct channel *ch) 2731static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
2728{ /* Begin setup_empty_event */ 2732{ /* Begin setup_empty_event */
2729 2733
2730 struct board_chan *bc = ch->brdchan; 2734 struct board_chan __iomem *bc = ch->brdchan;
2731 2735
2732 globalwinon(ch); 2736 globalwinon(ch);
2733 ch->statusflags |= EMPTYWAIT; 2737 ch->statusflags |= EMPTYWAIT;
diff --git a/drivers/char/epca.h b/drivers/char/epca.h
index 20eeb5a70e1a..456d6c8f94a8 100644
--- a/drivers/char/epca.h
+++ b/drivers/char/epca.h
@@ -128,17 +128,17 @@ struct channel
128 unsigned long c_cflag; 128 unsigned long c_cflag;
129 unsigned long c_lflag; 129 unsigned long c_lflag;
130 unsigned long c_oflag; 130 unsigned long c_oflag;
131 unsigned char *txptr; 131 unsigned char __iomem *txptr;
132 unsigned char *rxptr; 132 unsigned char __iomem *rxptr;
133 unsigned char *tmp_buf; 133 unsigned char *tmp_buf;
134 struct board_info *board; 134 struct board_info *board;
135 struct board_chan *brdchan; 135 struct board_chan __iomem *brdchan;
136 struct digi_struct digiext; 136 struct digi_struct digiext;
137 struct tty_struct *tty; 137 struct tty_struct *tty;
138 wait_queue_head_t open_wait; 138 wait_queue_head_t open_wait;
139 wait_queue_head_t close_wait; 139 wait_queue_head_t close_wait;
140 struct work_struct tqueue; 140 struct work_struct tqueue;
141 struct global_data *mailbox; 141 struct global_data __iomem *mailbox;
142}; 142};
143 143
144struct board_info 144struct board_info
@@ -149,8 +149,8 @@ struct board_info
149 unsigned short numports; 149 unsigned short numports;
150 unsigned long port; 150 unsigned long port;
151 unsigned long membase; 151 unsigned long membase;
152 unsigned char __iomem *re_map_port; 152 void __iomem *re_map_port;
153 unsigned char *re_map_membase; 153 void __iomem *re_map_membase;
154 unsigned long memory_seg; 154 unsigned long memory_seg;
155 void ( * memwinon ) (struct board_info *, unsigned int) ; 155 void ( * memwinon ) (struct board_info *, unsigned int) ;
156 void ( * memwinoff ) (struct board_info *, unsigned int) ; 156 void ( * memwinoff ) (struct board_info *, unsigned int) ;
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index de0379b6d502..c055bb630ffc 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -273,7 +273,6 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
273 273
274 vma->vm_flags |= VM_IO; 274 vma->vm_flags |= VM_IO;
275 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 275 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
276 addr = __pa(addr);
277 276
278 if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, 277 if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
279 PAGE_SIZE, vma->vm_page_prot)) { 278 PAGE_SIZE, vma->vm_page_prot)) {
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index cddb789902db..f92177634677 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -839,9 +839,6 @@ int __init hvc_init(void)
839 hvc_driver->flags = TTY_DRIVER_REAL_RAW; 839 hvc_driver->flags = TTY_DRIVER_REAL_RAW;
840 tty_set_operations(hvc_driver, &hvc_ops); 840 tty_set_operations(hvc_driver, &hvc_ops);
841 841
842 if (tty_register_driver(hvc_driver))
843 panic("Couldn't register hvc console driver\n");
844
845 /* Always start the kthread because there can be hotplug vty adapters 842 /* Always start the kthread because there can be hotplug vty adapters
846 * added later. */ 843 * added later. */
847 hvc_task = kthread_run(khvcd, NULL, "khvcd"); 844 hvc_task = kthread_run(khvcd, NULL, "khvcd");
@@ -851,6 +848,9 @@ int __init hvc_init(void)
851 return -EIO; 848 return -EIO;
852 } 849 }
853 850
851 if (tty_register_driver(hvc_driver))
852 panic("Couldn't register hvc console driver\n");
853
854 return 0; 854 return 0;
855} 855}
856module_init(hvc_init); 856module_init(hvc_init);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 463351d4f942..32fa82c78c73 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -2620,7 +2620,7 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
2620 spin_lock_irqsave(&(intf->waiting_msgs_lock), flags); 2620 spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
2621 if (!list_empty(&(intf->waiting_msgs))) { 2621 if (!list_empty(&(intf->waiting_msgs))) {
2622 list_add_tail(&(msg->link), &(intf->waiting_msgs)); 2622 list_add_tail(&(msg->link), &(intf->waiting_msgs));
2623 spin_unlock(&(intf->waiting_msgs_lock)); 2623 spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
2624 goto out_unlock; 2624 goto out_unlock;
2625 } 2625 }
2626 spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); 2626 spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
@@ -2629,9 +2629,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
2629 if (rv > 0) { 2629 if (rv > 0) {
2630 /* Could not handle the message now, just add it to a 2630 /* Could not handle the message now, just add it to a
2631 list to handle later. */ 2631 list to handle later. */
2632 spin_lock(&(intf->waiting_msgs_lock)); 2632 spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
2633 list_add_tail(&(msg->link), &(intf->waiting_msgs)); 2633 list_add_tail(&(msg->link), &(intf->waiting_msgs));
2634 spin_unlock(&(intf->waiting_msgs_lock)); 2634 spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
2635 } else if (rv == 0) { 2635 } else if (rv == 0) {
2636 ipmi_free_smi_msg(msg); 2636 ipmi_free_smi_msg(msg);
2637 } 2637 }
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index e82a96ba396b..f66947722e12 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -55,7 +55,7 @@ extern void (*pm_power_off)(void);
55static int poweroff_powercycle; 55static int poweroff_powercycle;
56 56
57/* parameter definition to allow user to flag power cycle */ 57/* parameter definition to allow user to flag power cycle */
58module_param(poweroff_powercycle, int, 0); 58module_param(poweroff_powercycle, int, 0644);
59MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down."); 59MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
60 60
61/* Stuff from the get device id command. */ 61/* Stuff from the get device id command. */
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 2291a87e8ada..97d6dc24b800 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -229,8 +229,8 @@ static int __init r3964_init(void)
229 TRACE_L("line discipline %d registered", N_R3964); 229 TRACE_L("line discipline %d registered", N_R3964);
230 TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags, 230 TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags,
231 tty_ldisc_N_R3964.num); 231 tty_ldisc_N_R3964.num);
232 TRACE_L("open=%x", (int)tty_ldisc_N_R3964.open); 232 TRACE_L("open=%p", tty_ldisc_N_R3964.open);
233 TRACE_L("tty_ldisc_N_R3964 = %x", (int)&tty_ldisc_N_R3964); 233 TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964);
234 } 234 }
235 else 235 else
236 { 236 {
@@ -267,8 +267,8 @@ static void add_tx_queue(struct r3964_info *pInfo, struct r3964_block_header *pH
267 267
268 spin_unlock_irqrestore(&pInfo->lock, flags); 268 spin_unlock_irqrestore(&pInfo->lock, flags);
269 269
270 TRACE_Q("add_tx_queue %x, length %d, tx_first = %x", 270 TRACE_Q("add_tx_queue %p, length %d, tx_first = %p",
271 (int)pHeader, pHeader->length, (int)pInfo->tx_first ); 271 pHeader, pHeader->length, pInfo->tx_first );
272} 272}
273 273
274static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code) 274static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
@@ -285,10 +285,10 @@ static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
285 return; 285 return;
286 286
287#ifdef DEBUG_QUEUE 287#ifdef DEBUG_QUEUE
288 printk("r3964: remove_from_tx_queue: %x, length %d - ", 288 printk("r3964: remove_from_tx_queue: %p, length %u - ",
289 (int)pHeader, (int)pHeader->length ); 289 pHeader, pHeader->length );
290 for(pDump=pHeader;pDump;pDump=pDump->next) 290 for(pDump=pHeader;pDump;pDump=pDump->next)
291 printk("%x ", (int)pDump); 291 printk("%p ", pDump);
292 printk("\n"); 292 printk("\n");
293#endif 293#endif
294 294
@@ -319,10 +319,10 @@ static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
319 spin_unlock_irqrestore(&pInfo->lock, flags); 319 spin_unlock_irqrestore(&pInfo->lock, flags);
320 320
321 kfree(pHeader); 321 kfree(pHeader);
322 TRACE_M("remove_from_tx_queue - kfree %x",(int)pHeader); 322 TRACE_M("remove_from_tx_queue - kfree %p",pHeader);
323 323
324 TRACE_Q("remove_from_tx_queue: tx_first = %x, tx_last = %x", 324 TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p",
325 (int)pInfo->tx_first, (int)pInfo->tx_last ); 325 pInfo->tx_first, pInfo->tx_last );
326} 326}
327 327
328static void add_rx_queue(struct r3964_info *pInfo, struct r3964_block_header *pHeader) 328static void add_rx_queue(struct r3964_info *pInfo, struct r3964_block_header *pHeader)
@@ -346,9 +346,9 @@ static void add_rx_queue(struct r3964_info *pInfo, struct r3964_block_header *pH
346 346
347 spin_unlock_irqrestore(&pInfo->lock, flags); 347 spin_unlock_irqrestore(&pInfo->lock, flags);
348 348
349 TRACE_Q("add_rx_queue: %x, length = %d, rx_first = %x, count = %d", 349 TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d",
350 (int)pHeader, pHeader->length, 350 pHeader, pHeader->length,
351 (int)pInfo->rx_first, pInfo->blocks_in_rx_queue); 351 pInfo->rx_first, pInfo->blocks_in_rx_queue);
352} 352}
353 353
354static void remove_from_rx_queue(struct r3964_info *pInfo, 354static void remove_from_rx_queue(struct r3964_info *pInfo,
@@ -360,10 +360,10 @@ static void remove_from_rx_queue(struct r3964_info *pInfo,
360 if(pHeader==NULL) 360 if(pHeader==NULL)
361 return; 361 return;
362 362
363 TRACE_Q("remove_from_rx_queue: rx_first = %x, rx_last = %x, count = %d", 363 TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
364 (int)pInfo->rx_first, (int)pInfo->rx_last, pInfo->blocks_in_rx_queue ); 364 pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue );
365 TRACE_Q("remove_from_rx_queue: %x, length %d", 365 TRACE_Q("remove_from_rx_queue: %p, length %u",
366 (int)pHeader, (int)pHeader->length ); 366 pHeader, pHeader->length );
367 367
368 spin_lock_irqsave(&pInfo->lock, flags); 368 spin_lock_irqsave(&pInfo->lock, flags);
369 369
@@ -401,10 +401,10 @@ static void remove_from_rx_queue(struct r3964_info *pInfo,
401 spin_unlock_irqrestore(&pInfo->lock, flags); 401 spin_unlock_irqrestore(&pInfo->lock, flags);
402 402
403 kfree(pHeader); 403 kfree(pHeader);
404 TRACE_M("remove_from_rx_queue - kfree %x",(int)pHeader); 404 TRACE_M("remove_from_rx_queue - kfree %p",pHeader);
405 405
406 TRACE_Q("remove_from_rx_queue: rx_first = %x, rx_last = %x, count = %d", 406 TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
407 (int)pInfo->rx_first, (int)pInfo->rx_last, pInfo->blocks_in_rx_queue ); 407 pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue );
408} 408}
409 409
410static void put_char(struct r3964_info *pInfo, unsigned char ch) 410static void put_char(struct r3964_info *pInfo, unsigned char ch)
@@ -506,8 +506,8 @@ static void transmit_block(struct r3964_info *pInfo)
506 if(tty->driver->write_room) 506 if(tty->driver->write_room)
507 room=tty->driver->write_room(tty); 507 room=tty->driver->write_room(tty);
508 508
509 TRACE_PS("transmit_block %x, room %d, length %d", 509 TRACE_PS("transmit_block %p, room %d, length %d",
510 (int)pBlock, room, pBlock->length); 510 pBlock, room, pBlock->length);
511 511
512 while(pInfo->tx_position < pBlock->length) 512 while(pInfo->tx_position < pBlock->length)
513 { 513 {
@@ -588,7 +588,7 @@ static void on_receive_block(struct r3964_info *pInfo)
588 588
589 /* prepare struct r3964_block_header: */ 589 /* prepare struct r3964_block_header: */
590 pBlock = kmalloc(length+sizeof(struct r3964_block_header), GFP_KERNEL); 590 pBlock = kmalloc(length+sizeof(struct r3964_block_header), GFP_KERNEL);
591 TRACE_M("on_receive_block - kmalloc %x",(int)pBlock); 591 TRACE_M("on_receive_block - kmalloc %p",pBlock);
592 592
593 if(pBlock==NULL) 593 if(pBlock==NULL)
594 return; 594 return;
@@ -868,11 +868,11 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
868 if(pMsg) 868 if(pMsg)
869 { 869 {
870 kfree(pMsg); 870 kfree(pMsg);
871 TRACE_M("enable_signals - msg kfree %x",(int)pMsg); 871 TRACE_M("enable_signals - msg kfree %p",pMsg);
872 } 872 }
873 } 873 }
874 kfree(pClient); 874 kfree(pClient);
875 TRACE_M("enable_signals - kfree %x",(int)pClient); 875 TRACE_M("enable_signals - kfree %p",pClient);
876 return 0; 876 return 0;
877 } 877 }
878 } 878 }
@@ -890,7 +890,7 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
890 { 890 {
891 /* add client to client list */ 891 /* add client to client list */
892 pClient=kmalloc(sizeof(struct r3964_client_info), GFP_KERNEL); 892 pClient=kmalloc(sizeof(struct r3964_client_info), GFP_KERNEL);
893 TRACE_M("enable_signals - kmalloc %x",(int)pClient); 893 TRACE_M("enable_signals - kmalloc %p",pClient);
894 if(pClient==NULL) 894 if(pClient==NULL)
895 return -ENOMEM; 895 return -ENOMEM;
896 896
@@ -954,7 +954,7 @@ static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
954queue_the_message: 954queue_the_message:
955 955
956 pMsg = kmalloc(sizeof(struct r3964_message), GFP_KERNEL); 956 pMsg = kmalloc(sizeof(struct r3964_message), GFP_KERNEL);
957 TRACE_M("add_msg - kmalloc %x",(int)pMsg); 957 TRACE_M("add_msg - kmalloc %p",pMsg);
958 if(pMsg==NULL) { 958 if(pMsg==NULL) {
959 return; 959 return;
960 } 960 }
@@ -1067,11 +1067,11 @@ static int r3964_open(struct tty_struct *tty)
1067 struct r3964_info *pInfo; 1067 struct r3964_info *pInfo;
1068 1068
1069 TRACE_L("open"); 1069 TRACE_L("open");
1070 TRACE_L("tty=%x, PID=%d, disc_data=%x", 1070 TRACE_L("tty=%p, PID=%d, disc_data=%p",
1071 (int)tty, current->pid, (int)tty->disc_data); 1071 tty, current->pid, tty->disc_data);
1072 1072
1073 pInfo=kmalloc(sizeof(struct r3964_info), GFP_KERNEL); 1073 pInfo=kmalloc(sizeof(struct r3964_info), GFP_KERNEL);
1074 TRACE_M("r3964_open - info kmalloc %x",(int)pInfo); 1074 TRACE_M("r3964_open - info kmalloc %p",pInfo);
1075 1075
1076 if(!pInfo) 1076 if(!pInfo)
1077 { 1077 {
@@ -1080,26 +1080,26 @@ static int r3964_open(struct tty_struct *tty)
1080 } 1080 }
1081 1081
1082 pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL); 1082 pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
1083 TRACE_M("r3964_open - rx_buf kmalloc %x",(int)pInfo->rx_buf); 1083 TRACE_M("r3964_open - rx_buf kmalloc %p",pInfo->rx_buf);
1084 1084
1085 if(!pInfo->rx_buf) 1085 if(!pInfo->rx_buf)
1086 { 1086 {
1087 printk(KERN_ERR "r3964: failed to alloc receive buffer\n"); 1087 printk(KERN_ERR "r3964: failed to alloc receive buffer\n");
1088 kfree(pInfo); 1088 kfree(pInfo);
1089 TRACE_M("r3964_open - info kfree %x",(int)pInfo); 1089 TRACE_M("r3964_open - info kfree %p",pInfo);
1090 return -ENOMEM; 1090 return -ENOMEM;
1091 } 1091 }
1092 1092
1093 pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL); 1093 pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL);
1094 TRACE_M("r3964_open - tx_buf kmalloc %x",(int)pInfo->tx_buf); 1094 TRACE_M("r3964_open - tx_buf kmalloc %p",pInfo->tx_buf);
1095 1095
1096 if(!pInfo->tx_buf) 1096 if(!pInfo->tx_buf)
1097 { 1097 {
1098 printk(KERN_ERR "r3964: failed to alloc transmit buffer\n"); 1098 printk(KERN_ERR "r3964: failed to alloc transmit buffer\n");
1099 kfree(pInfo->rx_buf); 1099 kfree(pInfo->rx_buf);
1100 TRACE_M("r3964_open - rx_buf kfree %x",(int)pInfo->rx_buf); 1100 TRACE_M("r3964_open - rx_buf kfree %p",pInfo->rx_buf);
1101 kfree(pInfo); 1101 kfree(pInfo);
1102 TRACE_M("r3964_open - info kfree %x",(int)pInfo); 1102 TRACE_M("r3964_open - info kfree %p",pInfo);
1103 return -ENOMEM; 1103 return -ENOMEM;
1104 } 1104 }
1105 1105
@@ -1154,11 +1154,11 @@ static void r3964_close(struct tty_struct *tty)
1154 if(pMsg) 1154 if(pMsg)
1155 { 1155 {
1156 kfree(pMsg); 1156 kfree(pMsg);
1157 TRACE_M("r3964_close - msg kfree %x",(int)pMsg); 1157 TRACE_M("r3964_close - msg kfree %p",pMsg);
1158 } 1158 }
1159 } 1159 }
1160 kfree(pClient); 1160 kfree(pClient);
1161 TRACE_M("r3964_close - client kfree %x",(int)pClient); 1161 TRACE_M("r3964_close - client kfree %p",pClient);
1162 pClient=pNext; 1162 pClient=pNext;
1163 } 1163 }
1164 /* Remove jobs from tx_queue: */ 1164 /* Remove jobs from tx_queue: */
@@ -1177,11 +1177,11 @@ static void r3964_close(struct tty_struct *tty)
1177 /* Free buffers: */ 1177 /* Free buffers: */
1178 wake_up_interruptible(&pInfo->read_wait); 1178 wake_up_interruptible(&pInfo->read_wait);
1179 kfree(pInfo->rx_buf); 1179 kfree(pInfo->rx_buf);
1180 TRACE_M("r3964_close - rx_buf kfree %x",(int)pInfo->rx_buf); 1180 TRACE_M("r3964_close - rx_buf kfree %p",pInfo->rx_buf);
1181 kfree(pInfo->tx_buf); 1181 kfree(pInfo->tx_buf);
1182 TRACE_M("r3964_close - tx_buf kfree %x",(int)pInfo->tx_buf); 1182 TRACE_M("r3964_close - tx_buf kfree %p",pInfo->tx_buf);
1183 kfree(pInfo); 1183 kfree(pInfo);
1184 TRACE_M("r3964_close - info kfree %x",(int)pInfo); 1184 TRACE_M("r3964_close - info kfree %p",pInfo);
1185} 1185}
1186 1186
1187static ssize_t r3964_read(struct tty_struct *tty, struct file *file, 1187static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
@@ -1234,7 +1234,7 @@ repeat:
1234 count = sizeof(struct r3964_client_message); 1234 count = sizeof(struct r3964_client_message);
1235 1235
1236 kfree(pMsg); 1236 kfree(pMsg);
1237 TRACE_M("r3964_read - msg kfree %x",(int)pMsg); 1237 TRACE_M("r3964_read - msg kfree %p",pMsg);
1238 1238
1239 if (copy_to_user(buf,&theMsg, count)) 1239 if (copy_to_user(buf,&theMsg, count))
1240 return -EFAULT; 1240 return -EFAULT;
@@ -1279,7 +1279,7 @@ static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
1279 * Allocate a buffer for the data and copy it from the buffer with header prepended 1279 * Allocate a buffer for the data and copy it from the buffer with header prepended
1280 */ 1280 */
1281 new_data = kmalloc (count+sizeof(struct r3964_block_header), GFP_KERNEL); 1281 new_data = kmalloc (count+sizeof(struct r3964_block_header), GFP_KERNEL);
1282 TRACE_M("r3964_write - kmalloc %x",(int)new_data); 1282 TRACE_M("r3964_write - kmalloc %p",new_data);
1283 if (new_data == NULL) { 1283 if (new_data == NULL) {
1284 if (pInfo->flags & R3964_DEBUG) 1284 if (pInfo->flags & R3964_DEBUG)
1285 { 1285 {
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 1e33cb032e07..e91268e86833 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -810,13 +810,14 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
810 * from the top and bottom of cursor position 810 * from the top and bottom of cursor position
811 */ 811 */
812 old_origin += (vc->vc_y - new_rows/2) * old_row_size; 812 old_origin += (vc->vc_y - new_rows/2) * old_row_size;
813 end = old_origin + new_screen_size; 813 end = old_origin + (old_row_size * new_rows);
814 } 814 }
815 } else 815 } else
816 /* 816 /*
817 * Cursor near the top, copy contents from the top of buffer 817 * Cursor near the top, copy contents from the top of buffer
818 */ 818 */
819 end = (old_rows > new_rows) ? old_origin + new_screen_size : 819 end = (old_rows > new_rows) ? old_origin +
820 (old_row_size * new_rows) :
820 vc->vc_scr_end; 821 vc->vc_scr_end;
821 822
822 update_attr(vc); 823 update_attr(vc);
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index fa789ea36bbe..344001b45af9 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -84,6 +84,17 @@ config 977_WATCHDOG
84 84
85 Not sure? It's safe to say N. 85 Not sure? It's safe to say N.
86 86
87config IXP2000_WATCHDOG
88 tristate "IXP2000 Watchdog"
89 depends on WATCHDOG && ARCH_IXP2000
90 help
91 Say Y here if to include support for the watchdog timer
92 in the Intel IXP2000(2400, 2800, 2850) network processors.
93 This driver can be built as a module by choosing M. The module
94 will be called ixp2000_wdt.
95
96 Say N if you are unsure.
97
87config IXP4XX_WATCHDOG 98config IXP4XX_WATCHDOG
88 tristate "IXP4xx Watchdog" 99 tristate "IXP4xx Watchdog"
89 depends on WATCHDOG && ARCH_IXP4XX 100 depends on WATCHDOG && ARCH_IXP4XX
@@ -100,17 +111,6 @@ config IXP4XX_WATCHDOG
100 111
101 Say N if you are unsure. 112 Say N if you are unsure.
102 113
103config IXP2000_WATCHDOG
104 tristate "IXP2000 Watchdog"
105 depends on WATCHDOG && ARCH_IXP2000
106 help
107 Say Y here if to include support for the watchdog timer
108 in the Intel IXP2000(2400, 2800, 2850) network processors.
109 This driver can be built as a module by choosing M. The module
110 will be called ixp2000_wdt.
111
112 Say N if you are unsure.
113
114config S3C2410_WATCHDOG 114config S3C2410_WATCHDOG
115 tristate "S3C2410 Watchdog" 115 tristate "S3C2410 Watchdog"
116 depends on WATCHDOG && ARCH_S3C2410 116 depends on WATCHDOG && ARCH_S3C2410
@@ -233,6 +233,16 @@ config IB700_WDT
233 233
234 Most people will say N. 234 Most people will say N.
235 235
236config IBMASR
237 tristate "IBM Automatic Server Restart"
238 depends on WATCHDOG && X86
239 help
240 This is the driver for the IBM Automatic Server Restart watchdog
241 timer builtin into some eServer xSeries machines.
242
243 To compile this driver as a module, choose M here: the
244 module will be called ibmasr.
245
236config WAFER_WDT 246config WAFER_WDT
237 tristate "ICP Wafer 5823 Single Board Computer Watchdog" 247 tristate "ICP Wafer 5823 Single Board Computer Watchdog"
238 depends on WATCHDOG && X86 248 depends on WATCHDOG && X86
@@ -243,6 +253,16 @@ config WAFER_WDT
243 To compile this driver as a module, choose M here: the 253 To compile this driver as a module, choose M here: the
244 module will be called wafer5823wdt. 254 module will be called wafer5823wdt.
245 255
256config I6300ESB_WDT
257 tristate "Intel 6300ESB Timer/Watchdog"
258 depends on WATCHDOG && X86 && PCI
259 ---help---
260 Hardware driver for the watchdog timer built into the Intel
261 6300ESB controller hub.
262
263 To compile this driver as a module, choose M here: the
264 module will be called i6300esb.
265
246config I8XX_TCO 266config I8XX_TCO
247 tristate "Intel i8xx TCO Timer/Watchdog" 267 tristate "Intel i8xx TCO Timer/Watchdog"
248 depends on WATCHDOG && (X86 || IA64) && PCI 268 depends on WATCHDOG && (X86 || IA64) && PCI
@@ -298,6 +318,19 @@ config 60XX_WDT
298 You can compile this driver directly into the kernel, or use 318 You can compile this driver directly into the kernel, or use
299 it as a module. The module will be called sbc60xxwdt. 319 it as a module. The module will be called sbc60xxwdt.
300 320
321config SBC8360_WDT
322 tristate "SBC8360 Watchdog Timer"
323 depends on WATCHDOG && X86
324 ---help---
325
326 This is the driver for the hardware watchdog on the SBC8360 Single
327 Board Computer produced by Axiomtek Co., Ltd. (www.axiomtek.com).
328
329 To compile this driver as a module, choose M here: the
330 module will be called sbc8360.ko.
331
332 Most people will say N.
333
301config CPU5_WDT 334config CPU5_WDT
302 tristate "SMA CPU5 Watchdog" 335 tristate "SMA CPU5 Watchdog"
303 depends on WATCHDOG && X86 336 depends on WATCHDOG && X86
@@ -336,6 +369,19 @@ config W83877F_WDT
336 369
337 Most people will say N. 370 Most people will say N.
338 371
372config W83977F_WDT
373 tristate "W83977F (PCM-5335) Watchdog Timer"
374 depends on WATCHDOG && X86
375 ---help---
376 This is the driver for the hardware watchdog on the W83977F I/O chip
377 as used in AAEON's PCM-5335 SBC (and likely others). This
378 watchdog simply watches your kernel to make sure it doesn't freeze,
379 and if it does, it reboots your computer after a certain amount of
380 time.
381
382 To compile this driver as a module, choose M here: the
383 module will be called w83977f_wdt.
384
339config MACHZ_WDT 385config MACHZ_WDT
340 tristate "ZF MachZ Watchdog" 386 tristate "ZF MachZ Watchdog"
341 depends on WATCHDOG && X86 387 depends on WATCHDOG && X86
@@ -355,6 +401,10 @@ config 8xx_WDT
355 tristate "MPC8xx Watchdog Timer" 401 tristate "MPC8xx Watchdog Timer"
356 depends on WATCHDOG && 8xx 402 depends on WATCHDOG && 8xx
357 403
404config MV64X60_WDT
405 tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
406 depends on WATCHDOG && MV64X60
407
358config BOOKE_WDT 408config BOOKE_WDT
359 tristate "PowerPC Book-E Watchdog Timer" 409 tristate "PowerPC Book-E Watchdog Timer"
360 depends on WATCHDOG && (BOOKE || 4xx) 410 depends on WATCHDOG && (BOOKE || 4xx)
@@ -362,6 +412,17 @@ config BOOKE_WDT
362 Please see Documentation/watchdog/watchdog-api.txt for 412 Please see Documentation/watchdog/watchdog-api.txt for
363 more information. 413 more information.
364 414
415# PPC64 Architecture
416
417config WATCHDOG_RTAS
418 tristate "RTAS watchdog"
419 depends on WATCHDOG && PPC_RTAS
420 help
421 This driver adds watchdog support for the RTAS watchdog.
422
423 To compile this driver as a module, choose M here. The module
424 will be called wdrtas.
425
365# MIPS Architecture 426# MIPS Architecture
366 427
367config INDYDOG 428config INDYDOG
@@ -430,16 +491,6 @@ config WATCHDOG_RIO
430 machines. The watchdog timeout period is normally one minute but 491 machines. The watchdog timeout period is normally one minute but
431 can be changed with a boot-time parameter. 492 can be changed with a boot-time parameter.
432 493
433# ppc64 RTAS watchdog
434config WATCHDOG_RTAS
435 tristate "RTAS watchdog"
436 depends on WATCHDOG && PPC_RTAS
437 help
438 This driver adds watchdog support for the RTAS watchdog.
439
440 To compile this driver as a module, choose M here. The module
441 will be called wdrtas.
442
443# 494#
444# ISA-based Watchdog Cards 495# ISA-based Watchdog Cards
445# 496#
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index bc6f5fe88c8c..cfd0a3987710 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -39,22 +39,27 @@ obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
39obj-$(CONFIG_SC520_WDT) += sc520_wdt.o 39obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
40obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o 40obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
41obj-$(CONFIG_IB700_WDT) += ib700wdt.o 41obj-$(CONFIG_IB700_WDT) += ib700wdt.o
42obj-$(CONFIG_IBMASR) += ibmasr.o
42obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o 43obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
44obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
43obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o 45obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o
44obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o 46obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
45obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o 47obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
46obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o 48obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
49obj-$(CONFIG_SBC8360_WDT) += sbc8360.o
47obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o 50obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
48obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o 51obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
49obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o 52obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
53obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
50obj-$(CONFIG_MACHZ_WDT) += machzwd.o 54obj-$(CONFIG_MACHZ_WDT) += machzwd.o
51 55
52# PowerPC Architecture 56# PowerPC Architecture
53obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o 57obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
58obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
59obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
54 60
55# PPC64 Architecture 61# PPC64 Architecture
56obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o 62obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
57obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
58 63
59# MIPS Architecture 64# MIPS Architecture
60obj-$(CONFIG_INDYDOG) += indydog.o 65obj-$(CONFIG_INDYDOG) += indydog.o
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c
new file mode 100644
index 000000000000..93785f13242e
--- /dev/null
+++ b/drivers/char/watchdog/i6300esb.c
@@ -0,0 +1,527 @@
1/*
2 * i6300esb: Watchdog timer driver for Intel 6300ESB chipset
3 *
4 * (c) Copyright 2004 Google Inc.
5 * (c) Copyright 2005 David Härdeman <david@2gen.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * based on i810-tco.c which is in turn based on softdog.c
13 *
14 * The timer is implemented in the following I/O controller hubs:
15 * (See the intel documentation on http://developer.intel.com.)
16 * 6300ESB chip : document number 300641-003
17 *
18 * 2004YYZZ Ross Biro
19 * Initial version 0.01
20 * 2004YYZZ Ross Biro
21 * Version 0.02
22 * 20050210 David Härdeman <david@2gen.com>
23 * Ported driver to kernel 2.6
24 */
25
26/*
27 * Includes, defines, variables, module parameters, ...
28 */
29
30#include <linux/module.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/fs.h>
34#include <linux/mm.h>
35#include <linux/miscdevice.h>
36#include <linux/watchdog.h>
37#include <linux/reboot.h>
38#include <linux/init.h>
39#include <linux/pci.h>
40#include <linux/ioport.h>
41
42#include <asm/uaccess.h>
43#include <asm/io.h>
44
45/* Module and version information */
46#define ESB_VERSION "0.03"
47#define ESB_MODULE_NAME "i6300ESB timer"
48#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
49#define PFX ESB_MODULE_NAME ": "
50
51/* PCI configuration registers */
52#define ESB_CONFIG_REG 0x60 /* Config register */
53#define ESB_LOCK_REG 0x68 /* WDT lock register */
54
55/* Memory mapped registers */
56#define ESB_TIMER1_REG BASEADDR + 0x00 /* Timer1 value after each reset */
57#define ESB_TIMER2_REG BASEADDR + 0x04 /* Timer2 value after each reset */
58#define ESB_GINTSR_REG BASEADDR + 0x08 /* General Interrupt Status Register */
59#define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */
60
61/* Lock register bits */
62#define ESB_WDT_FUNC ( 0x01 << 2 ) /* Watchdog functionality */
63#define ESB_WDT_ENABLE ( 0x01 << 1 ) /* Enable WDT */
64#define ESB_WDT_LOCK ( 0x01 << 0 ) /* Lock (nowayout) */
65
66/* Config register bits */
67#define ESB_WDT_REBOOT ( 0x01 << 5 ) /* Enable reboot on timeout */
68#define ESB_WDT_FREQ ( 0x01 << 2 ) /* Decrement frequency */
69#define ESB_WDT_INTTYPE ( 0x11 << 0 ) /* Interrupt type on timer1 timeout */
70
71/* Reload register bits */
72#define ESB_WDT_RELOAD ( 0x01 << 8 ) /* prevent timeout */
73
74/* Magic constants */
75#define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */
76#define ESB_UNLOCK2 0x86 /* Step 2 to unlock reset registers */
77
78/* internal variables */
79static void __iomem *BASEADDR;
80static spinlock_t esb_lock; /* Guards the hardware */
81static unsigned long timer_alive;
82static struct pci_dev *esb_pci;
83static unsigned short triggered; /* The status of the watchdog upon boot */
84static char esb_expect_close;
85
86/* module parameters */
87#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat (1<heartbeat<2*1023) */
88static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
89module_param(heartbeat, int, 0);
90MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
91
92static int nowayout = WATCHDOG_NOWAYOUT;
93module_param(nowayout, int, 0);
94MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
95
96/*
97 * Some i6300ESB specific functions
98 */
99
100/*
101 * Prepare for reloading the timer by unlocking the proper registers.
102 * This is performed by first writing 0x80 followed by 0x86 to the
103 * reload register. After this the appropriate registers can be written
104 * to once before they need to be unlocked again.
105 */
106static inline void esb_unlock_registers(void) {
107 writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
108 writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
109}
110
111static void esb_timer_start(void)
112{
113 u8 val;
114
115 /* Enable or Enable + Lock? */
116 val = 0x02 | (nowayout ? 0x01 : 0x00);
117
118 pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
119}
120
121static int esb_timer_stop(void)
122{
123 u8 val;
124
125 spin_lock(&esb_lock);
126 /* First, reset timers as suggested by the docs */
127 esb_unlock_registers();
128 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
129 /* Then disable the WDT */
130 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x0);
131 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val);
132 spin_unlock(&esb_lock);
133
134 /* Returns 0 if the timer was disabled, non-zero otherwise */
135 return (val & 0x01);
136}
137
138static void esb_timer_keepalive(void)
139{
140 spin_lock(&esb_lock);
141 esb_unlock_registers();
142 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
143 /* FIXME: Do we need to flush anything here? */
144 spin_unlock(&esb_lock);
145}
146
147static int esb_timer_set_heartbeat(int time)
148{
149 u32 val;
150
151 if (time < 0x1 || time > (2 * 0x03ff))
152 return -EINVAL;
153
154 spin_lock(&esb_lock);
155
156 /* We shift by 9, so if we are passed a value of 1 sec,
157 * val will be 1 << 9 = 512, then write that to two
158 * timers => 2 * 512 = 1024 (which is decremented at 1KHz)
159 */
160 val = time << 9;
161
162 /* Write timer 1 */
163 esb_unlock_registers();
164 writel(val, ESB_TIMER1_REG);
165
166 /* Write timer 2 */
167 esb_unlock_registers();
168 writel(val, ESB_TIMER2_REG);
169
170 /* Reload */
171 esb_unlock_registers();
172 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
173
174 /* FIXME: Do we need to flush everything out? */
175
176 /* Done */
177 heartbeat = time;
178 spin_unlock(&esb_lock);
179 return 0;
180}
181
182static int esb_timer_read (void)
183{
184 u32 count;
185
186 /* This isn't documented, and doesn't take into
187 * acount which stage is running, but it looks
188 * like a 20 bit count down, so we might as well report it.
189 */
190 pci_read_config_dword(esb_pci, 0x64, &count);
191 return (int)count;
192}
193
194/*
195 * /dev/watchdog handling
196 */
197
198static int esb_open (struct inode *inode, struct file *file)
199{
200 /* /dev/watchdog can only be opened once */
201 if (test_and_set_bit(0, &timer_alive))
202 return -EBUSY;
203
204 /* Reload and activate timer */
205 esb_timer_keepalive ();
206 esb_timer_start ();
207
208 return nonseekable_open(inode, file);
209}
210
211static int esb_release (struct inode *inode, struct file *file)
212{
213 /* Shut off the timer. */
214 if (esb_expect_close == 42) {
215 esb_timer_stop ();
216 } else {
217 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
218 esb_timer_keepalive ();
219 }
220 clear_bit(0, &timer_alive);
221 esb_expect_close = 0;
222 return 0;
223}
224
225static ssize_t esb_write (struct file *file, const char __user *data,
226 size_t len, loff_t * ppos)
227{
228 /* See if we got the magic character 'V' and reload the timer */
229 if (len) {
230 if (!nowayout) {
231 size_t i;
232
233 /* note: just in case someone wrote the magic character
234 * five months ago... */
235 esb_expect_close = 0;
236
237 /* scan to see whether or not we got the magic character */
238 for (i = 0; i != len; i++) {
239 char c;
240 if(get_user(c, data+i))
241 return -EFAULT;
242 if (c == 'V')
243 esb_expect_close = 42;
244 }
245 }
246
247 /* someone wrote to us, we should reload the timer */
248 esb_timer_keepalive ();
249 }
250 return len;
251}
252
253static int esb_ioctl (struct inode *inode, struct file *file,
254 unsigned int cmd, unsigned long arg)
255{
256 int new_options, retval = -EINVAL;
257 int new_heartbeat;
258 void __user *argp = (void __user *)arg;
259 int __user *p = argp;
260 static struct watchdog_info ident = {
261 .options = WDIOF_SETTIMEOUT |
262 WDIOF_KEEPALIVEPING |
263 WDIOF_MAGICCLOSE,
264 .firmware_version = 0,
265 .identity = ESB_MODULE_NAME,
266 };
267
268 switch (cmd) {
269 case WDIOC_GETSUPPORT:
270 return copy_to_user(argp, &ident,
271 sizeof (ident)) ? -EFAULT : 0;
272
273 case WDIOC_GETSTATUS:
274 return put_user (esb_timer_read(), p);
275
276 case WDIOC_GETBOOTSTATUS:
277 return put_user (triggered, p);
278
279 case WDIOC_KEEPALIVE:
280 esb_timer_keepalive ();
281 return 0;
282
283 case WDIOC_SETOPTIONS:
284 {
285 if (get_user (new_options, p))
286 return -EFAULT;
287
288 if (new_options & WDIOS_DISABLECARD) {
289 esb_timer_stop ();
290 retval = 0;
291 }
292
293 if (new_options & WDIOS_ENABLECARD) {
294 esb_timer_keepalive ();
295 esb_timer_start ();
296 retval = 0;
297 }
298
299 return retval;
300 }
301
302 case WDIOC_SETTIMEOUT:
303 {
304 if (get_user(new_heartbeat, p))
305 return -EFAULT;
306
307 if (esb_timer_set_heartbeat(new_heartbeat))
308 return -EINVAL;
309
310 esb_timer_keepalive ();
311 /* Fall */
312 }
313
314 case WDIOC_GETTIMEOUT:
315 return put_user(heartbeat, p);
316
317 default:
318 return -ENOIOCTLCMD;
319 }
320}
321
322/*
323 * Notify system
324 */
325
326static int esb_notify_sys (struct notifier_block *this, unsigned long code, void *unused)
327{
328 if (code==SYS_DOWN || code==SYS_HALT) {
329 /* Turn the WDT off */
330 esb_timer_stop ();
331 }
332
333 return NOTIFY_DONE;
334}
335
336/*
337 * Kernel Interfaces
338 */
339
340static struct file_operations esb_fops = {
341 .owner = THIS_MODULE,
342 .llseek = no_llseek,
343 .write = esb_write,
344 .ioctl = esb_ioctl,
345 .open = esb_open,
346 .release = esb_release,
347};
348
349static struct miscdevice esb_miscdev = {
350 .minor = WATCHDOG_MINOR,
351 .name = "watchdog",
352 .fops = &esb_fops,
353};
354
355static struct notifier_block esb_notifier = {
356 .notifier_call = esb_notify_sys,
357};
358
359/*
360 * Data for PCI driver interface
361 *
362 * This data only exists for exporting the supported
363 * PCI ids via MODULE_DEVICE_TABLE. We do not actually
364 * register a pci_driver, because someone else might one day
365 * want to register another driver on the same PCI id.
366 */
367static struct pci_device_id esb_pci_tbl[] = {
368 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
369 { 0, }, /* End of list */
370};
371MODULE_DEVICE_TABLE (pci, esb_pci_tbl);
372
373/*
374 * Init & exit routines
375 */
376
377static unsigned char __init esb_getdevice (void)
378{
379 u8 val1;
380 unsigned short val2;
381
382 struct pci_dev *dev = NULL;
383 /*
384 * Find the PCI device
385 */
386
387 for_each_pci_dev(dev) {
388 if (pci_match_id(esb_pci_tbl, dev)) {
389 esb_pci = dev;
390 break;
391 }
392 }
393
394 if (esb_pci) {
395 if (pci_enable_device(esb_pci)) {
396 printk (KERN_ERR PFX "failed to enable device\n");
397 goto err_devput;
398 }
399
400 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
401 printk (KERN_ERR PFX "failed to request region\n");
402 goto err_disable;
403 }
404
405 BASEADDR = ioremap(pci_resource_start(esb_pci, 0),
406 pci_resource_len(esb_pci, 0));
407 if (BASEADDR == NULL) {
408 /* Something's wrong here, BASEADDR has to be set */
409 printk (KERN_ERR PFX "failed to get BASEADDR\n");
410 goto err_release;
411 }
412
413 /*
414 * The watchdog has two timers, it can be setup so that the
415 * expiry of timer1 results in an interrupt and the expiry of
416 * timer2 results in a reboot. We set it to not generate
417 * any interrupts as there is not much we can do with it
418 * right now.
419 *
420 * We also enable reboots and set the timer frequency to
421 * the PCI clock divided by 2^15 (approx 1KHz).
422 */
423 pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
424
425 /* Check that the WDT isn't already locked */
426 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
427 if (val1 & ESB_WDT_LOCK)
428 printk (KERN_WARNING PFX "nowayout already set\n");
429
430 /* Set the timer to watchdog mode and disable it for now */
431 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
432
433 /* Check if the watchdog was previously triggered */
434 esb_unlock_registers();
435 val2 = readw(ESB_RELOAD_REG);
436 triggered = (val2 & (0x01 << 9) >> 9);
437
438 /* Reset trigger flag and timers */
439 esb_unlock_registers();
440 writew((0x11 << 8), ESB_RELOAD_REG);
441
442 /* Done */
443 return 1;
444
445err_release:
446 pci_release_region(esb_pci, 0);
447err_disable:
448 pci_disable_device(esb_pci);
449err_devput:
450 pci_dev_put(esb_pci);
451 }
452 return 0;
453}
454
455static int __init watchdog_init (void)
456{
457 int ret;
458
459 spin_lock_init(&esb_lock);
460
461 /* Check whether or not the hardware watchdog is there */
462 if (!esb_getdevice () || esb_pci == NULL)
463 return -ENODEV;
464
465 /* Check that the heartbeat value is within it's range ; if not reset to the default */
466 if (esb_timer_set_heartbeat (heartbeat)) {
467 esb_timer_set_heartbeat (WATCHDOG_HEARTBEAT);
468 printk(KERN_INFO PFX "heartbeat value must be 1<heartbeat<2046, using %d\n",
469 heartbeat);
470 }
471
472 ret = register_reboot_notifier(&esb_notifier);
473 if (ret != 0) {
474 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
475 ret);
476 goto err_unmap;
477 }
478
479 ret = misc_register(&esb_miscdev);
480 if (ret != 0) {
481 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
482 WATCHDOG_MINOR, ret);
483 goto err_notifier;
484 }
485
486 esb_timer_stop ();
487
488 printk (KERN_INFO PFX "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
489 BASEADDR, heartbeat, nowayout);
490
491 return 0;
492
493err_notifier:
494 unregister_reboot_notifier(&esb_notifier);
495err_unmap:
496 iounmap(BASEADDR);
497/* err_release: */
498 pci_release_region(esb_pci, 0);
499/* err_disable: */
500 pci_disable_device(esb_pci);
501/* err_devput: */
502 pci_dev_put(esb_pci);
503 return ret;
504}
505
506static void __exit watchdog_cleanup (void)
507{
508 /* Stop the timer before we leave */
509 if (!nowayout)
510 esb_timer_stop ();
511
512 /* Deregister */
513 misc_deregister(&esb_miscdev);
514 unregister_reboot_notifier(&esb_notifier);
515 iounmap(BASEADDR);
516 pci_release_region(esb_pci, 0);
517 pci_disable_device(esb_pci);
518 pci_dev_put(esb_pci);
519}
520
521module_init(watchdog_init);
522module_exit(watchdog_cleanup);
523
524MODULE_AUTHOR("Ross Biro and David Härdeman");
525MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
526MODULE_LICENSE("GPL");
527MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c
new file mode 100644
index 000000000000..294c474ae485
--- /dev/null
+++ b/drivers/char/watchdog/ibmasr.c
@@ -0,0 +1,405 @@
1/*
2 * IBM Automatic Server Restart driver.
3 *
4 * Copyright (c) 2005 Andrey Panin <pazke@donpac.ru>
5 *
6 * Based on driver written by Pete Reynolds.
7 * Copyright (c) IBM Corporation, 1998-2004.
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU Public License, incorporated herein by reference.
11 */
12
13#include <linux/config.h>
14#include <linux/fs.h>
15#include <linux/kernel.h>
16#include <linux/slab.h>
17#include <linux/module.h>
18#include <linux/pci.h>
19#include <linux/timer.h>
20#include <linux/miscdevice.h>
21#include <linux/watchdog.h>
22#include <linux/dmi.h>
23
24#include <asm/io.h>
25#include <asm/uaccess.h>
26
27
28enum {
29 ASMTYPE_UNKNOWN,
30 ASMTYPE_TOPAZ,
31 ASMTYPE_JASPER,
32 ASMTYPE_PEARL,
33 ASMTYPE_JUNIPER,
34 ASMTYPE_SPRUCE,
35};
36
37#define PFX "ibmasr: "
38
39#define TOPAZ_ASR_REG_OFFSET 4
40#define TOPAZ_ASR_TOGGLE 0x40
41#define TOPAZ_ASR_DISABLE 0x80
42
43/* PEARL ASR S/W REGISTER SUPERIO PORT ADDRESSES */
44#define PEARL_BASE 0xe04
45#define PEARL_WRITE 0xe06
46#define PEARL_READ 0xe07
47
48#define PEARL_ASR_DISABLE_MASK 0x80 /* bit 7: disable = 1, enable = 0 */
49#define PEARL_ASR_TOGGLE_MASK 0x40 /* bit 6: 0, then 1, then 0 */
50
51/* JASPER OFFSET FROM SIO BASE ADDR TO ASR S/W REGISTERS. */
52#define JASPER_ASR_REG_OFFSET 0x38
53
54#define JASPER_ASR_DISABLE_MASK 0x01 /* bit 0: disable = 1, enable = 0 */
55#define JASPER_ASR_TOGGLE_MASK 0x02 /* bit 1: 0, then 1, then 0 */
56
57#define JUNIPER_BASE_ADDRESS 0x54b /* Base address of Juniper ASR */
58#define JUNIPER_ASR_DISABLE_MASK 0x01 /* bit 0: disable = 1 enable = 0 */
59#define JUNIPER_ASR_TOGGLE_MASK 0x02 /* bit 1: 0, then 1, then 0 */
60
61#define SPRUCE_BASE_ADDRESS 0x118e /* Base address of Spruce ASR */
62#define SPRUCE_ASR_DISABLE_MASK 0x01 /* bit 1: disable = 1 enable = 0 */
63#define SPRUCE_ASR_TOGGLE_MASK 0x02 /* bit 0: 0, then 1, then 0 */
64
65
66static int nowayout = WATCHDOG_NOWAYOUT;
67
68static unsigned long asr_is_open;
69static char asr_expect_close;
70
71static unsigned int asr_type, asr_base, asr_length;
72static unsigned int asr_read_addr, asr_write_addr;
73static unsigned char asr_toggle_mask, asr_disable_mask;
74
75static void asr_toggle(void)
76{
77 unsigned char reg = inb(asr_read_addr);
78
79 outb(reg & ~asr_toggle_mask, asr_write_addr);
80 reg = inb(asr_read_addr);
81
82 outb(reg | asr_toggle_mask, asr_write_addr);
83 reg = inb(asr_read_addr);
84
85 outb(reg & ~asr_toggle_mask, asr_write_addr);
86 reg = inb(asr_read_addr);
87}
88
89static void asr_enable(void)
90{
91 unsigned char reg;
92
93 if (asr_type == ASMTYPE_TOPAZ) {
94 /* asr_write_addr == asr_read_addr */
95 reg = inb(asr_read_addr);
96 outb(reg & ~(TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE),
97 asr_read_addr);
98 } else {
99 /*
100 * First make sure the hardware timer is reset by toggling
101 * ASR hardware timer line.
102 */
103 asr_toggle();
104
105 reg = inb(asr_read_addr);
106 outb(reg & ~asr_disable_mask, asr_write_addr);
107 }
108 reg = inb(asr_read_addr);
109}
110
111static void asr_disable(void)
112{
113 unsigned char reg = inb(asr_read_addr);
114
115 if (asr_type == ASMTYPE_TOPAZ)
116 /* asr_write_addr == asr_read_addr */
117 outb(reg | TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE,
118 asr_read_addr);
119 else {
120 outb(reg | asr_toggle_mask, asr_write_addr);
121 reg = inb(asr_read_addr);
122
123 outb(reg | asr_disable_mask, asr_write_addr);
124 }
125 reg = inb(asr_read_addr);
126}
127
128static int __init asr_get_base_address(void)
129{
130 unsigned char low, high;
131 const char *type = "";
132
133 asr_length = 1;
134
135 switch (asr_type) {
136 case ASMTYPE_TOPAZ:
137 /* SELECT SuperIO CHIP FOR QUERYING (WRITE 0x07 TO BOTH 0x2E and 0x2F) */
138 outb(0x07, 0x2e);
139 outb(0x07, 0x2f);
140
141 /* SELECT AND READ THE HIGH-NIBBLE OF THE GPIO BASE ADDRESS */
142 outb(0x60, 0x2e);
143 high = inb(0x2f);
144
145 /* SELECT AND READ THE LOW-NIBBLE OF THE GPIO BASE ADDRESS */
146 outb(0x61, 0x2e);
147 low = inb(0x2f);
148
149 asr_base = (high << 16) | low;
150 asr_read_addr = asr_write_addr =
151 asr_base + TOPAZ_ASR_REG_OFFSET;
152 asr_length = 5;
153
154 break;
155
156 case ASMTYPE_JASPER:
157 type = "Jaspers ";
158
159 /* FIXME: need to use pci_config_lock here, but it's not exported */
160
161/* spin_lock_irqsave(&pci_config_lock, flags);*/
162
163 /* Select the SuperIO chip in the PCI I/O port register */
164 outl(0x8000f858, 0xcf8);
165
166 /*
167 * Read the base address for the SuperIO chip.
168 * Only the lower 16 bits are valid, but the address is word
169 * aligned so the last bit must be masked off.
170 */
171 asr_base = inl(0xcfc) & 0xfffe;
172
173/* spin_unlock_irqrestore(&pci_config_lock, flags);*/
174
175 asr_read_addr = asr_write_addr =
176 asr_base + JASPER_ASR_REG_OFFSET;
177 asr_toggle_mask = JASPER_ASR_TOGGLE_MASK;
178 asr_disable_mask = JASPER_ASR_DISABLE_MASK;
179 asr_length = JASPER_ASR_REG_OFFSET + 1;
180
181 break;
182
183 case ASMTYPE_PEARL:
184 type = "Pearls ";
185 asr_base = PEARL_BASE;
186 asr_read_addr = PEARL_READ;
187 asr_write_addr = PEARL_WRITE;
188 asr_toggle_mask = PEARL_ASR_TOGGLE_MASK;
189 asr_disable_mask = PEARL_ASR_DISABLE_MASK;
190 asr_length = 4;
191 break;
192
193 case ASMTYPE_JUNIPER:
194 type = "Junipers ";
195 asr_base = JUNIPER_BASE_ADDRESS;
196 asr_read_addr = asr_write_addr = asr_base;
197 asr_toggle_mask = JUNIPER_ASR_TOGGLE_MASK;
198 asr_disable_mask = JUNIPER_ASR_DISABLE_MASK;
199 break;
200
201 case ASMTYPE_SPRUCE:
202 type = "Spruce's ";
203 asr_base = SPRUCE_BASE_ADDRESS;
204 asr_read_addr = asr_write_addr = asr_base;
205 asr_toggle_mask = SPRUCE_ASR_TOGGLE_MASK;
206 asr_disable_mask = SPRUCE_ASR_DISABLE_MASK;
207 break;
208 }
209
210 if (!request_region(asr_base, asr_length, "ibmasr")) {
211 printk(KERN_ERR PFX "address %#x already in use\n",
212 asr_base);
213 return -EBUSY;
214 }
215
216 printk(KERN_INFO PFX "found %sASR @ addr %#x\n", type, asr_base);
217
218 return 0;
219}
220
221
222static ssize_t asr_write(struct file *file, const char __user *buf,
223 size_t count, loff_t *ppos)
224{
225 if (count) {
226 if (!nowayout) {
227 size_t i;
228
229 /* In case it was set long ago */
230 asr_expect_close = 0;
231
232 for (i = 0; i != count; i++) {
233 char c;
234 if (get_user(c, buf + i))
235 return -EFAULT;
236 if (c == 'V')
237 asr_expect_close = 42;
238 }
239 }
240 asr_toggle();
241 }
242 return count;
243}
244
245static int asr_ioctl(struct inode *inode, struct file *file,
246 unsigned int cmd, unsigned long arg)
247{
248 static const struct watchdog_info ident = {
249 .options = WDIOF_KEEPALIVEPING |
250 WDIOF_MAGICCLOSE,
251 .identity = "IBM ASR"
252 };
253 void __user *argp = (void __user *)arg;
254 int __user *p = argp;
255 int heartbeat;
256
257 switch (cmd) {
258 case WDIOC_GETSUPPORT:
259 return copy_to_user(argp, &ident, sizeof(ident)) ?
260 -EFAULT : 0;
261
262 case WDIOC_GETSTATUS:
263 case WDIOC_GETBOOTSTATUS:
264 return put_user(0, p);
265
266 case WDIOC_KEEPALIVE:
267 asr_toggle();
268 return 0;
269
270 /*
271 * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT
272 * and WDIOC_GETTIMEOUT always returns 256.
273 */
274 case WDIOC_GETTIMEOUT:
275 heartbeat = 256;
276 return put_user(heartbeat, p);
277
278 case WDIOC_SETOPTIONS: {
279 int new_options, retval = -EINVAL;
280
281 if (get_user(new_options, p))
282 return -EFAULT;
283
284 if (new_options & WDIOS_DISABLECARD) {
285 asr_disable();
286 retval = 0;
287 }
288
289 if (new_options & WDIOS_ENABLECARD) {
290 asr_enable();
291 asr_toggle();
292 retval = 0;
293 }
294
295 return retval;
296 }
297 }
298
299 return -ENOIOCTLCMD;
300}
301
302static int asr_open(struct inode *inode, struct file *file)
303{
304 if(test_and_set_bit(0, &asr_is_open))
305 return -EBUSY;
306
307 asr_toggle();
308 asr_enable();
309
310 return nonseekable_open(inode, file);
311}
312
313static int asr_release(struct inode *inode, struct file *file)
314{
315 if (asr_expect_close == 42)
316 asr_disable();
317 else {
318 printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n");
319 asr_toggle();
320 }
321 clear_bit(0, &asr_is_open);
322 asr_expect_close = 0;
323 return 0;
324}
325
326static struct file_operations asr_fops = {
327 .owner = THIS_MODULE,
328 .llseek = no_llseek,
329 .write = asr_write,
330 .ioctl = asr_ioctl,
331 .open = asr_open,
332 .release = asr_release,
333};
334
335static struct miscdevice asr_miscdev = {
336 .minor = WATCHDOG_MINOR,
337 .name = "watchdog",
338 .fops = &asr_fops,
339};
340
341
342struct ibmasr_id {
343 const char *desc;
344 int type;
345};
346
347static struct ibmasr_id __initdata ibmasr_id_table[] = {
348 { "IBM Automatic Server Restart - eserver xSeries 220", ASMTYPE_TOPAZ },
349 { "IBM Automatic Server Restart - Machine Type 8673", ASMTYPE_PEARL },
350 { "IBM Automatic Server Restart - Machine Type 8480", ASMTYPE_JASPER },
351 { "IBM Automatic Server Restart - Machine Type 8482", ASMTYPE_JUNIPER },
352 { "IBM Automatic Server Restart - Machine Type 8648", ASMTYPE_SPRUCE },
353 { NULL }
354};
355
356static int __init ibmasr_init(void)
357{
358 struct ibmasr_id *id;
359 int rc;
360
361 for (id = ibmasr_id_table; id->desc; id++) {
362 if (dmi_find_device(DMI_DEV_TYPE_OTHER, id->desc, NULL)) {
363 asr_type = id->type;
364 break;
365 }
366 }
367
368 if (!asr_type)
369 return -ENODEV;
370
371 rc = misc_register(&asr_miscdev);
372 if (rc < 0) {
373 printk(KERN_ERR PFX "failed to register misc device\n");
374 return rc;
375 }
376
377 rc = asr_get_base_address();
378 if (rc) {
379 misc_deregister(&asr_miscdev);
380 return rc;
381 }
382
383 return 0;
384}
385
386static void __exit ibmasr_exit(void)
387{
388 if (!nowayout)
389 asr_disable();
390
391 misc_deregister(&asr_miscdev);
392
393 release_region(asr_base, asr_length);
394}
395
396module_init(ibmasr_init);
397module_exit(ibmasr_exit);
398
399module_param(nowayout, int, 0);
400MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
401
402MODULE_DESCRIPTION("IBM Automatic Server Restart driver");
403MODULE_AUTHOR("Andrey Panin");
404MODULE_LICENSE("GPL");
405MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index c694eee1fb24..75ca84ed4adf 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -30,6 +30,8 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/device.h> 32#include <linux/device.h>
33
34#include <asm/hardware/arm_twd.h>
33#include <asm/uaccess.h> 35#include <asm/uaccess.h>
34 36
35struct mpcore_wdt { 37struct mpcore_wdt {
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
new file mode 100644
index 000000000000..6d3ff0836c44
--- /dev/null
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -0,0 +1,252 @@
1/*
2 * mv64x60_wdt.c - MV64X60 (Marvell Discovery) watchdog userspace interface
3 *
4 * Author: James Chapman <jchapman@katalix.com>
5 *
6 * Platform-specific setup code should configure the dog to generate
7 * interrupt or reset as required. This code only enables/disables
8 * and services the watchdog.
9 *
10 * Derived from mpc8xx_wdt.c, with the following copyright.
11 *
12 * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
13 * the terms of the GNU General Public License version 2. This program
14 * is licensed "as is" without any warranty of any kind, whether express
15 * or implied.
16 */
17
18#include <linux/config.h>
19#include <linux/fs.h>
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/miscdevice.h>
23#include <linux/module.h>
24#include <linux/watchdog.h>
25#include <asm/mv64x60.h>
26#include <asm/uaccess.h>
27#include <asm/io.h>
28
29/* MV64x60 WDC (config) register access definitions */
30#define MV64x60_WDC_CTL1_MASK (3 << 24)
31#define MV64x60_WDC_CTL1(val) ((val & 3) << 24)
32#define MV64x60_WDC_CTL2_MASK (3 << 26)
33#define MV64x60_WDC_CTL2(val) ((val & 3) << 26)
34
35/* Flags bits */
36#define MV64x60_WDOG_FLAG_OPENED 0
37#define MV64x60_WDOG_FLAG_ENABLED 1
38
39static unsigned long wdt_flags;
40static int wdt_status;
41static void __iomem *mv64x60_regs;
42static int mv64x60_wdt_timeout;
43
44static void mv64x60_wdt_reg_write(u32 val)
45{
46 /* Allow write only to CTL1 / CTL2 fields, retaining values in
47 * other fields.
48 */
49 u32 data = readl(mv64x60_regs + MV64x60_WDT_WDC);
50 data &= ~(MV64x60_WDC_CTL1_MASK | MV64x60_WDC_CTL2_MASK);
51 data |= val;
52 writel(data, mv64x60_regs + MV64x60_WDT_WDC);
53}
54
55static void mv64x60_wdt_service(void)
56{
57 /* Write 01 followed by 10 to CTL2 */
58 mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x01));
59 mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x02));
60}
61
62static void mv64x60_wdt_handler_disable(void)
63{
64 if (test_and_clear_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
65 /* Write 01 followed by 10 to CTL1 */
66 mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
67 mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
68 printk(KERN_NOTICE "mv64x60_wdt: watchdog deactivated\n");
69 }
70}
71
72static void mv64x60_wdt_handler_enable(void)
73{
74 if (!test_and_set_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
75 /* Write 01 followed by 10 to CTL1 */
76 mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
77 mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
78 printk(KERN_NOTICE "mv64x60_wdt: watchdog activated\n");
79 }
80}
81
82static int mv64x60_wdt_open(struct inode *inode, struct file *file)
83{
84 if (test_and_set_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags))
85 return -EBUSY;
86
87 mv64x60_wdt_service();
88 mv64x60_wdt_handler_enable();
89
90 nonseekable_open(inode, file);
91
92 return 0;
93}
94
95static int mv64x60_wdt_release(struct inode *inode, struct file *file)
96{
97 mv64x60_wdt_service();
98
99#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
100 mv64x60_wdt_handler_disable();
101#endif
102
103 clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags);
104
105 return 0;
106}
107
108static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
109 size_t len, loff_t * ppos)
110{
111 if (len)
112 mv64x60_wdt_service();
113
114 return len;
115}
116
117static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
118 unsigned int cmd, unsigned long arg)
119{
120 int timeout;
121 void __user *argp = (void __user *)arg;
122 static struct watchdog_info info = {
123 .options = WDIOF_KEEPALIVEPING,
124 .firmware_version = 0,
125 .identity = "MV64x60 watchdog",
126 };
127
128 switch (cmd) {
129 case WDIOC_GETSUPPORT:
130 if (copy_to_user(argp, &info, sizeof(info)))
131 return -EFAULT;
132 break;
133
134 case WDIOC_GETSTATUS:
135 case WDIOC_GETBOOTSTATUS:
136 if (put_user(wdt_status, (int __user *)argp))
137 return -EFAULT;
138 wdt_status &= ~WDIOF_KEEPALIVEPING;
139 break;
140
141 case WDIOC_GETTEMP:
142 return -EOPNOTSUPP;
143
144 case WDIOC_SETOPTIONS:
145 return -EOPNOTSUPP;
146
147 case WDIOC_KEEPALIVE:
148 mv64x60_wdt_service();
149 wdt_status |= WDIOF_KEEPALIVEPING;
150 break;
151
152 case WDIOC_SETTIMEOUT:
153 return -EOPNOTSUPP;
154
155 case WDIOC_GETTIMEOUT:
156 timeout = mv64x60_wdt_timeout * HZ;
157 if (put_user(timeout, (int __user *)argp))
158 return -EFAULT;
159 break;
160
161 default:
162 return -ENOIOCTLCMD;
163 }
164
165 return 0;
166}
167
168static struct file_operations mv64x60_wdt_fops = {
169 .owner = THIS_MODULE,
170 .llseek = no_llseek,
171 .write = mv64x60_wdt_write,
172 .ioctl = mv64x60_wdt_ioctl,
173 .open = mv64x60_wdt_open,
174 .release = mv64x60_wdt_release,
175};
176
177static struct miscdevice mv64x60_wdt_miscdev = {
178 .minor = WATCHDOG_MINOR,
179 .name = "watchdog",
180 .fops = &mv64x60_wdt_fops,
181};
182
183static int __devinit mv64x60_wdt_probe(struct device *dev)
184{
185 struct platform_device *pd = to_platform_device(dev);
186 struct mv64x60_wdt_pdata *pdata = pd->dev.platform_data;
187 int bus_clk = 133;
188
189 mv64x60_wdt_timeout = 10;
190 if (pdata) {
191 mv64x60_wdt_timeout = pdata->timeout;
192 bus_clk = pdata->bus_clk;
193 }
194
195 mv64x60_regs = mv64x60_get_bridge_vbase();
196
197 writel((mv64x60_wdt_timeout * (bus_clk * 1000000)) >> 8,
198 mv64x60_regs + MV64x60_WDT_WDC);
199
200 return misc_register(&mv64x60_wdt_miscdev);
201}
202
203static int __devexit mv64x60_wdt_remove(struct device *dev)
204{
205 misc_deregister(&mv64x60_wdt_miscdev);
206
207 mv64x60_wdt_service();
208 mv64x60_wdt_handler_disable();
209
210 return 0;
211}
212
213static struct device_driver mv64x60_wdt_driver = {
214 .name = MV64x60_WDT_NAME,
215 .bus = &platform_bus_type,
216 .probe = mv64x60_wdt_probe,
217 .remove = __devexit_p(mv64x60_wdt_remove),
218};
219
220static struct platform_device *mv64x60_wdt_dev;
221
222static int __init mv64x60_wdt_init(void)
223{
224 int ret;
225
226 printk(KERN_INFO "MV64x60 watchdog driver\n");
227
228 mv64x60_wdt_dev = platform_device_register_simple(MV64x60_WDT_NAME,
229 -1, NULL, 0);
230 if (IS_ERR(mv64x60_wdt_dev)) {
231 ret = PTR_ERR(mv64x60_wdt_dev);
232 goto out;
233 }
234
235 ret = driver_register(&mv64x60_wdt_driver);
236 out:
237 return ret;
238}
239
240static void __exit mv64x60_wdt_exit(void)
241{
242 driver_unregister(&mv64x60_wdt_driver);
243 platform_device_unregister(mv64x60_wdt_dev);
244}
245
246module_init(mv64x60_wdt_init);
247module_exit(mv64x60_wdt_exit);
248
249MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
250MODULE_DESCRIPTION("MV64x60 watchdog driver");
251MODULE_LICENSE("GPL");
252MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index 2b13afb09c5d..5a80adbf8032 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -29,27 +29,29 @@
29 * Includes, defines, variables, module parameters, ... 29 * Includes, defines, variables, module parameters, ...
30 */ 30 */
31 31
32#include <linux/config.h> 32#include <linux/config.h> /* For CONFIG_WATCHDOG_NOWAYOUT/... */
33#include <linux/module.h> 33#include <linux/module.h> /* For module specific items */
34#include <linux/moduleparam.h> 34#include <linux/moduleparam.h> /* For new moduleparam's */
35#include <linux/types.h> 35#include <linux/types.h> /* For standard types (like size_t) */
36#include <linux/delay.h> 36#include <linux/errno.h> /* For the -ENODEV/... values */
37#include <linux/miscdevice.h> 37#include <linux/kernel.h> /* For printk/panic/... */
38#include <linux/watchdog.h> 38#include <linux/delay.h> /* For mdelay function */
39#include <linux/notifier.h> 39#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
40#include <linux/reboot.h> 40#include <linux/watchdog.h> /* For the watchdog specific items */
41#include <linux/init.h> 41#include <linux/notifier.h> /* For notifier support */
42#include <linux/fs.h> 42#include <linux/reboot.h> /* For reboot_notifier stuff */
43#include <linux/pci.h> 43#include <linux/init.h> /* For __init/__exit/... */
44#include <linux/ioport.h> 44#include <linux/fs.h> /* For file operations */
45#include <linux/spinlock.h> 45#include <linux/pci.h> /* For pci functions */
46 46#include <linux/ioport.h> /* For io-port access */
47#include <asm/uaccess.h> 47#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
48#include <asm/io.h> 48
49#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
50#include <asm/io.h> /* For inb/outb/... */
49 51
50/* Module and version information */ 52/* Module and version information */
51#define WATCHDOG_VERSION "1.01" 53#define WATCHDOG_VERSION "1.01"
52#define WATCHDOG_DATE "15 Mar 2005" 54#define WATCHDOG_DATE "02 Sep 2005"
53#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" 55#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
54#define WATCHDOG_NAME "pcwd_pci" 56#define WATCHDOG_NAME "pcwd_pci"
55#define PFX WATCHDOG_NAME ": " 57#define PFX WATCHDOG_NAME ": "
@@ -335,12 +337,14 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
335 return -EFAULT; 337 return -EFAULT;
336 338
337 if (new_options & WDIOS_DISABLECARD) { 339 if (new_options & WDIOS_DISABLECARD) {
338 pcipcwd_stop(); 340 if (pcipcwd_stop())
341 return -EIO;
339 retval = 0; 342 retval = 0;
340 } 343 }
341 344
342 if (new_options & WDIOS_ENABLECARD) { 345 if (new_options & WDIOS_ENABLECARD) {
343 pcipcwd_start(); 346 if (pcipcwd_start())
347 return -EIO;
344 retval = 0; 348 retval = 0;
345 } 349 }
346 350
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 8b292bf343c4..3625b2601b42 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -464,7 +464,7 @@ static void s3c2410wdt_shutdown(struct device *dev)
464static unsigned long wtcon_save; 464static unsigned long wtcon_save;
465static unsigned long wtdat_save; 465static unsigned long wtdat_save;
466 466
467static int s3c2410wdt_suspend(struct device *dev, u32 state, u32 level) 467static int s3c2410wdt_suspend(struct device *dev, pm_message_t state, u32 level)
468{ 468{
469 if (level == SUSPEND_POWER_DOWN) { 469 if (level == SUSPEND_POWER_DOWN) {
470 /* Save watchdog state, and turn it off. */ 470 /* Save watchdog state, and turn it off. */
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c
new file mode 100644
index 000000000000..c6cbf808d8c2
--- /dev/null
+++ b/drivers/char/watchdog/sbc8360.c
@@ -0,0 +1,414 @@
1/*
2 * SBC8360 Watchdog driver
3 *
4 * (c) Copyright 2005 Webcon, Inc.
5 *
6 * Based on ib700wdt.c, which is based on advantechwdt.c which is based
7 * on acquirewdt.c which is based on wdt.c.
8 *
9 * (c) Copyright 2001 Charles Howes <chowes@vsol.net>
10 *
11 * Based on advantechwdt.c which is based on acquirewdt.c which
12 * is based on wdt.c.
13 *
14 * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
15 *
16 * Based on acquirewdt.c which is based on wdt.c.
17 * Original copyright messages:
18 *
19 * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
20 * http://www.redhat.com
21 *
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version
25 * 2 of the License, or (at your option) any later version.
26 *
27 * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
28 * warranty for any of this software. This material is provided
29 * "AS-IS" and at no charge.
30 *
31 * (c) Copyright 1995 Alan Cox <alan@redhat.com>
32 *
33 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
34 * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
35 * Added timeout module option to override default
36 *
37 */
38
39#include <linux/config.h>
40#include <linux/module.h>
41#include <linux/types.h>
42#include <linux/miscdevice.h>
43#include <linux/watchdog.h>
44#include <linux/ioport.h>
45#include <linux/delay.h>
46#include <linux/notifier.h>
47#include <linux/fs.h>
48#include <linux/reboot.h>
49#include <linux/init.h>
50#include <linux/spinlock.h>
51#include <linux/moduleparam.h>
52
53#include <asm/io.h>
54#include <asm/uaccess.h>
55#include <asm/system.h>
56
57static unsigned long sbc8360_is_open;
58static spinlock_t sbc8360_lock;
59static char expect_close;
60
61#define PFX "sbc8360: "
62
63/*
64 *
65 * Watchdog Timer Configuration
66 *
67 * The function of the watchdog timer is to reset the system automatically
68 * and is defined at I/O port 0120H and 0121H. To enable the watchdog timer
69 * and allow the system to reset, write appropriate values from the table
70 * below to I/O port 0120H and 0121H. To disable the timer, write a zero
71 * value to I/O port 0121H for the system to stop the watchdog function.
72 *
73 * The following describes how the timer should be programmed (according to
74 * the vendor documentation)
75 *
76 * Enabling Watchdog:
77 * MOV AX,000AH (enable, phase I)
78 * MOV DX,0120H
79 * OUT DX,AX
80 * MOV AX,000BH (enable, phase II)
81 * MOV DX,0120H
82 * OUT DX,AX
83 * MOV AX,000nH (set multiplier n, from 1-4)
84 * MOV DX,0120H
85 * OUT DX,AX
86 * MOV AX,000mH (set base timer m, from 0-F)
87 * MOV DX,0121H
88 * OUT DX,AX
89 *
90 * Reset timer:
91 * MOV AX,000mH (same as set base timer, above)
92 * MOV DX,0121H
93 * OUT DX,AX
94 *
95 * Disabling Watchdog:
96 * MOV AX,0000H (a zero value)
97 * MOV DX,0120H
98 * OUT DX,AX
99 *
100 * Watchdog timeout configuration values:
101 * N
102 * M | 1 2 3 4
103 * --|----------------------------------
104 * 0 | 0.5s 5s 50s 100s
105 * 1 | 1s 10s 100s 200s
106 * 2 | 1.5s 15s 150s 300s
107 * 3 | 2s 20s 200s 400s
108 * 4 | 2.5s 25s 250s 500s
109 * 5 | 3s 30s 300s 600s
110 * 6 | 3.5s 35s 350s 700s
111 * 7 | 4s 40s 400s 800s
112 * 8 | 4.5s 45s 450s 900s
113 * 9 | 5s 50s 500s 1000s
114 * A | 5.5s 55s 550s 1100s
115 * B | 6s 60s 600s 1200s
116 * C | 6.5s 65s 650s 1300s
117 * D | 7s 70s 700s 1400s
118 * E | 7.5s 75s 750s 1500s
119 * F | 8s 80s 800s 1600s
120 *
121 * Another way to say the same things is:
122 * For N=1, Timeout = (M+1) * 0.5s
123 * For N=2, Timeout = (M+1) * 5s
124 * For N=3, Timeout = (M+1) * 50s
125 * For N=4, Timeout = (M+1) * 100s
126 *
127 */
128
129static int wd_times[64][2] = {
130 {0, 1}, /* 0 = 0.5s */
131 {1, 1}, /* 1 = 1s */
132 {2, 1}, /* 2 = 1.5s */
133 {3, 1}, /* 3 = 2s */
134 {4, 1}, /* 4 = 2.5s */
135 {5, 1}, /* 5 = 3s */
136 {6, 1}, /* 6 = 3.5s */
137 {7, 1}, /* 7 = 4s */
138 {8, 1}, /* 8 = 4.5s */
139 {9, 1}, /* 9 = 5s */
140 {0xA, 1}, /* 10 = 5.5s */
141 {0xB, 1}, /* 11 = 6s */
142 {0xC, 1}, /* 12 = 6.5s */
143 {0xD, 1}, /* 13 = 7s */
144 {0xE, 1}, /* 14 = 7.5s */
145 {0xF, 1}, /* 15 = 8s */
146 {0, 2}, /* 16 = 5s */
147 {1, 2}, /* 17 = 10s */
148 {2, 2}, /* 18 = 15s */
149 {3, 2}, /* 19 = 20s */
150 {4, 2}, /* 20 = 25s */
151 {5, 2}, /* 21 = 30s */
152 {6, 2}, /* 22 = 35s */
153 {7, 2}, /* 23 = 40s */
154 {8, 2}, /* 24 = 45s */
155 {9, 2}, /* 25 = 50s */
156 {0xA, 2}, /* 26 = 55s */
157 {0xB, 2}, /* 27 = 60s */
158 {0xC, 2}, /* 28 = 65s */
159 {0xD, 2}, /* 29 = 70s */
160 {0xE, 2}, /* 30 = 75s */
161 {0xF, 2}, /* 31 = 80s */
162 {0, 3}, /* 32 = 50s */
163 {1, 3}, /* 33 = 100s */
164 {2, 3}, /* 34 = 150s */
165 {3, 3}, /* 35 = 200s */
166 {4, 3}, /* 36 = 250s */
167 {5, 3}, /* 37 = 300s */
168 {6, 3}, /* 38 = 350s */
169 {7, 3}, /* 39 = 400s */
170 {8, 3}, /* 40 = 450s */
171 {9, 3}, /* 41 = 500s */
172 {0xA, 3}, /* 42 = 550s */
173 {0xB, 3}, /* 43 = 600s */
174 {0xC, 3}, /* 44 = 650s */
175 {0xD, 3}, /* 45 = 700s */
176 {0xE, 3}, /* 46 = 750s */
177 {0xF, 3}, /* 47 = 800s */
178 {0, 4}, /* 48 = 100s */
179 {1, 4}, /* 49 = 200s */
180 {2, 4}, /* 50 = 300s */
181 {3, 4}, /* 51 = 400s */
182 {4, 4}, /* 52 = 500s */
183 {5, 4}, /* 53 = 600s */
184 {6, 4}, /* 54 = 700s */
185 {7, 4}, /* 55 = 800s */
186 {8, 4}, /* 56 = 900s */
187 {9, 4}, /* 57 = 1000s */
188 {0xA, 4}, /* 58 = 1100s */
189 {0xB, 4}, /* 59 = 1200s */
190 {0xC, 4}, /* 60 = 1300s */
191 {0xD, 4}, /* 61 = 1400s */
192 {0xE, 4}, /* 62 = 1500s */
193 {0xF, 4} /* 63 = 1600s */
194};
195
196#define SBC8360_ENABLE 0x120
197#define SBC8360_BASETIME 0x121
198
199static int timeout = 27;
200static int wd_margin = 0xB;
201static int wd_multiplier = 2;
202static int nowayout = WATCHDOG_NOWAYOUT;
203
204module_param(timeout, int, 27);
205MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))");
206module_param(nowayout, int, 0);
207MODULE_PARM_DESC(nowayout,
208 "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
209
210/*
211 * Kernel methods.
212 */
213
214/* Activate and pre-configure watchdog */
215static void sbc8360_activate(void)
216{
217 /* Enable the watchdog */
218 outb(0x0A, SBC8360_ENABLE);
219 msleep_interruptible(100);
220 outb(0x0B, SBC8360_ENABLE);
221 msleep_interruptible(100);
222 /* Set timeout multiplier */
223 outb(wd_multiplier, SBC8360_ENABLE);
224 msleep_interruptible(100);
225 /* Nothing happens until first sbc8360_ping() */
226}
227
228/* Kernel pings watchdog */
229static void sbc8360_ping(void)
230{
231 /* Write the base timer register */
232 outb(wd_margin, SBC8360_BASETIME);
233}
234
235/* Userspace pings kernel driver, or requests clean close */
236static ssize_t sbc8360_write(struct file *file, const char __user * buf,
237 size_t count, loff_t * ppos)
238{
239 if (count) {
240 if (!nowayout) {
241 size_t i;
242
243 /* In case it was set long ago */
244 expect_close = 0;
245
246 for (i = 0; i != count; i++) {
247 char c;
248 if (get_user(c, buf + i))
249 return -EFAULT;
250 if (c == 'V')
251 expect_close = 42;
252 }
253 }
254 sbc8360_ping();
255 }
256 return count;
257}
258
259static int sbc8360_open(struct inode *inode, struct file *file)
260{
261 spin_lock(&sbc8360_lock);
262 if (test_and_set_bit(0, &sbc8360_is_open)) {
263 spin_unlock(&sbc8360_lock);
264 return -EBUSY;
265 }
266 if (nowayout)
267 __module_get(THIS_MODULE);
268
269 /* Activate and ping once to start the countdown */
270 spin_unlock(&sbc8360_lock);
271 sbc8360_activate();
272 sbc8360_ping();
273 return nonseekable_open(inode, file);
274}
275
276static int sbc8360_close(struct inode *inode, struct file *file)
277{
278 spin_lock(&sbc8360_lock);
279 if (expect_close == 42)
280 outb(0, SBC8360_ENABLE);
281 else
282 printk(KERN_CRIT PFX
283 "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n");
284
285 clear_bit(0, &sbc8360_is_open);
286 expect_close = 0;
287 spin_unlock(&sbc8360_lock);
288 return 0;
289}
290
291/*
292 * Notifier for system down
293 */
294
295static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code,
296 void *unused)
297{
298 if (code == SYS_DOWN || code == SYS_HALT) {
299 /* Disable the SBC8360 Watchdog */
300 outb(0, SBC8360_ENABLE);
301 }
302 return NOTIFY_DONE;
303}
304
305/*
306 * Kernel Interfaces
307 */
308
309static struct file_operations sbc8360_fops = {
310 .owner = THIS_MODULE,
311 .llseek = no_llseek,
312 .write = sbc8360_write,
313 .open = sbc8360_open,
314 .release = sbc8360_close,
315};
316
317static struct miscdevice sbc8360_miscdev = {
318 .minor = WATCHDOG_MINOR,
319 .name = "watchdog",
320 .fops = &sbc8360_fops,
321};
322
323/*
324 * The SBC8360 needs to learn about soft shutdowns in order to
325 * turn the timebomb registers off.
326 */
327
328static struct notifier_block sbc8360_notifier = {
329 .notifier_call = sbc8360_notify_sys,
330};
331
332static int __init sbc8360_init(void)
333{
334 int res;
335 unsigned long int mseconds = 60000;
336
337 spin_lock_init(&sbc8360_lock);
338 res = misc_register(&sbc8360_miscdev);
339 if (res) {
340 printk(KERN_ERR PFX "failed to register misc device\n");
341 goto out_nomisc;
342 }
343
344 if (!request_region(SBC8360_ENABLE, 1, "SBC8360")) {
345 printk(KERN_ERR PFX "ENABLE method I/O %X is not available.\n",
346 SBC8360_ENABLE);
347 res = -EIO;
348 goto out_noenablereg;
349 }
350 if (!request_region(SBC8360_BASETIME, 1, "SBC8360")) {
351 printk(KERN_ERR PFX
352 "BASETIME method I/O %X is not available.\n",
353 SBC8360_BASETIME);
354 res = -EIO;
355 goto out_nobasetimereg;
356 }
357
358 res = register_reboot_notifier(&sbc8360_notifier);
359 if (res) {
360 printk(KERN_ERR PFX "Failed to register reboot notifier.\n");
361 goto out_noreboot;
362 }
363
364 if (timeout < 0 || timeout > 63) {
365 printk(KERN_ERR PFX "Invalid timeout index (must be 0-63).\n");
366 res = -EINVAL;
367 goto out_noreboot;
368 }
369
370 wd_margin = wd_times[timeout][0];
371 wd_multiplier = wd_times[timeout][1];
372
373 if (wd_multiplier == 1)
374 mseconds = (wd_margin + 1) * 500;
375 else if (wd_multiplier == 2)
376 mseconds = (wd_margin + 1) * 5000;
377 else if (wd_multiplier == 3)
378 mseconds = (wd_margin + 1) * 50000;
379 else if (wd_multiplier == 4)
380 mseconds = (wd_margin + 1) * 100000;
381
382 /* My kingdom for the ability to print "0.5 seconds" in the kernel! */
383 printk(KERN_INFO PFX "Timeout set at %ld ms.\n", mseconds);
384
385 return 0;
386
387 out_noreboot:
388 release_region(SBC8360_ENABLE, 1);
389 release_region(SBC8360_BASETIME, 1);
390 out_noenablereg:
391 out_nobasetimereg:
392 misc_deregister(&sbc8360_miscdev);
393 out_nomisc:
394 return res;
395}
396
397static void __exit sbc8360_exit(void)
398{
399 misc_deregister(&sbc8360_miscdev);
400 unregister_reboot_notifier(&sbc8360_notifier);
401 release_region(SBC8360_ENABLE, 1);
402 release_region(SBC8360_BASETIME, 1);
403}
404
405module_init(sbc8360_init);
406module_exit(sbc8360_exit);
407
408MODULE_AUTHOR("Ian E. Morgan <imorgan@webcon.ca>");
409MODULE_DESCRIPTION("SBC8360 watchdog driver");
410MODULE_LICENSE("GPL");
411MODULE_VERSION("1.0");
412MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
413
414/* end of sbc8360.c */
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c
new file mode 100644
index 000000000000..a7ff64c8921f
--- /dev/null
+++ b/drivers/char/watchdog/w83977f_wdt.c
@@ -0,0 +1,543 @@
1/*
2 * W83977F Watchdog Timer Driver for Winbond W83977F I/O Chip
3 *
4 * (c) Copyright 2005 Jose Goncalves <jose.goncalves@inov.pt>
5 *
6 * Based on w83877f_wdt.c by Scott Jennings,
7 * and wdt977.c by Woody Suwalski
8 *
9 * -----------------------
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/config.h>
21#include <linux/types.h>
22#include <linux/kernel.h>
23#include <linux/fs.h>
24#include <linux/miscdevice.h>
25#include <linux/init.h>
26#include <linux/ioport.h>
27#include <linux/watchdog.h>
28#include <linux/notifier.h>
29#include <linux/reboot.h>
30
31#include <asm/io.h>
32#include <asm/system.h>
33#include <asm/uaccess.h>
34
35#define WATCHDOG_VERSION "1.00"
36#define WATCHDOG_NAME "W83977F WDT"
37#define PFX WATCHDOG_NAME ": "
38#define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n"
39
40#define IO_INDEX_PORT 0x3F0
41#define IO_DATA_PORT (IO_INDEX_PORT+1)
42
43#define UNLOCK_DATA 0x87
44#define LOCK_DATA 0xAA
45#define DEVICE_REGISTER 0x07
46
47#define DEFAULT_TIMEOUT 45 /* default timeout in seconds */
48
49static int timeout = DEFAULT_TIMEOUT;
50static int timeoutW; /* timeout in watchdog counter units */
51static unsigned long timer_alive;
52static int testmode;
53static char expect_close;
54static spinlock_t spinlock;
55
56module_param(timeout, int, 0);
57MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (15..7635), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")");
58module_param(testmode, int, 0);
59MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
60
61static int nowayout = WATCHDOG_NOWAYOUT;
62module_param(nowayout, int, 0);
63MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
64
65/*
66 * Start the watchdog
67 */
68
69static int wdt_start(void)
70{
71 unsigned long flags;
72
73 spin_lock_irqsave(&spinlock, flags);
74
75 /* Unlock the SuperIO chip */
76 outb_p(UNLOCK_DATA,IO_INDEX_PORT);
77 outb_p(UNLOCK_DATA,IO_INDEX_PORT);
78
79 /*
80 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
81 * F2 has the timeout in watchdog counter units.
82 * F3 is set to enable watchdog LED blink at timeout.
83 * F4 is used to just clear the TIMEOUT'ed state (bit 0).
84 */
85 outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
86 outb_p(0x08,IO_DATA_PORT);
87 outb_p(0xF2,IO_INDEX_PORT);
88 outb_p(timeoutW,IO_DATA_PORT);
89 outb_p(0xF3,IO_INDEX_PORT);
90 outb_p(0x08,IO_DATA_PORT);
91 outb_p(0xF4,IO_INDEX_PORT);
92 outb_p(0x00,IO_DATA_PORT);
93
94 /* Set device Aux2 active */
95 outb_p(0x30,IO_INDEX_PORT);
96 outb_p(0x01,IO_DATA_PORT);
97
98 /*
99 * Select device Aux1 (dev=7) to set GP16 as the watchdog output
100 * (in reg E6) and GP13 as the watchdog LED output (in reg E3).
101 * Map GP16 at pin 119.
102 * In test mode watch the bit 0 on F4 to indicate "triggered" or
103 * check watchdog LED on SBC.
104 */
105 outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
106 outb_p(0x07,IO_DATA_PORT);
107 if (!testmode)
108 {
109 unsigned pin_map;
110
111 outb_p(0xE6,IO_INDEX_PORT);
112 outb_p(0x0A,IO_DATA_PORT);
113 outb_p(0x2C,IO_INDEX_PORT);
114 pin_map = inb_p(IO_DATA_PORT);
115 pin_map |= 0x10;
116 pin_map &= ~(0x20);
117 outb_p(0x2C,IO_INDEX_PORT);
118 outb_p(pin_map,IO_DATA_PORT);
119 }
120 outb_p(0xE3,IO_INDEX_PORT);
121 outb_p(0x08,IO_DATA_PORT);
122
123 /* Set device Aux1 active */
124 outb_p(0x30,IO_INDEX_PORT);
125 outb_p(0x01,IO_DATA_PORT);
126
127 /* Lock the SuperIO chip */
128 outb_p(LOCK_DATA,IO_INDEX_PORT);
129
130 spin_unlock_irqrestore(&spinlock, flags);
131
132 printk(KERN_INFO PFX "activated.\n");
133
134 return 0;
135}
136
137/*
138 * Stop the watchdog
139 */
140
141static int wdt_stop(void)
142{
143 unsigned long flags;
144
145 spin_lock_irqsave(&spinlock, flags);
146
147 /* Unlock the SuperIO chip */
148 outb_p(UNLOCK_DATA,IO_INDEX_PORT);
149 outb_p(UNLOCK_DATA,IO_INDEX_PORT);
150
151 /*
152 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
153 * F2 is reset to its default value (watchdog timer disabled).
154 * F3 is reset to its default state.
155 * F4 clears the TIMEOUT'ed state (bit 0) - back to default.
156 */
157 outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
158 outb_p(0x08,IO_DATA_PORT);
159 outb_p(0xF2,IO_INDEX_PORT);
160 outb_p(0xFF,IO_DATA_PORT);
161 outb_p(0xF3,IO_INDEX_PORT);
162 outb_p(0x00,IO_DATA_PORT);
163 outb_p(0xF4,IO_INDEX_PORT);
164 outb_p(0x00,IO_DATA_PORT);
165 outb_p(0xF2,IO_INDEX_PORT);
166 outb_p(0x00,IO_DATA_PORT);
167
168 /*
169 * Select device Aux1 (dev=7) to set GP16 (in reg E6) and
170 * Gp13 (in reg E3) as inputs.
171 */
172 outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
173 outb_p(0x07,IO_DATA_PORT);
174 if (!testmode)
175 {
176 outb_p(0xE6,IO_INDEX_PORT);
177 outb_p(0x01,IO_DATA_PORT);
178 }
179 outb_p(0xE3,IO_INDEX_PORT);
180 outb_p(0x01,IO_DATA_PORT);
181
182 /* Lock the SuperIO chip */
183 outb_p(LOCK_DATA,IO_INDEX_PORT);
184
185 spin_unlock_irqrestore(&spinlock, flags);
186
187 printk(KERN_INFO PFX "shutdown.\n");
188
189 return 0;
190}
191
192/*
193 * Send a keepalive ping to the watchdog
194 * This is done by simply re-writing the timeout to reg. 0xF2
195 */
196
197static int wdt_keepalive(void)
198{
199 unsigned long flags;
200
201 spin_lock_irqsave(&spinlock, flags);
202
203 /* Unlock the SuperIO chip */
204 outb_p(UNLOCK_DATA,IO_INDEX_PORT);
205 outb_p(UNLOCK_DATA,IO_INDEX_PORT);
206
207 /* Select device Aux2 (device=8) to kick watchdog reg F2 */
208 outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
209 outb_p(0x08,IO_DATA_PORT);
210 outb_p(0xF2,IO_INDEX_PORT);
211 outb_p(timeoutW,IO_DATA_PORT);
212
213 /* Lock the SuperIO chip */
214 outb_p(LOCK_DATA,IO_INDEX_PORT);
215
216 spin_unlock_irqrestore(&spinlock, flags);
217
218 return 0;
219}
220
221/*
222 * Set the watchdog timeout value
223 */
224
225static int wdt_set_timeout(int t)
226{
227 int tmrval;
228
229 /*
230 * Convert seconds to watchdog counter time units, rounding up.
231 * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup
232 * value. This information is supplied in the PCM-5335 manual and was
233 * checked by me on a real board. This is a bit strange because W83977f
234 * datasheet says counter unit is in minutes!
235 */
236 if (t < 15)
237 return -EINVAL;
238
239 tmrval = ((t + 15) + 29) / 30;
240
241 if (tmrval > 255)
242 return -EINVAL;
243
244 /*
245 * timeout is the timeout in seconds,
246 * timeoutW is the timeout in watchdog counter units.
247 */
248 timeoutW = tmrval;
249 timeout = (timeoutW * 30) - 15;
250 return 0;
251}
252
253/*
254 * Get the watchdog status
255 */
256
257static int wdt_get_status(int *status)
258{
259 int new_status;
260 unsigned long flags;
261
262 spin_lock_irqsave(&spinlock, flags);
263
264 /* Unlock the SuperIO chip */
265 outb_p(UNLOCK_DATA,IO_INDEX_PORT);
266 outb_p(UNLOCK_DATA,IO_INDEX_PORT);
267
268 /* Select device Aux2 (device=8) to read watchdog reg F4 */
269 outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
270 outb_p(0x08,IO_DATA_PORT);
271 outb_p(0xF4,IO_INDEX_PORT);
272 new_status = inb_p(IO_DATA_PORT);
273
274 /* Lock the SuperIO chip */
275 outb_p(LOCK_DATA,IO_INDEX_PORT);
276
277 spin_unlock_irqrestore(&spinlock, flags);
278
279 *status = 0;
280 if (new_status & 1)
281 *status |= WDIOF_CARDRESET;
282
283 return 0;
284}
285
286
287/*
288 * /dev/watchdog handling
289 */
290
291static int wdt_open(struct inode *inode, struct file *file)
292{
293 /* If the watchdog is alive we don't need to start it again */
294 if( test_and_set_bit(0, &timer_alive) )
295 return -EBUSY;
296
297 if (nowayout)
298 __module_get(THIS_MODULE);
299
300 wdt_start();
301 return nonseekable_open(inode, file);
302}
303
304static int wdt_release(struct inode *inode, struct file *file)
305{
306 /*
307 * Shut off the timer.
308 * Lock it in if it's a module and we set nowayout
309 */
310 if (expect_close == 42)
311 {
312 wdt_stop();
313 clear_bit(0, &timer_alive);
314 } else {
315 wdt_keepalive();
316 printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n");
317 }
318 expect_close = 0;
319 return 0;
320}
321
322/*
323 * wdt_write:
324 * @file: file handle to the watchdog
325 * @buf: buffer to write (unused as data does not matter here
326 * @count: count of bytes
327 * @ppos: pointer to the position to write. No seeks allowed
328 *
329 * A write to a watchdog device is defined as a keepalive signal. Any
330 * write of data will do, as we we don't define content meaning.
331 */
332
333static ssize_t wdt_write(struct file *file, const char __user *buf,
334 size_t count, loff_t *ppos)
335{
336 /* See if we got the magic character 'V' and reload the timer */
337 if(count)
338 {
339 if (!nowayout)
340 {
341 size_t ofs;
342
343 /* note: just in case someone wrote the magic character long ago */
344 expect_close = 0;
345
346 /* scan to see whether or not we got the magic character */
347 for(ofs = 0; ofs != count; ofs++)
348 {
349 char c;
350 if (get_user(c, buf + ofs))
351 return -EFAULT;
352 if (c == 'V') {
353 expect_close = 42;
354 }
355 }
356 }
357
358 /* someone wrote to us, we should restart timer */
359 wdt_keepalive();
360 }
361 return count;
362}
363
364/*
365 * wdt_ioctl:
366 * @inode: inode of the device
367 * @file: file handle to the device
368 * @cmd: watchdog command
369 * @arg: argument pointer
370 *
371 * The watchdog API defines a common set of functions for all watchdogs
372 * according to their available features.
373 */
374
375static struct watchdog_info ident = {
376 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
377 .firmware_version = 1,
378 .identity = WATCHDOG_NAME,
379};
380
381static int wdt_ioctl(struct inode *inode, struct file *file,
382 unsigned int cmd, unsigned long arg)
383{
384 int status;
385 int new_options, retval = -EINVAL;
386 int new_timeout;
387 union {
388 struct watchdog_info __user *ident;
389 int __user *i;
390 } uarg;
391
392 uarg.i = (int __user *)arg;
393
394 switch(cmd)
395 {
396 default:
397 return -ENOIOCTLCMD;
398
399 case WDIOC_GETSUPPORT:
400 return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0;
401
402 case WDIOC_GETSTATUS:
403 wdt_get_status(&status);
404 return put_user(status, uarg.i);
405
406 case WDIOC_GETBOOTSTATUS:
407 return put_user(0, uarg.i);
408
409 case WDIOC_KEEPALIVE:
410 wdt_keepalive();
411 return 0;
412
413 case WDIOC_SETOPTIONS:
414 if (get_user (new_options, uarg.i))
415 return -EFAULT;
416
417 if (new_options & WDIOS_DISABLECARD) {
418 wdt_stop();
419 retval = 0;
420 }
421
422 if (new_options & WDIOS_ENABLECARD) {
423 wdt_start();
424 retval = 0;
425 }
426
427 return retval;
428
429 case WDIOC_SETTIMEOUT:
430 if (get_user(new_timeout, uarg.i))
431 return -EFAULT;
432
433 if (wdt_set_timeout(new_timeout))
434 return -EINVAL;
435
436 wdt_keepalive();
437 /* Fall */
438
439 case WDIOC_GETTIMEOUT:
440 return put_user(timeout, uarg.i);
441
442 }
443}
444
445static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
446 void *unused)
447{
448 if (code==SYS_DOWN || code==SYS_HALT)
449 wdt_stop();
450 return NOTIFY_DONE;
451}
452
453static struct file_operations wdt_fops=
454{
455 .owner = THIS_MODULE,
456 .llseek = no_llseek,
457 .write = wdt_write,
458 .ioctl = wdt_ioctl,
459 .open = wdt_open,
460 .release = wdt_release,
461};
462
463static struct miscdevice wdt_miscdev=
464{
465 .minor = WATCHDOG_MINOR,
466 .name = "watchdog",
467 .fops = &wdt_fops,
468};
469
470static struct notifier_block wdt_notifier = {
471 .notifier_call = wdt_notify_sys,
472};
473
474static int __init w83977f_wdt_init(void)
475{
476 int rc;
477
478 printk(KERN_INFO PFX DRIVER_VERSION);
479
480 spin_lock_init(&spinlock);
481
482 /*
483 * Check that the timeout value is within it's range ;
484 * if not reset to the default
485 */
486 if (wdt_set_timeout(timeout)) {
487 wdt_set_timeout(DEFAULT_TIMEOUT);
488 printk(KERN_INFO PFX "timeout value must be 15<=timeout<=7635, using %d\n",
489 DEFAULT_TIMEOUT);
490 }
491
492 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME))
493 {
494 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
495 IO_INDEX_PORT);
496 rc = -EIO;
497 goto err_out;
498 }
499
500 rc = misc_register(&wdt_miscdev);
501 if (rc)
502 {
503 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
504 wdt_miscdev.minor, rc);
505 goto err_out_region;
506 }
507
508 rc = register_reboot_notifier(&wdt_notifier);
509 if (rc)
510 {
511 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
512 rc);
513 goto err_out_miscdev;
514 }
515
516 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n",
517 timeout, nowayout, testmode);
518
519 return 0;
520
521err_out_miscdev:
522 misc_deregister(&wdt_miscdev);
523err_out_region:
524 release_region(IO_INDEX_PORT,2);
525err_out:
526 return rc;
527}
528
529static void __exit w83977f_wdt_exit(void)
530{
531 wdt_stop();
532 misc_deregister(&wdt_miscdev);
533 unregister_reboot_notifier(&wdt_notifier);
534 release_region(IO_INDEX_PORT,2);
535}
536
537module_init(w83977f_wdt_init);
538module_exit(w83977f_wdt_exit);
539
540MODULE_AUTHOR("Jose Goncalves <jose.goncalves@inov.pt>");
541MODULE_DESCRIPTION("Driver for watchdog timer in W83977F I/O chip");
542MODULE_LICENSE("GPL");
543MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);