From patchwork Mon Jan 27 00:32:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghu Gandham X-Patchwork-Id: 3540461 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BD62EC02DC for ; Mon, 27 Jan 2014 00:34:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 94A55200FF for ; Mon, 27 Jan 2014 00:34:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BC8A42011E for ; Mon, 27 Jan 2014 00:34:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753625AbaA0AeA (ORCPT ); Sun, 26 Jan 2014 19:34:00 -0500 Received: from multi.imgtec.com ([194.200.65.239]:6370 "EHLO multi.imgtec.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753490AbaA0Adf (ORCPT ); Sun, 26 Jan 2014 19:33:35 -0500 From: Raghu Gandham To: Dmitry Torokhov CC: "aaro.koskinen@iki.fi" , "linux-input@vger.kernel.org" , "linux-mips@linux-mips.org" , "linux-kernel@vger.kernel.org" Subject: RE: [PATCH] Input: i8042-io - Exclude mips platforms when allocating/deallocating IO regions. Thread-Topic: [PATCH] Input: i8042-io - Exclude mips platforms when allocating/deallocating IO regions. Thread-Index: AQHPGgBYG66oCx9jPE6mIF95ddBIvJqYEzKA//+fccA= Date: Mon, 27 Jan 2014 00:32:36 +0000 Message-ID: References: <1390676514-30880-1-git-send-email-raghu.gandham@imgtec.com> <20140126214952.GD18840@core.coreip.homeip.net> In-Reply-To: <20140126214952.GD18840@core.coreip.homeip.net> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: yes X-MS-TNEF-Correlator: x-originating-ip: [192.168.150.77] MIME-Version: 1.0 X-SEF-Processed: 7_3_0_01192__2014_01_27_00_33_31 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_TVD_MIME_EPI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi Dmitry, > > On Sat, Jan 25, 2014 at 11:01:54AM -0800, Raghu Gandham wrote: > > The standard IO regions are already reserved by the platform code on > > most MIPS devices(malta, cobalt, sni). The Commit > > 197a1e96c8be5b6005145af3a4c0e45e2d651444 > > ("Input: i8042-io - fix up region handling on MIPS") introduced a bug > > on these MIPS platforms causing i8042 driver to fail when trying to reserve > IO ports. > > Prior to the above mentioned commit request_region is skipped on MIPS > > but release_region is called. > > > > This patch reverts commit 197a1e96c8be5b6005145af3a4c0e45e2d651444 > and > > also avoids calling release_region for MIPS. > > The problem is that IO regions are reserved on _most_, but not _all_ devices. > MIPS should figure out what they want to do with i8042 registers and be > consistent on all devices. Please examine the attached patch which went upstream in April of 2004. Since then it had been a convention not to call request_region routine in i8042 for MIPS. The attached patch had a glitch that it guarded request_region in i8042-io.h but skipped guarding release_region in i8042-io.h. I believe that the issue Aaro saw was due to this glitch. Below is the error quoted in Aaro's commit message. [ 2.112000] Trying to free nonexistent resource <0000000000000060-000000000000006f> My patch reinstates the convention followed on MIPS devices along with fixing Aaro's issue. Thanks, Raghu commit 2b7058b32c3f1706a80d54b06ad238f3c0bd09e9 Author: Andrew Morton Date: Wed Apr 21 23:37:12 2004 -0700 [PATCH] Merge missing MIPS i8042 bits From: Ralf Baechle - Add HPC3 PS/2 driver bits for SGI IP22 aka Indy - Add Mace PS/2 driver bits for SGI IP32 aka O2 - Add R4030 PS/2 driver bits for Jazz family - Don't register I/O ports where we're using the I/O port memory window to access the i8042 registers diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 10a54dd..cacd1f2 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -130,3 +130,13 @@ config SERIO_PCIPS2 To compile this driver as a module, choose M here: the module will be called pcips2. + +config SERIO_MACEPS2 + tristate "SGI O2 MACE PS/2 controller" + depends on SGI_IP32 && SERIO + help + Say Y here if you have SGI O2 workstation and want to use its + PS/2 ports. + + To compile this driver as a module, choose M here: the + module will be called maceps2. diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 2eb86eb..a47dec2 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o obj-$(CONFIG_SERIO_98KBD) += 98kbd-io.o obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o +obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h index 6b434f8..9b36485 100644 --- a/drivers/input/serio/i8042-io.h +++ b/drivers/input/serio/i8042-io.h @@ -69,7 +69,7 @@ static inline int i8042_platform_init(void) * On ix86 platforms touching the i8042 data register region can do really * bad things. Because of this the region is always reserved on ix86 boxes. */ -#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__) && !defined(__x86_64__) +#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__) && !defined(__x86_64__) && !defined(__mips__) if (!request_region(I8042_DATA_REG, 16, "i8042")) return -1; #endif diff --git a/drivers/input/serio/i8042-ip22io.h b/drivers/input/serio/i8042-ip22io.h new file mode 100644 index 0000000..863b9c9 --- /dev/null +++ b/drivers/input/serio/i8042-ip22io.h @@ -0,0 +1,76 @@ +#ifndef _I8042_IP22_H +#define _I8042_IP22_H + +#include +#include + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/* + * Names. + */ + +#define I8042_KBD_PHYS_DESC "hpc3ps2/serio0" +#define I8042_AUX_PHYS_DESC "hpc3ps2/serio1" +#define I8042_MUX_PHYS_DESC "hpc3ps2/serio%d" + +/* + * IRQs. + */ + +#define I8042_KBD_IRQ SGI_KEYBD_IRQ +#define I8042_AUX_IRQ SGI_KEYBD_IRQ + +/* + * Register numbers. + */ + +#define I8042_COMMAND_REG ((unsigned long)&sgioc->kbdmouse.command) +#define I8042_STATUS_REG ((unsigned long)&sgioc->kbdmouse.command) +#define I8042_DATA_REG ((unsigned long)&sgioc->kbdmouse.data) + +static inline int i8042_read_data(void) +{ + return sgioc->kbdmouse.data; +} + +static inline int i8042_read_status(void) +{ + return sgioc->kbdmouse.command; +} + +static inline void i8042_write_data(int val) +{ + sgioc->kbdmouse.data = val; +} + +static inline void i8042_write_command(int val) +{ + sgioc->kbdmouse.command = val; +} + +static inline int i8042_platform_init(void) +{ +#if 0 + /* XXX sgi_kh is a virtual address */ + if (!request_mem_region(sgi_kh, sizeof(struct hpc_keyb), "i8042")) + return 1; +#endif + + i8042_reset = 1; + + return 0; +} + +static inline void i8042_platform_exit(void) +{ +#if 0 + release_mem_region(JAZZ_KEYBOARD_ADDRESS, sizeof(struct hpc_keyb)); +#endif +} + +#endif /* _I8042_IP22_H */ diff --git a/drivers/input/serio/i8042-jazzio.h b/drivers/input/serio/i8042-jazzio.h new file mode 100644 index 0000000..5c20ab1 --- /dev/null +++ b/drivers/input/serio/i8042-jazzio.h @@ -0,0 +1,69 @@ +#ifndef _I8042_JAZZ_H +#define _I8042_JAZZ_H + +#include + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/* + * Names. + */ + +#define I8042_KBD_PHYS_DESC "R4030/serio0" +#define I8042_AUX_PHYS_DESC "R4030/serio1" +#define I8042_MUX_PHYS_DESC "R4030/serio%d" + +/* + * IRQs. + */ + +#define I8042_KBD_IRQ JAZZ_KEYBOARD_IRQ +#define I8042_AUX_IRQ JAZZ_MOUSE_IRQ + +#define I8042_COMMAND_REG ((unsigned long)&jazz_kh->command) +#define I8042_STATUS_REG ((unsigned long)&jazz_kh->command) +#define I8042_DATA_REG ((unsigned long)&jazz_kh->data) + +static inline int i8042_read_data(void) +{ + return jazz_kh->data; +} + +static inline int i8042_read_status(void) +{ + return jazz_kh->command; +} + +static inline void i8042_write_data(int val) +{ + jazz_kh->data = val; +} + +static inline void i8042_write_command(int val) +{ + jazz_kh->command = val; +} + +static inline int i8042_platform_init(void) +{ +#if 0 + /* XXX JAZZ_KEYBOARD_ADDRESS is a virtual address */ + if (!request_mem_region(JAZZ_KEYBOARD_ADDRESS, 2, "i8042")) + return 1; +#endif + + return 0; +} + +static inline void i8042_platform_exit(void) +{ +#if 0 + release_mem_region(JAZZ_KEYBOARD_ADDRESS, 2); +#endif +} + +#endif /* _I8042_JAZZ_H */ diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index 3d59eb2..f0f6374 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h @@ -1,6 +1,8 @@ #ifndef _I8042_H #define _I8042_H +#include + /* * Copyright (c) 1999-2002 Vojtech Pavlik * @@ -13,7 +15,11 @@ * Arch-dependent inline functions and defines. */ -#if defined(CONFIG_PPC) +#if defined(CONFIG_MIPS_JAZZ) +#include "i8042-jazzio.h" +#elif defined(CONFIG_SGI_IP22) +#include "i8042-ip22io.h" +#elif defined(CONFIG_PPC) #include "i8042-ppcio.h" #elif defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) #include "i8042-sparcio.h" diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c new file mode 100644 index 0000000..c7db1de --- /dev/null +++ b/drivers/input/serio/maceps2.c @@ -0,0 +1,160 @@ +/* + * SGI O2 MACE PS2 controller driver for linux + * + * Copyright (C) 2002 Vivien Chappelier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Vivien Chappelier driver)->port; + unsigned int timeout = MACE_PS2_TIMEOUT; + + do { + if (mace_read(port->status) & PS2_STATUS_TX_EMPTY) { + mace_write(val, port->tx); + return 0; + } + udelay(50); + } while (timeout--); + + return -1; +} + +static irqreturn_t maceps2_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + struct serio *dev = dev_id; + struct mace_ps2port *port = ((struct maceps2_data *)dev->driver)->port; + unsigned int byte; + + if (mace_read(port->status) & PS2_STATUS_RX_FULL) { + byte = mace_read(port->rx); + serio_interrupt(dev, byte & 0xff, 0, regs); + } + + return IRQ_HANDLED; +} + +static int maceps2_open(struct serio *dev) +{ + struct maceps2_data *data = (struct maceps2_data *)dev->driver; + + if (request_irq(data->irq, maceps2_interrupt, 0, "PS/2 port", dev)) { + printk(KERN_ERR "Could not allocate PS/2 IRQ\n"); + return -EBUSY; + } + + /* Reset port */ + mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET, + data->port->control); + udelay(100); + + /* Enable interrupts */ + mace_write(PS2_CONTROL_RX_CLOCK_ENABLE | PS2_CONTROL_TX_ENABLE | + PS2_CONTROL_RX_INT_ENABLE, data->port->control); + + return 0; +} + +static void maceps2_close(struct serio *dev) +{ + struct maceps2_data *data = (struct maceps2_data *)dev->driver; + + mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET, + data->port->control); + udelay(100); + free_irq(data->irq, dev); +} + +static struct maceps2_data port0_data, port1_data; + +static struct serio maceps2_port0 = +{ + .type = SERIO_8042, + .open = maceps2_open, + .close = maceps2_close, + .write = maceps2_write, + .name = "MACE PS/2 port0", + .phys = "mace/serio0", + .driver = &port0_data, +}; + +static struct serio maceps2_port1 = +{ + .type = SERIO_8042, + .open = maceps2_open, + .close = maceps2_close, + .write = maceps2_write, + .name = "MACE PS/2 port1", + .phys = "mace/serio1", + .driver = &port1_data, +}; + +static int __init maceps2_init(void) +{ + port0_data.port = &mace->perif.ps2.keyb; + port0_data.irq = MACEISA_KEYB_IRQ; + port1_data.port = &mace->perif.ps2.mouse; + port1_data.irq = MACEISA_MOUSE_IRQ; + serio_register_port(&maceps2_port0); + serio_register_port(&maceps2_port1); + + return 0; +} + +static void __exit maceps2_exit(void) +{ + serio_unregister_port(&maceps2_port0); + serio_unregister_port(&maceps2_port1); +} + +module_init(maceps2_init); +module_exit(maceps2_exit);