2004-06-28 05:09:53

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 0/19] New set of input patches

Hi,

Here is the 2nd version of my set of input patches that mostly do serio sysfs
integration. Among the changes - dropped psmouse KVM resync patch as it was
bogus, added platform devices to those of serio providers that don't have
proper parent device (i8042, q40kbd, etc).

01-psmouse-state-locking.patch
- Acquire underlying serio lock when changing psmouse state to
prevent interrupt handler running on us

02-serio-connect-mandatory.patch
- Make serio driviers connect/disconnect methods mandatory as these
methods open/close serio ports and link ports and drivers together.
Presently if a driver does not implement connect method it will not
be able to bind to a port anyway.

03-serio-rename-1.patch
- Rename serio->driver to serio->port_data as with sysfs integration
driver is not the best name for arbitrary data

04-serio-rename-2.patch
- Rename serio_dev to serio_driver as they are drivers in sysfs sense

05-serio-dynamic-alloc.patch
- Switch from static to dynamic serio port allocation so serio ports
drivers can be freely unloaded even if not all references to ports
are dropped (sysfs req.)

06-serio-no-recursion.patch
- Do not do recursive discovery of children ports, needed for sysfs
and generally better for stack usage.

07-serio-sysfs.patch
- sysfs integration. Register ports and drivers in driver model, link
them all together under /sys/bus/serio. Every driver has a default
attribute "descrip[tion" (from serio_driver->description); serio
ports have "decription", "driver" and "legacy_position".
Legacy_position porvides access to serio->phys to allow matching
with data in /proc/bus/input/devices

08-serio-rebind.patch
- allow user to disconnect or rebind serio port by writing appropriate
data to it's sysfs attribute:
echo -n "psmouse" > /sys/bus/serio/devices/serio0/driver
echo -n "none" > /sys/bus/serio/devices/serio0/driver
echo -n "reconnect" > /sys/bus/serio/devices/serio0/driver
echo -n "rescan" > /sys/bus/serio/devices/serio0/driver

09-serio-manual-bind.patch
- allow marking some drivers as requiring manual bind (to be used when
driver does not do automatic HW discovery)

10-serio_raw.patch
- raw access to serio data ala 2.4 /dev/psaux

(*) 11-platform-device-simple.patch
- Add platform_device_register_simple to register platform devices
requiring minimal resource and memory management. The release
function resides in driver core and that allows drivers registering
such devices be unloaded without waiting for the last reference to
be dropped.

12-i8042-to-platform-device.patch
- Convert i8042 to platform device instead of system device so
its ports have proper parent.

13-serio-add-platform-devices.patch
- Add platform devices to ct82c710, maceps2, q40kbd and rpckbd.

14-serio-set-up-parents.patch
- Set up parent devices for serio ports in ambakmi, gscps2,
pcips2 and sa1111ps2.c

15-synaptics-passthrough-handling.patch
- If data looks like a pass-through packet and tuchpad has
pass-through capability do not pass it to the main handler
if child port is disconnected.

(*) 16-bus-default-drv-attrs.patch
- Add bus' default driver attributes (similar to defaulr device
attributes)

17-serio-use-bus-default-attrs.patch
- Use bus' default driver and device attributes to manage serio
attributes

(*) 18-add-driver-find.patch
- Add driver_find function, similar to device_find, to search for a
driver by its name.

19-serio-use-driver-find.patch
- Use driver_find in serio_rebind_driver instead of implementing it
locally.

(*) These patches have also been sent to Greg KH.

This time I tried compiling the stuff using defconfing for SPACR64 and PPC64
(thanks to Andrew for pointing to me availability of cross-compile
tools), so I should be a bit better now... Alpha failed on cpumask.h...

The patches are against today's Linus tree + recent pull form Vojtech's tree
+ recent pull from Greg KH's tree. I have patches against 2.6.7 that will
bring it to my version of the tree at:

http://www.geocities.com/dt_or/input/2_6_7/

--
Dmitry


2004-06-28 05:09:45

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 1/19] psmouse state locking


===================================================================


[email protected], 2004-06-27 15:44:44-05:00, [email protected]
Input: when changing psmouse state (activated, ignore) do it while
holding serio lock so it will not fight with the interrupt
handler.

Signed-off-by: Dmitry Torokhov <[email protected]>


psmouse-base.c | 32 ++++++++++++++++++++++----------
1 files changed, 22 insertions(+), 10 deletions(-)


===================================================================



diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c 2004-06-27 17:46:50 -05:00
+++ b/drivers/input/mouse/psmouse-base.c 2004-06-27 17:46:50 -05:00
@@ -622,6 +622,23 @@
}

/*
+ * psmouse_set_state() sets new psmouse state and resets all flags and
+ * counters while holding serio lock so fighting with interrupt handler
+ * is not a concern.
+ */
+
+static void psmouse_set_state(struct psmouse *psmouse, unsigned char new_state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&psmouse->serio->lock, flags);
+ psmouse->state = new_state;
+ psmouse->pktcnt = psmouse->cmdcnt = psmouse->out_of_sync = 0;
+ psmouse->flags = 0;
+ spin_unlock_irqrestore(&psmouse->serio->lock, flags);
+}
+
+/*
* psmouse_activate() enables the mouse so that we get motion reports from it.
*/

@@ -630,7 +647,7 @@
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE))
printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse->serio->phys);

- psmouse->state = PSMOUSE_ACTIVATED;
+ psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
}

/*
@@ -652,7 +669,7 @@
{
struct psmouse *psmouse = serio->private;

- psmouse->state = PSMOUSE_CMD_MODE;
+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);

if (psmouse->ptport) {
if (psmouse->ptport->deactivate)
@@ -665,7 +682,7 @@
if (psmouse->disconnect)
psmouse->disconnect(psmouse);

- psmouse->state = PSMOUSE_IGNORE;
+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);

input_unregister_device(&psmouse->dev);
serio_close(serio);
@@ -693,9 +710,9 @@
psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
- psmouse->state = PSMOUSE_CMD_MODE;
psmouse->serio = serio;
psmouse->dev.private = psmouse;
+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);

serio->private = psmouse;
if (serio_open(serio, dev)) {
@@ -758,12 +775,7 @@
return -1;
}

- psmouse->state = PSMOUSE_CMD_MODE;
-
- clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
- clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
-
- psmouse->pktcnt = psmouse->out_of_sync = 0;
+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);

if (psmouse->reconnect) {
if (psmouse->reconnect(psmouse))

2004-06-28 05:11:51

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 2/19] serio connect/disconnect mandatory


===================================================================


[email protected], 2004-06-27 15:45:16-05:00, [email protected]
Input: make connect and disconnect methods mandatory for serio
drivers since that's where serio_{open|close} are called
from to actually bind driver to a port.

Signed-off-by: Dmitry Torokhov <[email protected]>


serio.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-06-27 17:47:10 -05:00
+++ b/drivers/input/serio/serio.c 2004-06-27 17:47:10 -05:00
@@ -68,8 +68,7 @@
list_for_each_entry(dev, &serio_dev_list, node) {
if (serio->dev)
break;
- if (dev->connect)
- dev->connect(serio, dev);
+ dev->connect(serio, dev);
}
}

@@ -160,7 +159,7 @@
/* reconnect failed - fall through to rescan */

case SERIO_RESCAN :
- if (event->serio->dev && event->serio->dev->disconnect)
+ if (event->serio->dev)
event->serio->dev->disconnect(event->serio);
serio_find_dev(event->serio);
break;
@@ -282,7 +281,7 @@
{
serio_remove_pending_events(serio);
list_del_init(&serio->node);
- if (serio->dev && serio->dev->disconnect)
+ if (serio->dev)
serio->dev->disconnect(serio);
}

@@ -296,7 +295,7 @@
down(&serio_sem);
list_add_tail(&dev->node, &serio_dev_list);
list_for_each_entry(serio, &serio_list, node)
- if (!serio->dev && dev->connect)
+ if (!serio->dev)
dev->connect(serio, dev);
up(&serio_sem);
}
@@ -309,7 +308,7 @@
list_del_init(&dev->node);

list_for_each_entry(serio, &serio_list, node) {
- if (serio->dev == dev && dev->disconnect)
+ if (serio->dev == dev)
dev->disconnect(serio);
serio_find_dev(serio);
}

2004-06-28 05:16:01

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 3/19] serio renames 1


===================================================================


[email protected], 2004-06-27 15:45:46-05:00, [email protected]
Input: rename serio->driver to serio->port_data in preparation
to sysfs integration

Signed-off-by: Dmitry Torokhov <[email protected]>


drivers/input/mouse/synaptics.c | 4 ++--
drivers/input/serio/ambakmi.c | 22 +++++++++++-----------
drivers/input/serio/gscps2.c | 8 ++++----
drivers/input/serio/i8042.c | 14 +++++++-------
drivers/input/serio/maceps2.c | 36 ++++++++++++++++++------------------
drivers/input/serio/pcips2.c | 8 ++++----
drivers/input/serio/sa1111ps2.c | 8 ++++----
drivers/input/serio/serport.c | 6 +++---
drivers/serial/sunsu.c | 8 ++++----
drivers/serial/sunzilog.c | 8 ++++----
include/linux/serio.h | 2 +-
11 files changed, 62 insertions(+), 62 deletions(-)


===================================================================



diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/input/mouse/synaptics.c 2004-06-27 17:47:31 -05:00
@@ -214,7 +214,7 @@
****************************************************************************/
static int synaptics_pt_write(struct serio *port, unsigned char c)
{
- struct psmouse *parent = port->driver;
+ struct psmouse *parent = port->port_data;
char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */

if (psmouse_sliced_command(parent, c))
@@ -273,7 +273,7 @@
port->serio.name = "Synaptics pass-through";
port->serio.phys = "synaptics-pt/serio0";
port->serio.write = synaptics_pt_write;
- port->serio.driver = psmouse;
+ port->serio.port_data = psmouse;

port->activate = synaptics_pt_activate;
}
diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/input/serio/ambakmi.c 2004-06-27 17:47:31 -05:00
@@ -54,7 +54,7 @@

static int amba_kmi_write(struct serio *io, unsigned char val)
{
- struct amba_kmi_port *kmi = io->driver;
+ struct amba_kmi_port *kmi = io->port_data;
unsigned int timeleft = 10000; /* timeout in 100ms */

while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--)
@@ -68,7 +68,7 @@

