]> err.no Git - linux-2.6/blobdiff - drivers/input/serio/hp_sdc.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes
[linux-2.6] / drivers / input / serio / hp_sdc.c
index 31826e601fba291fbb29bb97049569e9b0712d84..0d395979b2d19c2a35ddb31e6d8c915c363fcfd9 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/time.h>
+#include <linux/semaphore.h>
 #include <linux/slab.h>
 #include <linux/hil.h>
 #include <asm/io.h>
@@ -100,9 +101,14 @@ EXPORT_SYMBOL(hp_sdc_release_timer_irq);
 EXPORT_SYMBOL(hp_sdc_release_hil_irq);
 EXPORT_SYMBOL(hp_sdc_release_cooked_irq);
 
+EXPORT_SYMBOL(__hp_sdc_enqueue_transaction);
 EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
 EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
 
+static unsigned int hp_sdc_disabled;
+module_param_named(no_hpsdc, hp_sdc_disabled, bool, 0);
+MODULE_PARM_DESC(no_hpsdc, "Do not enable HP SDC driver.");
+
 static hp_i8042_sdc    hp_sdc; /* All driver state is kept in here. */
 
 /*************** primitives for use in any context *********************/
@@ -593,18 +599,15 @@ unsigned long hp_sdc_put(void)
 }
 
 /******* Functions called in either user or kernel context ****/
-int hp_sdc_enqueue_transaction(hp_sdc_transaction *this)
+int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this)
 {
-       unsigned long flags;
        int i;
 
        if (this == NULL) {
-               tasklet_schedule(&hp_sdc.task);
+               BUG();
                return -EINVAL;
        }
 
-       write_lock_irqsave(&hp_sdc.lock, flags);
-
        /* Can't have same transaction on queue twice */
        for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
                if (hp_sdc.tq[i] == this)
@@ -617,21 +620,29 @@ int hp_sdc_enqueue_transaction(hp_sdc_transaction *this)
        for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
                if (hp_sdc.tq[i] == NULL) {
                        hp_sdc.tq[i] = this;
-                       write_unlock_irqrestore(&hp_sdc.lock, flags);
                        tasklet_schedule(&hp_sdc.task);
                        return 0;
                }
 
-       write_unlock_irqrestore(&hp_sdc.lock, flags);
        printk(KERN_WARNING PREFIX "No free slot to add transaction.\n");
        return -EBUSY;
 
  fail:
-       write_unlock_irqrestore(&hp_sdc.lock,flags);
        printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n");
        return -EINVAL;
 }
 
+int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) {
+       unsigned long flags;
+       int ret;
+
+       write_lock_irqsave(&hp_sdc.lock, flags);
+       ret = __hp_sdc_enqueue_transaction(this);
+       write_unlock_irqrestore(&hp_sdc.lock,flags);
+
+       return ret;
+}
+
 int hp_sdc_dequeue_transaction(hp_sdc_transaction *this)
 {
        unsigned long flags;
@@ -938,11 +949,7 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d)
 
 #endif /* __hppa__ */
 
-#if !defined(__mc68000__) /* Link error on m68k! */
-static void __exit hp_sdc_exit(void)
-#else
 static void hp_sdc_exit(void)
-#endif
 {
        write_lock_irq(&hp_sdc.lock);
 
@@ -977,6 +984,11 @@ static int __init hp_sdc_register(void)
        unsigned char i;
 #endif
 
+       if (hp_sdc_disabled) {
+               printk(KERN_WARNING PREFIX "HP SDC driver disabled by no_hpsdc=1.\n");
+               return -ENODEV;
+       }
+
        hp_sdc.dev = NULL;
        hp_sdc.dev_err = 0;
 #if defined(__hppa__)