^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * drivers/input/serio/gscps2.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2004-2006 Helge Deller <deller@gmx.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * HP GSC PS/2 port driver, found in PA/RISC Workstations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * - Dino testing (did HP ever shipped a machine on which this port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * was usable/enabled ?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/serio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/parisc-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@parisc-linux.org>, Helge Deller <deller@gmx.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) MODULE_DESCRIPTION("HP GSC PS2 port driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define PFX "gscps2.c: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Driver constants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* various constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define ENABLE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define DISABLE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define GSC_DINO_OFFSET 0x0800 /* offset for DINO controller versus LASI one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* PS/2 IO port offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define GSC_ID 0x00 /* device ID offset (see: GSC_ID_XXX) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define GSC_RESET 0x00 /* reset port offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define GSC_RCVDATA 0x04 /* receive port offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define GSC_XMTDATA 0x04 /* transmit port offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define GSC_CONTROL 0x08 /* see: Control register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define GSC_STATUS 0x0C /* see: Status register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Control register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define GSC_CTRL_ENBL 0x01 /* enable interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define GSC_CTRL_LPBXR 0x02 /* loopback operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define GSC_CTRL_DIAG 0x20 /* directly control clock/data line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define GSC_CTRL_DATDIR 0x40 /* data line direct control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define GSC_CTRL_CLKDIR 0x80 /* clock line direct control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Status register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define GSC_STAT_RBNE 0x01 /* Receive Buffer Not Empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define GSC_STAT_TBNE 0x02 /* Transmit Buffer Not Empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define GSC_STAT_TERR 0x04 /* Timeout Error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define GSC_STAT_PERR 0x08 /* Parity Error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define GSC_STAT_CMPINTR 0x10 /* Composite Interrupt = irq on any port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define GSC_STAT_DATSHD 0x40 /* Data Line Shadow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define GSC_STAT_CLKSHD 0x80 /* Clock Line Shadow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* IDs returned by GSC_ID port register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define GSC_ID_KEYBOARD 0 /* device ID values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define GSC_ID_MOUSE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static irqreturn_t gscps2_interrupt(int irq, void *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define BUFFER_SIZE 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* GSC PS/2 port device struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct gscps2port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct parisc_device *padev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct serio *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) char __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u8 act, append; /* position in buffer[] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u8 str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) } buffer[BUFFER_SIZE+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * Various HW level routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define gscps2_readb_input(x) readb((x)+GSC_RCVDATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define gscps2_readb_control(x) readb((x)+GSC_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define gscps2_readb_status(x) readb((x)+GSC_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define gscps2_writeb_control(x, y) writeb((x), (y)+GSC_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * wait_TBE() - wait for Transmit Buffer Empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int wait_TBE(char __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int timeout = 25000; /* device is expected to react within 250 msec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) while (gscps2_readb_status(addr) & GSC_STAT_TBNE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!--timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return 0; /* This should not happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * gscps2_flush() - flush the receive buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void gscps2_flush(struct gscps2port *ps2port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) gscps2_readb_input(ps2port->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ps2port->act = ps2port->append = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * gscps2_writeb_output() - write a byte to the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * returns 1 on success, 0 on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) char __iomem *addr = ps2port->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!wait_TBE(addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) printk(KERN_DEBUG PFX "timeout - could not write byte %#x\n", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) while (gscps2_readb_status(addr) & GSC_STAT_RBNE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* wait */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) spin_lock_irqsave(&ps2port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) writeb(data, addr+GSC_XMTDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) spin_unlock_irqrestore(&ps2port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* this is ugly, but due to timing of the port it seems to be necessary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) mdelay(6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* make sure any received data is returned as fast as possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* this is important e.g. when we set the LEDs on the keyboard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) gscps2_interrupt(0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * gscps2_enable() - enables or disables the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static void gscps2_enable(struct gscps2port *ps2port, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* now enable/disable the port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) spin_lock_irqsave(&ps2port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) gscps2_flush(ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) data = gscps2_readb_control(ps2port->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) data |= GSC_CTRL_ENBL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) data &= ~GSC_CTRL_ENBL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) gscps2_writeb_control(data, ps2port->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) spin_unlock_irqrestore(&ps2port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) wait_TBE(ps2port->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) gscps2_flush(ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * gscps2_reset() - resets the PS/2 port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static void gscps2_reset(struct gscps2port *ps2port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* reset the interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) spin_lock_irqsave(&ps2port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) gscps2_flush(ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) writeb(0xff, ps2port->addr + GSC_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) gscps2_flush(ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) spin_unlock_irqrestore(&ps2port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static LIST_HEAD(ps2port_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * gscps2_interrupt() - Interruption service routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * This function reads received PS/2 bytes and processes them on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * all interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * The problematic part here is, that the keyboard and mouse PS/2 port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * share the same interrupt and it's not possible to send data if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * one of them holds input data. To solve this problem we try to receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * the data as fast as possible and handle the reporting to the upper layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static irqreturn_t gscps2_interrupt(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct gscps2port *ps2port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) list_for_each_entry(ps2port, &ps2port_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) spin_lock_irqsave(&ps2port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) while ( (ps2port->buffer[ps2port->append].str =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ps2port->buffer[ps2port->append].data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) gscps2_readb_input(ps2port->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) spin_unlock_irqrestore(&ps2port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) } /* list_for_each_entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* all data was read from the ports - now report the data to upper layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) list_for_each_entry(ps2port, &ps2port_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) while (ps2port->act != ps2port->append) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned int rxflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u8 data, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* Did new data arrived while we read existing data ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) If yes, exit now and let the new irq handler start over again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (gscps2_readb_status(ps2port->addr) & GSC_STAT_CMPINTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) status = ps2port->buffer[ps2port->act].str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) data = ps2port->buffer[ps2port->act].data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ps2port->act = ((ps2port->act+1) & BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) rxflags = ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ((status & GSC_STAT_PERR) ? SERIO_PARITY : 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) serio_interrupt(ps2port->port, data, rxflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) } /* while() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) } /* list_for_each_entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * gscps2_write() - send a byte out through the aux interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int gscps2_write(struct serio *port, unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct gscps2port *ps2port = port->port_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!gscps2_writeb_output(ps2port, data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) printk(KERN_DEBUG PFX "sending byte %#x failed.\n", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * gscps2_open() is called when a port is opened by the higher layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * It resets and enables the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int gscps2_open(struct serio *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct gscps2port *ps2port = port->port_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) gscps2_reset(ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* enable it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) gscps2_enable(ps2port, ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) gscps2_interrupt(0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * gscps2_close() disables the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static void gscps2_close(struct serio *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct gscps2port *ps2port = port->port_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) gscps2_enable(ps2port, DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * gscps2_probe() - Probes PS2 devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * @return: success/error report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int __init gscps2_probe(struct parisc_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct gscps2port *ps2port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct serio *serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) unsigned long hpa = dev->hpa.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (!dev->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* Offset for DINO PS/2. Works with LASI even */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (dev->id.sversion == 0x96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) hpa += GSC_DINO_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ps2port = kzalloc(sizeof(struct gscps2port), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!ps2port || !serio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) goto fail_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) dev_set_drvdata(&dev->dev, ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ps2port->port = serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ps2port->padev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ps2port->addr = ioremap(hpa, GSC_STATUS + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) spin_lock_init(&ps2port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) gscps2_reset(ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) serio->id.type = SERIO_8042;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) serio->write = gscps2_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) serio->open = gscps2_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) serio->close = gscps2_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) serio->port_data = ps2port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) serio->dev.parent = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (request_irq(dev->irq, gscps2_interrupt, IRQF_SHARED, ps2port->port->name, ps2port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) goto fail_miserably;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (ps2port->id != GSC_ID_KEYBOARD && ps2port->id != GSC_ID_MOUSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) printk(KERN_WARNING PFX "Unsupported PS/2 port at 0x%08lx (id=%d) ignored\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) hpa, ps2port->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (!request_mem_region(hpa, GSC_STATUS + 4, ps2port->port.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) pr_info("serio: %s port at 0x%08lx irq %d @ %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ps2port->port->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) hpa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ps2port->padev->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ps2port->port->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) serio_register_port(ps2port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) list_add_tail(&ps2port->node, &ps2port_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) free_irq(dev->irq, ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) fail_miserably:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) iounmap(ps2port->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) release_mem_region(dev->hpa.start, GSC_STATUS + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) fail_nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) kfree(ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) kfree(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * gscps2_remove() - Removes PS2 devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * @return: success/error report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static int __exit gscps2_remove(struct parisc_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) serio_unregister_port(ps2port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) free_irq(dev->irq, ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) gscps2_flush(ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) list_del(&ps2port->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) iounmap(ps2port->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) release_mem_region(dev->hpa, GSC_STATUS + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dev_set_drvdata(&dev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) kfree(ps2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static const struct parisc_device_id gscps2_device_tbl[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) #ifdef DINO_TESTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) { 0, } /* 0 terminated list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static struct parisc_driver parisc_ps2_driver __refdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .name = "gsc_ps2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .id_table = gscps2_device_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .probe = gscps2_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .remove = __exit_p(gscps2_remove),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int __init gscps2_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) register_parisc_driver(&parisc_ps2_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static void __exit gscps2_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) unregister_parisc_driver(&parisc_ps2_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) module_init(gscps2_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) module_exit(gscps2_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)