patch-2.4.10 linux/drivers/char/pc_keyb.c
Next file: linux/drivers/char/pcmcia/serial_cs.c
Previous file: linux/drivers/char/pc110pad.c
Back to the patch index
Back to the overall index
- Lines: 184
- Date:
Mon Sep 17 22:52:35 2001
- Orig file:
v2.4.9/linux/drivers/char/pc_keyb.c
- Orig date:
Mon Aug 27 12:41:41 2001
diff -u --recursive --new-file v2.4.9/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
@@ -31,7 +31,9 @@
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
#include <linux/smp_lock.h>
+#include <linux/kd.h>
#include <asm/keyboard.h>
#include <asm/bitops.h>
@@ -395,6 +397,32 @@
return 0200;
}
+void pckbd_pm_resume(void)
+{
+#if defined CONFIG_PSMOUSE
+ unsigned long flags;
+
+ if (queue) { /* Aux port detected */
+ if (aux_count == 0) { /* Mouse not in use */
+ spin_lock_irqsave(&kbd_controller_lock, flags);
+ /*
+ * Dell Lat. C600 A06 enables mouse after resume.
+ * When user touches the pad, it posts IRQ 12
+ * (which we do not process), thus holding keyboard.
+ */
+ kbd_write_command(KBD_CCMD_MOUSE_DISABLE);
+ /* kbd_write_cmd(AUX_INTS_OFF); */ /* Config & lock */
+ kb_wait();
+ kbd_write_command(KBD_CCMD_WRITE_MODE);
+ kb_wait();
+ kbd_write_output(AUX_INTS_OFF);
+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
+ }
+ }
+#endif
+}
+
+
static inline void handle_mouse_event(unsigned char scancode)
{
#ifdef CONFIG_PSMOUSE
@@ -519,7 +547,7 @@
mdelay(1);
if (!--timeout) {
#ifdef KBD_REPORT_TIMEOUTS
- printk(KERN_WARNING "keyboard: Timeout - AT keyboard not present?\n");
+ printk(KERN_WARNING "keyboard: Timeout - AT keyboard not present?(%02x)\n", data);
#endif
return 0;
}
@@ -602,7 +630,7 @@
return 1;
}
-int pckbd_rate(struct kbd_repeat *rep)
+static int pckbd_rate(struct kbd_repeat *rep)
{
if (rep == NULL)
return -EINVAL;
@@ -705,6 +733,53 @@
spin_unlock_irqrestore(&kbd_controller_lock, flags);
}
+#if defined(__alpha__)
+/*
+ * Some Alphas cannot mask some/all interrupts, so we have to
+ * make sure not to allow interrupts AT ALL when polling for
+ * specific return values from the keyboard.
+ *
+ * I think this should work on any architecture, but for now, only Alpha.
+ */
+static int kbd_write_command_w_and_wait(int data)
+{
+ unsigned long flags;
+ int input;
+
+ spin_lock_irqsave(&kbd_controller_lock, flags);
+ kb_wait();
+ kbd_write_command(data);
+ input = kbd_wait_for_input();
+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
+ return input;
+}
+
+static int kbd_write_output_w_and_wait(int data)
+{
+ unsigned long flags;
+ int input;
+
+ spin_lock_irqsave(&kbd_controller_lock, flags);
+ kb_wait();
+ kbd_write_output(data);
+ input = kbd_wait_for_input();
+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
+ return input;
+}
+#else
+static int kbd_write_command_w_and_wait(int data)
+{
+ kbd_write_command_w(data);
+ return kbd_wait_for_input();
+}
+
+static int kbd_write_output_w_and_wait(int data)
+{
+ kbd_write_output_w(data);
+ return kbd_wait_for_input();
+}
+#endif /* __alpha__ */
+
#if defined CONFIG_PSMOUSE
static void kbd_write_cmd(int cmd)
{
@@ -788,8 +863,8 @@
| KBD_MODE_KCC);
/* ibm powerpc portables need this to use scan-code set 1 -- Cort */
- kbd_write_command_w(KBD_CCMD_READ_MODE);
- if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
+ if (!(kbd_write_command_w_and_wait(KBD_CCMD_READ_MODE) & KBD_MODE_KCC))
+ {
/*
* If the controller does not support conversion,
* Set the keyboard to scan-code set 1.
@@ -800,20 +875,16 @@
kbd_wait_for_input();
}
-
- kbd_write_output_w(KBD_CMD_ENABLE);
- if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ if (kbd_write_output_w_and_wait(KBD_CMD_ENABLE) != KBD_REPLY_ACK)
return "Enable keyboard: no ACK";
/*
* Finally, set the typematic rate to maximum.
*/
- kbd_write_output_w(KBD_CMD_SET_RATE);
- if (kbd_wait_for_input() != KBD_REPLY_ACK)
- return "Set rate: no ACK";
- kbd_write_output_w(0x00);
- if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ if (kbd_write_output_w_and_wait(KBD_CMD_SET_RATE) != KBD_REPLY_ACK)
return "Set rate: no ACK";
+ if (kbd_write_output_w_and_wait(0x00) != KBD_REPLY_ACK)
+ return "Set rate: no 2nd ACK";
return NULL;
}
@@ -835,6 +906,8 @@
psaux_init();
#endif
+ kbd_rate = pckbd_rate;
+
/* Ok, finally allocate the IRQ, and off we go.. */
kbd_request_irq(keyboard_interrupt);
}
@@ -1105,13 +1178,20 @@
static int __init psaux_init(void)
{
+ int retval;
+
if (!detect_auxiliary_port())
return -EIO;
- misc_register(&psaux_mouse);
+ if ((retval = misc_register(&psaux_mouse)))
+ return retval;
+
queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
- if (queue == NULL)
- panic("psaux_init(): out of memory");
+ if (queue == NULL) {
+ printk(KERN_ERR "psaux_init(): out of memory\n");
+ misc_deregister(&psaux_mouse);
+ return -ENOMEM;
+ }
memset(queue, 0, sizeof(*queue));
queue->head = queue->tail = 0;
init_waitqueue_head(&queue->proc_list);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)