static int amba_kmi_open(struct serio *io)
{
- struct amba_kmi_port *kmi = io->driver;
+ struct amba_kmi_port *kmi = io->port_data;
unsigned int divisor;
int ret;

@@ -105,7 +105,7 @@

static void amba_kmi_close(struct serio *io)
{
- struct amba_kmi_port *kmi = io->driver;
+ struct amba_kmi_port *kmi = io->port_data;

writeb(0, KMICR);

@@ -131,15 +131,15 @@

memset(kmi, 0, sizeof(struct amba_kmi_port));

- kmi->io.type = SERIO_8042;
- kmi->io.write = amba_kmi_write;
- kmi->io.open = amba_kmi_open;
- kmi->io.close = amba_kmi_close;
- kmi->io.name = dev->dev.bus_id;
- kmi->io.phys = dev->dev.bus_id;
- kmi->io.driver = kmi;
+ kmi->io.type = SERIO_8042;
+ kmi->io.write = amba_kmi_write;
+ kmi->io.open = amba_kmi_open;
+ kmi->io.close = amba_kmi_close;
+ kmi->io.name = dev->dev.bus_id;
+ kmi->io.phys = dev->dev.bus_id;
+ kmi->io.port_data = kmi;

- kmi->base = ioremap(dev->res.start, KMI_SIZE);
+ kmi->base = ioremap(dev->res.start, KMI_SIZE);
if (!kmi->base) {
ret = -ENOMEM;
goto out;
diff -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
--- a/drivers/input/serio/gscps2.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/input/serio/gscps2.c 2004-06-27 17:47:31 -05:00
@@ -288,7 +288,7 @@

static int gscps2_write(struct serio *port, unsigned char data)
{
- struct gscps2port *ps2port = port->driver;
+ struct gscps2port *ps2port = port->port_data;

if (!gscps2_writeb_output(ps2port, data)) {
printk(KERN_DEBUG PFX "sending byte %#x failed.\n", data);
@@ -304,7 +304,7 @@

static int gscps2_open(struct serio *port)
{
- struct gscps2port *ps2port = port->driver;
+ struct gscps2port *ps2port = port->port_data;

gscps2_reset(ps2port);

@@ -319,7 +319,7 @@

static void gscps2_close(struct serio *port)
{
- struct gscps2port *ps2port = port->driver;
+ struct gscps2port *ps2port = port->port_data;
gscps2_enable(ps2port, DISABLE);
}

@@ -372,7 +372,7 @@
(ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" );

memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port));
- ps2port->port.driver = ps2port;
+ ps2port->port.port_data = ps2port;
ps2port->port.name = ps2port->name;
ps2port->port.phys = dev->dev.bus_id;

diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/input/serio/i8042.c 2004-06-27 17:47:31 -05:00
@@ -223,7 +223,7 @@

static int i8042_aux_write(struct serio *port, unsigned char c)
{
- struct i8042_values *values = port->driver;
+ struct i8042_values *values = port->port_data;
int retval;

/*
@@ -251,7 +251,7 @@

static int i8042_activate_port(struct serio *port)
{
- struct i8042_values *values = port->driver;
+ struct i8042_values *values = port->port_data;

i8042_flush();

@@ -279,7 +279,7 @@

static int i8042_open(struct serio *port)
{
- struct i8042_values *values = port->driver;
+ struct i8042_values *values = port->port_data;

if (values->mux != -1)
if (i8042_mux_open++)
@@ -318,7 +318,7 @@

static void i8042_close(struct serio *port)
{
- struct i8042_values *values = port->driver;
+ struct i8042_values *values = port->port_data;

if (values->mux != -1)
if (--i8042_mux_open)
@@ -353,7 +353,7 @@
.write = i8042_kbd_write,
.open = i8042_open,
.close = i8042_close,
- .driver = &i8042_kbd_values,
+ .port_data = &i8042_kbd_values,
.name = "i8042 Kbd Port",
.phys = I8042_KBD_PHYS_DESC,
};
@@ -371,7 +371,7 @@
.write = i8042_aux_write,
.open = i8042_open,
.close = i8042_close,
- .driver = &i8042_aux_values,
+ .port_data = &i8042_aux_values,
.name = "i8042 Aux Port",
.phys = I8042_AUX_PHYS_DESC,
};
@@ -941,7 +941,7 @@
sprintf(i8042_mux_short[index], "AUX%d", index);
port->name = i8042_mux_names[index];
port->phys = i8042_mux_phys[index];
- port->driver = values;
+ port->port_data = values;
values->name = i8042_mux_short[index];
values->mux = index;
}
diff -Nru a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
--- a/drivers/input/serio/maceps2.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/input/serio/maceps2.c 2004-06-27 17:47:31 -05:00
@@ -54,7 +54,7 @@

static int maceps2_write(struct serio *dev, unsigned char val)
{
- struct mace_ps2port *port = ((struct maceps2_data *)dev->driver)->port;
+ struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
unsigned int timeout = MACE_PS2_TIMEOUT;

do {
@@ -72,7 +72,7 @@
struct pt_regs *regs)
{
struct serio *dev = dev_id;
- struct mace_ps2port *port = ((struct maceps2_data *)dev->driver)->port;
+ struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
unsigned int byte;

if (mace_read(port->status) & PS2_STATUS_RX_FULL) {
@@ -85,7 +85,7 @@

static int maceps2_open(struct serio *dev)
{
- struct maceps2_data *data = (struct maceps2_data *)dev->driver;
+ struct maceps2_data *data = (struct maceps2_data *)dev->port_data;

if (request_irq(data->irq, maceps2_interrupt, 0, "PS/2 port", dev)) {
printk(KERN_ERR "Could not allocate PS/2 IRQ\n");
@@ -106,7 +106,7 @@

static void maceps2_close(struct serio *dev)
{
- struct maceps2_data *data = (struct maceps2_data *)dev->driver;
+ struct maceps2_data *data = (struct maceps2_data *)dev->port_data;

mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
data->port->control);
@@ -118,24 +118,24 @@

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,
+ .type = SERIO_8042,
+ .open = maceps2_open,
+ .close = maceps2_close,
+ .write = maceps2_write,
+ .name = "MACE PS/2 port0",
+ .phys = "mace/serio0",
+ .port_data = &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,
+ .type = SERIO_8042,
+ .open = maceps2_open,
+ .close = maceps2_close,
+ .write = maceps2_write,
+ .name = "MACE PS/2 port1",
+ .phys = "mace/serio1",
+ .port_data = &port1_data,
};

static int __init maceps2_init(void)
diff -Nru a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
--- a/drivers/input/serio/pcips2.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/input/serio/pcips2.c 2004-06-27 17:47:31 -05:00
@@ -45,7 +45,7 @@

static int pcips2_write(struct serio *io, unsigned char val)
{
- struct pcips2_data *ps2if = io->driver;
+ struct pcips2_data *ps2if = io->port_data;
unsigned int stat;

do {
@@ -101,7 +101,7 @@

static int pcips2_open(struct serio *io)
{
- struct pcips2_data *ps2if = io->driver;
+ struct pcips2_data *ps2if = io->port_data;
int ret, val = 0;

outb(PS2_CTRL_ENABLE, ps2if->base);
@@ -119,7 +119,7 @@

static void pcips2_close(struct serio *io)
{
- struct pcips2_data *ps2if = io->driver;
+ struct pcips2_data *ps2if = io->port_data;

outb(0, ps2if->base);

@@ -155,7 +155,7 @@
ps2if->io.close = pcips2_close;
ps2if->io.name = pci_name(dev);
ps2if->io.phys = dev->dev.bus_id;
- ps2if->io.driver = ps2if;
+ ps2if->io.port_data = ps2if;
ps2if->dev = dev;
ps2if->base = pci_resource_start(dev, 0);

diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
--- a/drivers/input/serio/sa1111ps2.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/input/serio/sa1111ps2.c 2004-06-27 17:47:31 -05:00
@@ -95,7 +95,7 @@
*/
static int ps2_write(struct serio *io, unsigned char val)
{
- struct ps2if *ps2if = io->driver;
+ struct ps2if *ps2if = io->port_data;
unsigned long flags;
unsigned int head;

@@ -122,7 +122,7 @@

static int ps2_open(struct serio *io)
{
- struct ps2if *ps2if = io->driver;
+ struct ps2if *ps2if = io->port_data;
int ret;

sa1111_enable_device(ps2if->dev);
@@ -154,7 +154,7 @@

static void ps2_close(struct serio *io)
{
- struct ps2if *ps2if = io->driver;
+ struct ps2if *ps2if = io->port_data;

sa1111_writel(0, ps2if->base + SA1111_PS2CR);

@@ -247,7 +247,7 @@
ps2if->io.close = ps2_close;
ps2if->io.name = dev->dev.bus_id;
ps2if->io.phys = dev->dev.bus_id;
- ps2if->io.driver = ps2if;
+ ps2if->io.port_data = ps2if;
ps2if->dev = dev;
sa1111_set_drvdata(dev, ps2if);

diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/input/serio/serport.c 2004-06-27 17:47:31 -05:00
@@ -44,13 +44,13 @@

static int serport_serio_write(struct serio *serio, unsigned char data)
{
- struct serport *serport = serio->driver;
+ struct serport *serport = serio->port_data;
return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1);
}

static void serport_serio_close(struct serio *serio)
{
- struct serport *serport = serio->driver;
+ struct serport *serport = serio->port_data;

serport->serio.type = 0;
wake_up_interruptible(&serport->wait);
@@ -83,7 +83,7 @@
serport->serio.type = SERIO_RS232;
serport->serio.write = serport_serio_write;
serport->serio.close = serport_serio_close;
- serport->serio.driver = serport;
+ serport->serio.port_data = serport;

init_waitqueue_head(&serport->wait);

diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/serial/sunsu.c 2004-06-27 17:47:31 -05:00
@@ -994,7 +994,7 @@

static int sunsu_serio_write(struct serio *serio, unsigned char ch)
{
- struct uart_sunsu_port *up = serio->driver;
+ struct uart_sunsu_port *up = serio->port_data;
unsigned long flags;
int lsr;

@@ -1014,7 +1014,7 @@

static int sunsu_serio_open(struct serio *serio)
{
- struct uart_sunsu_port *up = serio->driver;
+ struct uart_sunsu_port *up = serio->port_data;
unsigned long flags;
int ret;

@@ -1031,7 +1031,7 @@

static void sunsu_serio_close(struct serio *serio)
{
- struct uart_sunsu_port *up = serio->driver;
+ struct uart_sunsu_port *up = serio->port_data;
unsigned long flags;

spin_lock_irqsave(&sunsu_serio_lock, flags);
@@ -1311,7 +1311,7 @@
#ifdef CONFIG_SERIO
memset(&up->serio, 0, sizeof(up->serio));

- up->serio.driver = up;
+ up->serio.port_data = up;

up->serio.type = SERIO_RS232;
if (up->su_type == SU_PORT_KBD) {
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c 2004-06-27 17:47:31 -05:00
+++ b/drivers/serial/sunzilog.c 2004-06-27 17:47:31 -05:00
@@ -1295,7 +1295,7 @@

static int sunzilog_serio_write(struct serio *serio, unsigned char ch)
{
- struct uart_sunzilog_port *up = serio->driver;
+ struct uart_sunzilog_port *up = serio->port_data;
unsigned long flags;

spin_lock_irqsave(&sunzilog_serio_lock, flags);
@@ -1309,7 +1309,7 @@

static int sunzilog_serio_open(struct serio *serio)
{
- struct uart_sunzilog_port *up = serio->driver;
+ struct uart_sunzilog_port *up = serio->port_data;
unsigned long flags;
int ret;

@@ -1326,7 +1326,7 @@

static void sunzilog_serio_close(struct serio *serio)
{
- struct uart_sunzilog_port *up = serio->driver;
+ struct uart_sunzilog_port *up = serio->port_data;
unsigned long flags;

spin_lock_irqsave(&sunzilog_serio_lock, flags);
@@ -1549,7 +1549,7 @@
#ifdef CONFIG_SERIO
memset(&up->serio, 0, sizeof(up->serio));

- up->serio.driver = up;
+ up->serio.port_data = up;

up->serio.type = SERIO_RS232;
if (channel == KEYBOARD_LINE) {
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h 2004-06-27 17:47:31 -05:00
+++ b/include/linux/serio.h 2004-06-27 17:47:31 -05:00
@@ -21,7 +21,7 @@

struct serio {
void *private;
- void *driver;
+ void *port_data;
char *name;
char *phys;

2004-06-28 05:18:58

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 4/19] serio renames 2


===================================================================


[email protected], 2004-06-27 15:46:16-05:00, [email protected]
Input: more renames in serio in preparations to sysfs integration
- serio_dev -> serio_driver
- serio_[un]register_device -> serio_[un]register_driver

Signed-off-by: Dmitry Torokhov <[email protected]>


drivers/input/joystick/iforce/iforce-main.c | 4 -
drivers/input/joystick/iforce/iforce-serio.c | 6 +-
drivers/input/joystick/iforce/iforce.h | 2
drivers/input/joystick/magellan.c | 10 +--
drivers/input/joystick/spaceball.c | 10 +--
drivers/input/joystick/spaceorb.c | 10 +--
drivers/input/joystick/stinger.c | 10 +--
drivers/input/joystick/twidjoy.c | 10 +--
drivers/input/joystick/warrior.c | 10 +--
drivers/input/keyboard/atkbd.c | 14 ++---
drivers/input/keyboard/lkkbd.c | 10 +--
drivers/input/keyboard/newtonkbd.c | 10 +--
drivers/input/keyboard/sunkbd.c | 10 +--
drivers/input/keyboard/xtkbd.c | 10 +--
drivers/input/mouse/psmouse-base.c | 14 ++---
drivers/input/mouse/sermouse.c | 10 +--
drivers/input/mouse/synaptics.c | 2
drivers/input/mouse/vsxxxaa.c | 10 +--
drivers/input/serio/serio.c | 72 +++++++++++++--------------
drivers/input/serio/serport.c | 2
drivers/input/touchscreen/gunze.c | 10 +--
drivers/input/touchscreen/h3600_ts_input.c | 10 +--
include/linux/serio.h | 22 ++++----
23 files changed, 139 insertions(+), 139 deletions(-)


===================================================================



diff -Nru a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
--- a/drivers/input/joystick/iforce/iforce-main.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/joystick/iforce/iforce-main.c 2004-06-27 17:47:51 -05:00
@@ -524,7 +524,7 @@
usb_register(&iforce_usb_driver);
#endif
#ifdef CONFIG_JOYSTICK_IFORCE_232
- serio_register_device(&iforce_serio_dev);
+ serio_register_driver(&iforce_serio_drv);
#endif
return 0;
}
@@ -535,7 +535,7 @@
usb_deregister(&iforce_usb_driver);
#endif
#ifdef CONFIG_JOYSTICK_IFORCE_232
- serio_unregister_device(&iforce_serio_dev);
+ serio_unregister_driver(&iforce_serio_drv);
#endif
}

diff -Nru a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
--- a/drivers/input/joystick/iforce/iforce-serio.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/joystick/iforce/iforce-serio.c 2004-06-27 17:47:51 -05:00
@@ -124,7 +124,7 @@
return IRQ_HANDLED;
}

-static void iforce_serio_connect(struct serio *serio, struct serio_dev *dev)
+static void iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
{
struct iforce *iforce;
if (serio->type != (SERIO_RS232 | SERIO_IFORCE))
@@ -137,7 +137,7 @@
iforce->serio = serio;
serio->private = iforce;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(iforce);
return;
}
@@ -158,7 +158,7 @@
kfree(iforce);
}

-struct serio_dev iforce_serio_dev = {
+struct serio_driver iforce_serio_drv = {
.write_wakeup = iforce_serio_write_wakeup,
.interrupt = iforce_serio_irq,
.connect = iforce_serio_connect,
diff -Nru a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
--- a/drivers/input/joystick/iforce/iforce.h 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/joystick/iforce/iforce.h 2004-06-27 17:47:51 -05:00
@@ -187,5 +187,5 @@
int iforce_upload_condition(struct iforce*, struct ff_effect*, int is_update);

/* Public variables */
-extern struct serio_dev iforce_serio_dev;
+extern struct serio_driver iforce_serio_drv;
extern struct usb_driver iforce_usb_driver;
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
--- a/drivers/input/joystick/magellan.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/joystick/magellan.c 2004-06-27 17:47:51 -05:00
@@ -146,7 +146,7 @@
* it as an input device.
*/

-static void magellan_connect(struct serio *serio, struct serio_dev *dev)
+static void magellan_connect(struct serio *serio, struct serio_driver *drv)
{
struct magellan *magellan;
int i, t;
@@ -184,7 +184,7 @@

serio->private = magellan;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(magellan);
return;
}
@@ -199,7 +199,7 @@
* The serio device structure.
*/

-static struct serio_dev magellan_dev = {
+static struct serio_driver magellan_drv = {
.interrupt = magellan_interrupt,
.connect = magellan_connect,
.disconnect = magellan_disconnect,
@@ -211,13 +211,13 @@

int __init magellan_init(void)
{
- serio_register_device(&magellan_dev);
+ serio_register_driver(&magellan_drv);
return 0;
}

void __exit magellan_exit(void)
{
- serio_unregister_device(&magellan_dev);
+ serio_unregister_driver(&magellan_drv);
}

module_init(magellan_init);
diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
--- a/drivers/input/joystick/spaceball.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/joystick/spaceball.c 2004-06-27 17:47:51 -05:00
@@ -201,7 +201,7 @@
* it as an input device.
*/

-static void spaceball_connect(struct serio *serio, struct serio_dev *dev)
+static void spaceball_connect(struct serio *serio, struct serio_driver *drv)
{
struct spaceball *spaceball;
int i, t, id;
@@ -254,7 +254,7 @@

serio->private = spaceball;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(spaceball);
return;
}
@@ -269,7 +269,7 @@
* The serio device structure.
*/

-static struct serio_dev spaceball_dev = {
+static struct serio_driver spaceball_drv = {
.interrupt = spaceball_interrupt,
.connect = spaceball_connect,
.disconnect = spaceball_disconnect,
@@ -281,13 +281,13 @@

int __init spaceball_init(void)
{
- serio_register_device(&spaceball_dev);
+ serio_register_driver(&spaceball_drv);
return 0;
}

void __exit spaceball_exit(void)
{
- serio_unregister_device(&spaceball_dev);
+ serio_unregister_driver(&spaceball_drv);
}

module_init(spaceball_init);
diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
--- a/drivers/input/joystick/spaceorb.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/joystick/spaceorb.c 2004-06-27 17:47:51 -05:00
@@ -162,7 +162,7 @@
* it as an input device.
*/

-static void spaceorb_connect(struct serio *serio, struct serio_dev *dev)
+static void spaceorb_connect(struct serio *serio, struct serio_driver *drv)
{
struct spaceorb *spaceorb;
int i, t;
@@ -201,7 +201,7 @@

serio->private = spaceorb;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(spaceorb);
return;
}
@@ -213,7 +213,7 @@
* The serio device structure.
*/

-static struct serio_dev spaceorb_dev = {
+static struct serio_driver spaceorb_drv = {
.interrupt = spaceorb_interrupt,
.connect = spaceorb_connect,
.disconnect = spaceorb_disconnect,
@@ -225,13 +225,13 @@

int __init spaceorb_init(void)
{
- serio_register_device(&spaceorb_dev);
+ serio_register_driver(&spaceorb_drv);
return 0;
}

void __exit spaceorb_exit(void)
{
- serio_unregister_device(&spaceorb_dev);
+ serio_unregister_driver(&spaceorb_drv);
}

module_init(spaceorb_init);
diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
--- a/drivers/input/joystick/stinger.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/joystick/stinger.c 2004-06-27 17:47:51 -05:00
@@ -134,7 +134,7 @@
* it as an input device.
*/

-static void stinger_connect(struct serio *serio, struct serio_dev *dev)
+static void stinger_connect(struct serio *serio, struct serio_driver *drv)
{
struct stinger *stinger;
int i;
@@ -172,7 +172,7 @@
stinger->dev.private = stinger;
serio->private = stinger;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(stinger);
return;
}
@@ -187,7 +187,7 @@
* The serio device structure.
*/

-static struct serio_dev stinger_dev = {
+static struct serio_driver stinger_drv = {
.interrupt = stinger_interrupt,
.connect = stinger_connect,
.disconnect = stinger_disconnect,
@@ -199,13 +199,13 @@

int __init stinger_init(void)
{
- serio_register_device(&stinger_dev);
+ serio_register_driver(&stinger_drv);
return 0;
}

void __exit stinger_exit(void)
{
- serio_unregister_device(&stinger_dev);
+ serio_unregister_driver(&stinger_drv);
}

module_init(stinger_init);
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/joystick/twidjoy.c 2004-06-27 17:47:51 -05:00
@@ -187,7 +187,7 @@
* it as an input device.
*/

-static void twidjoy_connect(struct serio *serio, struct serio_dev *dev)
+static void twidjoy_connect(struct serio *serio, struct serio_driver *drv)
{
struct twidjoy_button_spec *bp;
struct twidjoy *twidjoy;
@@ -232,7 +232,7 @@
twidjoy->dev.private = twidjoy;
serio->private = twidjoy;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(twidjoy);
return;
}
@@ -246,7 +246,7 @@
* The serio device structure.
*/

-static struct serio_dev twidjoy_dev = {
+static struct serio_driver twidjoy_drv = {
.interrupt = twidjoy_interrupt,
.connect = twidjoy_connect,
.disconnect = twidjoy_disconnect,
@@ -258,13 +258,13 @@

int __init twidjoy_init(void)
{
- serio_register_device(&twidjoy_dev);
+ serio_register_driver(&twidjoy_drv);
return 0;
}

void __exit twidjoy_exit(void)
{
- serio_unregister_device(&twidjoy_dev);
+ serio_unregister_driver(&twidjoy_drv);
}

module_init(twidjoy_init);
diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
--- a/drivers/input/joystick/warrior.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/joystick/warrior.c 2004-06-27 17:47:51 -05:00
@@ -139,7 +139,7 @@
* it as an input device.
*/

-static void warrior_connect(struct serio *serio, struct serio_dev *dev)
+static void warrior_connect(struct serio *serio, struct serio_driver *drv)
{
struct warrior *warrior;
int i;
@@ -185,7 +185,7 @@

serio->private = warrior;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(warrior);
return;
}
@@ -199,7 +199,7 @@
* The serio device structure.
*/

-static struct serio_dev warrior_dev = {
+static struct serio_driver warrior_drv = {
.interrupt = warrior_interrupt,
.connect = warrior_connect,
.disconnect = warrior_disconnect,
@@ -211,13 +211,13 @@

int __init warrior_init(void)
{
- serio_register_device(&warrior_dev);
+ serio_register_driver(&warrior_drv);
return 0;
}

void __exit warrior_exit(void)
{
- serio_unregister_device(&warrior_dev);
+ serio_unregister_driver(&warrior_drv);
}

module_init(warrior_init);
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/keyboard/atkbd.c 2004-06-27 17:47:51 -05:00
@@ -732,7 +732,7 @@
* to the input module.
*/

-static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
+static void atkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct atkbd *atkbd;
int i;
@@ -785,7 +785,7 @@

serio->private = atkbd;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(atkbd);
return;
}
@@ -861,10 +861,10 @@
static int atkbd_reconnect(struct serio *serio)
{
struct atkbd *atkbd = serio->private;
- struct serio_dev *dev = serio->dev;
+ struct serio_driver *drv = serio->drv;
unsigned char param[1];

- if (!dev) {
+ if (!drv) {
printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
return -1;
}
@@ -890,7 +890,7 @@
return 0;
}

-static struct serio_dev atkbd_dev = {
+static struct serio_driver atkbd_drv = {
.interrupt = atkbd_interrupt,
.connect = atkbd_connect,
.reconnect = atkbd_reconnect,
@@ -900,13 +900,13 @@

int __init atkbd_init(void)
{
- serio_register_device(&atkbd_dev);
+ serio_register_driver(&atkbd_drv);
return 0;
}

void __exit atkbd_exit(void)
{
- serio_unregister_device(&atkbd_dev);
+ serio_unregister_driver(&atkbd_drv);
}

module_init(atkbd_init);
diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- a/drivers/input/keyboard/lkkbd.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/keyboard/lkkbd.c 2004-06-27 17:47:51 -05:00
@@ -622,7 +622,7 @@
* lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
*/
static void
-lkkbd_connect (struct serio *serio, struct serio_dev *dev)
+lkkbd_connect (struct serio *serio, struct serio_driver *drv)
{
struct lkkbd *lk;
int i;
@@ -665,7 +665,7 @@

serio->private = lk;

- if (serio_open (serio, dev)) {
+ if (serio_open (serio, drv)) {
kfree (lk);
return;
}
@@ -703,7 +703,7 @@
kfree (lk);
}

-static struct serio_dev lkkbd_dev = {
+static struct serio_driver lkkbd_drv = {
.connect = lkkbd_connect,
.disconnect = lkkbd_disconnect,
.interrupt = lkkbd_interrupt,
@@ -715,14 +715,14 @@
int __init
lkkbd_init (void)
{
- serio_register_device (&lkkbd_dev);
+ serio_register_driver(&lkkbd_drv);
return 0;
}

void __exit
lkkbd_exit (void)
{
- serio_unregister_device (&lkkbd_dev);
+ serio_unregister_driver(&lkkbd_drv);
}

module_init (lkkbd_init);
diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
--- a/drivers/input/keyboard/newtonkbd.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/keyboard/newtonkbd.c 2004-06-27 17:47:51 -05:00
@@ -82,7 +82,7 @@

}

-void nkbd_connect(struct serio *serio, struct serio_dev *dev)
+void nkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct nkbd *nkbd;
int i;
@@ -106,7 +106,7 @@
nkbd->dev.private = nkbd;
serio->private = nkbd;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(nkbd);
return;
}
@@ -138,7 +138,7 @@
kfree(nkbd);
}

-struct serio_dev nkbd_dev = {
+struct serio_driver nkbd_drv = {
.interrupt = nkbd_interrupt,
.connect = nkbd_connect,
.disconnect = nkbd_disconnect
@@ -146,13 +146,13 @@

int __init nkbd_init(void)
{
- serio_register_device(&nkbd_dev);
+ serio_register_driver(&nkbd_drv);
return 0;
}

void __exit nkbd_exit(void)
{
- serio_unregister_device(&nkbd_dev);
+ serio_unregister_driver(&nkbd_drv);
}

module_init(nkbd_init);
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/keyboard/sunkbd.c 2004-06-27 17:47:51 -05:00
@@ -221,7 +221,7 @@
* sunkbd_connect() probes for a Sun keyboard and fills the necessary structures.
*/

-static void sunkbd_connect(struct serio *serio, struct serio_dev *dev)
+static void sunkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct sunkbd *sunkbd;
int i;
@@ -257,7 +257,7 @@

serio->private = sunkbd;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(sunkbd);
return;
}
@@ -301,7 +301,7 @@
kfree(sunkbd);
}

-static struct serio_dev sunkbd_dev = {
+static struct serio_driver sunkbd_drv = {
.interrupt = sunkbd_interrupt,
.connect = sunkbd_connect,
.disconnect = sunkbd_disconnect
@@ -313,13 +313,13 @@

int __init sunkbd_init(void)
{
- serio_register_device(&sunkbd_dev);
+ serio_register_driver(&sunkbd_drv);
return 0;
}

void __exit sunkbd_exit(void)
{
- serio_unregister_device(&sunkbd_dev);
+ serio_unregister_driver(&sunkbd_drv);
}

module_init(sunkbd_init);
diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
--- a/drivers/input/keyboard/xtkbd.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/keyboard/xtkbd.c 2004-06-27 17:47:51 -05:00
@@ -86,7 +86,7 @@
return IRQ_HANDLED;
}

-void xtkbd_connect(struct serio *serio, struct serio_dev *dev)
+void xtkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct xtkbd *xtkbd;
int i;
@@ -111,7 +111,7 @@

serio->private = xtkbd;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(xtkbd);
return;
}
@@ -143,7 +143,7 @@
kfree(xtkbd);
}

-struct serio_dev xtkbd_dev = {
+struct serio_driver xtkbd_drv = {
.interrupt = xtkbd_interrupt,
.connect = xtkbd_connect,
.disconnect = xtkbd_disconnect
@@ -151,13 +151,13 @@

int __init xtkbd_init(void)
{
- serio_register_device(&xtkbd_dev);
+ serio_register_driver(&xtkbd_drv);
return 0;
}

void __exit xtkbd_exit(void)
{
- serio_unregister_device(&xtkbd_dev);
+ serio_unregister_driver(&xtkbd_drv);
}

module_init(xtkbd_init);
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/mouse/psmouse-base.c 2004-06-27 17:47:51 -05:00
@@ -693,7 +693,7 @@
* psmouse_connect() is a callback from the serio module when
* an unhandled serio port is found.
*/
-static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
+static void psmouse_connect(struct serio *serio, struct serio_driver *drv)
{
struct psmouse *psmouse;

@@ -715,7 +715,7 @@
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);

serio->private = psmouse;
- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(psmouse);
serio->private = NULL;
return;
@@ -768,9 +768,9 @@
static int psmouse_reconnect(struct serio *serio)
{
struct psmouse *psmouse = serio->private;
- struct serio_dev *dev = serio->dev;
+ struct serio_driver *drv = serio->drv;

- if (!dev || !psmouse) {
+ if (!drv || !psmouse) {
printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
return -1;
}
@@ -803,7 +803,7 @@
}


-static struct serio_dev psmouse_dev = {
+static struct serio_driver psmouse_drv = {
.interrupt = psmouse_interrupt,
.connect = psmouse_connect,
.reconnect = psmouse_reconnect,
@@ -828,13 +828,13 @@
int __init psmouse_init(void)
{
psmouse_parse_proto();
- serio_register_device(&psmouse_dev);
+ serio_register_driver(&psmouse_drv);
return 0;
}

void __exit psmouse_exit(void)
{
- serio_unregister_device(&psmouse_dev);
+ serio_unregister_driver(&psmouse_drv);
}

module_init(psmouse_init);
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- a/drivers/input/mouse/sermouse.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/mouse/sermouse.c 2004-06-27 17:47:51 -05:00
@@ -237,7 +237,7 @@
* an unhandled serio port is found.
*/

-static void sermouse_connect(struct serio *serio, struct serio_dev *dev)
+static void sermouse_connect(struct serio *serio, struct serio_driver *drv)
{
struct sermouse *sermouse;
unsigned char c;
@@ -279,7 +279,7 @@
sermouse->dev.id.product = c;
sermouse->dev.id.version = 0x0100;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(sermouse);
return;
}
@@ -289,7 +289,7 @@
printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys);
}

-static struct serio_dev sermouse_dev = {
+static struct serio_driver sermouse_drv = {
.interrupt = sermouse_interrupt,
.connect = sermouse_connect,
.disconnect = sermouse_disconnect
@@ -297,13 +297,13 @@

int __init sermouse_init(void)
{
- serio_register_device(&sermouse_dev);
+ serio_register_driver(&sermouse_drv);
return 0;
}

void __exit sermouse_exit(void)
{
- serio_unregister_device(&sermouse_dev);
+ serio_unregister_driver(&sermouse_drv);
}

module_init(sermouse_init);
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/mouse/synaptics.c 2004-06-27 17:47:51 -05:00
@@ -470,7 +470,7 @@
if (unlikely(priv->pkt_type == SYN_NEWABS))
priv->pkt_type = synaptics_detect_pkt_type(psmouse);

- if (psmouse->ptport && psmouse->ptport->serio.dev && synaptics_is_pt_packet(psmouse->packet))
+ if (psmouse->ptport && psmouse->ptport->serio.drv && synaptics_is_pt_packet(psmouse->packet))
synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
else
synaptics_process_packet(psmouse);
diff -Nru a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
--- a/drivers/input/mouse/vsxxxaa.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/mouse/vsxxxaa.c 2004-06-27 17:47:51 -05:00
@@ -482,7 +482,7 @@
}

static void
-vsxxxaa_connect (struct serio *serio, struct serio_dev *dev)
+vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
{
struct vsxxxaa *mouse;

@@ -524,7 +524,7 @@
mouse->dev.id.bustype = BUS_RS232;
mouse->serio = serio;

- if (serio_open (serio, dev)) {
+ if (serio_open (serio, drv)) {
kfree (mouse);
return;
}
@@ -540,7 +540,7 @@
printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys);
}

-static struct serio_dev vsxxxaa_dev = {
+static struct serio_driver vsxxxaa_drv = {
.connect = vsxxxaa_connect,
.interrupt = vsxxxaa_interrupt,
.disconnect = vsxxxaa_disconnect,
@@ -549,14 +549,14 @@
int __init
vsxxxaa_init (void)
{
- serio_register_device (&vsxxxaa_dev);
+ serio_register_driver(&vsxxxaa_drv);
return 0;
}

void __exit
vsxxxaa_exit (void)
{
- serio_unregister_device (&vsxxxaa_dev);
+ serio_unregister_driver(&vsxxxaa_drv);
}

module_init (vsxxxaa_init);
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/serio/serio.c 2004-06-27 17:47:51 -05:00
@@ -48,27 +48,27 @@
EXPORT_SYMBOL(serio_unregister_port);
EXPORT_SYMBOL(serio_unregister_port_delayed);
EXPORT_SYMBOL(__serio_unregister_port);
-EXPORT_SYMBOL(serio_register_device);
-EXPORT_SYMBOL(serio_unregister_device);
+EXPORT_SYMBOL(serio_register_driver);
+EXPORT_SYMBOL(serio_unregister_driver);
EXPORT_SYMBOL(serio_open);
EXPORT_SYMBOL(serio_close);
EXPORT_SYMBOL(serio_rescan);
EXPORT_SYMBOL(serio_reconnect);

-static DECLARE_MUTEX(serio_sem); /* protects serio_list and serio_dev_list */
+static DECLARE_MUTEX(serio_sem); /* protects serio_list and serio_diriver_list */
static LIST_HEAD(serio_list);
-static LIST_HEAD(serio_dev_list);
+static LIST_HEAD(serio_driver_list);

-/* serio_find_dev() must be called with serio_sem down. */
+/* serio_find_driver() must be called with serio_sem down. */

-static void serio_find_dev(struct serio *serio)
+static void serio_find_driver(struct serio *serio)
{
- struct serio_dev *dev;
+ struct serio_driver *drv;

- list_for_each_entry(dev, &serio_dev_list, node) {
- if (serio->dev)
+ list_for_each_entry(drv, &serio_driver_list, node) {
+ if (serio->drv)
break;
- dev->connect(serio, dev);
+ drv->connect(serio, drv);
}
}

@@ -153,15 +153,15 @@
break;

case SERIO_RECONNECT :
- if (event->serio->dev && event->serio->dev->reconnect)
- if (event->serio->dev->reconnect(event->serio) == 0)
+ if (event->serio->drv && event->serio->drv->reconnect)
+ if (event->serio->drv->reconnect(event->serio) == 0)
break;
/* reconnect failed - fall through to rescan */

case SERIO_RESCAN :
- if (event->serio->dev)
- event->serio->dev->disconnect(event->serio);
- serio_find_dev(event->serio);
+ if (event->serio->drv)
+ event->serio->drv->disconnect(event->serio);
+ serio_find_driver(event->serio);
break;
default:
break;
@@ -252,7 +252,7 @@
{
spin_lock_init(&serio->lock);
list_add_tail(&serio->node, &serio_list);
- serio_find_dev(serio);
+ serio_find_driver(serio);
}

void serio_unregister_port(struct serio *serio)
@@ -281,58 +281,58 @@
{
serio_remove_pending_events(serio);
list_del_init(&serio->node);
- if (serio->dev)
- serio->dev->disconnect(serio);
+ if (serio->drv)
+ serio->drv->disconnect(serio);
}

/*
- * Serio device operations
+ * Serio driver operations
*/

-void serio_register_device(struct serio_dev *dev)
+void serio_register_driver(struct serio_driver *drv)
{
struct serio *serio;
down(&serio_sem);
- list_add_tail(&dev->node, &serio_dev_list);
+ list_add_tail(&drv->node, &serio_driver_list);
list_for_each_entry(serio, &serio_list, node)
- if (!serio->dev)
- dev->connect(serio, dev);
+ if (!serio->drv)
+ drv->connect(serio, drv);
up(&serio_sem);
}

-void serio_unregister_device(struct serio_dev *dev)
+void serio_unregister_driver(struct serio_driver *drv)
{
struct serio *serio;

down(&serio_sem);
- list_del_init(&dev->node);
+ list_del_init(&drv->node);

list_for_each_entry(serio, &serio_list, node) {
- if (serio->dev == dev)
- dev->disconnect(serio);
- serio_find_dev(serio);
+ if (serio->drv == drv)
+ drv->disconnect(serio);
+ serio_find_driver(serio);
}
up(&serio_sem);
}

-/* called from serio_dev->connect/disconnect methods under serio_sem */
-int serio_open(struct serio *serio, struct serio_dev *dev)
+/* called from serio_driver->connect/disconnect methods under serio_sem */
+int serio_open(struct serio *serio, struct serio_driver *drv)
{
unsigned long flags;

spin_lock_irqsave(&serio->lock, flags);
- serio->dev = dev;
+ serio->drv = drv;
spin_unlock_irqrestore(&serio->lock, flags);
if (serio->open && serio->open(serio)) {
spin_lock_irqsave(&serio->lock, flags);
- serio->dev = NULL;
+ serio->drv = NULL;
spin_unlock_irqrestore(&serio->lock, flags);
return -1;
}
return 0;
}

-/* called from serio_dev->connect/disconnect methods under serio_sem */
+/* called from serio_driver->connect/disconnect methods under serio_sem */
void serio_close(struct serio *serio)
{
unsigned long flags;
@@ -340,7 +340,7 @@
if (serio->close)
serio->close(serio);
spin_lock_irqsave(&serio->lock, flags);
- serio->dev = NULL;
+ serio->drv = NULL;
spin_unlock_irqrestore(&serio->lock, flags);
}

@@ -352,8 +352,8 @@

spin_lock_irqsave(&serio->lock, flags);

- if (likely(serio->dev)) {
- ret = serio->dev->interrupt(serio, data, dfl, regs);
+ if (likely(serio->drv)) {
+ ret = serio->drv->interrupt(serio, data, dfl, regs);
} else {
if (!dfl) {
if ((serio->type != SERIO_8042 &&
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/serio/serport.c 2004-06-27 17:47:51 -05:00
@@ -170,7 +170,7 @@
{
struct serport *sp = (struct serport *) tty->disc_data;

- serio_dev_write_wakeup(&sp->serio);
+ serio_drv_write_wakeup(&sp->serio);
}

/*
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
--- a/drivers/input/touchscreen/gunze.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/touchscreen/gunze.c 2004-06-27 17:47:51 -05:00
@@ -111,7 +111,7 @@
* and if yes, registers it as an input device.
*/

-static void gunze_connect(struct serio *serio, struct serio_dev *dev)
+static void gunze_connect(struct serio *serio, struct serio_driver *drv)
{
struct gunze *gunze;

@@ -142,7 +142,7 @@
gunze->dev.id.product = 0x0051;
gunze->dev.id.version = 0x0100;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
kfree(gunze);
return;
}
@@ -156,7 +156,7 @@
* The serio device structure.
*/

-static struct serio_dev gunze_dev = {
+static struct serio_driver gunze_drv = {
.interrupt = gunze_interrupt,
.connect = gunze_connect,
.disconnect = gunze_disconnect,
@@ -168,13 +168,13 @@

int __init gunze_init(void)
{
- serio_register_device(&gunze_dev);
+ serio_register_driver(&gunze_drv);
return 0;
}

void __exit gunze_exit(void)
{
- serio_unregister_device(&gunze_dev);
+ serio_unregister_driver(&gunze_drv);
}

module_init(gunze_init);
diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c 2004-06-27 17:47:51 -05:00
+++ b/drivers/input/touchscreen/h3600_ts_input.c 2004-06-27 17:47:51 -05:00
@@ -373,7 +373,7 @@
* new serio device. It looks whether it was registered as a H3600 touchscreen
* and if yes, registers it as an input device.
*/
-static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
+static void h3600ts_connect(struct serio *serio, struct serio_driver *drv)
{
struct h3600_dev *ts;

@@ -441,7 +441,7 @@
ts->dev.id.product = 0x0666; /* FIXME !!! We can ask the hardware */
ts->dev.id.version = 0x0100;

- if (serio_open(serio, dev)) {
+ if (serio_open(serio, drv)) {
free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts);
free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts);
kfree(ts);
@@ -478,7 +478,7 @@
* The serio device structure.
*/

-static struct serio_dev h3600ts_dev = {
+static struct serio_driver h3600ts_drv = {
.interrupt = h3600ts_interrupt,
.connect = h3600ts_connect,
.disconnect = h3600ts_disconnect,
@@ -490,13 +490,13 @@

static int __init h3600ts_init(void)
{
- serio_register_device(&h3600ts_dev);
+ serio_register_driver(&h3600ts_drv);
return 0;
}

static void __exit h3600ts_exit(void)
{
- serio_unregister_device(&h3600ts_dev);
+ serio_unregister_driver(&h3600ts_drv);
}

module_init(h3600ts_init);
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h 2004-06-27 17:47:51 -05:00
+++ b/include/linux/serio.h 2004-06-27 17:47:51 -05:00
@@ -39,19 +39,19 @@
int (*open)(struct serio *);
void (*close)(struct serio *);

- struct serio_dev *dev; /* Accessed from interrupt, writes must be protected by serio_lock */
+ struct serio_driver *drv; /* Accessed from interrupt, writes must be protected by serio_lock */

struct list_head node;
};

-struct serio_dev {
+struct serio_driver {
void *private;
char *name;

void (*write_wakeup)(struct serio *);
irqreturn_t (*interrupt)(struct serio *, unsigned char,
unsigned int, struct pt_regs *);
- void (*connect)(struct serio *, struct serio_dev *dev);
+ void (*connect)(struct serio *, struct serio_driver *drv);
int (*reconnect)(struct serio *);
void (*disconnect)(struct serio *);
void (*cleanup)(struct serio *);
@@ -59,7 +59,7 @@
struct list_head node;
};

-int serio_open(struct serio *serio, struct serio_dev *dev);
+int serio_open(struct serio *serio, struct serio_driver *drv);
void serio_close(struct serio *serio);
void serio_rescan(struct serio *serio);
void serio_reconnect(struct serio *serio);
@@ -71,8 +71,8 @@
void serio_unregister_port(struct serio *serio);
void serio_unregister_port_delayed(struct serio *serio);
void __serio_unregister_port(struct serio *serio);
-void serio_register_device(struct serio_dev *dev);
-void serio_unregister_device(struct serio_dev *dev);
+void serio_register_driver(struct serio_driver *drv);
+void serio_unregister_driver(struct serio_driver *drv);

static __inline__ int serio_write(struct serio *serio, unsigned char data)
{
@@ -82,16 +82,16 @@
return -1;
}

-static __inline__ void serio_dev_write_wakeup(struct serio *serio)
+static __inline__ void serio_drv_write_wakeup(struct serio *serio)
{
- if (serio->dev && serio->dev->write_wakeup)
- serio->dev->write_wakeup(serio);
+ if (serio->drv && serio->drv->write_wakeup)
+ serio->drv->write_wakeup(serio);
}

static __inline__ void serio_cleanup(struct serio *serio)
{
- if (serio->dev && serio->dev->cleanup)
- serio->dev->cleanup(serio);
+ if (serio->drv && serio->drv->cleanup)
+ serio->drv->cleanup(serio);
}

#endif

2004-06-28 05:23:36

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 5/19] serio dynamic allocation


===================================================================


[email protected], 2004-06-27 15:54:09-05:00, [email protected]
Input: switch to dynamic (heap) serio port allocation in preparation
to sysfs integration. By having all data structures dynamically
allocated serio driver modules can be unloaded without waiting
for the last reference to the port to be dropped.

Signed-off-by: Dmitry Torokhov <[email protected]>


drivers/input/mouse/psmouse-base.c | 12 +-
drivers/input/mouse/psmouse.h | 3
drivers/input/mouse/synaptics.c | 33 +++--
drivers/input/serio/ambakmi.c | 35 +++---
drivers/input/serio/ct82c710.c | 62 ++++++-----
drivers/input/serio/gscps2.c | 55 ++++++---
drivers/input/serio/i8042.c | 208 ++++++++++++++++++++-----------------
drivers/input/serio/i8042.h | 7 +
drivers/input/serio/maceps2.c | 69 ++++++------
drivers/input/serio/parkbd.c | 47 +++++---
drivers/input/serio/pcips2.c | 30 +++--
drivers/input/serio/q40kbd.c | 107 ++++++++++++++-----
drivers/input/serio/rpckbd.c | 40 +++++--
drivers/input/serio/sa1111ps2.c | 32 +++--
drivers/input/serio/serio.c | 1
drivers/input/serio/serport.c | 45 ++++----
drivers/serial/sunsu.c | 83 ++++++++------
drivers/serial/sunzilog.c | 60 ++++++----
include/linux/serio.h | 5
19 files changed, 562 insertions(+), 372 deletions(-)


===================================================================



diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/mouse/psmouse-base.c 2004-06-27 17:48:12 -05:00
@@ -674,7 +674,7 @@
if (psmouse->ptport) {
if (psmouse->ptport->deactivate)
psmouse->ptport->deactivate(psmouse);
- __serio_unregister_port(&psmouse->ptport->serio); /* we have serio_sem */
+ __serio_unregister_port(psmouse->ptport->serio); /* we have serio_sem */
kfree(psmouse->ptport);
psmouse->ptport = NULL;
}
@@ -755,8 +755,8 @@
psmouse_initialize(psmouse);

if (psmouse->ptport) {
- printk(KERN_INFO "serio: %s port at %s\n", psmouse->ptport->serio.name, psmouse->phys);
- __serio_register_port(&psmouse->ptport->serio); /* we have serio_sem */
+ printk(KERN_INFO "serio: %s port at %s\n", psmouse->ptport->serio->name, psmouse->phys);
+ __serio_register_port(psmouse->ptport->serio); /* we have serio_sem */
if (psmouse->ptport->activate)
psmouse->ptport->activate(psmouse);
}
@@ -790,9 +790,9 @@
psmouse_initialize(psmouse);

if (psmouse->ptport) {
- if (psmouse_reconnect(&psmouse->ptport->serio)) {
- __serio_unregister_port(&psmouse->ptport->serio);
- __serio_register_port(&psmouse->ptport->serio);
+ if (psmouse_reconnect(psmouse->ptport->serio)) {
+ __serio_unregister_port(psmouse->ptport->serio);
+ __serio_register_port(psmouse->ptport->serio);
if (psmouse->ptport->activate)
psmouse->ptport->activate(psmouse);
}
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/mouse/psmouse.h 2004-06-27 17:48:12 -05:00
@@ -37,7 +37,8 @@
struct psmouse;

struct psmouse_ptport {
- struct serio serio;
+ struct serio *serio;
+ struct psmouse *parent;

void (*activate)(struct psmouse *parent);
void (*deactivate)(struct psmouse *parent);
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/mouse/synaptics.c 2004-06-27 17:48:12 -05:00
@@ -214,12 +214,12 @@
****************************************************************************/
static int synaptics_pt_write(struct serio *port, unsigned char c)
{
- struct psmouse *parent = port->port_data;
+ struct psmouse_ptport *ptport = port->port_data;
char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */

- if (psmouse_sliced_command(parent, c))
+ if (psmouse_sliced_command(ptport->parent, c))
return -1;
- if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
+ if (psmouse_command(ptport->parent, &rate_param, PSMOUSE_CMD_SETRATE))
return -1;
return 0;
}
@@ -248,7 +248,7 @@

static void synaptics_pt_activate(struct psmouse *psmouse)
{
- struct psmouse *child = psmouse->ptport->serio.private;
+ struct psmouse *child = psmouse->ptport->serio->private;

/* adjust the touchpad to child's choice of protocol */
if (child && child->type >= PSMOUSE_GENPS) {
@@ -260,22 +260,29 @@
static void synaptics_pt_create(struct psmouse *psmouse)
{
struct psmouse_ptport *port;
+ struct serio *serio;

- psmouse->ptport = port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
- if (!port) {
+ port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (!port || !serio) {
printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
return;
}

memset(port, 0, sizeof(struct psmouse_ptport));
+ memset(serio, 0, sizeof(struct serio));

- port->serio.type = SERIO_PS_PSTHRU;
- port->serio.name = "Synaptics pass-through";
- port->serio.phys = "synaptics-pt/serio0";
- port->serio.write = synaptics_pt_write;
- port->serio.port_data = psmouse;
+ serio->type = SERIO_PS_PSTHRU;
+ strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
+ strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name));
+ serio->write = synaptics_pt_write;
+ serio->port_data = port;

+ port->serio = serio;
+ port->parent = psmouse;
port->activate = synaptics_pt_activate;
+
+ psmouse->ptport = port;
}

/*****************************************************************************
@@ -470,8 +477,8 @@
if (unlikely(priv->pkt_type == SYN_NEWABS))
priv->pkt_type = synaptics_detect_pkt_type(psmouse);

- if (psmouse->ptport && psmouse->ptport->serio.drv && synaptics_is_pt_packet(psmouse->packet))
- synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
+ if (psmouse->ptport && psmouse->ptport->serio->drv && synaptics_is_pt_packet(psmouse->packet))
+ synaptics_pass_pt_packet(psmouse->ptport->serio, psmouse->packet);
else
synaptics_process_packet(psmouse);

diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/ambakmi.c 2004-06-27 17:48:12 -05:00
@@ -29,7 +29,7 @@
#define KMI_BASE (kmi->base)

struct amba_kmi_port {
- struct serio io;
+ struct serio *io;
struct clk *clk;
unsigned char *base;
unsigned int irq;
@@ -44,7 +44,7 @@
int handled = IRQ_NONE;

while (status & KMIIR_RXINTR) {
- serio_interrupt(&kmi->io, readb(KMIDATA), 0, regs);
+ serio_interrupt(kmi->io, readb(KMIDATA), 0, regs);
status = readb(KMIIR);
handled = IRQ_HANDLED;
}
@@ -117,6 +117,7 @@
static int amba_kmi_probe(struct amba_device *dev, void *id)
{
struct amba_kmi_port *kmi;
+ struct serio *io;
int ret;

ret = amba_request_regions(dev, NULL);
@@ -124,22 +125,25 @@
return ret;

kmi = kmalloc(sizeof(struct amba_kmi_port), GFP_KERNEL);
- if (!kmi) {
+ io = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (!kmi || !io) {
ret = -ENOMEM;
goto out;
}

memset(kmi, 0, sizeof(struct amba_kmi_port));
+ memset(io, 0, sizeof(struct serio));

- kmi->io.type = SERIO_8042;
- kmi->io.write = amba_kmi_write;
- kmi->io.open = amba_kmi_open;
- kmi->io.close = amba_kmi_close;
- kmi->io.name = dev->dev.bus_id;
- kmi->io.phys = dev->dev.bus_id;
- kmi->io.port_data = kmi;
+ io->type = SERIO_8042;
+ io->write = amba_kmi_write;
+ io->open = amba_kmi_open;
+ io->close = amba_kmi_close;
+ strlcpy(io->name, dev->dev.bus_id, sizeof(io->name));
+ strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys));
+ io->port_data = kmi;

- kmi->base = ioremap(dev->res.start, KMI_SIZE);
+ kmi->io = io;
+ kmi->base = ioremap(dev->res.start, KMI_SIZE);
if (!kmi->base) {
ret = -ENOMEM;
goto out;
@@ -154,13 +158,14 @@
kmi->irq = dev->irq[0];
amba_set_drvdata(dev, kmi);

- serio_register_port(&kmi->io);
+ serio_register_port(kmi->io);
return 0;

unmap:
iounmap(kmi->base);
out:
kfree(kmi);
+ kfree(io);
amba_release_regions(dev);
return ret;
}
@@ -171,7 +176,7 @@

amba_set_drvdata(dev, NULL);

- serio_unregister_port(&kmi->io);
+ serio_unregister_port(kmi->io);
clk_put(kmi->clk);
iounmap(kmi->base);
kfree(kmi);
@@ -184,7 +189,7 @@
struct amba_kmi_port *kmi = amba_get_drvdata(dev);

/* kick the serio layer to rescan this port */
- serio_rescan(&kmi->io);
+ serio_reconnect(kmi->io);

return 0;
}
@@ -214,7 +219,7 @@

static void __exit amba_kmi_exit(void)
{
- return amba_driver_unregister(&ambakmi_driver);
+ amba_driver_unregister(&ambakmi_driver);
}

module_init(amba_kmi_init);
diff -Nru a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
--- a/drivers/input/serio/ct82c710.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/ct82c710.c 2004-06-27 17:48:12 -05:00
@@ -43,9 +43,6 @@
MODULE_DESCRIPTION("82C710 C&T mouse port chip driver");
MODULE_LICENSE("GPL");

-static char ct82c710_name[] = "C&T 82c710 mouse port";
-static char ct82c710_phys[16];
-
/*
* ct82c710 interface
*/
@@ -61,10 +58,20 @@

#define CT82C710_IRQ 12

+static struct serio *ct82c710_port;
static int ct82c710_data;
static int ct82c710_status;

-static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs);
+
+/*
+ * Interrupt handler for the 82C710 mouse port. A character
+ * is waiting in the 82C710.
+ */
+
+static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
+{
+ return serio_interrupt(ct82c710_port, inb(ct82c710_data), 0, regs);
+}

/*
* Wait for device to send output char and flush any input char.
@@ -139,26 +146,6 @@
return 0;
}

-static struct serio ct82c710_port =
-{
- .type = SERIO_8042,
- .name = ct82c710_name,
- .phys = ct82c710_phys,
- .write = ct82c710_write,
- .open = ct82c710_open,
- .close = ct82c710_close,
-};
-
-/*
- * Interrupt handler for the 82C710 mouse port. A character
- * is waiting in the 82C710.
- */
-
-static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
-{
- return serio_interrupt(&ct82c710_port, inb(ct82c710_data), 0, regs);
-}
-
/*
* See if we can find a 82C710 device. Read mouse address.
*/
@@ -183,6 +170,24 @@
return 0;
}

+static struct serio * __init ct82c710_allocate_port(void)
+{
+ struct serio *serio;
+
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ memset(serio, 0, sizeof(struct serio));
+ serio->type = SERIO_8042;
+ serio->open = ct82c710_open;
+ serio->close = ct82c710_close;
+ serio->write = ct82c710_write;
+ strlcpy(serio->name, "C&T 82c710 mouse port", sizeof(serio->name));
+ snprintf(serio->phys, sizeof(serio->phys), "isa%04x/serio0", ct82c710_data);
+ }
+
+ return serio;
+}
+
int __init ct82c710_init(void)
{
if (ct82c710_probe())
@@ -191,9 +196,12 @@
if (request_region(ct82c710_data, 2, "ct82c710"))
return -EBUSY;

- sprintf(ct82c710_phys, "isa%04x/serio0", ct82c710_data);
+ if (!(ct82c710_port = ct82c710_allocate_port())) {
+ release_region(ct82c710_data, 2);
+ return -ENOMEM;
+ }

- serio_register_port(&ct82c710_port);
+ serio_register_port(ct82c710_port);

printk(KERN_INFO "serio: C&T 82c710 mouse port at %#x irq %d\n",
ct82c710_data, CT82C710_IRQ);
@@ -203,7 +211,7 @@

void __exit ct82c710_exit(void)
{
- serio_unregister_port(&ct82c710_port);
+ serio_unregister_port(ct82c710_port);
release_region(ct82c710_data, 2);
}

diff -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
--- a/drivers/input/serio/gscps2.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/gscps2.c 2004-06-27 17:48:12 -05:00
@@ -91,7 +91,7 @@
struct gscps2port {
struct list_head node;
struct parisc_device *padev;
- struct serio port;
+ struct serio *port;
spinlock_t lock;
char *addr;
u8 act, append; /* position in buffer[] */
@@ -100,7 +100,6 @@
u8 str;
} buffer[BUFFER_SIZE+1];
int id;
- char name[32];
};

/*
@@ -272,7 +271,7 @@
rxflags = ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
((status & GSC_STAT_PERR) ? SERIO_PARITY : 0 );

- serio_interrupt(&ps2port->port, data, rxflags, regs);
+ serio_interrupt(ps2port->port, data, rxflags, regs);

} /* while() */

@@ -343,7 +342,8 @@

static int __init gscps2_probe(struct parisc_device *dev)
{
- struct gscps2port *ps2port;
+ struct gscps2port *ps2port;
+ struct serio *serio;
unsigned long hpa = dev->hpa;
int ret;

@@ -355,34 +355,44 @@
hpa += GSC_DINO_OFFSET;

ps2port = kmalloc(sizeof(struct gscps2port), GFP_KERNEL);
- if (!ps2port)
- return -ENOMEM;
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (!ps2port || !serio) {
+ ret = -ENOMEM;
+ goto fail_nomem;
+ }

dev_set_drvdata(&dev->dev, ps2port);

memset(ps2port, 0, sizeof(struct gscps2port));
+ memset(serio, 0, sizeof(struct serio));
+ ps2port->port = serio;
ps2port->padev = dev;
ps2port->addr = ioremap(hpa, GSC_STATUS + 4);
spin_lock_init(&ps2port->lock);

gscps2_reset(ps2port);
- ps2port->id = readb(ps2port->addr+GSC_ID) & 0x0f;
- snprintf(ps2port->name, sizeof(ps2port->name)-1, "%s %s",
- gscps2_serio_port.name,
- (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" );
-
- memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port));
- ps2port->port.port_data = ps2port;
- ps2port->port.name = ps2port->name;
- ps2port->port.phys = dev->dev.bus_id;
+ ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
+
+ snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
+ (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
+ strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+ serio->idbus = BUS_GSC;
+ serio->idvendor = PCI_VENDOR_ID_HP;
+ serio->idproduct = 0x0001;
+ serio->idversion = 0x0010;
+ serio->type = SERIO_8042;
+ serio->write = gscps2_write;
+ serio->open = gscps2_open;
+ serio->close = gscps2_close;
+ serio->port_data = ps2port;

list_add_tail(&ps2port->node, &ps2port_list);

ret = -EBUSY;
- if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->name, ps2port))
+ if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->port->name, ps2port))
goto fail_miserably;

- if ( (ps2port->id != GSC_ID_KEYBOARD) && (ps2port->id != GSC_ID_MOUSE) ) {
+ if (ps2port->id != GSC_ID_KEYBOARD && ps2port->id != GSC_ID_MOUSE) {
printk(KERN_WARNING PFX "Unsupported PS/2 port at 0x%08lx (id=%d) ignored\n",
hpa, ps2port->id);
ret = -ENODEV;
@@ -395,12 +405,12 @@
#endif

printk(KERN_INFO "serio: %s port at 0x%p irq %d @ %s\n",
- ps2port->name,
+ ps2port->port->name,
ps2port->addr,
ps2port->padev->irq,
- ps2port->port.phys);
+ ps2port->port->phys);

- serio_register_port(&ps2port->port);
+ serio_register_port(ps2port->port);

return 0;

@@ -411,7 +421,10 @@
list_del(&ps2port->node);
iounmap(ps2port->addr);
release_mem_region(dev->hpa, GSC_STATUS + 4);
+
+fail_nomem:
kfree(ps2port);
+ kfree(serio);
return ret;
}

@@ -424,7 +437,7 @@
{
struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);

- serio_unregister_port(&ps2port->port);
+ serio_unregister_port(ps2port->port);
free_irq(dev->irq, ps2port);
gscps2_flush(ps2port);
list_del(&ps2port->node);
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/i8042.c 2004-06-27 17:48:12 -05:00
@@ -75,19 +75,35 @@
unsigned char irqen;
unsigned char exists;
signed char mux;
- unsigned char *name;
- unsigned char *phys;
+ char name[8];
};

-static struct serio i8042_kbd_port;
-static struct serio i8042_aux_port;
+static struct i8042_values i8042_kbd_values = {
+ .disable = I8042_CTR_KBDDIS,
+ .irqen = I8042_CTR_KBDINT,
+ .mux = -1,
+ .name = "KBD",
+};
+
+static struct i8042_values i8042_aux_values = {
+ .disable = I8042_CTR_AUXDIS,
+ .irqen = I8042_CTR_AUXINT,
+ .mux = -1,
+ .name = "AUX",
+};
+
+static struct i8042_values i8042_mux_values[I8042_NUM_MUX_PORTS];
+
+static struct serio *i8042_kbd_port;
+static struct serio *i8042_aux_port;
+static struct serio *i8042_mux_port[I8042_NUM_MUX_PORTS];
static unsigned char i8042_initial_ctr;
static unsigned char i8042_ctr;
static unsigned char i8042_mux_open;
static unsigned char i8042_mux_present;
static unsigned char i8042_sysdev_initialized;
static struct pm_dev *i8042_pm_dev;
-struct timer_list i8042_timer;
+static struct timer_list i8042_timer;

/*
* Shared IRQ's require a device pointer, but this driver doesn't support
@@ -337,52 +353,6 @@
}

/*
- * Structures for registering the devices in the serio.c module.
- */
-
-static struct i8042_values i8042_kbd_values = {
- .irqen = I8042_CTR_KBDINT,
- .disable = I8042_CTR_KBDDIS,
- .name = "KBD",
- .mux = -1,
-};
-
-static struct serio i8042_kbd_port =
-{
- .type = SERIO_8042_XL,
- .write = i8042_kbd_write,
- .open = i8042_open,
- .close = i8042_close,
- .port_data = &i8042_kbd_values,
- .name = "i8042 Kbd Port",
- .phys = I8042_KBD_PHYS_DESC,
-};
-
-static struct i8042_values i8042_aux_values = {
- .irqen = I8042_CTR_AUXINT,
- .disable = I8042_CTR_AUXDIS,
- .name = "AUX",
- .mux = -1,
-};
-
-static struct serio i8042_aux_port =
-{
- .type = SERIO_8042,
- .write = i8042_aux_write,
- .open = i8042_open,
- .close = i8042_close,
- .port_data = &i8042_aux_values,
- .name = "i8042 Aux Port",
- .phys = I8042_AUX_PHYS_DESC,
-};
-
-static struct i8042_values i8042_mux_values[4];
-static struct serio i8042_mux_port[4];
-static char i8042_mux_names[4][32];
-static char i8042_mux_short[4][16];
-static char i8042_mux_phys[4][32];
-
-/*
* i8042_interrupt() is the most important function in this driver -
* it handles the interrupts from the i8042, and sends incoming bytes
* to the upper layers.
@@ -428,7 +398,7 @@
dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : "");

- serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs);
+ serio_interrupt(i8042_mux_port[(str >> 6) & 3], data, dfl, regs);

goto irq_ret;
}
@@ -439,14 +409,14 @@
dfl & SERIO_TIMEOUT ? ", timeout" : "");

if (i8042_aux_values.exists && (str & I8042_STR_AUXDATA)) {
- serio_interrupt(&i8042_aux_port, data, dfl, regs);
+ serio_interrupt(i8042_aux_port, data, dfl, regs);
goto irq_ret;
}

if (!i8042_kbd_values.exists)
goto irq_ret;

- serio_interrupt(&i8042_kbd_port, data, dfl, regs);
+ serio_interrupt(i8042_kbd_port, data, dfl, regs);

irq_ret:
ret = 1;
@@ -639,8 +609,10 @@
* registers it, and reports to the user.
*/

-static int __init i8042_port_register(struct i8042_values *values, struct serio *port)
+static int __init i8042_port_register(struct serio *port)
{
+ struct i8042_values *values = port->port_data;
+
values->exists = 1;

i8042_ctr &= ~values->disable;
@@ -748,10 +720,8 @@
* BIOSes.
*/

- if (i8042_direct) {
+ if (i8042_direct)
i8042_ctr &= ~I8042_CTR_XLATE;
- i8042_kbd_port.type = SERIO_8042;
- }

/*
* Write CTR back.
@@ -805,14 +775,14 @@
*/

if (i8042_kbd_values.exists)
- serio_cleanup(&i8042_kbd_port);
+ serio_cleanup(i8042_kbd_port);

if (i8042_aux_values.exists)
- serio_cleanup(&i8042_aux_port);
+ serio_cleanup(i8042_aux_port);

- for (i = 0; i < 4; i++)
+ for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
if (i8042_mux_values[i].exists)
- serio_cleanup(i8042_mux_port + i);
+ serio_cleanup(i8042_mux_port[i]);

i8042_controller_reset();
}
@@ -854,15 +824,15 @@
* Reconnect anything that was connected to the ports.
*/

- if (i8042_kbd_values.exists && i8042_activate_port(&i8042_kbd_port) == 0)
- serio_reconnect(&i8042_kbd_port);
+ if (i8042_kbd_values.exists && i8042_activate_port(i8042_kbd_port) == 0)
+ serio_reconnect(i8042_kbd_port);

- if (i8042_aux_values.exists && i8042_activate_port(&i8042_aux_port) == 0)
- serio_reconnect(&i8042_aux_port);
+ if (i8042_aux_values.exists && i8042_activate_port(i8042_aux_port) == 0)
+ serio_reconnect(i8042_aux_port);

- for (i = 0; i < 4; i++)
- if (i8042_mux_values[i].exists && i8042_activate_port(i8042_mux_port + i) == 0)
- serio_reconnect(i8042_mux_port + i);
+ for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
+ if (i8042_mux_values[i].exists && i8042_activate_port(i8042_mux_port[i]) == 0)
+ serio_reconnect(i8042_mux_port[i]);
/*
* Restart timer (for polling "stuck" data)
*/
@@ -932,18 +902,66 @@
return 0;
}

-static void __init i8042_init_mux_values(struct i8042_values *values, struct serio *port, int index)
+static struct serio * __init i8042_allocate_kbd_port(void)
+{
+ struct serio *serio;
+
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ memset(serio, 0, sizeof(struct serio));
+ serio->type = i8042_direct ? SERIO_8042 : SERIO_8042_XL,
+ serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write,
+ serio->open = i8042_open,
+ serio->close = i8042_close,
+ serio->port_data = &i8042_kbd_values,
+ strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
+ strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
+ }
+
+ return serio;
+}
+
+static struct serio * __init i8042_allocate_aux_port(void)
{
- memcpy(port, &i8042_aux_port, sizeof(struct serio));
- memcpy(values, &i8042_aux_values, sizeof(struct i8042_values));
- sprintf(i8042_mux_names[index], "i8042 Aux-%d Port", index);
- sprintf(i8042_mux_phys[index], I8042_MUX_PHYS_DESC, index + 1);
- sprintf(i8042_mux_short[index], "AUX%d", index);
- port->name = i8042_mux_names[index];
- port->phys = i8042_mux_phys[index];
- port->port_data = values;
- values->name = i8042_mux_short[index];
- values->mux = index;
+ struct serio *serio;
+
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ memset(serio, 0, sizeof(struct serio));
+ serio->type = SERIO_8042;
+ serio->write = i8042_aux_write;
+ serio->open = i8042_open;
+ serio->close = i8042_close;
+ serio->port_data = &i8042_aux_values,
+ strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
+ strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+ }
+
+ return serio;
+}
+
+static struct serio * __init i8042_allocate_mux_port(int index)
+{
+ struct serio *serio;
+ struct i8042_values *values = &i8042_mux_values[index];
+
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ *values = i8042_aux_values;
+ snprintf(values->name, sizeof(values->name), "AUX%d", index);
+ values->mux = index;
+
+ memset(serio, 0, sizeof(struct serio));
+ serio->type = SERIO_8042;
+ serio->write = i8042_aux_write;
+ serio->open = i8042_open;
+ serio->close = i8042_close;
+ serio->port_data = values;
+ snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
+ snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
+ }
+
+ return serio;
}

int __init i8042_init(void)
@@ -964,9 +982,6 @@
if (i8042_controller_init())
return -ENODEV;

- if (i8042_dumbkbd)
- i8042_kbd_port.write = NULL;
-
#ifdef __i386__
if (i8042_dmi_noloop) {
printk(KERN_INFO "i8042.c: AUX LoopBack command disabled by DMI.\n");
@@ -976,15 +991,21 @@

if (!i8042_noaux && !i8042_check_aux(&i8042_aux_values)) {
if (!i8042_nomux && !i8042_check_mux(&i8042_aux_values))
- for (i = 0; i < 4; i++) {
- i8042_init_mux_values(i8042_mux_values + i, i8042_mux_port + i, i);
- i8042_port_register(i8042_mux_values + i, i8042_mux_port + i);
+ for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
+ i8042_mux_port[i] = i8042_allocate_mux_port(i);
+ if (i8042_mux_port[i])
+ i8042_port_register(i8042_mux_port[i]);
}
- else
- i8042_port_register(&i8042_aux_values, &i8042_aux_port);
+ else {
+ i8042_aux_port = i8042_allocate_aux_port();
+ if (i8042_aux_port)
+ i8042_port_register(i8042_aux_port);
+ }
}

- i8042_port_register(&i8042_kbd_values, &i8042_kbd_port);
+ i8042_kbd_port = i8042_allocate_kbd_port();
+ if (i8042_kbd_port)
+ i8042_port_register(i8042_kbd_port);

mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);

@@ -1019,14 +1040,15 @@
i8042_controller_cleanup();

if (i8042_kbd_values.exists)
- serio_unregister_port(&i8042_kbd_port);
+ serio_unregister_port(i8042_kbd_port);

if (i8042_aux_values.exists)
- serio_unregister_port(&i8042_aux_port);
+ serio_unregister_port(i8042_aux_port);

- for (i = 0; i < 4; i++)
+ for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
if (i8042_mux_values[i].exists)
- serio_unregister_port(i8042_mux_port + i);
+ serio_unregister_port(i8042_mux_port[i]);
+
del_timer_sync(&i8042_timer);

i8042_platform_exit();
diff -Nru a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
--- a/drivers/input/serio/i8042.h 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/i8042.h 2004-06-27 17:48:12 -05:00
@@ -104,6 +104,13 @@
#define I8042_BUFFER_SIZE 32

/*
+ * Number of AUX ports on controllers supporting active multiplexing
+ * specification
+ */
+
+#define I8042_NUM_MUX_PORTS 4
+
+/*
* Debug.
*/

diff -Nru a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
--- a/drivers/input/serio/maceps2.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/maceps2.c 2004-06-27 17:48:12 -05:00
@@ -46,12 +46,14 @@
#define PS2_CONTROL_RX_CLOCK_ENABLE BIT(4) /* pause reception if set to 0 */
#define PS2_CONTROL_RESET BIT(5) /* reset */

-
struct maceps2_data {
struct mace_ps2port *port;
int irq;
};

+static struct maceps2_data port_data[2];
+static struct serio *maceps2_port[2];
+
static int maceps2_write(struct serio *dev, unsigned char val)
{
struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
@@ -68,8 +70,7 @@
return -1;
}

-static irqreturn_t maceps2_interrupt(int irq, void *dev_id,
- struct pt_regs *regs)
+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->port_data)->port;
@@ -114,46 +115,52 @@
free_irq(data->irq, dev);
}

-static struct maceps2_data port0_data, port1_data;

-static struct serio maceps2_port0 =
+static struct serio * __init maceps2_allocate_port(int idx)
{
- .type = SERIO_8042,
- .open = maceps2_open,
- .close = maceps2_close,
- .write = maceps2_write,
- .name = "MACE PS/2 port0",
- .phys = "mace/serio0",
- .port_data = &port0_data,
-};
+ struct serio *serio;
+
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ memset(serio, 0, sizeof(struct serio));
+ serio->type = SERIO_8042;
+ serio->write = maceps2_write;
+ serio->open = maceps2_open;
+ serio->close = maceps2_close;
+ snprintf(serio->name, sizeof(serio->name), "MACE PS/2 port%d", idx);
+ snprintf(serio->phys, sizeof(serio->phys), "mace/serio%d", idx);
+ serio->port_data = &port_data[idx];
+ }
+
+ return serio;
+}

-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",
- .port_data = &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);
+ port_data[0].port = &mace->perif.ps2.keyb;
+ port_data[0].irq = MACEISA_KEYB_IRQ;
+ port_data[1].port = &mace->perif.ps2.mouse;
+ port_data[1].irq = MACEISA_MOUSE_IRQ;
+
+ maceps2_port[0] = maceps2_allocate_port(0);
+ maceps2_port[1] = maceps2_allocate_port(1);
+ if (!maceps2_port[0] || !maceps2_port[1]) {
+ kfree(maceps2_port[0]);
+ kfree(maceps2_port[1]);
+ return -ENOMEM;
+ }
+
+ serio_register_port(maceps2_port[0]);
+ serio_register_port(maceps2_port[1]);

return 0;
}

static void __exit maceps2_exit(void)
{
- serio_unregister_port(&maceps2_port0);
- serio_unregister_port(&maceps2_port1);
+ serio_unregister_port(maceps2_port[0]);
+ serio_unregister_port(maceps2_port[1]);
}

module_init(maceps2_init);
diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
--- a/drivers/input/serio/parkbd.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/parkbd.c 2004-06-27 17:48:12 -05:00
@@ -53,9 +53,7 @@
static unsigned long parkbd_start;

static struct pardevice *parkbd_dev;
-
-static char parkbd_name[] = "PARKBD AT/XT keyboard adapter";
-static char parkbd_phys[32];
+static struct serio *parkbd_port;

static int parkbd_readlines(void)
{
@@ -86,13 +84,6 @@
return 0;
}

-static struct serio parkbd_port =
-{
- .write = parkbd_write,
- .name = parkbd_name,
- .phys = parkbd_phys,
-};
-
static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{

@@ -125,7 +116,7 @@
parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;

if (parkbd_counter == parkbd_mode + 10)
- serio_interrupt(&parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
+ serio_interrupt(parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
}

parkbd_last = jiffies;
@@ -163,16 +154,38 @@
return 0;
}

+static struct serio * __init parkbd_allocate_serio(void)
+{
+ struct serio *serio;
+
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ serio->type = parkbd_mode;
+ serio->write = parkbd_write,
+ strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name));
+ snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", parkbd_dev->port->name);
+ }
+
+ return serio;
+}

int __init parkbd_init(void)
{
- if (parkbd_getport()) return -1;
- parkbd_writelines(3);
- parkbd_port.type = parkbd_mode;
+ int err;

- sprintf(parkbd_phys, "%s/serio0", parkbd_dev->port->name);
+ err = parkbd_getport();
+ if (err)
+ return err;
+
+ parkbd_port = parkbd_allocate_serio();
+ if (!parkbd_port) {
+ parport_release(parkbd_dev);
+ return -ENOMEM;
+ }
+
+ parkbd_writelines(3);

- serio_register_port(&parkbd_port);
+ serio_register_port(parkbd_port);

printk(KERN_INFO "serio: PARKBD %s adapter on %s\n",
parkbd_mode ? "AT" : "XT", parkbd_dev->port->name);
@@ -183,7 +196,7 @@
void __exit parkbd_exit(void)
{
parport_release(parkbd_dev);
- serio_unregister_port(&parkbd_port);
+ serio_unregister_port(parkbd_port);
parport_unregister_device(parkbd_dev);
}

diff -Nru a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
--- a/drivers/input/serio/pcips2.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/pcips2.c 2004-06-27 17:48:12 -05:00
@@ -38,7 +38,7 @@
#define PS2_STAT_TXEMPTY (1<<7)

struct pcips2_data {
- struct serio io;
+ struct serio *io;
unsigned int base;
struct pci_dev *dev;
};
@@ -80,7 +80,7 @@
if (hweight8(scancode) & 1)
flag ^= SERIO_PARITY;

- serio_interrupt(&ps2if->io, scancode, flag, regs);
+ serio_interrupt(ps2if->io, scancode, flag, regs);
} while (1);
return IRQ_RETVAL(handled);
}
@@ -129,6 +129,7 @@
static int __devinit pcips2_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct pcips2_data *ps2if;
+ struct serio *serio;
int ret;

ret = pci_enable_device(dev);
@@ -142,29 +143,34 @@
}

ps2if = kmalloc(sizeof(struct pcips2_data), GFP_KERNEL);
- if (!ps2if) {
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (!ps2if || !serio) {
ret = -ENOMEM;
goto release;
}

memset(ps2if, 0, sizeof(struct pcips2_data));
+ memset(serio, 0, sizeof(struct serio));

- ps2if->io.type = SERIO_8042;
- ps2if->io.write = pcips2_write;
- ps2if->io.open = pcips2_open;
- ps2if->io.close = pcips2_close;
- ps2if->io.name = pci_name(dev);
- ps2if->io.phys = dev->dev.bus_id;
- ps2if->io.port_data = ps2if;
+ serio->type = SERIO_8042;
+ serio->write = pcips2_write;
+ serio->open = pcips2_open;
+ serio->close = pcips2_close;
+ strlcpy(serio->name, pci_name(dev), sizeof(serio->name));
+ strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+ serio->port_data = ps2if;
+ ps2if->io = serio;
ps2if->dev = dev;
ps2if->base = pci_resource_start(dev, 0);

pci_set_drvdata(dev, ps2if);

- serio_register_port(&ps2if->io);
+ serio_register_port(ps2if->io);
return 0;

release:
+ kfree(ps2if);
+ kfree(serio);
release_region(pci_resource_start(dev, 0),
pci_resource_len(dev, 0));
disable:
@@ -176,7 +182,7 @@
{
struct pcips2_data *ps2if = pci_get_drvdata(dev);

- serio_unregister_port(&ps2if->io);
+ serio_unregister_port(ps2if->io);
release_region(pci_resource_start(dev, 0),
pci_resource_len(dev, 0));
pci_set_drvdata(dev, NULL);
diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
--- a/drivers/input/serio/q40kbd.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/q40kbd.c 2004-06-27 17:48:12 -05:00
@@ -47,43 +47,98 @@
MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
MODULE_LICENSE("GPL");

-static struct serio q40kbd_port =
-{
- .type = SERIO_8042,
- .name = "Q40 kbd port",
- .phys = "Q40",
- .write = NULL,
-};
+spinlock_t q40kbd_lock = SPIN_LOCK_UNLOCKED;
+static struct serio *q40kbd_port;

-static irqreturn_t q40kbd_interrupt(int irq, void *dev_id,
- struct pt_regs *regs)
+static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&q40kbd_lock, flags);
+
if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
- serio_interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0, regs);
+ serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0, regs);

master_outb(-1, KEYBOARD_UNLOCK_REG);
+
+ spin_unlock_irqrestore(&q40kbd_lock, flags);
+
return IRQ_HANDLED;
}

-static int __init q40kbd_init(void)
+/*
+ * q40kbd_flush() flushes all data that may be in the keyboard buffers
+ */
+
+static void q40kbd_flush(void)
{
- int maxread = 100;
+ int maxread = 100;
+ unsigned long flags;
+
+ spin_lock_irqsave(&q40kbd_lock, flags);
+
+ while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
+ master_inb(KEYCODE_REG);
+
+ spin_unlock_irqrestore(&q40kbd_lock, flags);
+}
+
+/*
+ * q40kbd_open() is called when a port is open by the higher layer.
+ * It allocates the interrupt and enables in in the chip.
+ */
+
+static int q40kbd_open(struct serio *port)
+{
+ q40kbd_flush();
+
+ if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) {
+ printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD);
+ return -1;
+ }
+
+ /* off we go */
+ master_outb(-1, KEYBOARD_UNLOCK_REG);
+ master_outb(1, KEY_IRQ_ENABLE_REG);
+
+ return 0;
+}

+static void q40kbd_close(struct serio *port)
+{
+ master_outb(0, KEY_IRQ_ENABLE_REG);
+ master_outb(-1, KEYBOARD_UNLOCK_REG);
+ free_irq(Q40_IRQ_KEYBOARD, NULL);
+
+ q40kbd_flush();
+}
+
+static struct serio * __init q40kbd_allocate_port(void)
+{
+ struct serio *serio;
+
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ memset(serio, 0, sizeof(struct serio));
+ serio->type = SERIO_8042;
+ serio->open = q40kbd_open;
+ serio->close = q40kbd_close;
+ strlcpy(serio->name, "Q40 Kbd Port", sizeof(serio->name));
+ strlcpy(serio->phys, "Q40", sizeof(serio->phys));
+ }
+
+ return serio;
+}
+
+static int __init q40kbd_init(void)
+{
if (!MACH_IS_Q40)
return -EIO;

- /* allocate the IRQ */
- request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL);
-
- /* flush any pending input */
- while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
- master_inb(KEYCODE_REG);
-
- /* off we go */
- master_outb(-1,KEYBOARD_UNLOCK_REG);
- master_outb(1,KEY_IRQ_ENABLE_REG);
+ if (!(q40kbd_port = q40kbd_allocate_port()))
+ return -ENOMEM;

- serio_register_port(&q40kbd_port);
+ serio_register_port(q40kbd_port);
printk(KERN_INFO "serio: Q40 kbd registered\n");

return 0;
@@ -91,11 +146,7 @@

static void __exit q40kbd_exit(void)
{
- master_outb(0,KEY_IRQ_ENABLE_REG);
- master_outb(-1,KEYBOARD_UNLOCK_REG);
-
- serio_unregister_port(&q40kbd_port);
- free_irq(Q40_IRQ_KEYBOARD, NULL);
+ serio_unregister_port(q40kbd_port);
}

module_init(q40kbd_init);
diff -Nru a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
--- a/drivers/input/serio/rpckbd.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/rpckbd.c 2004-06-27 17:48:12 -05:00
@@ -44,6 +44,8 @@
MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
MODULE_LICENSE("GPL");

+static struct serio *rpckbd_port;
+
static int rpckbd_write(struct serio *port, unsigned char val)
{
while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
@@ -101,25 +103,41 @@
free_irq(IRQ_KEYBOARDTX, port);
}

-static struct serio rpckbd_port =
-{
- .type = SERIO_8042,
- .open = rpckbd_open,
- .close = rpckbd_close,
- .write = rpckbd_write,
- .name = "RiscPC PS/2 kbd port",
- .phys = "rpckbd/serio0",
-};
+/*
+ * Allocate and initialize serio structure for subsequent registration
+ * with serio core.
+ */
+
+static struct serio * __init rpckbd_allocate_port(void)
+{
+ struct serio *serio;
+
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ memset(serio, 0, sizeof(struct serio));
+ serio->type = SERIO_8042;
+ serio->write = rpckbd_write;
+ serio->open = rpckbd_open;
+ serio->close = rpckbd_close;
+ strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
+ strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
+ }
+
+ return serio;
+}

static int __init rpckbd_init(void)
{
- serio_register_port(&rpckbd_port);
+ if (!(rpckbd_port = rpckbd_allocate_port()))
+ return -ENOMEM;
+
+ serio_register_port(rpckbd_port);
return 0;
}

static void __exit rpckbd_exit(void)
{
- serio_unregister_port(&rpckbd_port);
+ serio_unregister_port(rpckbd_port);
}

module_init(rpckbd_init);
diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
--- a/drivers/input/serio/sa1111ps2.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/sa1111ps2.c 2004-06-27 17:48:12 -05:00
@@ -26,7 +26,7 @@
#include <asm/hardware/sa1111.h>

struct ps2if {
- struct serio io;
+ struct serio *io;
struct sa1111_dev *dev;
unsigned long base;
unsigned int open;
@@ -59,7 +59,7 @@
if (hweight8(scancode) & 1)
flag ^= SERIO_PARITY;

- serio_interrupt(&ps2if->io, scancode, flag, regs);
+ serio_interrupt(ps2if->io, scancode, flag, regs);

status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
}
@@ -232,22 +232,27 @@
static int ps2_probe(struct sa1111_dev *dev)
{
struct ps2if *ps2if;
+ struct serio *serio;
int ret;

ps2if = kmalloc(sizeof(struct ps2if), GFP_KERNEL);
- if (!ps2if) {
- return -ENOMEM;
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (!ps2if || !serio) {
+ ret = -ENOMEM;
+ goto free;
}

memset(ps2if, 0, sizeof(struct ps2if));
+ memset(serio, 0, sizeof(struct serio));

- ps2if->io.type = SERIO_8042;
- ps2if->io.write = ps2_write;
- ps2if->io.open = ps2_open;
- ps2if->io.close = ps2_close;
- ps2if->io.name = dev->dev.bus_id;
- ps2if->io.phys = dev->dev.bus_id;
- ps2if->io.port_data = ps2if;
+ serio->type = SERIO_8042;
+ serio->write = ps2_write;
+ serio->open = ps2_open;
+ serio->close = ps2_close;
+ strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name));
+ strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+ serio->port_data = ps2if;
+ ps2if->io = serio;
ps2if->dev = dev;
sa1111_set_drvdata(dev, ps2if);

@@ -292,7 +297,7 @@
ps2_clear_input(ps2if);

sa1111_disable_device(ps2if->dev);
- serio_register_port(&ps2if->io);
+ serio_register_port(ps2if->io);
return 0;

out:
@@ -302,6 +307,7 @@
free:
sa1111_set_drvdata(dev, NULL);
kfree(ps2if);
+ kfree(serio);
return ret;
}

@@ -312,7 +318,7 @@
{
struct ps2if *ps2if = sa1111_get_drvdata(dev);

- serio_unregister_port(&ps2if->io);
+ serio_unregister_port(ps2if->io);
release_mem_region(dev->res.start,
dev->res.end - dev->res.start + 1);
sa1111_set_drvdata(dev, NULL);
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/serio.c 2004-06-27 17:48:12 -05:00
@@ -283,6 +283,7 @@
list_del_init(&serio->node);
if (serio->drv)
serio->drv->disconnect(serio);
+ kfree(serio);
}

/*
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/input/serio/serport.c 2004-06-27 17:48:12 -05:00
@@ -31,13 +31,10 @@
struct serport {
struct tty_struct *tty;
wait_queue_head_t wait;
- struct serio serio;
+ struct serio *serio;
unsigned long flags;
- char phys[32];
};

-char serport_name[] = "Serial port";
-
/*
* Callback functions from the serio code.
*/
@@ -52,7 +49,7 @@
{
struct serport *serport = serio->port_data;

- serport->serio.type = 0;
+ serport->serio->type = 0;
wake_up_interruptible(&serport->wait);
}

@@ -64,26 +61,30 @@
static int serport_ldisc_open(struct tty_struct *tty)
{
struct serport *serport;
+ struct serio *serio;
char name[64];

serport = kmalloc(sizeof(struct serport), GFP_KERNEL);
- if (unlikely(!serport))
+ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (unlikely(!serport || !serio)) {
+ kfree(serport);
+ kfree(serio);
return -ENOMEM;
- memset(serport, 0, sizeof(struct serport));
+ }

+ memset(serport, 0, sizeof(struct serport));
+ serport->serio = serio;
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
serport->tty = tty;
tty->disc_data = serport;

- snprintf(serport->phys, sizeof(serport->phys), "%s/serio0", tty_name(tty, name));
-
- serport->serio.name = serport_name;
- serport->serio.phys = serport->phys;
-
- serport->serio.type = SERIO_RS232;
- serport->serio.write = serport_serio_write;
- serport->serio.close = serport_serio_close;
- serport->serio.port_data = serport;
+ memset(serio, 0, sizeof(struct serio));
+ strlcpy(serio->name, "Serial port", sizeof(serio->name));
+ snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name));
+ serio->type = SERIO_RS232;
+ serio->write = serport_serio_write;
+ serio->close = serport_serio_close;
+ serio->port_data = serport;

init_waitqueue_head(&serport->wait);

@@ -114,7 +115,7 @@
struct serport *serport = (struct serport*) tty->disc_data;
int i;
for (i = 0; i < count; i++)
- serio_interrupt(&serport->serio, cp[i], 0, NULL);
+ serio_interrupt(serport->serio, cp[i], 0, NULL);
}

/*
@@ -142,10 +143,10 @@
if (test_and_set_bit(SERPORT_BUSY, &serport->flags))
return -EBUSY;

- serio_register_port(&serport->serio);
+ serio_register_port(serport->serio);
printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name));
- wait_event_interruptible(serport->wait, !serport->serio.type);
- serio_unregister_port(&serport->serio);
+ wait_event_interruptible(serport->wait, !serport->serio->type);
+ serio_unregister_port(serport->serio);

clear_bit(SERPORT_BUSY, &serport->flags);

@@ -161,7 +162,7 @@
struct serport *serport = (struct serport*) tty->disc_data;

if (cmd == SPIOCSTYPE)
- return get_user(serport->serio.type, (unsigned long __user *) arg);
+ return get_user(serport->serio->type, (unsigned long __user *) arg);

return -EINVAL;
}
@@ -170,7 +171,7 @@
{
struct serport *sp = (struct serport *) tty->disc_data;

- serio_drv_write_wakeup(&sp->serio);
+ serio_drv_write_wakeup(sp->serio);
}

/*
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/serial/sunsu.c 2004-06-27 17:48:12 -05:00
@@ -98,7 +98,7 @@
unsigned int irq;

#ifdef CONFIG_SERIO
- struct serio serio;
+ struct serio *serio;
int serio_open;
#endif
};
@@ -520,7 +520,7 @@
/* Stop-A is handled by drivers/char/keyboard.c now. */
if (up->su_type == SU_PORT_KBD) {
#ifdef CONFIG_SERIO
- serio_interrupt(&up->serio, ch, 0, regs);
+ serio_interrupt(up->serio, ch, 0, regs);
#endif
} else if (up->su_type == SU_PORT_MS) {
int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -534,7 +534,7 @@

case 0:
#ifdef CONFIG_SERIO
- serio_interrupt(&up->serio, ch, 0, regs);
+ serio_interrupt(up->serio, ch, 0, regs);
#endif
break;
};
@@ -1284,54 +1284,58 @@
.major = TTY_MAJOR,
};

-static int __init sunsu_kbd_ms_init(void)
+static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
{
- struct uart_sunsu_port *up;
- int i;
+ struct serio *serio;

- for (i = 0, up = sunsu_ports; i < 2; i++, up++) {
- up->port.line = i;
- up->port.type = PORT_UNKNOWN;
- up->port.uartclk = (SU_BASE_BAUD * 16);
+ up->port.line = channel;
+ up->port.type = PORT_UNKNOWN;
+ up->port.uartclk = (SU_BASE_BAUD * 16);

- if (up->su_type == SU_PORT_KBD)
- up->cflag = B1200 | CS8 | CLOCAL | CREAD;
- else
- up->cflag = B4800 | CS8 | CLOCAL | CREAD;
+ if (up->su_type == SU_PORT_KBD)
+ up->cflag = B1200 | CS8 | CLOCAL | CREAD;
+ else
+ up->cflag = B4800 | CS8 | CLOCAL | CREAD;

- sunsu_autoconfig(up);
- if (up->port.type == PORT_UNKNOWN)
- continue;
+ sunsu_autoconfig(up);
+ if (up->port.type == PORT_UNKNOWN)
+ return -1;

- printk(KERN_INFO "su%d at 0x%p (irq = %s) is a %s\n",
- i,
- up->port.membase, __irq_itoa(up->irq),
- sunsu_type(&up->port));
+ printk(KERN_INFO "su%d at 0x%p (irq = %s) is a %s\n",
+ channel,
+ up->port.membase, __irq_itoa(up->irq),
+ sunsu_type(&up->port));

#ifdef CONFIG_SERIO
- memset(&up->serio, 0, sizeof(up->serio));
+ up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ memset(serio, 0, sizeof(serio));

- up->serio.port_data = up;
+ serio->port_data = up;

- up->serio.type = SERIO_RS232;
+ serio->type = SERIO_RS232;
if (up->su_type == SU_PORT_KBD) {
- up->serio.type |= SERIO_SUNKBD;
- up->serio.name = "sukbd";
+ serio->type |= SERIO_SUNKBD;
+ strlcpy(serio->name, "sukbd", sizeof(serio->name));
} else {
- up->serio.type |= (SERIO_SUN | (1 << 16));
- up->serio.name = "sums";
+ serio->type |= (SERIO_SUN | (1 << 16));
+ strlcpy(serio->name, "sums", sizeof(serio->name));
}
- up->serio.phys = (i == 0 ? "su/serio0" : "su/serio1");
+ strlcpy(serio->phys, (channel == 0 ? "su/serio0" : "su/serio1"),
+ sizeof(serio->phys));

- up->serio.write = sunsu_serio_write;
- up->serio.open = sunsu_serio_open;
- up->serio.close = sunsu_serio_close;
+ serio->write = sunsu_serio_write;
+ serio->open = sunsu_serio_open;
+ serio->close = sunsu_serio_close;

- serio_register_port(&up->serio);
+ serio_register_port(serio);
+ } else {
+ printk(KERN_WARNING "su%d: not enough memory for serio port\n",
+ channel);
+ }
#endif

- sunsu_startup(&up->port);
- }
+ sunsu_startup(&up->port);
return 0;
}

@@ -1680,10 +1684,12 @@
if (scan.msx != -1 && scan.kbx != -1) {
sunsu_ports[0].su_type = SU_PORT_MS;
sunsu_ports[0].port_node = scan.msnode;
+ sunsu_kbd_ms_init(&sunsu_ports[0], 0);
+
sunsu_ports[1].su_type = SU_PORT_KBD;
sunsu_ports[1].port_node = scan.kbnode;
+ sunsu_kbd_ms_init(&sunsu_ports[1], 1);

- sunsu_kbd_ms_init();
return 0;
}

@@ -1715,7 +1721,10 @@
if (up->su_type == SU_PORT_MS ||
up->su_type == SU_PORT_KBD) {
#ifdef CONFIG_SERIO
- serio_unregister_port(&up->serio);
+ if (up->serio) {
+ serio_unregister_port(up->serio);
+ up->serio = NULL;
+ }
#endif
} else if (up->port.type != PORT_UNKNOWN) {
uart_remove_one_port(&sunsu_reg, &up->port);
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c 2004-06-27 17:48:12 -05:00
+++ b/drivers/serial/sunzilog.c 2004-06-27 17:48:12 -05:00
@@ -107,7 +107,7 @@
unsigned char prev_status;

#ifdef CONFIG_SERIO
- struct serio serio;
+ struct serio *serio;
int serio_open;
#endif
};
@@ -291,7 +291,7 @@
/* Stop-A is handled by drivers/char/keyboard.c now. */
#ifdef CONFIG_SERIO
if (up->serio_open)
- serio_interrupt(&up->serio, ch, 0, regs);
+ serio_interrupt(up->serio, ch, 0, regs);
#endif
} else if (ZS_IS_MOUSE(up)) {
int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -306,7 +306,7 @@
case 0:
#ifdef CONFIG_SERIO
if (up->serio_open)
- serio_interrupt(&up->serio, ch, 0, regs);
+ serio_interrupt(up->serio, ch, 0, regs);
#endif
break;
};
@@ -1529,6 +1529,7 @@
static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
{
int baud, brg;
+ struct serio *serio;

if (channel == KEYBOARD_LINE) {
up->flags |= SUNZILOG_FLAG_CONS_KEYB;
@@ -1547,26 +1548,34 @@
sunzilog_convert_to_zs(up, up->cflag, 0, brg);

#ifdef CONFIG_SERIO
- memset(&up->serio, 0, sizeof(up->serio));
+ up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {

- up->serio.port_data = up;
+ memset(serio, 0, sizeof(serio));

- up->serio.type = SERIO_RS232;
- if (channel == KEYBOARD_LINE) {
- up->serio.type |= SERIO_SUNKBD;
- up->serio.name = "zskbd";
- } else {
- up->serio.type |= (SERIO_SUN | (1 << 16));
- up->serio.name = "zsms";
- }
- up->serio.phys = (channel == KEYBOARD_LINE ?
- "zs/serio0" : "zs/serio1");
+ serio->port_data = up;

- up->serio.write = sunzilog_serio_write;
- up->serio.open = sunzilog_serio_open;
- up->serio.close = sunzilog_serio_close;
+ serio->type = SERIO_RS232;
+ if (channel == KEYBOARD_LINE) {
+ serio->type |= SERIO_SUNKBD;
+ strlcpy(serio->name, "zskbd", sizeof(serio->name));
+ } else {
+ serio->type |= (SERIO_SUN | (1 << 16));
+ strlcpy(serio->name, "zsms", sizeof(serio->name));
+ }
+ strlcpy(serio->phys,
+ (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
+ sizeof(serio->phys));
+
+ serio->write = sunzilog_serio_write;
+ serio->open = sunzilog_serio_open;
+ serio->close = sunzilog_serio_close;

- serio_register_port(&up->serio);
+ serio_register_port(serio);
+ } else {
+ printk(KERN_WARNING "zs%d: not enough memory for serio port\n",
+ channel);
+ }
#endif

sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
@@ -1732,10 +1741,15 @@
for (i = 0; i < NUM_CHANNELS; i++) {
struct uart_sunzilog_port *up = &sunzilog_port_table[i];

- if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up))
- continue;
-
- uart_remove_one_port(&sunzilog_reg, &up->port);
+ if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
+#ifdef CONFIG_SERIO
+ if (up->serio) {
+ serio_unregister_port(up->serio);
+ up->serio = NULL;
+ }
+#endif
+ } else
+ uart_remove_one_port(&sunzilog_reg, &up->port);
}

uart_unregister_driver(&sunzilog_reg);
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h 2004-06-27 17:48:12 -05:00
+++ b/include/linux/serio.h 2004-06-27 17:48:12 -05:00
@@ -22,8 +22,9 @@
struct serio {
void *private;
void *port_data;
- char *name;
- char *phys;
+
+ char name[32];
+ char phys[32];

unsigned short idbus;
unsigned short idvendor;

2004-06-28 05:24:35

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 6/19] serio avoid recursion


===================================================================


[email protected], 2004-06-27 15:55:06-05:00, [email protected]
Input: allow serio drivers to create children ports and register these
ports for them in serio core to avoid having recursion in connect
methods.

Signed-off-by: Dmitry Torokhov <[email protected]>


drivers/input/mouse/psmouse-base.c | 75 ++++++++----
drivers/input/mouse/psmouse.h | 16 --
drivers/input/mouse/synaptics.c | 27 +---
drivers/input/serio/serio.c | 215 ++++++++++++++++++++++++++++---------
include/linux/serio.h | 4
5 files changed, 231 insertions(+), 106 deletions(-)


===================================================================



diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c 2004-06-27 17:48:33 -05:00
+++ b/drivers/input/mouse/psmouse-base.c 2004-06-27 17:48:33 -05:00
@@ -667,16 +667,15 @@

static void psmouse_disconnect(struct serio *serio)
{
- struct psmouse *psmouse = serio->private;
+ struct psmouse *psmouse, *parent;

+ psmouse = serio->private;
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);

- if (psmouse->ptport) {
- if (psmouse->ptport->deactivate)
- psmouse->ptport->deactivate(psmouse);
- __serio_unregister_port(psmouse->ptport->serio); /* we have serio_sem */
- kfree(psmouse->ptport);
- psmouse->ptport = NULL;
+ if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
+ parent = serio->parent->private;
+ if (parent->pt_deactivate)
+ parent->pt_deactivate(parent);
}

if (psmouse->disconnect)
@@ -695,14 +694,17 @@
*/
static void psmouse_connect(struct serio *serio, struct serio_driver *drv)
{
- struct psmouse *psmouse;
+ struct psmouse *psmouse, *parent = NULL;

if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
(serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)
return;

+ if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU)
+ parent = serio->parent->private;
+
if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL)))
- return;
+ goto out;

memset(psmouse, 0, sizeof(struct psmouse));

@@ -718,14 +720,14 @@
if (serio_open(serio, drv)) {
kfree(psmouse);
serio->private = NULL;
- return;
+ goto out;
}

if (psmouse_probe(psmouse) < 0) {
serio_close(serio);
kfree(psmouse);
serio->private = NULL;
- return;
+ goto out;
}

psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
@@ -754,20 +756,36 @@

psmouse_initialize(psmouse);

- if (psmouse->ptport) {
- printk(KERN_INFO "serio: %s port at %s\n", psmouse->ptport->serio->name, psmouse->phys);
- __serio_register_port(psmouse->ptport->serio); /* we have serio_sem */
- if (psmouse->ptport->activate)
- psmouse->ptport->activate(psmouse);
- }
+ if (parent && parent->pt_activate)
+ parent->pt_activate(parent);

- psmouse_activate(psmouse);
+ /*
+ * OK, the device is ready, we just need to activate it (turn the
+ * stream mode on). But if mouse has a pass-through port we don't
+ * want to do it yet to not disturb child detection.
+ * The child will activate this port when it's ready.
+ */
+
+ if (serio->child) {
+ /*
+ * Nothing to be done here, serio core will detect that
+ * the driver set serio->child and will register it for us.
+ */
+ printk(KERN_INFO "serio: %s port at %s\n", serio->child->name, psmouse->phys);
+ } else
+ psmouse_activate(psmouse);
+
+out:
+ /* If this is a pass-through port the parent awaits to be activated */
+ if (parent)
+ psmouse_activate(parent);
}


static int psmouse_reconnect(struct serio *serio)
{
struct psmouse *psmouse = serio->private;
+ struct psmouse *parent = NULL;
struct serio_driver *drv = serio->drv;

if (!drv || !psmouse) {
@@ -789,16 +807,19 @@
*/
psmouse_initialize(psmouse);

- if (psmouse->ptport) {
- if (psmouse_reconnect(psmouse->ptport->serio)) {
- __serio_unregister_port(psmouse->ptport->serio);
- __serio_register_port(psmouse->ptport->serio);
- if (psmouse->ptport->activate)
- psmouse->ptport->activate(psmouse);
- }
- }
+ if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU)
+ parent = serio->parent->private;
+
+ if (parent && parent->pt_activate)
+ parent->pt_activate(parent);
+
+ if (!serio->child)
+ psmouse_activate(psmouse);
+
+ /* If this is a pass-through port the parent waits to be activated */
+ if (parent)
+ psmouse_activate(parent);

- psmouse_activate(psmouse);
return 0;
}

diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h 2004-06-27 17:48:33 -05:00
+++ b/drivers/input/mouse/psmouse.h 2004-06-27 17:48:33 -05:00
@@ -34,21 +34,10 @@
PSMOUSE_FULL_PACKET
} psmouse_ret_t;

-struct psmouse;
-
-struct psmouse_ptport {
- struct serio *serio;
- struct psmouse *parent;
-
- void (*activate)(struct psmouse *parent);
- void (*deactivate)(struct psmouse *parent);
-};
-
struct psmouse {
void *private;
struct input_dev dev;
struct serio *serio;
- struct psmouse_ptport *ptport;
char *vendor;
char *name;
unsigned char cmdbuf[8];
@@ -66,9 +55,12 @@
char phys[32];
unsigned long flags;

- psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
+ psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
int (*reconnect)(struct psmouse *psmouse);
void (*disconnect)(struct psmouse *psmouse);
+
+ void (*pt_activate)(struct psmouse *psmouse);
+ void (*pt_deactivate)(struct psmouse *psmouse);
};

#define PSMOUSE_PS2 1
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c 2004-06-27 17:48:33 -05:00
+++ b/drivers/input/mouse/synaptics.c 2004-06-27 17:48:33 -05:00
@@ -212,14 +212,14 @@
/*****************************************************************************
* Synaptics pass-through PS/2 port support
****************************************************************************/
-static int synaptics_pt_write(struct serio *port, unsigned char c)
+static int synaptics_pt_write(struct serio *serio, unsigned char c)
{
- struct psmouse_ptport *ptport = port->port_data;
+ struct psmouse *parent = serio->parent->private;
char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */

- if (psmouse_sliced_command(ptport->parent, c))
+ if (psmouse_sliced_command(parent, c))
return -1;
- if (psmouse_command(ptport->parent, &rate_param, PSMOUSE_CMD_SETRATE))
+ if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
return -1;
return 0;
}
@@ -248,7 +248,7 @@

static void synaptics_pt_activate(struct psmouse *psmouse)
{
- struct psmouse *child = psmouse->ptport->serio->private;
+ struct psmouse *child = psmouse->serio->child->private;

/* adjust the touchpad to child's choice of protocol */
if (child && child->type >= PSMOUSE_GENPS) {
@@ -259,30 +259,25 @@

static void synaptics_pt_create(struct psmouse *psmouse)
{
- struct psmouse_ptport *port;
struct serio *serio;

- port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
- if (!port || !serio) {
+ if (!serio) {
printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
return;
}

- memset(port, 0, sizeof(struct psmouse_ptport));
memset(serio, 0, sizeof(struct serio));

serio->type = SERIO_PS_PSTHRU;
strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name));
serio->write = synaptics_pt_write;
- serio->port_data = port;
+ serio->parent = psmouse->serio;

- port->serio = serio;
- port->parent = psmouse;
- port->activate = synaptics_pt_activate;
+ psmouse->pt_activate = synaptics_pt_activate;

- psmouse->ptport = port;
+ psmouse->serio->child = serio;
}

/*****************************************************************************
@@ -477,8 +472,8 @@
if (unlikely(priv->pkt_type == SYN_NEWABS))
priv->pkt_type = synaptics_detect_pkt_type(psmouse);

- if (psmouse->ptport && psmouse->ptport->serio->drv && synaptics_is_pt_packet(psmouse->packet))
- synaptics_pass_pt_packet(psmouse->ptport->serio, psmouse->packet);
+ if (psmouse->serio->child && psmouse->serio->child->drv && synaptics_is_pt_packet(psmouse->packet))
+ synaptics_pass_pt_packet(psmouse->serio->child, psmouse->packet);
else
synaptics_process_packet(psmouse);

diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-06-27 17:48:33 -05:00
+++ b/drivers/input/serio/serio.c 2004-06-27 17:48:33 -05:00
@@ -44,10 +44,8 @@
EXPORT_SYMBOL(serio_interrupt);
EXPORT_SYMBOL(serio_register_port);
EXPORT_SYMBOL(serio_register_port_delayed);
-EXPORT_SYMBOL(__serio_register_port);
EXPORT_SYMBOL(serio_unregister_port);
EXPORT_SYMBOL(serio_unregister_port_delayed);
-EXPORT_SYMBOL(__serio_unregister_port);
EXPORT_SYMBOL(serio_register_driver);
EXPORT_SYMBOL(serio_unregister_driver);
EXPORT_SYMBOL(serio_open);
@@ -59,17 +57,28 @@
static LIST_HEAD(serio_list);
static LIST_HEAD(serio_driver_list);

-/* serio_find_driver() must be called with serio_sem down. */
+static void serio_find_driver(struct serio *serio);
+static void serio_create_port(struct serio *serio);
+static void serio_destroy_port(struct serio *serio);
+static void serio_connect_port(struct serio *serio, struct serio_driver *drv);
+static void serio_reconnect_port(struct serio *serio);
+static void serio_disconnect_port(struct serio *serio);
+
+static int serio_bind_driver(struct serio *serio, struct serio_driver *drv)
+{
+ drv->connect(serio, drv);
+
+ return serio->drv != NULL;
+}

+/* serio_find_driver() must be called with serio_sem down. */
static void serio_find_driver(struct serio *serio)
{
struct serio_driver *drv;

- list_for_each_entry(drv, &serio_driver_list, node) {
- if (serio->drv)
+ list_for_each_entry(drv, &serio_driver_list, node)
+ if (serio_bind_driver(serio, drv))
break;
- drv->connect(serio, drv);
- }
}

/*
@@ -145,23 +154,22 @@

switch (event->type) {
case SERIO_REGISTER_PORT :
- __serio_register_port(event->serio);
+ serio_create_port(event->serio);
+ serio_connect_port(event->serio, NULL);
break;

case SERIO_UNREGISTER_PORT :
- __serio_unregister_port(event->serio);
+ serio_disconnect_port(event->serio);
+ serio_destroy_port(event->serio);
break;

case SERIO_RECONNECT :
- if (event->serio->drv && event->serio->drv->reconnect)
- if (event->serio->drv->reconnect(event->serio) == 0)
- break;
- /* reconnect failed - fall through to rescan */
+ serio_reconnect_port(event->serio);
+ break;

case SERIO_RESCAN :
- if (event->serio->drv)
- event->serio->drv->disconnect(event->serio);
- serio_find_driver(event->serio);
+ serio_disconnect_port(event->serio);
+ serio_connect_port(event->serio, NULL);
break;
default:
break;
@@ -216,6 +224,118 @@
* Serio port operations
*/

+static void serio_create_port(struct serio *serio)
+{
+ spin_lock_init(&serio->lock);
+ list_add_tail(&serio->node, &serio_list);
+}
+
+/*
+ * serio_destroy_port() completes deregistration process and removes
+ * port from the system
+ */
+static void serio_destroy_port(struct serio *serio)
+{
+ struct serio_driver *drv = serio->drv;
+ unsigned long flags;
+
+ serio_remove_pending_events(serio);
+ list_del_init(&serio->node);
+
+ if (drv)
+ drv->disconnect(serio);
+
+ if (serio->parent) {
+ spin_lock_irqsave(&serio->parent->lock, flags);
+ serio->parent->child = NULL;
+ spin_unlock_irqrestore(&serio->parent->lock, flags);
+ }
+
+ kfree(serio);
+}
+
+/*
+ * serio_connect_port() tries to bind the port and possible all its
+ * children to appropriate drivers. If driver passed in the function will not
+ * try otehr drivers when binding parent port.
+ */
+static void serio_connect_port(struct serio *serio, struct serio_driver *drv)
+{
+ WARN_ON(serio->drv);
+ WARN_ON(serio->child);
+
+ if (drv)
+ serio_bind_driver(serio, drv);
+ else
+ serio_find_driver(serio);
+
+ /* Ok, now bind children, if any */
+ while (serio->child) {
+ serio = serio->child;
+
+ WARN_ON(serio->drv);
+ WARN_ON(serio->child);
+
+ serio_create_port(serio);
+
+ /*
+ * With children we just _prefer_ passed in driver,
+ * but we will try other options in case preferred
+ * is not the one
+ */
+ if (!drv || !serio_bind_driver(serio, drv))
+ serio_find_driver(serio);
+ }
+}
+
+/*
+ *
+ */
+static void serio_reconnect_port(struct serio *serio)
+{
+ do {
+ if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
+ serio_disconnect_port(serio);
+ serio_connect_port(serio, NULL);
+ /* Ok, old children are now gone, we are done */
+ break;
+ }
+ serio = serio->child;
+ } while (serio);
+}
+
+/*
+ * serio_disconnect_port() unbinds a port from its driver. As a side effect
+ * all child ports are unbound and destroyed.
+ */
+static void serio_disconnect_port(struct serio *serio)
+{
+ struct serio_driver *drv = serio->drv;
+ struct serio *s;
+
+ if (serio->child) {
+ /*
+ * Children ports should be disconnected and destroyed
+ * first, staring with the leaf one, since we don't want
+ * to do recursion
+ */
+ do {
+ s = serio->child;
+ } while (s->child);
+
+ while (s != serio) {
+ s = s->parent;
+ serio_destroy_port(s->child);
+ }
+ }
+
+ /*
+ * Ok, no children left, now disconnect this port
+ */
+ if (drv)
+ drv->disconnect(serio);
+}
+
void serio_rescan(struct serio *serio)
{
serio_queue_event(serio, SERIO_RESCAN);
@@ -229,7 +349,8 @@
void serio_register_port(struct serio *serio)
{
down(&serio_sem);
- __serio_register_port(serio);
+ serio_create_port(serio);
+ serio_connect_port(serio, NULL);
up(&serio_sem);
}

@@ -243,22 +364,11 @@
serio_queue_event(serio, SERIO_REGISTER_PORT);
}

-/*
- * Should only be called directly if serio_sem has already been taken,
- * for example when unregistering a serio from other input device's
- * connect() function.
- */
-void __serio_register_port(struct serio *serio)
-{
- spin_lock_init(&serio->lock);
- list_add_tail(&serio->node, &serio_list);
- serio_find_driver(serio);
-}
-
void serio_unregister_port(struct serio *serio)
{
down(&serio_sem);
- __serio_unregister_port(serio);
+ serio_disconnect_port(serio);
+ serio_destroy_port(serio);
up(&serio_sem);
}

@@ -272,32 +382,33 @@
serio_queue_event(serio, SERIO_UNREGISTER_PORT);
}

-/*
- * Should only be called directly if serio_sem has already been taken,
- * for example when unregistering a serio from other input device's
- * disconnect() function.
- */
-void __serio_unregister_port(struct serio *serio)
-{
- serio_remove_pending_events(serio);
- list_del_init(&serio->node);
- if (serio->drv)
- serio->drv->disconnect(serio);
- kfree(serio);
-}

/*
* Serio driver operations
*/

+
void serio_register_driver(struct serio_driver *drv)
{
struct serio *serio;
+
down(&serio_sem);
+
list_add_tail(&drv->node, &serio_driver_list);
- list_for_each_entry(serio, &serio_list, node)
- if (!serio->drv)
- drv->connect(serio, drv);
+
+start_over:
+ list_for_each_entry(serio, &serio_list, node) {
+ if (!serio->drv) {
+ serio_connect_port(serio, drv);
+ /*
+ * if new child appeared then the list is changed,
+ * we need to start over
+ */
+ if (serio->child)
+ goto start_over;
+ }
+ }
+
up(&serio_sem);
}

@@ -306,13 +417,19 @@
struct serio *serio;

down(&serio_sem);
+
list_del_init(&drv->node);

+start_over:
list_for_each_entry(serio, &serio_list, node) {
- if (serio->drv == drv)
- drv->disconnect(serio);
- serio_find_driver(serio);
+ if (serio->drv == drv) {
+ serio_disconnect_port(serio);
+ serio_connect_port(serio, NULL);
+ /* we could've deleted some ports, restart */
+ goto start_over;
+ }
}
+
up(&serio_sem);
}

diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h 2004-06-27 17:48:33 -05:00
+++ b/include/linux/serio.h 2004-06-27 17:48:33 -05:00
@@ -40,6 +40,8 @@
int (*open)(struct serio *);
void (*close)(struct serio *);

+ struct serio *parent, *child;
+
struct serio_driver *drv; /* Accessed from interrupt, writes must be protected by serio_lock */

struct list_head node;
@@ -68,10 +70,8 @@

void serio_register_port(struct serio *serio);
void serio_register_port_delayed(struct serio *serio);
-void __serio_register_port(struct serio *serio);
void serio_unregister_port(struct serio *serio);
void serio_unregister_port_delayed(struct serio *serio);
-void __serio_unregister_port(struct serio *serio);
void serio_register_driver(struct serio_driver *drv);
void serio_unregister_driver(struct serio_driver *drv);

2004-06-28 05:27:42

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 7/19] serio sysfs intergration


===================================================================


[email protected], 2004-06-27 15:55:37-05:00, [email protected]
Input: serio sysfs integration

Signed-off-by: Dmitry Torokhov <[email protected]>


drivers/Makefile | 2
drivers/input/joystick/iforce/iforce-serio.c | 12 ++-
drivers/input/joystick/magellan.c | 14 ++--
drivers/input/joystick/spaceball.c | 14 ++--
drivers/input/joystick/spaceorb.c | 14 ++--
drivers/input/joystick/stinger.c | 14 ++--
drivers/input/joystick/twidjoy.c | 10 ++
drivers/input/joystick/warrior.c | 14 ++--
drivers/input/keyboard/atkbd.c | 18 +++--
drivers/input/keyboard/lkkbd.c | 14 ++--
drivers/input/keyboard/newtonkbd.c | 14 ++--
drivers/input/keyboard/sunkbd.c | 14 ++--
drivers/input/keyboard/xtkbd.c | 14 ++--
drivers/input/mouse/psmouse-base.c | 18 +++--
drivers/input/mouse/sermouse.c | 14 ++--
drivers/input/mouse/vsxxxaa.c | 14 ++--
drivers/input/serio/serio.c | 93 ++++++++++++++++++++++++---
drivers/input/touchscreen/gunze.c | 14 ++--
drivers/input/touchscreen/h3600_ts_input.c | 14 ++--
include/linux/serio.h | 9 ++
20 files changed, 261 insertions(+), 83 deletions(-)


===================================================================



diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile 2004-06-27 17:48:52 -05:00
+++ b/drivers/Makefile 2004-06-27 17:48:52 -05:00
@@ -37,9 +37,9 @@
obj-$(CONFIG_TC) += tc/
obj-$(CONFIG_USB) += usb/
obj-$(CONFIG_USB_GADGET) += usb/gadget/
+obj-$(CONFIG_SERIO) += input/serio/
obj-$(CONFIG_INPUT) += input/
obj-$(CONFIG_GAMEPORT) += input/gameport/
-obj-$(CONFIG_SERIO) += input/serio/
obj-$(CONFIG_I2O) += message/
obj-$(CONFIG_I2C) += i2c/
obj-$(CONFIG_PHONE) += telephony/
diff -Nru a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
--- a/drivers/input/joystick/iforce/iforce-serio.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/joystick/iforce/iforce-serio.c 2004-06-27 17:48:52 -05:00
@@ -159,8 +159,12 @@
}

struct serio_driver iforce_serio_drv = {
- .write_wakeup = iforce_serio_write_wakeup,
- .interrupt = iforce_serio_irq,
- .connect = iforce_serio_connect,
- .disconnect = iforce_serio_disconnect,
+ .driver = {
+ .name = "iforce",
+ },
+ .description = "RS232 I-Force joysticks and wheels driver",
+ .write_wakeup = iforce_serio_write_wakeup,
+ .interrupt = iforce_serio_irq,
+ .connect = iforce_serio_connect,
+ .disconnect = iforce_serio_disconnect,
};
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
--- a/drivers/input/joystick/magellan.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/joystick/magellan.c 2004-06-27 17:48:52 -05:00
@@ -35,8 +35,10 @@
#include <linux/serio.h>
#include <linux/init.h>

+#define DRIVER_DESC "Magellan and SpaceMouse 6dof controller driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("Magellan and SpaceMouse 6dof controller driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
@@ -200,9 +202,13 @@
*/

static struct serio_driver magellan_drv = {
- .interrupt = magellan_interrupt,
- .connect = magellan_connect,
- .disconnect = magellan_disconnect,
+ .driver = {
+ .name = "magellan",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = magellan_interrupt,
+ .connect = magellan_connect,
+ .disconnect = magellan_disconnect,
};

/*
diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
--- a/drivers/input/joystick/spaceball.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/joystick/spaceball.c 2004-06-27 17:48:52 -05:00
@@ -39,8 +39,10 @@
#include <linux/input.h>
#include <linux/serio.h>

+#define DRIVER_DESC "SpaceTec SpaceBall 2003/3003/4000 FLX driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("SpaceTec SpaceBall 2003/3003/4000 FLX driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
@@ -270,9 +272,13 @@
*/

static struct serio_driver spaceball_drv = {
- .interrupt = spaceball_interrupt,
- .connect = spaceball_connect,
- .disconnect = spaceball_disconnect,
+ .driver = {
+ .name = "spaceball",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = spaceball_interrupt,
+ .connect = spaceball_connect,
+ .disconnect = spaceball_disconnect,
};

/*
diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
--- a/drivers/input/joystick/spaceorb.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/joystick/spaceorb.c 2004-06-27 17:48:52 -05:00
@@ -38,8 +38,10 @@
#include <linux/input.h>
#include <linux/serio.h>

+#define DRIVER_DESC "SpaceTec SpaceOrb 360 and Avenger 6dof controller driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("SpaceTec SpaceOrb 360 and Avenger 6dof controller driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
@@ -214,9 +216,13 @@
*/

static struct serio_driver spaceorb_drv = {
- .interrupt = spaceorb_interrupt,
- .connect = spaceorb_connect,
- .disconnect = spaceorb_disconnect,
+ .driver = {
+ .name = "spaceorb",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = spaceorb_interrupt,
+ .connect = spaceorb_connect,
+ .disconnect = spaceorb_disconnect,
};

/*
diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
--- a/drivers/input/joystick/stinger.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/joystick/stinger.c 2004-06-27 17:48:52 -05:00
@@ -36,8 +36,10 @@
#include <linux/serio.h>
#include <linux/init.h>

+#define DRIVER_DESC "Gravis Stinger gamepad driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("Gravis Stinger gamepad driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
@@ -188,9 +190,13 @@
*/

static struct serio_driver stinger_drv = {
- .interrupt = stinger_interrupt,
- .connect = stinger_connect,
- .disconnect = stinger_disconnect,
+ .driver = {
+ .name = "stinger",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = stinger_interrupt,
+ .connect = stinger_connect,
+ .disconnect = stinger_disconnect,
};

/*
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/joystick/twidjoy.c 2004-06-27 17:48:52 -05:00
@@ -247,9 +247,13 @@
*/

static struct serio_driver twidjoy_drv = {
- .interrupt = twidjoy_interrupt,
- .connect = twidjoy_connect,
- .disconnect = twidjoy_disconnect,
+ .driver = {
+ .name = "twidjoy",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = twidjoy_interrupt,
+ .connect = twidjoy_connect,
+ .disconnect = twidjoy_disconnect,
};

/*
diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
--- a/drivers/input/joystick/warrior.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/joystick/warrior.c 2004-06-27 17:48:52 -05:00
@@ -35,8 +35,10 @@
#include <linux/serio.h>
#include <linux/init.h>

+#define DRIVER_DESC "Logitech WingMan Warrior joystick driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("Logitech WingMan Warrior joystick driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
@@ -200,9 +202,13 @@
*/

static struct serio_driver warrior_drv = {
- .interrupt = warrior_interrupt,
- .connect = warrior_connect,
- .disconnect = warrior_disconnect,
+ .driver = {
+ .name = "warrior",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = warrior_interrupt,
+ .connect = warrior_connect,
+ .disconnect = warrior_disconnect,
};

/*
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/keyboard/atkbd.c 2004-06-27 17:48:52 -05:00
@@ -27,8 +27,10 @@
#include <linux/serio.h>
#include <linux/workqueue.h>

+#define DRIVER_DESC "AT and PS/2 keyboard driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

static int atkbd_set = 2;
@@ -891,11 +893,15 @@
}

static struct serio_driver atkbd_drv = {
- .interrupt = atkbd_interrupt,
- .connect = atkbd_connect,
- .reconnect = atkbd_reconnect,
- .disconnect = atkbd_disconnect,
- .cleanup = atkbd_cleanup,
+ .driver = {
+ .name = "atkbd",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = atkbd_interrupt,
+ .connect = atkbd_connect,
+ .reconnect = atkbd_reconnect,
+ .disconnect = atkbd_disconnect,
+ .cleanup = atkbd_cleanup,
};

int __init atkbd_init(void)
diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- a/drivers/input/keyboard/lkkbd.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/keyboard/lkkbd.c 2004-06-27 17:48:52 -05:00
@@ -76,8 +76,10 @@
#include <linux/serio.h>
#include <linux/workqueue.h>

+#define DRIVER_DESC "LK keyboard driver"
+
MODULE_AUTHOR ("Jan-Benedict Glaw <[email protected]>");
-MODULE_DESCRIPTION ("LK keyboard driver");
+MODULE_DESCRIPTION (DRIVER_DESC);
MODULE_LICENSE ("GPL");

/*
@@ -704,9 +706,13 @@
}

static struct serio_driver lkkbd_drv = {
- .connect = lkkbd_connect,
- .disconnect = lkkbd_disconnect,
- .interrupt = lkkbd_interrupt,
+ .driver = {
+ .name = "lkkbd",
+ },
+ .description = DRIVER_DESC,
+ .connect = lkkbd_connect,
+ .disconnect = lkkbd_disconnect,
+ .interrupt = lkkbd_interrupt,
};

/*
diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
--- a/drivers/input/keyboard/newtonkbd.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/keyboard/newtonkbd.c 2004-06-27 17:48:52 -05:00
@@ -32,8 +32,10 @@
#include <linux/init.h>
#include <linux/serio.h>

+#define DRIVER_DESC "Newton keyboard driver"
+
MODULE_AUTHOR("Justin Cormack <[email protected]>");
-MODULE_DESCRIPTION("Newton keyboard driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

#define NKBD_KEY 0x7f
@@ -139,9 +141,13 @@
}

struct serio_driver nkbd_drv = {
- .interrupt = nkbd_interrupt,
- .connect = nkbd_connect,
- .disconnect = nkbd_disconnect
+ .driver = {
+ .name = "newtonkbd",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = nkbd_interrupt,
+ .connect = nkbd_connect,
+ .disconnect = nkbd_disconnect,
};

int __init nkbd_init(void)
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/keyboard/sunkbd.c 2004-06-27 17:48:52 -05:00
@@ -37,8 +37,10 @@
#include <linux/serio.h>
#include <linux/workqueue.h>

+#define DRIVER_DESC "Sun keyboard driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("Sun keyboard driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

static unsigned char sunkbd_keycode[128] = {
@@ -302,9 +304,13 @@
}

static struct serio_driver sunkbd_drv = {
- .interrupt = sunkbd_interrupt,
- .connect = sunkbd_connect,
- .disconnect = sunkbd_disconnect
+ .driver = {
+ .name = "sunkbd",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = sunkbd_interrupt,
+ .connect = sunkbd_connect,
+ .disconnect = sunkbd_disconnect,
};

/*
diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
--- a/drivers/input/keyboard/xtkbd.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/keyboard/xtkbd.c 2004-06-27 17:48:52 -05:00
@@ -34,8 +34,10 @@
#include <linux/init.h>
#include <linux/serio.h>

+#define DRIVER_DESC "XT keyboard driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("XT keyboard driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

#define XTKBD_EMUL0 0xe0
@@ -144,9 +146,13 @@
}

struct serio_driver xtkbd_drv = {
- .interrupt = xtkbd_interrupt,
- .connect = xtkbd_connect,
- .disconnect = xtkbd_disconnect
+ .driver = {
+ .name = "xtkbd",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = xtkbd_interrupt,
+ .connect = xtkbd_connect,
+ .disconnect = xtkbd_disconnect,
};

int __init xtkbd_init(void)
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/mouse/psmouse-base.c 2004-06-27 17:48:52 -05:00
@@ -22,8 +22,10 @@
#include "synaptics.h"
#include "logips2pp.h"

+#define DRIVER_DESC "PS/2 mouse driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("PS/2 mouse driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

static char *psmouse_proto;
@@ -825,11 +827,15 @@


static struct serio_driver psmouse_drv = {
- .interrupt = psmouse_interrupt,
- .connect = psmouse_connect,
- .reconnect = psmouse_reconnect,
- .disconnect = psmouse_disconnect,
- .cleanup = psmouse_cleanup,
+ .driver = {
+ .name = "psmouse",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = psmouse_interrupt,
+ .connect = psmouse_connect,
+ .reconnect = psmouse_reconnect,
+ .disconnect = psmouse_disconnect,
+ .cleanup = psmouse_cleanup,
};

static inline void psmouse_parse_proto(void)
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- a/drivers/input/mouse/sermouse.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/mouse/sermouse.c 2004-06-27 17:48:52 -05:00
@@ -37,8 +37,10 @@
#include <linux/serio.h>
#include <linux/init.h>

+#define DRIVER_DESC "Serial mouse driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("Serial mouse driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

static char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse",
@@ -290,9 +292,13 @@
}

static struct serio_driver sermouse_drv = {
- .interrupt = sermouse_interrupt,
- .connect = sermouse_connect,
- .disconnect = sermouse_disconnect
+ .driver = {
+ .name = "sermouse",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = sermouse_interrupt,
+ .connect = sermouse_connect,
+ .disconnect = sermouse_disconnect,
};

int __init sermouse_init(void)
diff -Nru a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
--- a/drivers/input/mouse/vsxxxaa.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/mouse/vsxxxaa.c 2004-06-27 17:48:52 -05:00
@@ -82,8 +82,10 @@
#include <linux/serio.h>
#include <linux/init.h>

+#define DRIVER_DESC "Serial DEC VSXXX-AA/GA mouse / DEC tablet driver"
+
MODULE_AUTHOR ("Jan-Benedict Glaw <[email protected]>");
-MODULE_DESCRIPTION ("Serial DEC VSXXX-AA/GA mouse / DEC tablet driver");
+MODULE_DESCRIPTION (DRIVER_DESC);
MODULE_LICENSE ("GPL");

#undef VSXXXAA_DEBUG
@@ -541,9 +543,13 @@
}

static struct serio_driver vsxxxaa_drv = {
- .connect = vsxxxaa_connect,
- .interrupt = vsxxxaa_interrupt,
- .disconnect = vsxxxaa_disconnect,
+ .driver = {
+ .name = "vsxxxaa",
+ },
+ .description = DRIVER_DESC,
+ .connect = vsxxxaa_connect,
+ .interrupt = vsxxxaa_interrupt,
+ .disconnect = vsxxxaa_disconnect,
};

int __init
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/serio/serio.c 2004-06-27 17:48:52 -05:00
@@ -56,6 +56,11 @@
static DECLARE_MUTEX(serio_sem); /* protects serio_list and serio_diriver_list */
static LIST_HEAD(serio_list);
static LIST_HEAD(serio_driver_list);
+static unsigned int serio_no;
+
+struct bus_type serio_bus = {
+ .name = "serio",
+};

static void serio_find_driver(struct serio *serio);
static void serio_create_port(struct serio *serio);
@@ -66,9 +71,19 @@

static int serio_bind_driver(struct serio *serio, struct serio_driver *drv)
{
+ get_driver(&drv->driver);
+
drv->connect(serio, drv);
+ if (serio->drv) {
+ down_write(&serio_bus.subsys.rwsem);
+ serio->dev.driver = &drv->driver;
+ device_bind_driver(&serio->dev);
+ up_write(&serio_bus.subsys.rwsem);
+ return 1;
+ }

- return serio->drv != NULL;
+ put_driver(&drv->driver);
+ return 0;
}

/* serio_find_driver() must be called with serio_sem down. */
@@ -224,10 +239,49 @@
* Serio port operations
*/

+static ssize_t serio_show_description(struct device *dev, char *buf)
+{
+ struct serio *serio = to_serio_port(dev);
+ return sprintf(buf, "%s\n", serio->name);
+}
+static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL);
+
+static ssize_t serio_show_legacy_position(struct device *dev, char *buf)
+{
+ struct serio *serio = to_serio_port(dev);
+ return sprintf(buf, "%s\n", serio->phys);
+}
+static DEVICE_ATTR(legacy_position, S_IRUGO, serio_show_legacy_position, NULL);
+
+static ssize_t serio_show_driver(struct device *dev, char *buf)
+{
+ return sprintf(buf, "%s\n", dev->driver ? dev->driver->name : "(none)");
+}
+static DEVICE_ATTR(driver, S_IRUGO, serio_show_driver, NULL);
+
+static void serio_release_port(struct device *dev)
+{
+ struct serio *serio = to_serio_port(dev);
+
+ kfree(serio);
+ module_put(THIS_MODULE);
+}
+
static void serio_create_port(struct serio *serio)
{
+ try_module_get(THIS_MODULE);
+
spin_lock_init(&serio->lock);
list_add_tail(&serio->node, &serio_list);
+ snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), "serio%d", serio_no++);
+ serio->dev.bus = &serio_bus;
+ serio->dev.release = serio_release_port;
+ if (serio->parent)
+ serio->dev.parent = &serio->parent->dev;
+ device_register(&serio->dev);
+ device_create_file(&serio->dev, &dev_attr_description);
+ device_create_file(&serio->dev, &dev_attr_legacy_position);
+ device_create_file(&serio->dev, &dev_attr_driver);
}

/*
@@ -242,8 +296,13 @@
serio_remove_pending_events(serio);
list_del_init(&serio->node);

- if (drv)
+ if (drv) {
drv->disconnect(serio);
+ down_write(&serio_bus.subsys.rwsem);
+ device_release_driver(&serio->dev);
+ up_write(&serio_bus.subsys.rwsem);
+ put_driver(&drv->driver);
+ }

if (serio->parent) {
spin_lock_irqsave(&serio->parent->lock, flags);
@@ -251,7 +310,7 @@
spin_unlock_irqrestore(&serio->parent->lock, flags);
}

- kfree(serio);
+ device_unregister(&serio->dev);
}

/*
@@ -332,8 +391,13 @@
/*
* Ok, no children left, now disconnect this port
*/
- if (drv)
+ if (drv) {
drv->disconnect(serio);
+ down_write(&serio_bus.subsys.rwsem);
+ device_release_driver(&serio->dev);
+ up_write(&serio_bus.subsys.rwsem);
+ put_driver(&drv->driver);
+ }
}

void serio_rescan(struct serio *serio)
@@ -387,6 +451,12 @@
* Serio driver operations
*/

+static ssize_t serio_driver_show_description(struct device_driver *drv, char *buf)
+{
+ struct serio_driver *driver = to_serio_driver(drv);
+ return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)");
+}
+static DRIVER_ATTR(description, S_IRUGO, serio_driver_show_description, NULL);

void serio_register_driver(struct serio_driver *drv)
{
@@ -396,6 +466,10 @@

list_add_tail(&drv->node, &serio_driver_list);

+ drv->driver.bus = &serio_bus;
+ driver_register(&drv->driver);
+ driver_create_file(&drv->driver, &driver_attr_description);
+
start_over:
list_for_each_entry(serio, &serio_list, node) {
if (!serio->drv) {
@@ -430,6 +504,8 @@
}
}

+ driver_unregister(&drv->driver);
+
up(&serio_sem);
}

@@ -489,22 +565,19 @@

static int __init serio_init(void)
{
- int pid;
-
- pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL);
-
- if (!pid) {
+ if (!(serio_pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL))) {
printk(KERN_WARNING "serio: Failed to start kseriod\n");
return -1;
}

- serio_pid = pid;
+ bus_register(&serio_bus);

return 0;
}

static void __exit serio_exit(void)
{
+ bus_unregister(&serio_bus);
kill_proc(serio_pid, SIGTERM, 1);
wait_for_completion(&serio_exited);
}
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
--- a/drivers/input/touchscreen/gunze.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/touchscreen/gunze.c 2004-06-27 17:48:52 -05:00
@@ -36,8 +36,10 @@
#include <linux/serio.h>
#include <linux/init.h>

+#define DRIVER_DESC "Gunze AHL-51S touchscreen driver"
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
-MODULE_DESCRIPTION("Gunze AHL-51S touchscreen driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
@@ -157,9 +159,13 @@
*/

static struct serio_driver gunze_drv = {
- .interrupt = gunze_interrupt,
- .connect = gunze_connect,
- .disconnect = gunze_disconnect,
+ .driver = {
+ .name = "gunze",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = gunze_interrupt,
+ .connect = gunze_connect,
+ .disconnect = gunze_disconnect,
};

/*
diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c 2004-06-27 17:48:52 -05:00
+++ b/drivers/input/touchscreen/h3600_ts_input.c 2004-06-27 17:48:52 -05:00
@@ -45,8 +45,10 @@
#include <asm/arch/hardware.h>
#include <asm/arch/irqs.h>

+#define DRIVER_DESC "H3600 touchscreen driver"
+
MODULE_AUTHOR("James Simmons <[email protected]>");
-MODULE_DESCRIPTION("H3600 touchscreen driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
@@ -479,9 +481,13 @@
*/

static struct serio_driver h3600ts_drv = {
- .interrupt = h3600ts_interrupt,
- .connect = h3600ts_connect,
- .disconnect = h3600ts_disconnect,
+ .driver = {
+ .name = "h3600ts",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = h3600ts_interrupt,
+ .connect = h3600ts_connect,
+ .disconnect = h3600ts_disconnect,
};

/*
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h 2004-06-27 17:48:52 -05:00
+++ b/include/linux/serio.h 2004-06-27 17:48:52 -05:00
@@ -18,6 +18,7 @@

#include <linux/list.h>
#include <linux/spinlock.h>
+#include <linux/device.h>

struct serio {
void *private;
@@ -44,12 +45,15 @@

struct serio_driver *drv; /* Accessed from interrupt, writes must be protected by serio_lock */

+ struct device dev;
+
struct list_head node;
};
+#define to_serio_port(d) container_of(d, struct serio, dev)

struct serio_driver {
void *private;
- char *name;
+ char *description;

void (*write_wakeup)(struct serio *);
irqreturn_t (*interrupt)(struct serio *, unsigned char,
@@ -59,8 +63,11 @@
void (*disconnect)(struct serio *);
void (*cleanup)(struct serio *);

+ struct device_driver driver;
+
struct list_head node;
};
+#define to_serio_driver(d) container_of(d, struct serio_driver, driver)

int serio_open(struct serio *serio, struct serio_driver *drv);
void serio_close(struct serio *serio);

2004-06-28 05:28:26

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 8/19] serio rebind


===================================================================


[email protected], 2004-06-27 15:56:07-05:00, [email protected]
Input: allow users manually rebind serio ports, like this:
echo -n "psmouse" > /sys/bus/serio/devices/serio0/driver
echo -n "atkbd" > /sys/bus/serio/devices/serio1/driver
echo -n "none" > /sys/bus/serio/devices/serio1/driver
echo -n "reconnect" > /sys/bus/serio/devices/serio1/driver
echo -n "rescan" > /sys/bus/serio/devices/serio1/driver

Signed-off-by: Dmitry Torokhov <[email protected]>


serio.c | 34 +++++++++++++++++++++++++++++++++-
1 files changed, 33 insertions(+), 1 deletion(-)


===================================================================



diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-06-27 17:49:15 -05:00
+++ b/drivers/input/serio/serio.c 2004-06-27 17:49:15 -05:00
@@ -257,7 +257,39 @@
{
return sprintf(buf, "%s\n", dev->driver ? dev->driver->name : "(none)");
}
-static DEVICE_ATTR(driver, S_IRUGO, serio_show_driver, NULL);
+
+static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t count)
+{
+ struct serio *serio = to_serio_port(dev);
+ struct device_driver *drv;
+ struct kobject *k;
+ int retval;
+
+ retval = down_interruptible(&serio_sem);
+ if (retval)
+ return retval;
+
+ retval = count;
+ if (!strncmp(buf, "none", count)) {
+ serio_disconnect_port(serio);
+ } else if (!strncmp(buf, "reconnect", count)) {
+ serio_reconnect_port(serio);
+ } else if (!strncmp(buf, "rescan", count)) {
+ serio_disconnect_port(serio);
+ serio_connect_port(serio, NULL);
+ } else if ((k = kset_find_obj(&serio_bus.drivers, buf)) != NULL) {
+ drv = container_of(k, struct device_driver, kobj);
+ serio_disconnect_port(serio);
+ serio_connect_port(serio, to_serio_driver(drv));
+ } else {
+ retval = -EINVAL;
+ }
+
+ up(&serio_sem);
+
+ return retval;
+}
+static DEVICE_ATTR(driver, S_IWUSR | S_IRUGO, serio_show_driver, serio_rebind_driver);

static void serio_release_port(struct device *dev)
{

2004-06-28 05:31:15

by Dmitry Torokhov

[permalink] [raw]
Subject: PATCH 9/19] serio manual bind


===================================================================


[email protected], 2004-06-27 15:56:35-05:00, [email protected]
Input: allow marking some drivers (that don't do HW autodetection)
as manual bind only. Such drivers will only be bound to a
serio port if user requests it by echoing driver name into
port's sysfs driver attribute.

Signed-off-by: Dmitry Torokhov <[email protected]>


drivers/input/serio/serio.c | 9 +++++++--
include/linux/serio.h | 2 ++
2 files changed, 9 insertions(+), 2 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-06-27 17:49:39 -05:00
+++ b/drivers/input/serio/serio.c 2004-06-27 17:49:39 -05:00
@@ -92,8 +92,9 @@
struct serio_driver *drv;

list_for_each_entry(drv, &serio_driver_list, node)
- if (serio_bind_driver(serio, drv))
- break;
+ if (!drv->manual_bind)
+ if (serio_bind_driver(serio, drv))
+ break;
}

/*
@@ -502,6 +503,9 @@
driver_register(&drv->driver);
driver_create_file(&drv->driver, &driver_attr_description);

+ if (drv->manual_bind)
+ goto out;
+
start_over:
list_for_each_entry(serio, &serio_list, node) {
if (!serio->drv) {
@@ -515,6 +519,7 @@
}
}

+out:
up(&serio_sem);
}

diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h 2004-06-27 17:49:39 -05:00
+++ b/include/linux/serio.h 2004-06-27 17:49:39 -05:00
@@ -55,6 +55,8 @@
void *private;
char *description;

+ int manual_bind;
+
void (*write_wakeup)(struct serio *);
irqreturn_t (*interrupt)(struct serio *, unsigned char,
unsigned int, struct pt_regs *);

2004-06-28 05:31:14

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 11/19] add platform_device_register_simple


===================================================================


[email protected], 2004-06-27 15:57:46-05:00, [email protected]
sysfs: add platform_device_register_simple to register platform devices
requiring minimal resource and memory management. The device will
have standard release function that just frees memory occupied by
the platform device. By having release function in the driver core
modules using such devices can be unloaded without waiting for the
last reference to the device to be dropped.

Suggested by Russell King

Signed-off-by: Dmitry Torokhov <[email protected]>


drivers/base/platform.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/device.h | 2 +
2 files changed, 70 insertions(+)


===================================================================



diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c
--- a/drivers/base/platform.c 2004-06-27 17:50:23 -05:00
+++ b/drivers/base/platform.c 2004-06-27 17:50:23 -05:00
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/err.h>

struct device platform_bus = {
.bus_id = "platform",
@@ -131,6 +132,13 @@
return ret;
}

+/**
+ * platform_device_unregister - remove a platform-level device
+ * @dev: platform device we're removing
+ *
+ * Note that this function will also release all memory- and port-based
+ * resources owned by the device (@dev->resource).
+ */
void platform_device_unregister(struct platform_device * pdev)
{
int i;
@@ -146,6 +154,65 @@
}
}

+struct platform_object {
+ struct platform_device pdev;
+ struct resource resources[0];
+};
+
+static void platform_device_release_simple(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ kfree(container_of(pdev, struct platform_object, pdev));
+}
+
+/**
+ * platform_device_register_simple
+ * @name: base name of the device we're adding
+ * @id: instance id
+ * @res: set of resources that needs to be allocated for the device
+ * @num: number of resources
+ *
+ * This function creates a simple platform device that requires minimal
+ * resource and memory management. Canned release function freeing
+ * memory allocated for the device allows drivers using such devices
+ * to be unloaded iwithout waiting for the last reference to the device
+ * to be dropped.
+ */
+struct platform_device *platform_device_register_simple(char *name, unsigned int id,
+ struct resource *res, unsigned int num)
+{
+ struct platform_object *pobj;
+ int retval;
+
+ pobj = kmalloc(sizeof(struct platform_object) + sizeof(struct resource) * num, GFP_KERNEL);
+ if (!pobj) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ memset(pobj, 0, sizeof(*pobj));
+ pobj->pdev.name = name;
+ pobj->pdev.id = id;
+ pobj->pdev.dev.release = platform_device_release_simple;
+
+ if (num) {
+ memcpy(pobj->resources, res, sizeof(struct resource) * num);
+ pobj->pdev.resource = pobj->resources;
+ pobj->pdev.num_resources = num;
+ }
+
+ retval = platform_device_register(&pobj->pdev);
+ if (retval)
+ goto error;
+
+ return &pobj->pdev;
+
+error:
+ kfree(pobj);
+ return ERR_PTR(retval);
+}
+

/**
* platform_match - bind platform device to platform driver.
@@ -213,6 +280,7 @@
EXPORT_SYMBOL(platform_bus);
EXPORT_SYMBOL(platform_bus_type);
EXPORT_SYMBOL(platform_device_register);
+EXPORT_SYMBOL(platform_device_register_simple);
EXPORT_SYMBOL(platform_device_unregister);
EXPORT_SYMBOL(platform_get_irq);
EXPORT_SYMBOL(platform_get_resource);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h 2004-06-27 17:50:23 -05:00
+++ b/include/linux/device.h 2004-06-27 17:50:23 -05:00
@@ -381,6 +381,8 @@
extern int platform_get_irq(struct platform_device *, unsigned int);
extern int platform_add_devices(struct platform_device **, int);

+extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int);
+
/* drivers/base/power.c */
extern void device_shutdown(void);

2004-06-28 05:35:05

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 12/19] convert i8042 into a platform device


===================================================================


[email protected], 2004-06-27 15:58:25-05:00, [email protected]
Input: make i8042 a platform device instead of system device so
its serio ports have proper parent

Signed-off-by: Dmitry Torokhov <[email protected]>


i8042.c | 60 ++++++++++++++++++++++++++++++++++--------------------------
1 files changed, 34 insertions(+), 26 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c 2004-06-27 17:50:42 -05:00
+++ b/drivers/input/serio/i8042.c 2004-06-27 17:50:42 -05:00
@@ -21,6 +21,7 @@
#include <linux/sysdev.h>
#include <linux/pm.h>
#include <linux/serio.h>
+#include <linux/err.h>

#include <asm/io.h>

@@ -101,9 +102,9 @@
static unsigned char i8042_ctr;
static unsigned char i8042_mux_open;
static unsigned char i8042_mux_present;
-static unsigned char i8042_sysdev_initialized;
static struct pm_dev *i8042_pm_dev;
static struct timer_list i8042_timer;
+static struct platform_device *i8042_platform_device;

/*
* Shared IRQ's require a device pointer, but this driver doesn't support
@@ -855,7 +856,7 @@
return NOTIFY_DONE;
}

-static struct notifier_block i8042_notifier=
+static struct notifier_block i8042_notifier =
{
i8042_notify_sys,
NULL,
@@ -865,25 +866,27 @@
/*
* Suspend/resume handlers for the new PM scheme (driver model)
*/
-static int i8042_suspend(struct sys_device *dev, u32 state)
+static int i8042_suspend(struct device *dev, u32 state, u32 level)
{
- return i8042_controller_suspend();
+ return level == SUSPEND_DISABLE ? i8042_controller_suspend() : 0;
}

-static int i8042_resume(struct sys_device *dev)
+static int i8042_resume(struct device *dev, u32 level)
{
- return i8042_controller_resume();
+ return level == RESUME_ENABLE ? i8042_controller_resume() : 0;
}

-static struct sysdev_class kbc_sysclass = {
- set_kset_name("i8042"),
- .suspend = i8042_suspend,
- .resume = i8042_resume,
-};
+static void i8042_shutdown(struct device *dev)
+{
+ i8042_controller_cleanup();
+}

-static struct sys_device device_i8042 = {
- .id = 0,
- .cls = &kbc_sysclass,
+static struct device_driver i8042_driver = {
+ .name = "i8042",
+ .bus = &platform_bus_type,
+ .suspend = i8042_suspend,
+ .resume = i8042_resume,
+ .shutdown = i8042_shutdown,
};

/*
@@ -914,6 +917,7 @@
serio->open = i8042_open,
serio->close = i8042_close,
serio->port_data = &i8042_kbd_values,
+ serio->dev.parent = &i8042_platform_device->dev;
strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
}
@@ -933,6 +937,7 @@
serio->open = i8042_open;
serio->close = i8042_close;
serio->port_data = &i8042_aux_values,
+ serio->dev.parent = &i8042_platform_device->dev;
strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
}
@@ -957,6 +962,7 @@
serio->open = i8042_open;
serio->close = i8042_close;
serio->port_data = values;
+ serio->dev.parent = &i8042_platform_device->dev;
snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
}
@@ -967,6 +973,7 @@
int __init i8042_init(void)
{
int i;
+ int err;

dbg_init();

@@ -989,6 +996,16 @@
}
#endif

+ err = driver_register(&i8042_driver);
+ if (err)
+ return err;
+
+ i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0);
+ if (IS_ERR(i8042_platform_device)) {
+ driver_unregister(&i8042_driver);
+ return PTR_ERR(i8042_platform_device);
+ }
+
if (!i8042_noaux && !i8042_check_aux(&i8042_aux_values)) {
if (!i8042_nomux && !i8042_check_mux(&i8042_aux_values))
for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
@@ -1009,13 +1026,6 @@

mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);

- if (sysdev_class_register(&kbc_sysclass) == 0) {
- if (sysdev_register(&device_i8042) == 0)
- i8042_sysdev_initialized = 1;
- else
- sysdev_class_unregister(&kbc_sysclass);
- }
-
i8042_pm_dev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, i8042_pm_callback);

register_reboot_notifier(&i8042_notifier);
@@ -1032,11 +1042,6 @@
if (i8042_pm_dev)
pm_unregister(i8042_pm_dev);

- if (i8042_sysdev_initialized) {
- sysdev_unregister(&device_i8042);
- sysdev_class_unregister(&kbc_sysclass);
- }
-
i8042_controller_cleanup();

if (i8042_kbd_values.exists)
@@ -1050,6 +1055,9 @@
serio_unregister_port(i8042_mux_port[i]);

del_timer_sync(&i8042_timer);
+
+ platform_device_unregister(i8042_platform_device);
+ driver_unregister(&i8042_driver);

i8042_platform_exit();
}

2004-06-28 05:35:04

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 13/19] more platform device conversions


===================================================================


[email protected], 2004-06-27 15:58:55-05:00, [email protected]
Input: integrate ct82c710, maceps2, q40kbd and rpckbd with sysfs
as platform devices so their serio ports have proper parents

Signed-off-by: Dmitry Torokhov <[email protected]>


ct82c710.c | 50 ++++++++++++++++++++++++++++----------------------
maceps2.c | 19 ++++++++++++++-----
q40kbd.c | 18 ++++++++++++++----
rpckbd.c | 20 +++++++++++++++-----
4 files changed, 71 insertions(+), 36 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
--- a/drivers/input/serio/ct82c710.c 2004-06-27 17:51:01 -05:00
+++ b/drivers/input/serio/ct82c710.c 2004-06-27 17:51:01 -05:00
@@ -36,6 +36,7 @@
#include <linux/interrupt.h>
#include <linux/serio.h>
#include <linux/errno.h>
+#include <linux/err.h>

#include <asm/io.h>

@@ -58,10 +59,12 @@

#define CT82C710_IRQ 12

-static struct serio *ct82c710_port;
-static int ct82c710_data;
-static int ct82c710_status;
+#define CT82C710_DATA ct82c710_iores.start
+#define CT82C710_STATUS (ct82c710_iores.start + 1)

+static struct serio *ct82c710_port;
+static struct platform_device *ct82c710_device;
+static struct resource ct82c710_iores;

/*
* Interrupt handler for the 82C710 mouse port. A character
@@ -70,7 +73,7 @@

static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
{
- return serio_interrupt(ct82c710_port, inb(ct82c710_data), 0, regs);
+ return serio_interrupt(ct82c710_port, inb(CT82C710_DATA), 0, regs);
}

/*
@@ -81,10 +84,10 @@
{
int timeout = 60000;

- while ((inb(ct82c710_status) & (CT82C710_RX_FULL | CT82C710_TX_IDLE | CT82C710_DEV_IDLE))
+ while ((inb(CT82C710_STATUS) & (CT82C710_RX_FULL | CT82C710_TX_IDLE | CT82C710_DEV_IDLE))
!= (CT82C710_DEV_IDLE | CT82C710_TX_IDLE) && timeout) {

- if (inb_p(ct82c710_status) & CT82C710_RX_FULL) inb_p(ct82c710_data);
+ if (inb_p(CT82C710_STATUS) & CT82C710_RX_FULL) inb_p(CT82C710_DATA);

udelay(1);
timeout--;
@@ -98,7 +101,7 @@
if (ct82c170_wait())
printk(KERN_WARNING "ct82c710.c: Device busy in close()\n");

- outb_p(inb_p(ct82c710_status) & ~(CT82C710_ENABLE | CT82C710_INTS_ON), ct82c710_status);
+ outb_p(inb_p(CT82C710_STATUS) & ~(CT82C710_ENABLE | CT82C710_INTS_ON), CT82C710_STATUS);

if (ct82c170_wait())
printk(KERN_WARNING "ct82c710.c: Device busy in close()\n");
@@ -113,21 +116,21 @@
if (request_irq(CT82C710_IRQ, ct82c710_interrupt, 0, "ct82c710", NULL))
return -1;

- status = inb_p(ct82c710_status);
+ status = inb_p(CT82C710_STATUS);

status |= (CT82C710_ENABLE | CT82C710_RESET);
- outb_p(status, ct82c710_status);
+ outb_p(status, CT82C710_STATUS);

status &= ~(CT82C710_RESET);
- outb_p(status, ct82c710_status);
+ outb_p(status, CT82C710_STATUS);

status |= CT82C710_INTS_ON;
- outb_p(status, ct82c710_status); /* Enable interrupts */
+ outb_p(status, CT82C710_STATUS); /* Enable interrupts */

while (ct82c170_wait()) {
printk(KERN_ERR "ct82c710: Device busy in open()\n");
status &= ~(CT82C710_ENABLE | CT82C710_INTS_ON);
- outb_p(status, ct82c710_status);
+ outb_p(status, CT82C710_STATUS);
free_irq(CT82C710_IRQ, NULL);
return -1;
}
@@ -142,7 +145,7 @@
static int ct82c710_write(struct serio *port, unsigned char c)
{
if (ct82c170_wait()) return -1;
- outb_p(c, ct82c710_data);
+ outb_p(c, CT82C710_DATA);
return 0;
}

@@ -162,8 +165,9 @@
return -1; /* No: no 82C710 here */

outb_p(0x0d, 0x390); /* Write index */
- ct82c710_data = inb_p(0x391) << 2; /* Get mouse I/O address */
- ct82c710_status = ct82c710_data + 1;
+ ct82c710_iores.start = inb_p(0x391) << 2; /* Get mouse I/O address */
+ ct82c710_iores.end = ct82c710_iores.start + 1;
+ ct82c710_iores.flags = IORESOURCE_IO;
outb_p(0x0f, 0x390);
outb_p(0x0f, 0x391); /* Close config mode */

@@ -181,8 +185,9 @@
serio->open = ct82c710_open;
serio->close = ct82c710_close;
serio->write = ct82c710_write;
+ serio->dev.parent = &ct82c710_device->dev;
strlcpy(serio->name, "C&T 82c710 mouse port", sizeof(serio->name));
- snprintf(serio->phys, sizeof(serio->phys), "isa%04x/serio0", ct82c710_data);
+ snprintf(serio->phys, sizeof(serio->phys), "isa%04lx/serio0", CT82C710_DATA);
}

return serio;
@@ -193,18 +198,19 @@
if (ct82c710_probe())
return -ENODEV;

- if (request_region(ct82c710_data, 2, "ct82c710"))
- return -EBUSY;
+ ct82c710_device = platform_device_register_simple("ct82c710", -1, &ct82c710_iores, 1);
+ if (IS_ERR(ct82c710_device))
+ return PTR_ERR(ct82c710_device);

if (!(ct82c710_port = ct82c710_allocate_port())) {
- release_region(ct82c710_data, 2);
+ platform_device_unregister(ct82c710_device);
return -ENOMEM;
}

serio_register_port(ct82c710_port);

- printk(KERN_INFO "serio: C&T 82c710 mouse port at %#x irq %d\n",
- ct82c710_data, CT82C710_IRQ);
+ printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n",
+ CT82C710_DATA, CT82C710_IRQ);

return 0;
}
@@ -212,7 +218,7 @@
void __exit ct82c710_exit(void)
{
serio_unregister_port(ct82c710_port);
- release_region(ct82c710_data, 2);
+ platform_device_unregister(ct82c710_device);
}

module_init(ct82c710_init);
diff -Nru a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
--- a/drivers/input/serio/maceps2.c 2004-06-27 17:51:01 -05:00
+++ b/drivers/input/serio/maceps2.c 2004-06-27 17:51:01 -05:00
@@ -17,6 +17,7 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <linux/err.h>

#include <asm/io.h>
#include <asm/irq.h>
@@ -53,6 +54,7 @@

static struct maceps2_data port_data[2];
static struct serio *maceps2_port[2];
+static struct platform_device *maceps2_device;

static int maceps2_write(struct serio *dev, unsigned char val)
{
@@ -123,13 +125,14 @@
serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
if (serio) {
memset(serio, 0, sizeof(struct serio));
- serio->type = SERIO_8042;
- serio->write = maceps2_write;
- serio->open = maceps2_open;
- serio->close = maceps2_close;
+ serio->type = SERIO_8042;
+ serio->write = maceps2_write;
+ serio->open = maceps2_open;
+ serio->close = maceps2_close;
snprintf(serio->name, sizeof(serio->name), "MACE PS/2 port%d", idx);
snprintf(serio->phys, sizeof(serio->phys), "mace/serio%d", idx);
- serio->port_data = &port_data[idx];
+ serio->port_data = &port_data[idx];
+ serio->dev.parent = &maceps2_device->dev;
}

return serio;
@@ -138,6 +141,10 @@

static int __init maceps2_init(void)
{
+ maceps2_device = platform_device_register_simple("maceps2", -1, NULL, 0);
+ if (IS_ERR(maceps2_device))
+ return PTR_ERR(maceps2_device);
+
port_data[0].port = &mace->perif.ps2.keyb;
port_data[0].irq = MACEISA_KEYB_IRQ;
port_data[1].port = &mace->perif.ps2.mouse;
@@ -148,6 +155,7 @@
if (!maceps2_port[0] || !maceps2_port[1]) {
kfree(maceps2_port[0]);
kfree(maceps2_port[1]);
+ platform_device_unregister(maceps2_device);
return -ENOMEM;
}

@@ -161,6 +169,7 @@
{
serio_unregister_port(maceps2_port[0]);
serio_unregister_port(maceps2_port[1]);
+ platform_device_unregister(maceps2_device);
}

module_init(maceps2_init);
diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
--- a/drivers/input/serio/q40kbd.c 2004-06-27 17:51:01 -05:00
+++ b/drivers/input/serio/q40kbd.c 2004-06-27 17:51:01 -05:00
@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/interrupt.h>
+#include <linux/err.h>

#include <asm/bitops.h>
#include <asm/io.h>
@@ -49,6 +50,7 @@

spinlock_t q40kbd_lock = SPIN_LOCK_UNLOCKED;
static struct serio *q40kbd_port;
+static struct platform_device *q40kbd_device;

static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
@@ -120,9 +122,10 @@
serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
if (serio) {
memset(serio, 0, sizeof(struct serio));
- serio->type = SERIO_8042;
- serio->open = q40kbd_open;
- serio->close = q40kbd_close;
+ serio->type = SERIO_8042;
+ serio->open = q40kbd_open;
+ serio->close = q40kbd_close;
+ serio->dev.parent = &q40kbd_device->dev;
strlcpy(serio->name, "Q40 Kbd Port", sizeof(serio->name));
strlcpy(serio->phys, "Q40", sizeof(serio->phys));
}
@@ -135,8 +138,14 @@
if (!MACH_IS_Q40)
return -EIO;

- if (!(q40kbd_port = q40kbd_allocate_port()))
+ q40kbd_device = platform_device_register_simple("q40kbd", -1, NULL, 0);
+ if (IS_ERR(q40kbd_device))
+ return PTR_ERR(q40kbd_device);
+
+ if (!(q40kbd_port = q40kbd_allocate_port())) {
+ platform_device_unregister(q40kbd_device);
return -ENOMEM;
+ }

serio_register_port(q40kbd_port);
printk(KERN_INFO "serio: Q40 kbd registered\n");
@@ -147,6 +156,7 @@
static void __exit q40kbd_exit(void)
{
serio_unregister_port(q40kbd_port);
+ platform_device_unregister(q40kbd_device);
}

module_init(q40kbd_init);
diff -Nru a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
--- a/drivers/input/serio/rpckbd.c 2004-06-27 17:51:01 -05:00
+++ b/drivers/input/serio/rpckbd.c 2004-06-27 17:51:01 -05:00
@@ -33,6 +33,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/serio.h>
+#include <linux/err.h>

#include <asm/irq.h>
#include <asm/hardware.h>
@@ -45,6 +46,7 @@
MODULE_LICENSE("GPL");

static struct serio *rpckbd_port;
+static struct platform_device *rpckbd_device;

static int rpckbd_write(struct serio *port, unsigned char val)
{
@@ -115,10 +117,11 @@
serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
if (serio) {
memset(serio, 0, sizeof(struct serio));
- serio->type = SERIO_8042;
- serio->write = rpckbd_write;
- serio->open = rpckbd_open;
- serio->close = rpckbd_close;
+ serio->type = SERIO_8042;
+ serio->write = rpckbd_write;
+ serio->open = rpckbd_open;
+ serio->close = rpckbd_close;
+ serio->dev.parent = &rpckbd_device->dev;
strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
}
@@ -128,8 +131,14 @@

static int __init rpckbd_init(void)
{
- if (!(rpckbd_port = rpckbd_allocate_port()))
+ rpckbd_device = platform_device_register_simple("rpckbd", -1, NULL, 0);
+ if (IS_ERR(rpckbd_device))
+ return PTR_ERR(rpckbd_device);
+
+ if (!(rpckbd_port = rpckbd_allocate_port())) {
+ platform_device_unregister(rpckbd_device);
return -ENOMEM;
+ }

serio_register_port(rpckbd_port);
return 0;
@@ -138,6 +147,7 @@
static void __exit rpckbd_exit(void)
{
serio_unregister_port(rpckbd_port);
+ platform_device_unregister(rpckbd_device);
}

module_init(rpckbd_init);

2004-06-28 05:39:22

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 16/19] add bus' default driver attributes


===================================================================


[email protected], 2004-06-27 19:22:44-05:00, [email protected]
Driver core: add default driver attributes to struct bus_type

Signed-off-by: Dmitry Torokhov <[email protected]>


drivers/base/bus.c | 37 +++++++++++++++++++++++++++++++++++--
include/linux/device.h | 1 +
2 files changed, 36 insertions(+), 2 deletions(-)


===================================================================



diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c 2004-06-27 19:24:04 -05:00
+++ b/drivers/base/bus.c 2004-06-27 19:24:04 -05:00
@@ -415,7 +415,7 @@
static void device_remove_attrs(struct bus_type * bus, struct device * dev)
{
int i;
-
+
if (bus->dev_attrs) {
for (i = 0; attr_name(bus->dev_attrs[i]); i++)
device_remove_file(dev,&bus->dev_attrs[i]);
@@ -471,6 +471,37 @@
}
}

+static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv)
+{
+ int error = 0;
+ int i;
+
+ if (bus->drv_attrs) {
+ for (i = 0; attr_name(bus->drv_attrs[i]); i++) {
+ error = driver_create_file(drv, &bus->drv_attrs[i]);
+ if (error)
+ goto Err;
+ }
+ }
+ Done:
+ return error;
+ Err:
+ while (--i >= 0)
+ driver_remove_file(drv, &bus->drv_attrs[i]);
+ goto Done;
+}
+
+
+static void driver_remove_attrs(struct bus_type * bus, struct device_driver * drv)
+{
+ int i;
+
+ if (bus->drv_attrs) {
+ for (i = 0; attr_name(bus->drv_attrs[i]); i++)
+ driver_remove_file(drv, &bus->drv_attrs[i]);
+ }
+}
+

/**
* bus_add_driver - Add a driver to the bus.
@@ -499,6 +530,7 @@
driver_attach(drv);
up_write(&bus->subsys.rwsem);

+ driver_add_attrs(bus, drv);
}
return error;
}
@@ -516,6 +548,7 @@
void bus_remove_driver(struct device_driver * drv)
{
if (drv->bus) {
+ driver_remove_attrs(drv->bus, drv);
down_write(&drv->bus->subsys.rwsem);
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
driver_detach(drv);
@@ -610,7 +643,7 @@
static void bus_remove_attrs(struct bus_type * bus)
{
int i;
-
+
if (bus->bus_attrs) {
for (i = 0; attr_name(bus->bus_attrs[i]); i++)
bus_remove_file(bus,&bus->bus_attrs[i]);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h 2004-06-27 19:24:04 -05:00
+++ b/include/linux/device.h 2004-06-27 19:24:04 -05:00
@@ -56,6 +56,7 @@

struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs;
+ struct driver_attribute * drv_attrs;

int (*match)(struct device * dev, struct device_driver * drv);
struct device * (*add) (struct device * parent, char * bus_id);

2004-06-28 05:40:22

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 15/19] synaptics passthrough handling


===================================================================


[email protected], 2004-06-27 16:03:33-05:00, [email protected]
Input: synaptics - do not try to process packets from slave device
as if they were coming form the touchpad itself if pass-through
port is disconnected

Signed-off-by: Dmitry Torokhov <[email protected]>


synaptics.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)


===================================================================



diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c 2004-06-27 17:51:38 -05:00
+++ b/drivers/input/mouse/synaptics.c 2004-06-27 17:51:38 -05:00
@@ -472,9 +472,10 @@
if (unlikely(priv->pkt_type == SYN_NEWABS))
priv->pkt_type = synaptics_detect_pkt_type(psmouse);

- if (psmouse->serio->child && psmouse->serio->child->drv && synaptics_is_pt_packet(psmouse->packet))
- synaptics_pass_pt_packet(psmouse->serio->child, psmouse->packet);
- else
+ if (SYN_CAP_PASS_THROUGH(priv->capabilities) && synaptics_is_pt_packet(psmouse->packet)) {
+ if (psmouse->serio->child && psmouse->serio->child->drv)
+ synaptics_pass_pt_packet(psmouse->serio->child, psmouse->packet);
+ } else
synaptics_process_packet(psmouse);

return PSMOUSE_FULL_PACKET;

2004-06-28 05:43:25

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 18/19] add driver_find


===================================================================


[email protected], 2004-06-27 20:49:01-05:00, [email protected]
Driver core: add driver_find helper to find a driver by its name

Signed-off-by: Dmitry Torokhov <[email protected]>


drivers/base/driver.c | 16 ++++++++++++++++
include/linux/device.h | 1 +
2 files changed, 17 insertions(+)


===================================================================



diff -Nru a/drivers/base/driver.c b/drivers/base/driver.c
--- a/drivers/base/driver.c 2004-06-27 21:24:06 -05:00
+++ b/drivers/base/driver.c 2004-06-27 21:24:06 -05:00
@@ -111,10 +111,26 @@
up(&drv->unload_sem);
}

+/**
+ * driver_find - find driver on a given bus by its name.
+ * @name: name of the driver.
+ * @bus: bus to seatch for the driver
+ */
+
+struct device_driver *driver_find(const char *name, struct bus_type *bus)
+{
+ struct kobject *k = kset_find_obj(&bus->drivers, name);
+ if (k)
+ return to_drv(k);
+ return NULL;
+}
+
+
EXPORT_SYMBOL(driver_register);
EXPORT_SYMBOL(driver_unregister);
EXPORT_SYMBOL(get_driver);
EXPORT_SYMBOL(put_driver);
+EXPORT_SYMBOL(driver_find);

EXPORT_SYMBOL(driver_create_file);
EXPORT_SYMBOL(driver_remove_file);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h 2004-06-27 21:24:06 -05:00
+++ b/include/linux/device.h 2004-06-27 21:24:06 -05:00
@@ -120,6 +120,7 @@

extern struct device_driver * get_driver(struct device_driver * drv);
extern void put_driver(struct device_driver * drv);
+extern struct device_driver *driver_find(const char *name, struct bus_type *bus);


/* driverfs interface for exporting driver attributes */

2004-06-28 05:43:24

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 19/19] serio use driver_find


===================================================================


[email protected], 2004-06-27 21:09:35-05:00, [email protected]
Input: serio - make use of driver_find instead of re-implementing it

Signed-off-by: Dmitry Torokhov <[email protected]>


serio.c | 4 +---
1 files changed, 1 insertion(+), 3 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-06-27 21:24:26 -05:00
+++ b/drivers/input/serio/serio.c 2004-06-27 21:24:26 -05:00
@@ -261,7 +261,6 @@
{
struct serio *serio = to_serio_port(dev);
struct device_driver *drv;
- struct kobject *k;
int retval;

retval = down_interruptible(&serio_sem);
@@ -276,8 +275,7 @@
} else if (!strncmp(buf, "rescan", count)) {
serio_disconnect_port(serio);
serio_connect_port(serio, NULL);
- } else if ((k = kset_find_obj(&serio_bus.drivers, buf)) != NULL) {
- drv = container_of(k, struct device_driver, kobj);
+ } else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
serio_disconnect_port(serio);
serio_connect_port(serio, to_serio_driver(drv));
} else {

2004-06-28 05:47:07

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 17/19] serio use bus' default driver/device attributes


===================================================================


[email protected], 2004-06-27 19:39:04-05:00, [email protected]
Input: Switch to use bus' default device and driver attributes to
manage serio sysfs attributes

Signed-off-by: Dmitry Torokhov <[email protected]>


serio.c | 23 +++++++++++++++--------
1 files changed, 15 insertions(+), 8 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-06-27 21:23:42 -05:00
+++ b/drivers/input/serio/serio.c 2004-06-27 21:23:42 -05:00
@@ -245,14 +245,12 @@
struct serio *serio = to_serio_port(dev);
return sprintf(buf, "%s\n", serio->name);
}
-static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL);

static ssize_t serio_show_legacy_position(struct device *dev, char *buf)
{
struct serio *serio = to_serio_port(dev);
return sprintf(buf, "%s\n", serio->phys);
}
-static DEVICE_ATTR(legacy_position, S_IRUGO, serio_show_legacy_position, NULL);

static ssize_t serio_show_driver(struct device *dev, char *buf)
{
@@ -290,7 +288,14 @@

return retval;
}
-static DEVICE_ATTR(driver, S_IWUSR | S_IRUGO, serio_show_driver, serio_rebind_driver);
+
+static struct device_attribute serio_device_attrs[] = {
+ __ATTR(description, S_IRUGO, serio_show_description, NULL),
+ __ATTR(legacy_position, S_IRUGO, serio_show_legacy_position, NULL),
+ __ATTR(driver, S_IWUSR | S_IRUGO, serio_show_driver, serio_rebind_driver),
+ __ATTR_NULL
+};
+

static void serio_release_port(struct device *dev)
{
@@ -312,9 +317,6 @@
if (serio->parent)
serio->dev.parent = &serio->parent->dev;
device_register(&serio->dev);
- device_create_file(&serio->dev, &dev_attr_description);
- device_create_file(&serio->dev, &dev_attr_legacy_position);
- device_create_file(&serio->dev, &dev_attr_driver);
}

/*
@@ -489,7 +491,11 @@
struct serio_driver *driver = to_serio_driver(drv);
return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)");
}
-static DRIVER_ATTR(description, S_IRUGO, serio_driver_show_description, NULL);
+
+static struct driver_attribute serio_driver_attrs[] = {
+ __ATTR(description, S_IRUGO, serio_driver_show_description, NULL),
+ __ATTR_NULL
+};

void serio_register_driver(struct serio_driver *drv)
{
@@ -501,7 +507,6 @@

drv->driver.bus = &serio_bus;
driver_register(&drv->driver);
- driver_create_file(&drv->driver, &driver_attr_description);

if (drv->manual_bind)
goto out;
@@ -607,6 +612,8 @@
return -1;
}

+ serio_bus.dev_attrs = serio_device_attrs;
+ serio_bus.drv_attrs = serio_driver_attrs;
bus_register(&serio_bus);

return 0;

2004-06-28 05:31:14

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 10/19] serio_raw driver


===================================================================


[email protected], 2004-06-27 15:57:09-05:00, [email protected]
Input: Add serio_raw driver that binds to serio ports and provides
unobstructed access to the underlying serio port via a char
device. The driver tries to register char device 10,1
(/dev/psaux) first and if it fails goes for dynamically
allocated minor. To bind use sysfs interface:

echo -n "serio_raw" > /sys/bus/serio/devices/serioX/driver

Signed-off-by: Dmitry Torokhov <[email protected]>


Kconfig | 16 ++
Makefile | 1
serio_raw.c | 390 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 407 insertions(+)


===================================================================



diff -Nru a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
--- a/drivers/input/serio/Kconfig 2004-06-27 17:50:05 -05:00
+++ b/drivers/input/serio/Kconfig 2004-06-27 17:50:05 -05:00
@@ -130,3 +130,19 @@

To compile this driver as a module, choose M here: the
module will be called maceps2.
+
+config SERIO_RAW
+ tristate "Raw access to serio ports"
+ depends on SERIO
+ help
+ Say Y here if you want to have raw access to serio ports, such as
+ AUX ports on i8042 keyboard controller. Each serio port that is
+ bound to this driver will be accessible via a char device with
+ major 10 and dynamically allocated minor. The driver will try
+ allocating minor 1 (that historically corresponds to /dev/psaux)
+ first. To bind this driver to a serio port use sysfs interface:
+
+ echo -n "serio_raw" > /sys/bus/serio/devices/serioX/driver
+
+ To compile this driver as a module, choose M here: the
+ module will be called serio_raw.
diff -Nru a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
--- a/drivers/input/serio/Makefile 2004-06-27 17:50:05 -05:00
+++ b/drivers/input/serio/Makefile 2004-06-27 17:50:05 -05:00
@@ -17,3 +17,4 @@
obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o
obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o
obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o
+obj-$(CONFIG_SERIO_RAW) += serio_raw.o
diff -Nru a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/input/serio/serio_raw.c 2004-06-27 17:50:05 -05:00
@@ -0,0 +1,390 @@
+/*
+ * Raw serio device providing access to a raw byte stream from underlying
+ * serio port. Closely emulates behavior of pre-2.6 /dev/psaux device
+ *
+ * Copyright (c) 2004 Dmitry Torokhov
+ *
+ * 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 <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/module.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/device.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/wait.h>
+
+#define DRIVER_DESC "Raw serio driver"
+
+MODULE_AUTHOR("Dmitry Torokhov <[email protected]>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+#define SERIO_RAW_QUEUE_LEN 64
+struct serio_raw {
+ unsigned char queue[SERIO_RAW_QUEUE_LEN];
+ unsigned int tail, head;
+
+ char name[16];
+ unsigned int refcnt;
+ struct serio *serio;
+ struct miscdevice dev;
+ wait_queue_head_t wait;
+ struct list_head list;
+ struct list_head node;
+};
+
+struct serio_raw_list {
+ struct fasync_struct *fasync;
+ struct serio_raw *serio_raw;
+ struct list_head node;
+};
+
+static DECLARE_MUTEX(serio_raw_sem);
+static LIST_HEAD(serio_raw_list);
+static unsigned int serio_raw_no;
+
+/*********************************************************************
+ * Interface with userspace (file operations) *
+ *********************************************************************/
+
+static int serio_raw_fasync(int fd, struct file *file, int on)
+{
+ struct serio_raw_list *list = file->private_data;
+ int retval;
+
+ retval = fasync_helper(fd, file, on, &list->fasync);
+ return retval < 0 ? retval : 0;
+}
+
+static struct serio_raw *serio_raw_locate(int minor)
+{
+ struct serio_raw *serio_raw;
+
+ list_for_each_entry(serio_raw, &serio_raw_list, node) {
+ if (serio_raw->dev.minor == minor)
+ return serio_raw;
+ }
+
+ return NULL;
+}
+
+static int serio_raw_open(struct inode *inode, struct file *file)
+{
+ struct serio_raw *serio_raw;
+ struct serio_raw_list *list;
+ int retval = 0;
+
+ retval = down_interruptible(&serio_raw_sem);
+ if (retval)
+ return retval;
+
+ if (!(serio_raw = serio_raw_locate(iminor(inode)))) {
+ retval = -ENODEV;
+ goto out;
+ }
+
+ if (!serio_raw->serio) {
+ retval = -ENODEV;
+ goto out;
+ }
+
+ if (!(list = kmalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) {
+ retval = -ENOMEM;
+ goto out;
+ }
+
+ memset(list, 0, sizeof(struct serio_raw_list));
+ list->serio_raw = serio_raw;
+ file->private_data = list;
+
+ serio_raw->refcnt++;
+ list_add_tail(&list->node, &serio_raw->list);
+
+out:
+ up(&serio_raw_sem);
+ return retval;
+}
+
+static int serio_raw_cleanup(struct serio_raw *serio_raw)
+{
+ if (--serio_raw->refcnt == 0) {
+ misc_deregister(&serio_raw->dev);
+ list_del_init(&serio_raw->node);
+ kfree(serio_raw);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int serio_raw_release(struct inode *inode, struct file *file)
+{
+ struct serio_raw_list *list = file->private_data;
+ struct serio_raw *serio_raw = list->serio_raw;
+
+ down(&serio_raw_sem);
+
+ serio_raw_fasync(-1, file, 0);
+ serio_raw_cleanup(serio_raw);
+
+ up(&serio_raw_sem);
+ return 0;
+}
+
+static int serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
+{
+ unsigned long flags;
+ int empty;
+
+ spin_lock_irqsave(&serio_raw->serio->lock, flags);
+
+ empty = serio_raw->head == serio_raw->tail;
+ if (!empty) {
+ *c = serio_raw->queue[serio_raw->tail];
+ serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
+ }
+
+ spin_unlock_irqrestore(&serio_raw->serio->lock, flags);
+
+ return !empty;
+}
+
+static ssize_t serio_raw_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+ struct serio_raw_list *list = file->private_data;
+ struct serio_raw *serio_raw = list->serio_raw;
+ char c;
+ ssize_t retval = 0;
+
+ if (!serio_raw->serio)
+ return -ENODEV;
+
+ if (serio_raw->head == serio_raw->tail && (file->f_flags & O_NONBLOCK))
+ return -EAGAIN;
+
+ retval = wait_event_interruptible(list->serio_raw->wait,
+ serio_raw->head != serio_raw->tail || !serio_raw->serio);
+ if (retval)
+ return retval;
+
+ if (!serio_raw->serio)
+ return -ENODEV;
+
+ while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) {
+ if (put_user(c, buffer++))
+ return -EFAULT;
+ retval++;
+ }
+
+ return retval;
+}
+
+static ssize_t serio_raw_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+ struct serio_raw_list *list = file->private_data;
+ ssize_t written = 0;
+ int retval;
+ unsigned char c;
+
+ retval = down_interruptible(&serio_raw_sem);
+ if (retval)
+ return retval;
+
+ if (!list->serio_raw->serio) {
+ retval = -ENODEV;
+ goto out;
+ }
+
+ if (count > 32)
+ count = 32;
+
+ while (count--) {
+ if (get_user(c, buffer++)) {
+ retval = -EFAULT;
+ goto out;
+ }
+ if (serio_write(list->serio_raw->serio, c)) {
+ retval = -EIO;
+ goto out;
+ }
+ written++;
+ };
+
+out:
+ up(&serio_raw_sem);
+ return written;
+}
+
+static unsigned int serio_raw_poll(struct file *file, poll_table *wait)
+{
+ struct serio_raw_list *list = file->private_data;
+
+ poll_wait(file, &list->serio_raw->wait, wait);
+
+ if (list->serio_raw->head != list->serio_raw->tail)
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+}
+
+struct file_operations serio_raw_fops = {
+ .owner = THIS_MODULE,
+ .open = serio_raw_open,
+ .release = serio_raw_release,
+ .read = serio_raw_read,
+ .write = serio_raw_write,
+ .poll = serio_raw_poll,
+ .fasync = serio_raw_fasync,
+};
+
+
+/*********************************************************************
+ * Interface with serio port *
+ *********************************************************************/
+
+static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
+ unsigned int dfl, struct pt_regs *regs)
+{
+ struct serio_raw *serio_raw = serio->private;
+ struct serio_raw_list *list;
+ unsigned int head = serio_raw->head;
+
+ /* we are holding serio->lock here so we are prootected */
+ serio_raw->queue[head] = data;
+ head = (head + 1) % SERIO_RAW_QUEUE_LEN;
+ if (likely(head != serio_raw->tail)) {
+ serio_raw->head = head;
+ list_for_each_entry(list, &serio_raw->list, node)
+ kill_fasync(&list->fasync, SIGIO, POLL_IN);
+ wake_up_interruptible(&serio_raw->wait);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void serio_raw_connect(struct serio *serio, struct serio_driver *drv)
+{
+ struct serio_raw *serio_raw;
+ int err;
+
+ if ((serio->type & SERIO_TYPE) != SERIO_8042)
+ return;
+
+ if (!(serio_raw = kmalloc(sizeof(struct serio_raw), GFP_KERNEL))) {
+ printk(KERN_ERR "serio_raw.c: can't allocate memory for a device\n");
+ return;
+ }
+
+ down(&serio_raw_sem);
+
+ memset(serio_raw, 0, sizeof(struct serio_raw));
+ snprintf(serio_raw->name, sizeof(serio_raw->name), "serio_raw%d", serio_raw_no++);
+ serio_raw->refcnt = 1;
+ serio_raw->serio = serio;
+ INIT_LIST_HEAD(&serio_raw->list);
+ init_waitqueue_head(&serio_raw->wait);
+
+ serio->private = serio_raw;
+ if (serio_open(serio, drv))
+ goto out_free;
+
+ list_add_tail(&serio_raw->node, &serio_raw_list);
+
+ serio_raw->dev.minor = PSMOUSE_MINOR;
+ serio_raw->dev.name = serio_raw->name;
+ serio_raw->dev.fops = &serio_raw_fops;
+
+ err = misc_register(&serio_raw->dev);
+ if (err) {
+ serio_raw->dev.minor = MISC_DYNAMIC_MINOR;
+ err = misc_register(&serio_raw->dev);
+ }
+
+ if (err) {
+ printk(KERN_INFO "serio_raw: failed to register raw access device for %s\n",
+ serio->phys);
+ goto out_close;
+ }
+
+ printk(KERN_INFO "serio_raw: raw access enabled on %s (%s, minor %d)\n",
+ serio->phys, serio_raw->name, serio_raw->dev.minor);
+ goto out;
+
+out_close:
+ serio_close(serio);
+ list_del_init(&serio_raw->node);
+out_free:
+ serio->private = NULL;
+ kfree(serio_raw);
+out:
+ up(&serio_raw_sem);
+}
+
+static int serio_raw_reconnect(struct serio *serio)
+{
+ struct serio_raw *serio_raw = serio->private;
+ struct serio_driver *drv = serio->drv;
+
+ if (!drv || !serio_raw) {
+ printk(KERN_DEBUG "serio_raw: reconnect request, but serio is disconnected, ignoring...\n");
+ return -1;
+ }
+
+ /*
+ * Nothing needs to be done here, we just need this method to
+ * keep the same device.
+ */
+ return 0;
+}
+
+static void serio_raw_disconnect(struct serio *serio)
+{
+ struct serio_raw *serio_raw;
+
+ down(&serio_raw_sem);
+
+ serio_raw = serio->private;
+
+ serio_close(serio);
+ serio->private = NULL;
+
+ serio_raw->serio = NULL;
+ if (!serio_raw_cleanup(serio_raw))
+ wake_up_interruptible(&serio_raw->wait);
+
+ up(&serio_raw_sem);
+}
+
+static struct serio_driver serio_raw_drv = {
+ .driver = {
+ .name = "serio_raw",
+ },
+ .description = DRIVER_DESC,
+ .interrupt = serio_raw_interrupt,
+ .connect = serio_raw_connect,
+ .reconnect = serio_raw_reconnect,
+ .disconnect = serio_raw_disconnect,
+ .manual_bind = 1,
+};
+
+int __init serio_raw_init(void)
+{
+ serio_register_driver(&serio_raw_drv);
+ return 0;
+}
+
+void __exit serio_raw_exit(void)
+{
+ serio_unregister_driver(&serio_raw_drv);
+}
+
+module_init(serio_raw_init);
+module_exit(serio_raw_exit);

2004-06-28 05:52:11

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH 14/19] bind serio ports and their parents


===================================================================


[email protected], 2004-06-27 16:01:48-05:00, [email protected]
Input: link serio ports to their parent devices in ambakmi,
gscps2, pcips2 and sa1111ps2 drivers

Signed-off-by: Dmitry Torokhov <[email protected]>


ambakmi.c | 1 +
gscps2.c | 1 +
pcips2.c | 1 +
sa1111ps2.c | 1 +
4 files changed, 4 insertions(+)


===================================================================



diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c 2004-06-27 17:51:19 -05:00
+++ b/drivers/input/serio/ambakmi.c 2004-06-27 17:51:19 -05:00
@@ -141,6 +141,7 @@
strlcpy(io->name, dev->dev.bus_id, sizeof(io->name));
strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys));
io->port_data = kmi;
+ io->dev.parent = &dev->dev;

