root/drivers/input/serio/rpckbd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rpckbd_write
  2. rpckbd_rx
  3. rpckbd_tx
  4. rpckbd_open
  5. rpckbd_close
  6. rpckbd_probe
  7. rpckbd_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Copyright (c) 2000-2001 Vojtech Pavlik
   4  *  Copyright (c) 2002 Russell King
   5  */
   6 
   7 /*
   8  * Acorn RiscPC PS/2 keyboard controller driver for Linux/ARM
   9  */
  10 
  11 /*
  12  */
  13 
  14 #include <linux/module.h>
  15 #include <linux/interrupt.h>
  16 #include <linux/serio.h>
  17 #include <linux/err.h>
  18 #include <linux/platform_device.h>
  19 #include <linux/io.h>
  20 #include <linux/slab.h>
  21 
  22 #include <mach/hardware.h>
  23 #include <asm/hardware/iomd.h>
  24 
  25 MODULE_AUTHOR("Vojtech Pavlik, Russell King");
  26 MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
  27 MODULE_LICENSE("GPL");
  28 MODULE_ALIAS("platform:kart");
  29 
  30 struct rpckbd_data {
  31         int tx_irq;
  32         int rx_irq;
  33 };
  34 
  35 static int rpckbd_write(struct serio *port, unsigned char val)
  36 {
  37         while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
  38                 cpu_relax();
  39 
  40         iomd_writeb(val, IOMD_KARTTX);
  41 
  42         return 0;
  43 }
  44 
  45 static irqreturn_t rpckbd_rx(int irq, void *dev_id)
  46 {
  47         struct serio *port = dev_id;
  48         unsigned int byte;
  49         int handled = IRQ_NONE;
  50 
  51         while (iomd_readb(IOMD_KCTRL) & (1 << 5)) {
  52                 byte = iomd_readb(IOMD_KARTRX);
  53 
  54                 serio_interrupt(port, byte, 0);
  55                 handled = IRQ_HANDLED;
  56         }
  57         return handled;
  58 }
  59 
  60 static irqreturn_t rpckbd_tx(int irq, void *dev_id)
  61 {
  62         return IRQ_HANDLED;
  63 }
  64 
  65 static int rpckbd_open(struct serio *port)
  66 {
  67         struct rpckbd_data *rpckbd = port->port_data;
  68 
  69         /* Reset the keyboard state machine. */
  70         iomd_writeb(0, IOMD_KCTRL);
  71         iomd_writeb(8, IOMD_KCTRL);
  72         iomd_readb(IOMD_KARTRX);
  73 
  74         if (request_irq(rpckbd->rx_irq, rpckbd_rx, 0, "rpckbd", port) != 0) {
  75                 printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n");
  76                 return -EBUSY;
  77         }
  78 
  79         if (request_irq(rpckbd->tx_irq, rpckbd_tx, 0, "rpckbd", port) != 0) {
  80                 printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n");
  81                 free_irq(rpckbd->rx_irq, port);
  82                 return -EBUSY;
  83         }
  84 
  85         return 0;
  86 }
  87 
  88 static void rpckbd_close(struct serio *port)
  89 {
  90         struct rpckbd_data *rpckbd = port->port_data;
  91 
  92         free_irq(rpckbd->rx_irq, port);
  93         free_irq(rpckbd->tx_irq, port);
  94 }
  95 
  96 /*
  97  * Allocate and initialize serio structure for subsequent registration
  98  * with serio core.
  99  */
 100 static int rpckbd_probe(struct platform_device *dev)
 101 {
 102         struct rpckbd_data *rpckbd;
 103         struct serio *serio;
 104         int tx_irq, rx_irq;
 105 
 106         rx_irq = platform_get_irq(dev, 0);
 107         if (rx_irq <= 0)
 108                 return rx_irq < 0 ? rx_irq : -ENXIO;
 109 
 110         tx_irq = platform_get_irq(dev, 1);
 111         if (tx_irq <= 0)
 112                 return tx_irq < 0 ? tx_irq : -ENXIO;
 113 
 114         serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
 115         rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL);
 116         if (!serio || !rpckbd) {
 117                 kfree(rpckbd);
 118                 kfree(serio);
 119                 return -ENOMEM;
 120         }
 121 
 122         rpckbd->rx_irq = rx_irq;
 123         rpckbd->tx_irq = tx_irq;
 124 
 125         serio->id.type          = SERIO_8042;
 126         serio->write            = rpckbd_write;
 127         serio->open             = rpckbd_open;
 128         serio->close            = rpckbd_close;
 129         serio->dev.parent       = &dev->dev;
 130         serio->port_data        = rpckbd;
 131         strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
 132         strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
 133 
 134         platform_set_drvdata(dev, serio);
 135         serio_register_port(serio);
 136         return 0;
 137 }
 138 
 139 static int rpckbd_remove(struct platform_device *dev)
 140 {
 141         struct serio *serio = platform_get_drvdata(dev);
 142         struct rpckbd_data *rpckbd = serio->port_data;
 143 
 144         serio_unregister_port(serio);
 145         kfree(rpckbd);
 146 
 147         return 0;
 148 }
 149 
 150 static struct platform_driver rpckbd_driver = {
 151         .probe          = rpckbd_probe,
 152         .remove         = rpckbd_remove,
 153         .driver         = {
 154                 .name   = "kart",
 155         },
 156 };
 157 module_platform_driver(rpckbd_driver);

/* [<][>][^][v][top][bottom][index][help] */