Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * HP i8042-based System Device Controller driver.
0003  *
0004  * Copyright (c) 2001 Brian S. Julin
0005  * All rights reserved.
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions, and the following disclaimer,
0012  *    without modification.
0013  * 2. The name of the author may not be used to endorse or promote products
0014  *    derived from this software without specific prior written permission.
0015  *
0016  * Alternatively, this software may be distributed under the terms of the
0017  * GNU General Public License ("GPL").
0018  *
0019  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0020  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0022  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
0023  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0024  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0025  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0026  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0027  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0028  *
0029  * References:
0030  * System Device Controller Microprocessor Firmware Theory of Operation
0031  *      for Part Number 1820-4784 Revision B.  Dwg No. A-1820-4784-2
0032  * Helge Deller's original hilkbd.c port for PA-RISC.
0033  *
0034  *
0035  * Driver theory of operation:
0036  *
0037  * hp_sdc_put does all writing to the SDC.  ISR can run on a different
0038  * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time
0039  * (it cannot really benefit from SMP anyway.)  A tasket fit this perfectly.
0040  *
0041  * All data coming back from the SDC is sent via interrupt and can be read
0042  * fully in the ISR, so there are no latency/throughput problems there.
0043  * The problem is with output, due to the slow clock speed of the SDC
0044  * compared to the CPU.  This should not be too horrible most of the time,
0045  * but if used with HIL devices that support the multibyte transfer command,
0046  * keeping outbound throughput flowing at the 6500KBps that the HIL is
0047  * capable of is more than can be done at HZ=100.
0048  *
0049  * Busy polling for IBF clear wastes CPU cycles and bus cycles.  hp_sdc.ibf
0050  * is set to 0 when the IBF flag in the status register has cleared.  ISR
0051  * may do this, and may also access the parts of queued transactions related
0052  * to reading data back from the SDC, but otherwise will not touch the
0053  * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1.
0054  *
0055  * The i8042 write index and the values in the 4-byte input buffer
0056  * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively,
0057  * to minimize the amount of IO needed to the SDC.  However these values
0058  * do not need to be locked since they are only ever accessed by hp_sdc_put.
0059  *
0060  * A timer task schedules the tasklet once per second just to make
0061  * sure it doesn't freeze up and to allow for bad reads to time out.
0062  */
0063 
0064 #include <linux/hp_sdc.h>
0065 #include <linux/errno.h>
0066 #include <linux/init.h>
0067 #include <linux/module.h>
0068 #include <linux/ioport.h>
0069 #include <linux/time.h>
0070 #include <linux/semaphore.h>
0071 #include <linux/slab.h>
0072 #include <linux/hil.h>
0073 #include <asm/io.h>
0074 
0075 /* Machine-specific abstraction */
0076 
0077 #if defined(__hppa__)
0078 # include <asm/parisc-device.h>
0079 # define sdc_readb(p)       gsc_readb(p)
0080 # define sdc_writeb(v,p)    gsc_writeb((v),(p))
0081 #elif defined(__mc68000__)
0082 #include <linux/uaccess.h>
0083 # define sdc_readb(p)       in_8(p)
0084 # define sdc_writeb(v,p)    out_8((p),(v))
0085 #else
0086 # error "HIL is not supported on this platform"
0087 #endif
0088 
0089 #define PREFIX "HP SDC: "
0090 
0091 MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
0092 MODULE_DESCRIPTION("HP i8042-based SDC Driver");
0093 MODULE_LICENSE("Dual BSD/GPL");
0094 
0095 EXPORT_SYMBOL(hp_sdc_request_timer_irq);
0096 EXPORT_SYMBOL(hp_sdc_request_hil_irq);
0097 EXPORT_SYMBOL(hp_sdc_request_cooked_irq);
0098 
0099 EXPORT_SYMBOL(hp_sdc_release_timer_irq);
0100 EXPORT_SYMBOL(hp_sdc_release_hil_irq);
0101 EXPORT_SYMBOL(hp_sdc_release_cooked_irq);
0102 
0103 EXPORT_SYMBOL(__hp_sdc_enqueue_transaction);
0104 EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
0105 EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
0106 
0107 static bool hp_sdc_disabled;
0108 module_param_named(no_hpsdc, hp_sdc_disabled, bool, 0);
0109 MODULE_PARM_DESC(no_hpsdc, "Do not enable HP SDC driver.");
0110 
0111 static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */
0112 
0113 /*************** primitives for use in any context *********************/
0114 static inline uint8_t hp_sdc_status_in8(void)
0115 {
0116     uint8_t status;
0117     unsigned long flags;
0118 
0119     write_lock_irqsave(&hp_sdc.ibf_lock, flags);
0120     status = sdc_readb(hp_sdc.status_io);
0121     if (!(status & HP_SDC_STATUS_IBF))
0122         hp_sdc.ibf = 0;
0123     write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
0124 
0125     return status;
0126 }
0127 
0128 static inline uint8_t hp_sdc_data_in8(void)
0129 {
0130     return sdc_readb(hp_sdc.data_io);
0131 }
0132 
0133 static inline void hp_sdc_status_out8(uint8_t val)
0134 {
0135     unsigned long flags;
0136 
0137     write_lock_irqsave(&hp_sdc.ibf_lock, flags);
0138     hp_sdc.ibf = 1;
0139     if ((val & 0xf0) == 0xe0)
0140         hp_sdc.wi = 0xff;
0141     sdc_writeb(val, hp_sdc.status_io);
0142     write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
0143 }
0144 
0145 static inline void hp_sdc_data_out8(uint8_t val)
0146 {
0147     unsigned long flags;
0148 
0149     write_lock_irqsave(&hp_sdc.ibf_lock, flags);
0150     hp_sdc.ibf = 1;
0151     sdc_writeb(val, hp_sdc.data_io);
0152     write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
0153 }
0154 
0155 /*  Care must be taken to only invoke hp_sdc_spin_ibf when
0156  *  absolutely needed, or in rarely invoked subroutines.
0157  *  Not only does it waste CPU cycles, it also wastes bus cycles.
0158  */
0159 static inline void hp_sdc_spin_ibf(void)
0160 {
0161     unsigned long flags;
0162     rwlock_t *lock;
0163 
0164     lock = &hp_sdc.ibf_lock;
0165 
0166     read_lock_irqsave(lock, flags);
0167     if (!hp_sdc.ibf) {
0168         read_unlock_irqrestore(lock, flags);
0169         return;
0170     }
0171     read_unlock(lock);
0172     write_lock(lock);
0173     while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF)
0174         { }
0175     hp_sdc.ibf = 0;
0176     write_unlock_irqrestore(lock, flags);
0177 }
0178 
0179 
0180 /************************ Interrupt context functions ************************/
0181 static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data)
0182 {
0183     hp_sdc_transaction *curr;
0184 
0185     read_lock(&hp_sdc.rtq_lock);
0186     if (hp_sdc.rcurr < 0) {
0187         read_unlock(&hp_sdc.rtq_lock);
0188         return;
0189     }
0190     curr = hp_sdc.tq[hp_sdc.rcurr];
0191     read_unlock(&hp_sdc.rtq_lock);
0192 
0193     curr->seq[curr->idx++] = status;
0194     curr->seq[curr->idx++] = data;
0195     hp_sdc.rqty -= 2;
0196     hp_sdc.rtime = ktime_get();
0197 
0198     if (hp_sdc.rqty <= 0) {
0199         /* All data has been gathered. */
0200         if (curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE)
0201             if (curr->act.semaphore)
0202                 up(curr->act.semaphore);
0203 
0204         if (curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK)
0205             if (curr->act.irqhook)
0206                 curr->act.irqhook(irq, dev_id, status, data);
0207 
0208         curr->actidx = curr->idx;
0209         curr->idx++;
0210         /* Return control of this transaction */
0211         write_lock(&hp_sdc.rtq_lock);
0212         hp_sdc.rcurr = -1;
0213         hp_sdc.rqty = 0;
0214         write_unlock(&hp_sdc.rtq_lock);
0215         tasklet_schedule(&hp_sdc.task);
0216     }
0217 }
0218 
0219 static irqreturn_t hp_sdc_isr(int irq, void *dev_id)
0220 {
0221     uint8_t status, data;
0222 
0223     status = hp_sdc_status_in8();
0224     /* Read data unconditionally to advance i8042. */
0225     data =   hp_sdc_data_in8();
0226 
0227     /* For now we are ignoring these until we get the SDC to behave. */
0228     if (((status & 0xf1) == 0x51) && data == 0x82)
0229         return IRQ_HANDLED;
0230 
0231     switch (status & HP_SDC_STATUS_IRQMASK) {
0232     case 0: /* This case is not documented. */
0233         break;
0234 
0235     case HP_SDC_STATUS_USERTIMER:
0236     case HP_SDC_STATUS_PERIODIC:
0237     case HP_SDC_STATUS_TIMER:
0238         read_lock(&hp_sdc.hook_lock);
0239         if (hp_sdc.timer != NULL)
0240             hp_sdc.timer(irq, dev_id, status, data);
0241         read_unlock(&hp_sdc.hook_lock);
0242         break;
0243 
0244     case HP_SDC_STATUS_REG:
0245         hp_sdc_take(irq, dev_id, status, data);
0246         break;
0247 
0248     case HP_SDC_STATUS_HILCMD:
0249     case HP_SDC_STATUS_HILDATA:
0250         read_lock(&hp_sdc.hook_lock);
0251         if (hp_sdc.hil != NULL)
0252             hp_sdc.hil(irq, dev_id, status, data);
0253         read_unlock(&hp_sdc.hook_lock);
0254         break;
0255 
0256     case HP_SDC_STATUS_PUP:
0257         read_lock(&hp_sdc.hook_lock);
0258         if (hp_sdc.pup != NULL)
0259             hp_sdc.pup(irq, dev_id, status, data);
0260         else
0261             printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n");
0262         read_unlock(&hp_sdc.hook_lock);
0263         break;
0264 
0265     default:
0266         read_lock(&hp_sdc.hook_lock);
0267         if (hp_sdc.cooked != NULL)
0268             hp_sdc.cooked(irq, dev_id, status, data);
0269         read_unlock(&hp_sdc.hook_lock);
0270         break;
0271     }
0272 
0273     return IRQ_HANDLED;
0274 }
0275 
0276 
0277 static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id)
0278 {
0279     int status;
0280 
0281     status = hp_sdc_status_in8();
0282     printk(KERN_WARNING PREFIX "NMI !\n");
0283 
0284 #if 0
0285     if (status & HP_SDC_NMISTATUS_FHS) {
0286         read_lock(&hp_sdc.hook_lock);
0287         if (hp_sdc.timer != NULL)
0288             hp_sdc.timer(irq, dev_id, status, 0);
0289         read_unlock(&hp_sdc.hook_lock);
0290     } else {
0291         /* TODO: pass this on to the HIL handler, or do SAK here? */
0292         printk(KERN_WARNING PREFIX "HIL NMI\n");
0293     }
0294 #endif
0295 
0296     return IRQ_HANDLED;
0297 }
0298 
0299 
0300 /***************** Kernel (tasklet) context functions ****************/
0301 
0302 unsigned long hp_sdc_put(void);
0303 
0304 static void hp_sdc_tasklet(unsigned long foo)
0305 {
0306     write_lock_irq(&hp_sdc.rtq_lock);
0307 
0308     if (hp_sdc.rcurr >= 0) {
0309         ktime_t now = ktime_get();
0310 
0311         if (ktime_after(now, ktime_add_us(hp_sdc.rtime,
0312                           HP_SDC_MAX_REG_DELAY))) {
0313             hp_sdc_transaction *curr;
0314             uint8_t tmp;
0315 
0316             curr = hp_sdc.tq[hp_sdc.rcurr];
0317             /* If this turns out to be a normal failure mode
0318              * we'll need to figure out a way to communicate
0319              * it back to the application. and be less verbose.
0320              */
0321             printk(KERN_WARNING PREFIX "read timeout (%lldus)!\n",
0322                    ktime_us_delta(now, hp_sdc.rtime));
0323             curr->idx += hp_sdc.rqty;
0324             hp_sdc.rqty = 0;
0325             tmp = curr->seq[curr->actidx];
0326             curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD;
0327             if (tmp & HP_SDC_ACT_SEMAPHORE)
0328                 if (curr->act.semaphore)
0329                     up(curr->act.semaphore);
0330 
0331             if (tmp & HP_SDC_ACT_CALLBACK) {
0332                 /* Note this means that irqhooks may be called
0333                  * in tasklet/bh context.
0334                  */
0335                 if (curr->act.irqhook)
0336                     curr->act.irqhook(0, NULL, 0, 0);
0337             }
0338 
0339             curr->actidx = curr->idx;
0340             curr->idx++;
0341             hp_sdc.rcurr = -1;
0342         }
0343     }
0344     write_unlock_irq(&hp_sdc.rtq_lock);
0345     hp_sdc_put();
0346 }
0347 
0348 unsigned long hp_sdc_put(void)
0349 {
0350     hp_sdc_transaction *curr;
0351     uint8_t act;
0352     int idx, curridx;
0353 
0354     int limit = 0;
0355 
0356     write_lock(&hp_sdc.lock);
0357 
0358     /* If i8042 buffers are full, we cannot do anything that
0359        requires output, so we skip to the administrativa. */
0360     if (hp_sdc.ibf) {
0361         hp_sdc_status_in8();
0362         if (hp_sdc.ibf)
0363             goto finish;
0364     }
0365 
0366  anew:
0367     /* See if we are in the middle of a sequence. */
0368     if (hp_sdc.wcurr < 0)
0369         hp_sdc.wcurr = 0;
0370     read_lock_irq(&hp_sdc.rtq_lock);
0371     if (hp_sdc.rcurr == hp_sdc.wcurr)
0372         hp_sdc.wcurr++;
0373     read_unlock_irq(&hp_sdc.rtq_lock);
0374     if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
0375         hp_sdc.wcurr = 0;
0376     curridx = hp_sdc.wcurr;
0377 
0378     if (hp_sdc.tq[curridx] != NULL)
0379         goto start;
0380 
0381     while (++curridx != hp_sdc.wcurr) {
0382         if (curridx >= HP_SDC_QUEUE_LEN) {
0383             curridx = -1; /* Wrap to top */
0384             continue;
0385         }
0386         read_lock_irq(&hp_sdc.rtq_lock);
0387         if (hp_sdc.rcurr == curridx) {
0388             read_unlock_irq(&hp_sdc.rtq_lock);
0389             continue;
0390         }
0391         read_unlock_irq(&hp_sdc.rtq_lock);
0392         if (hp_sdc.tq[curridx] != NULL)
0393             break; /* Found one. */
0394     }
0395     if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */
0396         curridx = -1;
0397     }
0398     hp_sdc.wcurr = curridx;
0399 
0400  start:
0401 
0402     /* Check to see if the interrupt mask needs to be set. */
0403     if (hp_sdc.set_im) {
0404         hp_sdc_status_out8(hp_sdc.im | HP_SDC_CMD_SET_IM);
0405         hp_sdc.set_im = 0;
0406         goto finish;
0407     }
0408 
0409     if (hp_sdc.wcurr == -1)
0410         goto done;
0411 
0412     curr = hp_sdc.tq[curridx];
0413     idx = curr->actidx;
0414 
0415     if (curr->actidx >= curr->endidx) {
0416         hp_sdc.tq[curridx] = NULL;
0417         /* Interleave outbound data between the transactions. */
0418         hp_sdc.wcurr++;
0419         if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
0420             hp_sdc.wcurr = 0;
0421         goto finish;
0422     }
0423 
0424     act = curr->seq[idx];
0425     idx++;
0426 
0427     if (curr->idx >= curr->endidx) {
0428         if (act & HP_SDC_ACT_DEALLOC)
0429             kfree(curr);
0430         hp_sdc.tq[curridx] = NULL;
0431         /* Interleave outbound data between the transactions. */
0432         hp_sdc.wcurr++;
0433         if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
0434             hp_sdc.wcurr = 0;
0435         goto finish;
0436     }
0437 
0438     while (act & HP_SDC_ACT_PRECMD) {
0439         if (curr->idx != idx) {
0440             idx++;
0441             act &= ~HP_SDC_ACT_PRECMD;
0442             break;
0443         }
0444         hp_sdc_status_out8(curr->seq[idx]);
0445         curr->idx++;
0446         /* act finished? */
0447         if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD)
0448             goto actdone;
0449         /* skip quantity field if data-out sequence follows. */
0450         if (act & HP_SDC_ACT_DATAOUT)
0451             curr->idx++;
0452         goto finish;
0453     }
0454     if (act & HP_SDC_ACT_DATAOUT) {
0455         int qty;
0456 
0457         qty = curr->seq[idx];
0458         idx++;
0459         if (curr->idx - idx < qty) {
0460             hp_sdc_data_out8(curr->seq[curr->idx]);
0461             curr->idx++;
0462             /* act finished? */
0463             if (curr->idx - idx >= qty &&
0464                 (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)
0465                 goto actdone;
0466             goto finish;
0467         }
0468         idx += qty;
0469         act &= ~HP_SDC_ACT_DATAOUT;
0470     } else
0471         while (act & HP_SDC_ACT_DATAREG) {
0472         int mask;
0473         uint8_t w7[4];
0474 
0475         mask = curr->seq[idx];
0476         if (idx != curr->idx) {
0477             idx++;
0478             idx += !!(mask & 1);
0479             idx += !!(mask & 2);
0480             idx += !!(mask & 4);
0481             idx += !!(mask & 8);
0482             act &= ~HP_SDC_ACT_DATAREG;
0483             break;
0484         }
0485 
0486         w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0];
0487         w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1];
0488         w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2];
0489         w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3];
0490 
0491         if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 ||
0492             w7[hp_sdc.wi - 0x70] == hp_sdc.r7[hp_sdc.wi - 0x70]) {
0493             int i = 0;
0494 
0495             /* Need to point the write index register */
0496             while (i < 4 && w7[i] == hp_sdc.r7[i])
0497                 i++;
0498 
0499             if (i < 4) {
0500                 hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i);
0501                 hp_sdc.wi = 0x70 + i;
0502                 goto finish;
0503             }
0504 
0505             idx++;
0506             if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG)
0507                 goto actdone;
0508 
0509             curr->idx = idx;
0510             act &= ~HP_SDC_ACT_DATAREG;
0511             break;
0512         }
0513 
0514         hp_sdc_data_out8(w7[hp_sdc.wi - 0x70]);
0515         hp_sdc.r7[hp_sdc.wi - 0x70] = w7[hp_sdc.wi - 0x70];
0516         hp_sdc.wi++; /* write index register autoincrements */
0517         {
0518             int i = 0;
0519 
0520             while ((i < 4) && w7[i] == hp_sdc.r7[i])
0521                 i++;
0522             if (i >= 4) {
0523                 curr->idx = idx + 1;
0524                 if ((act & HP_SDC_ACT_DURING) ==
0525                     HP_SDC_ACT_DATAREG)
0526                     goto actdone;
0527             }
0528         }
0529         goto finish;
0530     }
0531     /* We don't go any further in the command if there is a pending read,
0532        because we don't want interleaved results. */
0533     read_lock_irq(&hp_sdc.rtq_lock);
0534     if (hp_sdc.rcurr >= 0) {
0535         read_unlock_irq(&hp_sdc.rtq_lock);
0536         goto finish;
0537     }
0538     read_unlock_irq(&hp_sdc.rtq_lock);
0539 
0540 
0541     if (act & HP_SDC_ACT_POSTCMD) {
0542         uint8_t postcmd;
0543 
0544         /* curr->idx should == idx at this point. */
0545         postcmd = curr->seq[idx];
0546         curr->idx++;
0547         if (act & HP_SDC_ACT_DATAIN) {
0548 
0549             /* Start a new read */
0550             hp_sdc.rqty = curr->seq[curr->idx];
0551             hp_sdc.rtime = ktime_get();
0552             curr->idx++;
0553             /* Still need to lock here in case of spurious irq. */
0554             write_lock_irq(&hp_sdc.rtq_lock);
0555             hp_sdc.rcurr = curridx;
0556             write_unlock_irq(&hp_sdc.rtq_lock);
0557             hp_sdc_status_out8(postcmd);
0558             goto finish;
0559         }
0560         hp_sdc_status_out8(postcmd);
0561         goto actdone;
0562     }
0563 
0564  actdone:
0565     if (act & HP_SDC_ACT_SEMAPHORE)
0566         up(curr->act.semaphore);
0567     else if (act & HP_SDC_ACT_CALLBACK)
0568         curr->act.irqhook(0,NULL,0,0);
0569 
0570     if (curr->idx >= curr->endidx) { /* This transaction is over. */
0571         if (act & HP_SDC_ACT_DEALLOC)
0572             kfree(curr);
0573         hp_sdc.tq[curridx] = NULL;
0574     } else {
0575         curr->actidx = idx + 1;
0576         curr->idx = idx + 2;
0577     }
0578     /* Interleave outbound data between the transactions. */
0579     hp_sdc.wcurr++;
0580     if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
0581         hp_sdc.wcurr = 0;
0582 
0583  finish:
0584     /* If by some quirk IBF has cleared and our ISR has run to
0585        see that that has happened, do it all again. */
0586     if (!hp_sdc.ibf && limit++ < 20)
0587         goto anew;
0588 
0589  done:
0590     if (hp_sdc.wcurr >= 0)
0591         tasklet_schedule(&hp_sdc.task);
0592     write_unlock(&hp_sdc.lock);
0593 
0594     return 0;
0595 }
0596 
0597 /******* Functions called in either user or kernel context ****/
0598 int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this)
0599 {
0600     int i;
0601 
0602     if (this == NULL) {
0603         BUG();
0604         return -EINVAL;
0605     }
0606 
0607     /* Can't have same transaction on queue twice */
0608     for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
0609         if (hp_sdc.tq[i] == this)
0610             goto fail;
0611 
0612     this->actidx = 0;
0613     this->idx = 1;
0614 
0615     /* Search for empty slot */
0616     for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
0617         if (hp_sdc.tq[i] == NULL) {
0618             hp_sdc.tq[i] = this;
0619             tasklet_schedule(&hp_sdc.task);
0620             return 0;
0621         }
0622 
0623     printk(KERN_WARNING PREFIX "No free slot to add transaction.\n");
0624     return -EBUSY;
0625 
0626  fail:
0627     printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n");
0628     return -EINVAL;
0629 }
0630 
0631 int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) {
0632     unsigned long flags;
0633     int ret;
0634 
0635     write_lock_irqsave(&hp_sdc.lock, flags);
0636     ret = __hp_sdc_enqueue_transaction(this);
0637     write_unlock_irqrestore(&hp_sdc.lock,flags);
0638 
0639     return ret;
0640 }
0641 
0642 int hp_sdc_dequeue_transaction(hp_sdc_transaction *this)
0643 {
0644     unsigned long flags;
0645     int i;
0646 
0647     write_lock_irqsave(&hp_sdc.lock, flags);
0648 
0649     /* TODO: don't remove it if it's not done. */
0650 
0651     for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
0652         if (hp_sdc.tq[i] == this)
0653             hp_sdc.tq[i] = NULL;
0654 
0655     write_unlock_irqrestore(&hp_sdc.lock, flags);
0656     return 0;
0657 }
0658 
0659 
0660 
0661 /********************** User context functions **************************/
0662 int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback)
0663 {
0664     if (callback == NULL || hp_sdc.dev == NULL)
0665         return -EINVAL;
0666 
0667     write_lock_irq(&hp_sdc.hook_lock);
0668     if (hp_sdc.timer != NULL) {
0669         write_unlock_irq(&hp_sdc.hook_lock);
0670         return -EBUSY;
0671     }
0672 
0673     hp_sdc.timer = callback;
0674     /* Enable interrupts from the timers */
0675     hp_sdc.im &= ~HP_SDC_IM_FH;
0676         hp_sdc.im &= ~HP_SDC_IM_PT;
0677     hp_sdc.im &= ~HP_SDC_IM_TIMERS;
0678     hp_sdc.set_im = 1;
0679     write_unlock_irq(&hp_sdc.hook_lock);
0680 
0681     tasklet_schedule(&hp_sdc.task);
0682 
0683     return 0;
0684 }
0685 
0686 int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback)
0687 {
0688     if (callback == NULL || hp_sdc.dev == NULL)
0689         return -EINVAL;
0690 
0691     write_lock_irq(&hp_sdc.hook_lock);
0692     if (hp_sdc.hil != NULL) {
0693         write_unlock_irq(&hp_sdc.hook_lock);
0694         return -EBUSY;
0695     }
0696 
0697     hp_sdc.hil = callback;
0698     hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET);
0699     hp_sdc.set_im = 1;
0700     write_unlock_irq(&hp_sdc.hook_lock);
0701 
0702     tasklet_schedule(&hp_sdc.task);
0703 
0704     return 0;
0705 }
0706 
0707 int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback)
0708 {
0709     if (callback == NULL || hp_sdc.dev == NULL)
0710         return -EINVAL;
0711 
0712     write_lock_irq(&hp_sdc.hook_lock);
0713     if (hp_sdc.cooked != NULL) {
0714         write_unlock_irq(&hp_sdc.hook_lock);
0715         return -EBUSY;
0716     }
0717 
0718     /* Enable interrupts from the HIL MLC */
0719     hp_sdc.cooked = callback;
0720     hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET);
0721     hp_sdc.set_im = 1;
0722     write_unlock_irq(&hp_sdc.hook_lock);
0723 
0724     tasklet_schedule(&hp_sdc.task);
0725 
0726     return 0;
0727 }
0728 
0729 int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback)
0730 {
0731     write_lock_irq(&hp_sdc.hook_lock);
0732     if ((callback != hp_sdc.timer) ||
0733         (hp_sdc.timer == NULL)) {
0734         write_unlock_irq(&hp_sdc.hook_lock);
0735         return -EINVAL;
0736     }
0737 
0738     /* Disable interrupts from the timers */
0739     hp_sdc.timer = NULL;
0740     hp_sdc.im |= HP_SDC_IM_TIMERS;
0741     hp_sdc.im |= HP_SDC_IM_FH;
0742     hp_sdc.im |= HP_SDC_IM_PT;
0743     hp_sdc.set_im = 1;
0744     write_unlock_irq(&hp_sdc.hook_lock);
0745     tasklet_schedule(&hp_sdc.task);
0746 
0747     return 0;
0748 }
0749 
0750 int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback)
0751 {
0752     write_lock_irq(&hp_sdc.hook_lock);
0753     if ((callback != hp_sdc.hil) ||
0754         (hp_sdc.hil == NULL)) {
0755         write_unlock_irq(&hp_sdc.hook_lock);
0756         return -EINVAL;
0757     }
0758 
0759     hp_sdc.hil = NULL;
0760     /* Disable interrupts from HIL only if there is no cooked driver. */
0761     if(hp_sdc.cooked == NULL) {
0762         hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET);
0763         hp_sdc.set_im = 1;
0764     }
0765     write_unlock_irq(&hp_sdc.hook_lock);
0766     tasklet_schedule(&hp_sdc.task);
0767 
0768     return 0;
0769 }
0770 
0771 int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback)
0772 {
0773     write_lock_irq(&hp_sdc.hook_lock);
0774     if ((callback != hp_sdc.cooked) ||
0775         (hp_sdc.cooked == NULL)) {
0776         write_unlock_irq(&hp_sdc.hook_lock);
0777         return -EINVAL;
0778     }
0779 
0780     hp_sdc.cooked = NULL;
0781     /* Disable interrupts from HIL only if there is no raw HIL driver. */
0782     if(hp_sdc.hil == NULL) {
0783         hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET);
0784         hp_sdc.set_im = 1;
0785     }
0786     write_unlock_irq(&hp_sdc.hook_lock);
0787     tasklet_schedule(&hp_sdc.task);
0788 
0789     return 0;
0790 }
0791 
0792 /************************* Keepalive timer task *********************/
0793 
0794 static void hp_sdc_kicker(struct timer_list *unused)
0795 {
0796     tasklet_schedule(&hp_sdc.task);
0797     /* Re-insert the periodic task. */
0798     mod_timer(&hp_sdc.kicker, jiffies + HZ);
0799 }
0800 
0801 /************************** Module Initialization ***************************/
0802 
0803 #if defined(__hppa__)
0804 
0805 static const struct parisc_device_id hp_sdc_tbl[] __initconst = {
0806     {
0807         .hw_type =  HPHW_FIO,
0808         .hversion_rev = HVERSION_REV_ANY_ID,
0809         .hversion = HVERSION_ANY_ID,
0810         .sversion = 0x73,
0811      },
0812     { 0, }
0813 };
0814 
0815 MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
0816 
0817 static int __init hp_sdc_init_hppa(struct parisc_device *d);
0818 static struct delayed_work moduleloader_work;
0819 
0820 static struct parisc_driver hp_sdc_driver __refdata = {
0821     .name =     "hp_sdc",
0822     .id_table = hp_sdc_tbl,
0823     .probe =    hp_sdc_init_hppa,
0824 };
0825 
0826 #endif /* __hppa__ */
0827 
0828 static int __init hp_sdc_init(void)
0829 {
0830     char *errstr;
0831     hp_sdc_transaction t_sync;
0832     uint8_t ts_sync[6];
0833     struct semaphore s_sync;
0834 
0835     rwlock_init(&hp_sdc.lock);
0836     rwlock_init(&hp_sdc.ibf_lock);
0837     rwlock_init(&hp_sdc.rtq_lock);
0838     rwlock_init(&hp_sdc.hook_lock);
0839 
0840     hp_sdc.timer        = NULL;
0841     hp_sdc.hil      = NULL;
0842     hp_sdc.pup      = NULL;
0843     hp_sdc.cooked       = NULL;
0844     hp_sdc.im       = HP_SDC_IM_MASK;  /* Mask maskable irqs */
0845     hp_sdc.set_im       = 1;
0846     hp_sdc.wi       = 0xff;
0847     hp_sdc.r7[0]        = 0xff;
0848     hp_sdc.r7[1]        = 0xff;
0849     hp_sdc.r7[2]        = 0xff;
0850     hp_sdc.r7[3]        = 0xff;
0851     hp_sdc.ibf      = 1;
0852 
0853     memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq));
0854 
0855     hp_sdc.wcurr        = -1;
0856         hp_sdc.rcurr        = -1;
0857     hp_sdc.rqty     = 0;
0858 
0859     hp_sdc.dev_err = -ENODEV;
0860 
0861     errstr = "IO not found for";
0862     if (!hp_sdc.base_io)
0863         goto err0;
0864 
0865     errstr = "IRQ not found for";
0866     if (!hp_sdc.irq)
0867         goto err0;
0868 
0869     hp_sdc.dev_err = -EBUSY;
0870 
0871 #if defined(__hppa__)
0872     errstr = "IO not available for";
0873         if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name))
0874         goto err0;
0875 #endif
0876 
0877     errstr = "IRQ not available for";
0878     if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED,
0879             "HP SDC", &hp_sdc))
0880         goto err1;
0881 
0882     errstr = "NMI not available for";
0883     if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED,
0884             "HP SDC NMI", &hp_sdc))
0885         goto err2;
0886 
0887     pr_info(PREFIX "HP SDC at 0x%08lx, IRQ %d (NMI IRQ %d)\n",
0888            hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
0889 
0890     hp_sdc_status_in8();
0891     hp_sdc_data_in8();
0892 
0893     tasklet_init(&hp_sdc.task, hp_sdc_tasklet, 0);
0894 
0895     /* Sync the output buffer registers, thus scheduling hp_sdc_tasklet. */
0896     t_sync.actidx   = 0;
0897     t_sync.idx  = 1;
0898     t_sync.endidx   = 6;
0899     t_sync.seq  = ts_sync;
0900     ts_sync[0]  = HP_SDC_ACT_DATAREG | HP_SDC_ACT_SEMAPHORE;
0901     ts_sync[1]  = 0x0f;
0902     ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0;
0903     t_sync.act.semaphore = &s_sync;
0904     sema_init(&s_sync, 0);
0905     hp_sdc_enqueue_transaction(&t_sync);
0906     down(&s_sync); /* Wait for t_sync to complete */
0907 
0908     /* Create the keepalive task */
0909     timer_setup(&hp_sdc.kicker, hp_sdc_kicker, 0);
0910     hp_sdc.kicker.expires = jiffies + HZ;
0911     add_timer(&hp_sdc.kicker);
0912 
0913     hp_sdc.dev_err = 0;
0914     return 0;
0915  err2:
0916     free_irq(hp_sdc.irq, &hp_sdc);
0917  err1:
0918     release_region(hp_sdc.data_io, 2);
0919  err0:
0920     printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n",
0921         errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
0922     hp_sdc.dev = NULL;
0923 
0924     return hp_sdc.dev_err;
0925 }
0926 
0927 #if defined(__hppa__)
0928 
0929 static void request_module_delayed(struct work_struct *work)
0930 {
0931     request_module("hp_sdc_mlc");
0932 }
0933 
0934 static int __init hp_sdc_init_hppa(struct parisc_device *d)
0935 {
0936     int ret;
0937 
0938     if (!d)
0939         return 1;
0940     if (hp_sdc.dev != NULL)
0941         return 1;   /* We only expect one SDC */
0942 
0943     hp_sdc.dev      = d;
0944     hp_sdc.irq      = d->irq;
0945     hp_sdc.nmi      = d->aux_irq;
0946     hp_sdc.base_io      = d->hpa.start;
0947     hp_sdc.data_io      = d->hpa.start + 0x800;
0948     hp_sdc.status_io    = d->hpa.start + 0x801;
0949 
0950     INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed);
0951 
0952     ret = hp_sdc_init();
0953     /* after successful initialization give SDC some time to settle
0954      * and then load the hp_sdc_mlc upper layer driver */
0955     if (!ret)
0956         schedule_delayed_work(&moduleloader_work,
0957             msecs_to_jiffies(2000));
0958 
0959     return ret;
0960 }
0961 
0962 #endif /* __hppa__ */
0963 
0964 static void hp_sdc_exit(void)
0965 {
0966     /* do nothing if we don't have a SDC */
0967     if (!hp_sdc.dev)
0968         return;
0969 
0970     write_lock_irq(&hp_sdc.lock);
0971 
0972     /* Turn off all maskable "sub-function" irq's. */
0973     hp_sdc_spin_ibf();
0974     sdc_writeb(HP_SDC_CMD_SET_IM | HP_SDC_IM_MASK, hp_sdc.status_io);
0975 
0976     /* Wait until we know this has been processed by the i8042 */
0977     hp_sdc_spin_ibf();
0978 
0979     free_irq(hp_sdc.nmi, &hp_sdc);
0980     free_irq(hp_sdc.irq, &hp_sdc);
0981     write_unlock_irq(&hp_sdc.lock);
0982 
0983     del_timer_sync(&hp_sdc.kicker);
0984 
0985     tasklet_kill(&hp_sdc.task);
0986 
0987 #if defined(__hppa__)
0988     cancel_delayed_work_sync(&moduleloader_work);
0989     if (unregister_parisc_driver(&hp_sdc_driver))
0990         printk(KERN_WARNING PREFIX "Error unregistering HP SDC");
0991 #endif
0992 }
0993 
0994 static int __init hp_sdc_register(void)
0995 {
0996     hp_sdc_transaction tq_init;
0997     uint8_t tq_init_seq[5];
0998     struct semaphore tq_init_sem;
0999 #if defined(__mc68000__)
1000     unsigned char i;
1001 #endif
1002 
1003     if (hp_sdc_disabled) {
1004         printk(KERN_WARNING PREFIX "HP SDC driver disabled by no_hpsdc=1.\n");
1005         return -ENODEV;
1006     }
1007 
1008     hp_sdc.dev = NULL;
1009     hp_sdc.dev_err = 0;
1010 #if defined(__hppa__)
1011     if (register_parisc_driver(&hp_sdc_driver)) {
1012         printk(KERN_WARNING PREFIX "Error registering SDC with system bus tree.\n");
1013         return -ENODEV;
1014     }
1015 #elif defined(__mc68000__)
1016     if (!MACH_IS_HP300)
1017         return -ENODEV;
1018 
1019     hp_sdc.irq   = 1;
1020     hp_sdc.nmi   = 7;
1021     hp_sdc.base_io   = (unsigned long) 0xf0428000;
1022     hp_sdc.data_io   = (unsigned long) hp_sdc.base_io + 1;
1023     hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3;
1024     if (!copy_from_kernel_nofault(&i, (unsigned char *)hp_sdc.data_io, 1))
1025         hp_sdc.dev = (void *)1;
1026     hp_sdc.dev_err   = hp_sdc_init();
1027 #endif
1028     if (hp_sdc.dev == NULL) {
1029         printk(KERN_WARNING PREFIX "No SDC found.\n");
1030         return hp_sdc.dev_err;
1031     }
1032 
1033     sema_init(&tq_init_sem, 0);
1034 
1035     tq_init.actidx      = 0;
1036     tq_init.idx     = 1;
1037     tq_init.endidx      = 5;
1038     tq_init.seq     = tq_init_seq;
1039     tq_init.act.semaphore   = &tq_init_sem;
1040 
1041     tq_init_seq[0] =
1042         HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
1043     tq_init_seq[1] = HP_SDC_CMD_READ_KCC;
1044     tq_init_seq[2] = 1;
1045     tq_init_seq[3] = 0;
1046     tq_init_seq[4] = 0;
1047 
1048     hp_sdc_enqueue_transaction(&tq_init);
1049 
1050     down(&tq_init_sem);
1051     up(&tq_init_sem);
1052 
1053     if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
1054         printk(KERN_WARNING PREFIX "Error reading config byte.\n");
1055         hp_sdc_exit();
1056         return -ENODEV;
1057     }
1058     hp_sdc.r11 = tq_init_seq[4];
1059     if (hp_sdc.r11 & HP_SDC_CFG_NEW) {
1060         const char *str;
1061         printk(KERN_INFO PREFIX "New style SDC\n");
1062         tq_init_seq[1] = HP_SDC_CMD_READ_XTD;
1063         tq_init.actidx      = 0;
1064         tq_init.idx     = 1;
1065         down(&tq_init_sem);
1066         hp_sdc_enqueue_transaction(&tq_init);
1067         down(&tq_init_sem);
1068         up(&tq_init_sem);
1069         if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
1070             printk(KERN_WARNING PREFIX "Error reading extended config byte.\n");
1071             return -ENODEV;
1072         }
1073         hp_sdc.r7e = tq_init_seq[4];
1074         HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str)
1075         printk(KERN_INFO PREFIX "Revision: %s\n", str);
1076         if (hp_sdc.r7e & HP_SDC_XTD_BEEPER)
1077             printk(KERN_INFO PREFIX "TI SN76494 beeper present\n");
1078         if (hp_sdc.r7e & HP_SDC_XTD_BBRTC)
1079             printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n");
1080         printk(KERN_INFO PREFIX "Spunking the self test register to force PUP "
1081                "on next firmware reset.\n");
1082         tq_init_seq[0] = HP_SDC_ACT_PRECMD |
1083             HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
1084         tq_init_seq[1] = HP_SDC_CMD_SET_STR;
1085         tq_init_seq[2] = 1;
1086         tq_init_seq[3] = 0;
1087         tq_init.actidx      = 0;
1088         tq_init.idx     = 1;
1089         tq_init.endidx      = 4;
1090         down(&tq_init_sem);
1091         hp_sdc_enqueue_transaction(&tq_init);
1092         down(&tq_init_sem);
1093         up(&tq_init_sem);
1094     } else
1095         printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n",
1096                (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087");
1097 
1098         return 0;
1099 }
1100 
1101 module_init(hp_sdc_register);
1102 module_exit(hp_sdc_exit);
1103 
1104 /* Timing notes:  These measurements taken on my 64MHz 7100-LC (715/64)
1105  *                                              cycles cycles-adj    time
1106  * between two consecutive mfctl(16)'s:              4        n/a    63ns
1107  * hp_sdc_spin_ibf when idle:                      119        115   1.7us
1108  * gsc_writeb status register:                      83         79   1.2us
1109  * IBF to clear after sending SET_IM:             6204       6006    93us
1110  * IBF to clear after sending LOAD_RT:            4467       4352    68us
1111  * IBF to clear after sending two LOAD_RTs:      18974      18859   295us
1112  * READ_T1, read status/data, IRQ, call handler: 35564        n/a   556us
1113  * cmd to ~IBF READ_T1 2nd time right after:   5158403        n/a    81ms
1114  * between IRQ received and ~IBF for above:    2578877        n/a    40ms
1115  *
1116  * Performance stats after a run of this module configuring HIL and
1117  * receiving a few mouse events:
1118  *
1119  * status in8  282508 cycles 7128 calls
1120  * status out8   8404 cycles  341 calls
1121  * data out8     1734 cycles   78 calls
1122  * isr         174324 cycles  617 calls (includes take)
1123  * take          1241 cycles    2 calls
1124  * put        1411504 cycles 6937 calls
1125  * task       1655209 cycles 6937 calls (includes put)
1126  *
1127  */