kmi->io = io;
kmi->base = ioremap(dev->res.start, KMI_SIZE);
diff -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
--- a/drivers/input/serio/gscps2.c 2004-06-27 17:51:19 -05:00
+++ b/drivers/input/serio/gscps2.c 2004-06-27 17:51:19 -05:00
@@ -385,6 +385,7 @@
serio->open = gscps2_open;
serio->close = gscps2_close;
serio->port_data = ps2port;
+ serio->dev.parent = &dev->dev;

list_add_tail(&ps2port->node, &ps2port_list);

diff -Nru a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
--- a/drivers/input/serio/pcips2.c 2004-06-27 17:51:19 -05:00
+++ b/drivers/input/serio/pcips2.c 2004-06-27 17:51:19 -05:00
@@ -159,6 +159,7 @@
strlcpy(serio->name, pci_name(dev), sizeof(serio->name));
strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
serio->port_data = ps2if;
+ serio->dev.parent = &dev->dev;
ps2if->io = serio;
ps2if->dev = dev;
ps2if->base = pci_resource_start(dev, 0);
diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
--- a/drivers/input/serio/sa1111ps2.c 2004-06-27 17:51:19 -05:00
+++ b/drivers/input/serio/sa1111ps2.c 2004-06-27 17:51:19 -05:00
@@ -252,6 +252,7 @@
strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name));
strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
serio->port_data = ps2if;
+ serio->dev.parent = &dev->dev;
ps2if->io = serio;
ps2if->dev = dev;
sa1111_set_drvdata(dev, ps2if);

