diff options
Diffstat (limited to 'drivers/input/serio/rpckbd.c')
| -rw-r--r-- | drivers/input/serio/rpckbd.c | 66 | 
1 files changed, 41 insertions, 25 deletions
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 9da6fbcaaa7..e462e7791bb 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -29,23 +29,25 @@  #include <linux/module.h>  #include <linux/interrupt.h> -#include <linux/init.h>  #include <linux/serio.h>  #include <linux/err.h>  #include <linux/platform_device.h>  #include <linux/io.h>  #include <linux/slab.h> -#include <asm/irq.h>  #include <mach/hardware.h>  #include <asm/hardware/iomd.h> -#include <asm/system.h>  MODULE_AUTHOR("Vojtech Pavlik, Russell King");  MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");  MODULE_LICENSE("GPL");  MODULE_ALIAS("platform:kart"); +struct rpckbd_data { +	int tx_irq; +	int rx_irq; +}; +  static int rpckbd_write(struct serio *port, unsigned char val)  {  	while (!(iomd_readb(IOMD_KCTRL) & (1 << 7))) @@ -78,19 +80,21 @@ static irqreturn_t rpckbd_tx(int irq, void *dev_id)  static int rpckbd_open(struct serio *port)  { +	struct rpckbd_data *rpckbd = port->port_data; +  	/* Reset the keyboard state machine. */  	iomd_writeb(0, IOMD_KCTRL);  	iomd_writeb(8, IOMD_KCTRL);  	iomd_readb(IOMD_KARTRX); -	if (request_irq(IRQ_KEYBOARDRX, rpckbd_rx, 0, "rpckbd", port) != 0) { +	if (request_irq(rpckbd->rx_irq, rpckbd_rx, 0, "rpckbd", port) != 0) {  		printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n");  		return -EBUSY;  	} -	if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) { +	if (request_irq(rpckbd->tx_irq, rpckbd_tx, 0, "rpckbd", port) != 0) {  		printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n"); -		free_irq(IRQ_KEYBOARDRX, NULL); +		free_irq(rpckbd->rx_irq, port);  		return -EBUSY;  	} @@ -99,27 +103,47 @@ static int rpckbd_open(struct serio *port)  static void rpckbd_close(struct serio *port)  { -	free_irq(IRQ_KEYBOARDRX, port); -	free_irq(IRQ_KEYBOARDTX, port); +	struct rpckbd_data *rpckbd = port->port_data; + +	free_irq(rpckbd->rx_irq, port); +	free_irq(rpckbd->tx_irq, port);  }  /*   * Allocate and initialize serio structure for subsequent registration   * with serio core.   */ -static int __devinit rpckbd_probe(struct platform_device *dev) +static int rpckbd_probe(struct platform_device *dev)  { +	struct rpckbd_data *rpckbd;  	struct serio *serio; +	int tx_irq, rx_irq; + +	rx_irq = platform_get_irq(dev, 0); +	if (rx_irq <= 0) +		return rx_irq < 0 ? rx_irq : -ENXIO; + +	tx_irq = platform_get_irq(dev, 1); +	if (tx_irq <= 0) +		return tx_irq < 0 ? tx_irq : -ENXIO;  	serio = kzalloc(sizeof(struct serio), GFP_KERNEL); -	if (!serio) +	rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL); +	if (!serio || !rpckbd) { +		kfree(rpckbd); +		kfree(serio);  		return -ENOMEM; +	} + +	rpckbd->rx_irq = rx_irq; +	rpckbd->tx_irq = tx_irq;  	serio->id.type		= SERIO_8042;  	serio->write		= rpckbd_write;  	serio->open		= rpckbd_open;  	serio->close		= rpckbd_close;  	serio->dev.parent	= &dev->dev; +	serio->port_data	= rpckbd;  	strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));  	strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys)); @@ -128,31 +152,23 @@ static int __devinit rpckbd_probe(struct platform_device *dev)  	return 0;  } -static int __devexit rpckbd_remove(struct platform_device *dev) +static int rpckbd_remove(struct platform_device *dev)  {  	struct serio *serio = platform_get_drvdata(dev); +	struct rpckbd_data *rpckbd = serio->port_data; +  	serio_unregister_port(serio); +	kfree(rpckbd); +  	return 0;  }  static struct platform_driver rpckbd_driver = {  	.probe		= rpckbd_probe, -	.remove		= __devexit_p(rpckbd_remove), +	.remove		= rpckbd_remove,  	.driver		= {  		.name	= "kart",  		.owner	= THIS_MODULE,  	},  }; - -static int __init rpckbd_init(void) -{ -	return platform_driver_register(&rpckbd_driver); -} - -static void __exit rpckbd_exit(void) -{ -	platform_driver_unregister(&rpckbd_driver); -} - -module_init(rpckbd_init); -module_exit(rpckbd_exit); +module_platform_driver(rpckbd_driver);  | 
