mISDN: Add watchdog functionality to hfcmulti driver
authorAndreas Eversberg <andreas@eversberg.eu>
Fri, 22 May 2009 11:04:44 +0000 (11:04 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 May 2009 07:51:18 +0000 (00:51 -0700)
This patch was made by Titus Moldovan and provides IOCTL functions for enabling
and disabling the controller's built in watchdog. The use is optional.

Signed-off-by: Andreas Eversberg <andreas@eversberg.eu>
Signed-off-by: Karsten Keil <keil@b1-systems.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/isdn/hardware/mISDN/hfc_multi.h
drivers/isdn/hardware/mISDN/hfcmulti.c
include/linux/mISDNif.h

index 663b77f..5765e19 100644 (file)
@@ -62,6 +62,7 @@ struct hfcm_hw {
        u_char  r_sci_msk;
        u_char  r_tx0, r_tx1;
        u_char  a_st_ctrl0[8];
+       u_char  r_bert_wd_md;
        timer_t timer;
 };
 
index 0b28141..ca153de 100644 (file)
@@ -4013,11 +4013,41 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
 static int
 channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
 {
+       struct hfc_multi        *hc = dch->hw;
        int     ret = 0;
+       int     wd_mode, wd_cnt;
 
        switch (cq->op) {
        case MISDN_CTRL_GETOP:
-               cq->op = 0;
+               cq->op = MISDN_CTRL_HFC_OP;
+               break;
+       case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */
+               wd_cnt = cq->p1 & 0xf;
+               wd_mode = !!(cq->p1 >> 4);
+               if (debug & DEBUG_HFCMULTI_MSG)
+                       printk(KERN_DEBUG
+                           "%s: MISDN_CTRL_HFC_WD_INIT mode %s counter 0x%x\n",
+                           __func__, wd_mode ? "AUTO" : "MANUAL", wd_cnt);
+               /* set the watchdog timer */
+               HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4));
+               hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0);
+               if (hc->ctype == HFC_TYPE_XHFC)
+                       hc->hw.r_bert_wd_md |= 0x40 /* V_WD_EN */;
+               /* init the watchdog register and reset the counter */
+               HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
+               if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
+                       /* enable the watchdog output for Speech-Design */
+                       HFC_outb(hc, R_GPIO_SEL, V_GPIO_SEL7);
+                       HFC_outb(hc, R_GPIO_EN1, V_GPIO_EN15);
+                       HFC_outb(hc, R_GPIO_OUT1, 0);
+                       HFC_outb(hc, R_GPIO_OUT1, V_GPIO_OUT15);
+               }
+               break;
+       case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */
+               if (debug & DEBUG_HFCMULTI_MSG)
+                       printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n",
+                           __func__);
+               HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
                break;
        default:
                printk(KERN_WARNING "%s: unknown Op %x\n",
index 5da3d95..cf97459 100644 (file)
@@ -362,7 +362,8 @@ clear_channelmap(u_int nr, u_char *map)
 #define MISDN_CTRL_HFC_RECEIVE_ON      0x4006
 #define MISDN_CTRL_HFC_ECHOCAN_ON      0x4007
 #define MISDN_CTRL_HFC_ECHOCAN_OFF     0x4008
-
+#define MISDN_CTRL_HFC_WD_INIT         0x4009
+#define MISDN_CTRL_HFC_WD_RESET                0x400A
 
 /* socket options */
 #define MISDN_TIME_STAMP               0x0001