2004-06-28 06:53:17

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

On Mon, Jun 28, 2004 at 12:08:21AM -0500, Dmitry Torokhov wrote:
> Hi,
>
> Here is the 2nd version of my set of input patches that mostly do serio sysfs
> integration. Among the changes - dropped psmouse KVM resync patch as it was
> bogus, added platform devices to those of serio providers that don't have
> proper parent device (i8042, q40kbd, etc).
>
> 01-psmouse-state-locking.patch
> - Acquire underlying serio lock when changing psmouse state to
> prevent interrupt handler running on us

IMO drivers have no bussiness messing with the serio locks. We could use
'plug' and 'unplug' functions like the network driver use, or handle it
inside the driver, but taking the lock is the wrong thing to do.

> 02-serio-connect-mandatory.patch
> - Make serio driviers connect/disconnect methods mandatory as these
> methods open/close serio ports and link ports and drivers together.
> Presently if a driver does not implement connect method it will not
> be able to bind to a port anyway.

OK

> 03-serio-rename-1.patch
> - Rename serio->driver to serio->port_data as with sysfs integration
> driver is not the best name for arbitrary data

OK

> 04-serio-rename-2.patch
> - Rename serio_dev to serio_driver as they are drivers in sysfs sense

OK

> 05-serio-dynamic-alloc.patch
> - Switch from static to dynamic serio port allocation so serio ports
> drivers can be freely unloaded even if not all references to ports
> are dropped (sysfs req.)

OK

> 06-serio-no-recursion.patch
> - Do not do recursive discovery of children ports, needed for sysfs
> and generally better for stack usage.

Yes, this is very good.

> 07-serio-sysfs.patch
> - sysfs integration. Register ports and drivers in driver model, link
> them all together under /sys/bus/serio. Every driver has a default
> attribute "descrip[tion" (from serio_driver->description); serio
> ports have "decription", "driver" and "legacy_position".
> Legacy_position porvides access to serio->phys to allow matching
> with data in /proc/bus/input/devices

I'm not sure if we really need the 'legacy position' thing. We probably
should drop the 'phys' stuff some time after we transition to sysfs, and
exporting it through sysfs will make that harder.

> 08-serio-rebind.patch
> - allow user to disconnect or rebind serio port by writing appropriate
> data to it's sysfs attribute:
> echo -n "psmouse" > /sys/bus/serio/devices/serio0/driver
> echo -n "none" > /sys/bus/serio/devices/serio0/driver
> echo -n "reconnect" > /sys/bus/serio/devices/serio0/driver
> echo -n "rescan" > /sys/bus/serio/devices/serio0/driver

Very good idea.

> 09-serio-manual-bind.patch
> - allow marking some drivers as requiring manual bind (to be used when
> driver does not do automatic HW discovery)

OK

> 10-serio_raw.patch
> - raw access to serio data ala 2.4 /dev/psaux

OK, finally those who insist on /dev/psaux can shut up

> (*) 11-platform-device-simple.patch
> - Add platform_device_register_simple to register platform devices
> requiring minimal resource and memory management. The release
> function resides in driver core and that allows drivers registering
> such devices be unloaded without waiting for the last reference to
> be dropped.
>
> 12-i8042-to-platform-device.patch
> - Convert i8042 to platform device instead of system device so
> its ports have proper parent.

OK

> 13-serio-add-platform-devices.patch
> - Add platform devices to ct82c710, maceps2, q40kbd and rpckbd.

OK

> 14-serio-set-up-parents.patch
> - Set up parent devices for serio ports in ambakmi, gscps2,
> pcips2 and sa1111ps2.c

OK

> 15-synaptics-passthrough-handling.patch
> - If data looks like a pass-through packet and tuchpad has
> pass-through capability do not pass it to the main handler
> if child port is disconnected.

I'll have to look closer on this one - I think we want to pass the data
to the serio layer even if there is no driver listening on the
passthrough serio.

> (*) 16-bus-default-drv-attrs.patch
> - Add bus' default driver attributes (similar to defaulr device
> attributes)
>
> 17-serio-use-bus-default-attrs.patch
> - Use bus' default driver and device attributes to manage serio
> attributes
>
> (*) 18-add-driver-find.patch
> - Add driver_find function, similar to device_find, to search for a
> driver by its name.
>
> 19-serio-use-driver-find.patch
> - Use driver_find in serio_rebind_driver instead of implementing it
> locally.

Very good.

> (*) These patches have also been sent to Greg KH.

Did he accept them already?

> This time I tried compiling the stuff using defconfing for SPACR64 and PPC64
> (thanks to Andrew for pointing to me availability of cross-compile
> tools), so I should be a bit better now... Alpha failed on cpumask.h...

Great! ;)

> The patches are against today's Linus tree + recent pull form Vojtech's tree
> + recent pull from Greg KH's tree. I have patches against 2.6.7 that will
> bring it to my version of the tree at:
>
> http://www.geocities.com/dt_or/input/2_6_7/

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-06-28 07:14:08

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

On Monday 28 June 2004 01:52 am, Vojtech Pavlik wrote:
> On Mon, Jun 28, 2004 at 12:08:21AM -0500, Dmitry Torokhov wrote:
> > Hi,
> >
> > Here is the 2nd version of my set of input patches that mostly do serio sysfs
> > integration. Among the changes - dropped psmouse KVM resync patch as it was
> > bogus, added platform devices to those of serio providers that don't have
> > proper parent device (i8042, q40kbd, etc).
> >
> > 01-psmouse-state-locking.patch
> > - Acquire underlying serio lock when changing psmouse state to
> > prevent interrupt handler running on us
>
> IMO drivers have no bussiness messing with the serio locks. We could use
> 'plug' and 'unplug' functions like the network driver use, or handle it
> inside the driver, but taking the lock is the wrong thing to do.

OK, I just don't want to introduce another lock just for that...

>
> I'm not sure if we really need the 'legacy position' thing. We probably
> should drop the 'phys' stuff some time after we transition to sysfs, and
> exporting it through sysfs will make that harder.
>

I'll drop it then...

>
> > 10-serio_raw.patch
> > - raw access to serio data ala 2.4 /dev/psaux
>
> OK, finally those who insist on /dev/psaux can shut up

:)

>
> > 15-synaptics-passthrough-handling.patch
> > - If data looks like a pass-through packet and tuchpad has
> > pass-through capability do not pass it to the main handler
> > if child port is disconnected.
>
> I'll have to look closer on this one - I think we want to pass the data
> to the serio layer even if there is no driver listening on the
> passthrough serio.

We probably should issue serio_interrupt on child port to force rescan but
that packet has no business in parent's motion handling routine and that's
what this patch tries to fix. Anyway, I will look at it more later.

>
> > (*) These patches have also been sent to Greg KH.
>
> Did he accept them already?
>

No, not yet. He promised to take a look at platoform_device_register_simple by
the end of the week but I guess kernel.bkbits.net troubles might intervene...
And other 2 I just send out today.

> > This time I tried compiling the stuff using defconfing for SPACR64 and PPC64
> > (thanks to Andrew for pointing to me availability of cross-compile
> > tools), so I should be a bit better now... Alpha failed on cpumask.h...
>
> Great! ;)
>
> > The patches are against today's Linus tree + recent pull form Vojtech's tree
> > + recent pull from Greg KH's tree. I have patches against 2.6.7 that will
> > bring it to my version of the tree at:
> >
> > http://www.geocities.com/dt_or/input/2_6_7/
>

--
Dmitry

2004-06-28 07:51:53

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

On Mon, Jun 28, 2004 at 02:13:58AM -0500, Dmitry Torokhov wrote:

> > IMO drivers have no bussiness messing with the serio locks. We could use
> > 'plug' and 'unplug' functions like the network driver use, or handle it
> > inside the driver, but taking the lock is the wrong thing to do.
>
> OK, I just don't want to introduce another lock just for that...

I think a bit in flags "PSMOUSE_ENABLED", like we have the
"ATKBD_ENABLED" bit might be just fine - handle the interrupt, but throw
away the data during the protocol switch. We aren't interested in the
data anyway.

> > > 15-synaptics-passthrough-handling.patch
> > > - If data looks like a pass-through packet and tuchpad has
> > > pass-through capability do not pass it to the main handler
> > > if child port is disconnected.
> >
> > I'll have to look closer on this one - I think we want to pass the data
> > to the serio layer even if there is no driver listening on the
> > passthrough serio.
>
> We probably should issue serio_interrupt on child port to force rescan but
> that packet has no business in parent's motion handling routine and that's
> what this patch tries to fix. Anyway, I will look at it more later.

Indeed, we need it for the rescan. It shouldn't be that hard to fix at
once.

>
> > > (*) These patches have also been sent to Greg KH.
> >
> > Did he accept them already?
>
> No, not yet. He promised to take a look at platoform_device_register_simple by
> the end of the week but I guess kernel.bkbits.net troubles might intervene...
> And other 2 I just send out today.

Ok. I'll wait then.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-06-28 10:05:50

by Sau Dan Lee

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

>>>>> "Vojtech" == Vojtech Pavlik <[email protected]> writes:

On Mon, Jun 28, 2004 at 12:08:21AM -0500, Dmitry Torokhov wrote:

...
> 08-serio-rebind.patch
> - allow user to disconnect or rebind serio port by writing appropriate
> data to it's sysfs attribute:
> echo -n "psmouse" > /sys/bus/serio/devices/serio0/driver
> echo -n "none" > /sys/bus/serio/devices/serio0/driver
> echo -n "reconnect" > /sys/bus/serio/devices/serio0/driver
> echo -n "rescan" > /sys/bus/serio/devices/serio0/driver

Vojtech> Very good idea.

...


>> 10-serio_raw.patch - raw access to serio data ala 2.4
>> /dev/psaux

Vojtech> OK, finally those who insist on /dev/psaux can shut up


Now, guess who originated these ideas!?




--
Sau Dan LEE ???u??(Big5) ~{@nJX6X~}(HZ)

E-mail: [email protected]
Home page: http://www.informatik.uni-freiburg.de/~danlee

2004-06-28 10:32:59

by NeilBrown

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

On Monday June 28, [email protected] wrote:
> On Mon, Jun 28, 2004 at 12:08:21AM -0500, Dmitry Torokhov wrote:
>
> > 10-serio_raw.patch
> > - raw access to serio data ala 2.4 /dev/psaux
>
> OK, finally those who insist on /dev/psaux can shut up
>

Alternatively, we could say thank you. So..

Thank you, very much!

NeilBrown

2004-06-28 10:50:55

by Tuukka Toivonen

[permalink] [raw]
Subject: SERIO_USERDEV patch (was: Re: [PATCH 0/19] New set of input patches)

>On Mon, Jun 28, 2004 at 12:08:21AM -0500, Dmitry Torokhov wrote:
> >> 10-serio_raw.patch - raw access to serio data ala 2.4
> >> /dev/psaux
> Vojtech> OK, finally those who insist on /dev/psaux can shut up

Nice. So serio_userdev is now out of question and I can stop maintaining
it?

Here's still the last version against clean 2.6.7 kernel (but it certainly
won't apply after Dmitry's changes):

http://www.ee.oulu.fi/~tuukkat/tmp/linux-2.6.7-userdev.20040625.patch

Nothing new, just updated for 2.6.7.

P.S. I'm looking for documentation about the __user thing. Is there any?

And just for completeness here's the diff between serio.c and serio-core.c
(which is renamed by the patch):

--- linux-2.6.7/drivers/input/serio/serio.c Fri Jun 25 13:38:11 2004
+++ linux-2.6.7userdev/drivers/input/serio/serio-core.c Fri Jun 25 14:06:31 2004
@@ -30,6 +30,8 @@
* Changes:
* 20 Jul. 2003 Daniele Bellucci <[email protected]>
* Minor cleanups.
+ * 31 May 2004 Tuukka Toivonen <[email protected]>
+ * Added hooks for serio-dev.c, renamed from serio.c.
*/

#include <linux/stddef.h>
@@ -43,6 +45,10 @@
#include <linux/suspend.h>
#include <linux/slab.h>

+#ifdef CONFIG_SERIO_USERDEV
+#include "serio-dev.h"
+#endif
+
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
MODULE_DESCRIPTION("Serio abstraction core");
MODULE_LICENSE("GPL");
@@ -67,16 +73,20 @@
struct list_head node;
};

-static DECLARE_MUTEX(serio_sem);
-static LIST_HEAD(serio_list);
+DECLARE_MUTEX(serio_sem);
+LIST_HEAD(serio_list);
static LIST_HEAD(serio_dev_list);
static LIST_HEAD(serio_event_list);
static int serio_pid;

-static void serio_find_dev(struct serio *serio)
+void serio_find_dev(struct serio *serio)
{
struct serio_dev *dev;

+#ifdef CONFIG_SERIO_USERDEV
+ if (serio_userdev_writers(serio) > 0)
+ return;
+#endif
list_for_each_entry(dev, &serio_dev_list, node) {
if (serio->dev)
break;
@@ -189,18 +199,25 @@
irqreturn_t serio_interrupt(struct serio *serio,
unsigned char data, unsigned int flags, struct pt_regs *regs)
{
- irqreturn_t ret = IRQ_NONE;
+ irqreturn_t r, ret = IRQ_NONE;
+ int rescan = 1;

- if (serio->dev && serio->dev->interrupt) {
- ret = serio->dev->interrupt(serio, data, flags, regs);
- } else {
- if (!flags) {
- if ((serio->type == SERIO_8042 ||
- serio->type == SERIO_8042_XL) && (data != 0xaa))
- return ret;
- serio_rescan(serio);
- ret = IRQ_HANDLED;
- }
+#ifdef CONFIG_SERIO_USERDEV
+ ret = serio_userdev_newbyte(serio, data);
+ if (ret == IRQ_HANDLED)
+ rescan = 0;
+#endif
+ if (serio->dev && serio->dev->interrupt) {
+ r = serio->dev->interrupt(serio, data, flags, regs);
+ if (ret == IRQ_NONE) ret = r;
+ rescan = 0;
+ }
+ if (rescan && !flags) {
+ if ((serio->type == SERIO_8042 ||
+ serio->type == SERIO_8042_XL) && (data != 0xaa))
+ return ret;
+ serio_rescan(serio);
+ ret = IRQ_HANDLED;
}
return ret;
}
@@ -231,6 +248,9 @@
{
list_add_tail(&serio->node, &serio_list);
serio_find_dev(serio);
+#ifdef CONFIG_SERIO_USERDEV
+ serio_userdev_init(serio);
+#endif
}

void serio_unregister_port(struct serio *serio)
@@ -257,6 +277,11 @@
*/
void __serio_unregister_port(struct serio *serio)
{
+#ifdef CONFIG_SERIO_USERDEV
+ /* Here we assume that the interrupt handler is not anymore
+ * called and is not still executing from previous call */
+ serio_userdev_cleanup(serio);
+#endif
serio_invalidate_pending_events(serio);
list_del_init(&serio->node);
if (serio->dev && serio->dev->disconnect)
@@ -268,9 +293,14 @@
struct serio *serio;
down(&serio_sem);
list_add_tail(&dev->node, &serio_dev_list);
- list_for_each_entry(serio, &serio_list, node)
+ list_for_each_entry(serio, &serio_list, node) {
+#ifdef CONFIG_SERIO_USERDEV
+ if (serio_userdev_writers(serio) > 0)
+ continue;
+#endif
if (!serio->dev && dev->connect)
dev->connect(serio, dev);
+ }
up(&serio_sem);
}

@@ -293,7 +323,13 @@
int serio_open(struct serio *serio, struct serio_dev *dev)
{
serio->dev = dev;
- if (serio->open && serio->open(serio)) {
+#ifdef CONFIG_SERIO_USERDEV
+ /* When there are processes having the userdev open,
+ * the port is already open and needs not to be re-opened. */
+ if (serio_userdev_users(serio) > 0)
+ return 0;
+#endif
+ if (serio->open(serio)) {
serio->dev = NULL;
return -1;
}
@@ -303,7 +339,10 @@
/* called from serio_dev->connect/disconnect methods under serio_sem */
void serio_close(struct serio *serio)
{
- if (serio->close)
+#ifdef CONFIG_SERIO_USERDEV
+ /* Close only if the port is not open by userspace drivers */
+ if (serio_userdev_users(serio) <= 0)
+#endif
serio->close(serio);
serio->dev = NULL;
}

2004-06-28 12:13:49

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

On Mon, Jun 28, 2004 at 08:32:36PM +1000, Neil Brown wrote:
> On Monday June 28, [email protected] wrote:
> > On Mon, Jun 28, 2004 at 12:08:21AM -0500, Dmitry Torokhov wrote:
> >
> > > 10-serio_raw.patch
> > > - raw access to serio data ala 2.4 /dev/psaux
> >
> > OK, finally those who insist on /dev/psaux can shut up
> >
>
> Alternatively, we could say thank you. So..
>
> Thank you, very much!

You're welcome.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-06-28 14:58:47

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

Vojtech Pavlik wrote:
> On Mon, Jun 28, 2004 at 02:13:58AM -0500, Dmitry Torokhov wrote:
>
> > > IMO drivers have no bussiness messing with the serio locks. We could
> use
> > > 'plug' and 'unplug' functions like the network driver use, or handle
> it
> > > inside the driver, but taking the lock is the wrong thing to do.
> >
> > OK, I just don't want to introduce another lock just for that...
>
> I think a bit in flags "PSMOUSE_ENABLED", like we have the
> "ATKBD_ENABLED" bit might be just fine - handle the interrupt, but throw
> away the data during the protocol switch. We aren't interested in the
> data anyway.
>

But the flag will not give you atomicity of resetting other fields, like
pktcount. I guess we can ensure it by carefully rearranging the states
and what is reset at what point but it is too fragile.

Would you accept a pair serio_rx_suspend/serio_rx_resume that would still
take the lock internally but not expose this fact to the driver?

> > > > 15-synaptics-passthrough-handling.patch
> > > > - If data looks like a pass-through packet and tuchpad has
> > > > pass-through capability do not pass it to the main handler
> > > > if child port is disconnected.
> > >
> > > I'll have to look closer on this one - I think we want to pass the
> data
> > > to the serio layer even if there is no driver listening on the
> > > passthrough serio.
> >
> > We probably should issue serio_interrupt on child port to force rescan
> but
> > that packet has no business in parent's motion handling routine and
> that's
> > what this patch tries to fix. Anyway, I will look at it more later.
>
> Indeed, we need it for the rescan. It shouldn't be that hard to fix at
> once.
>

Ok

> >
> > > > (*) These patches have also been sent to Greg KH.
> > >
> > > Did he accept them already?
> >
> > No, not yet. He promised to take a look at
> platoform_device_register_simple by
> > the end of the week but I guess kernel.bkbits.net troubles might
> intervene...
> > And other 2 I just send out today.
>
> Ok. I'll wait then.

Sysfs changes should be useable even without platform device changes
and I would like start syncing with you. Would you take patches 2
through 10 (I will drop the legacy_position stuff)?

--
Dmitry

2004-06-28 15:09:06

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

On Mon, Jun 28, 2004 at 07:54:53AM -0700, Dmitry Torokhov wrote:

> But the flag will not give you atomicity of resetting other fields, like
> pktcount. I guess we can ensure it by carefully rearranging the states
> and what is reset at what point but it is too fragile.
>
> Would you accept a pair serio_rx_suspend/serio_rx_resume that would still
> take the lock internally but not expose this fact to the driver?

Yes, but don't call them suspend/resume. That sounds too much like
powermanagement, which it isn't. Network uses start/stop. Block layer
uses plug/unplug - in the sense that you have a pipe, and if you don't
want any more data, you plug it.

> > > > > (*) These patches have also been sent to Greg KH.
> > > >
> > > > Did he accept them already?
> > >
> > > No, not yet. He promised to take a look at
> > platoform_device_register_simple by
> > > the end of the week but I guess kernel.bkbits.net troubles might
> > intervene...
> > > And other 2 I just send out today.
> >
> > Ok. I'll wait then.
>
> Sysfs changes should be useable even without platform device changes
> and I would like start syncing with you. Would you take patches 2
> through 10 (I will drop the legacy_position stuff)?

Yes.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-06-29 07:01:43

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

On Monday 28 June 2004 10:07 am, Vojtech Pavlik wrote:
> On Mon, Jun 28, 2004 at 07:54:53AM -0700, Dmitry Torokhov wrote:
> >
> > Sysfs changes should be useable even without platform device changes
> > and I would like start syncing with you. Would you take patches 2
> > through 10 (I will drop the legacy_position stuff)?
>
> Yes.
>

Vojtech,

As we discussed I dropped the legacy_position sysfs attribute and moved
patches 2 through 10 to my repository on bkbits.net. I also moved patch
#14 because sa1111ps2, gscps2, ambakmi and pcips2 have already been
integrated with sysfs so linking their serio ports to their devices
are simple one-liners not depending on anything I sent to Greg.

Please do:

bk pull bk://dtor.bkbits.net/input

--
Dmitry

2004-06-29 07:25:47

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 0/19] New set of input patches

On Tue, Jun 29, 2004 at 02:01:28AM -0500, Dmitry Torokhov wrote:
> On Monday 28 June 2004 10:07 am, Vojtech Pavlik wrote:
> > On Mon, Jun 28, 2004 at 07:54:53AM -0700, Dmitry Torokhov wrote:
> > >
> > > Sysfs changes should be useable even without platform device changes
> > > and I would like start syncing with you. Would you take patches 2
> > > through 10 (I will drop the legacy_position stuff)?
> >
> > Yes.
> >
>
> Vojtech,
>
> As we discussed I dropped the legacy_position sysfs attribute and moved
> patches 2 through 10 to my repository on bkbits.net. I also moved patch
> #14 because sa1111ps2, gscps2, ambakmi and pcips2 have already been
> integrated with sysfs so linking their serio ports to their devices
> are simple one-liners not depending on anything I sent to Greg.
>
> Please do:
>
> bk pull bk://dtor.bkbits.net/input

Thanks!

--
Vojtech Pavlik
SuSE Labs, SuSE CR