Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / include / linux / serio.h
index 28f6247..6348e83 100644 (file)
  */
 
 #include <linux/ioctl.h>
-#include <linux/interrupt.h>
 
 #define SPIOCSTYPE     _IOW('q', 0x01, unsigned long)
 
 #ifdef __KERNEL__
 
+#include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
 
 struct serio {
-       void *private;
-       void *driver;
-       char *name;
-       char *phys;
+       void *port_data;
+
+       char name[32];
+       char phys[32];
 
-       unsigned short idbus;
-       unsigned short idvendor;
-       unsigned short idproduct;
-       unsigned short idversion;
+       unsigned int manual_bind;
 
-       unsigned long type;
-       unsigned long event;
+       struct serio_device_id id;
+
+       spinlock_t lock;                /* protects critical sections from port's interrupt handler */
 
        int (*write)(struct serio *, unsigned char);
        int (*open)(struct serio *);
        void (*close)(struct serio *);
+       int (*start)(struct serio *);
+       void (*stop)(struct serio *);
+
+       struct serio *parent, *child;
+
+       struct serio_driver *drv;       /* accessed from interrupt, must be protected by serio->lock and serio->sem */
+       struct mutex drv_mutex;         /* protects serio->drv so attributes can pin driver */
 
-       struct serio_dev *dev;
+       struct device dev;
+       unsigned int registered;        /* port has been fully registered with driver core */
 
        struct list_head node;
 };
+#define to_serio_port(d)       container_of(d, struct serio, dev)
 
-struct serio_dev {
+struct serio_driver {
        void *private;
-       char *name;
+       char *description;
+
+       struct serio_device_id *id_table;
+       unsigned int manual_bind;
 
        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);
+       int  (*connect)(struct serio *, struct serio_driver *drv);
        int  (*reconnect)(struct serio *);
        void (*disconnect)(struct serio *);
        void (*cleanup)(struct serio *);
 
-       struct list_head node;
+       struct device_driver driver;
 };
+#define to_serio_driver(d)     container_of(d, struct serio_driver, driver)
 
-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);
 irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
 
-void serio_register_port(struct serio *serio);
-void serio_register_port_delayed(struct serio *serio);
-void __serio_register_port(struct serio *serio);
+void __serio_register_port(struct serio *serio, struct module *owner);
+static inline void serio_register_port(struct serio *serio)
+{
+       __serio_register_port(serio, THIS_MODULE);
+}
+
 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_unregister_child_port(struct serio *serio);
+void __serio_unregister_port_delayed(struct serio *serio, struct module *owner);
+static inline void serio_unregister_port_delayed(struct serio *serio)
+{
+       __serio_unregister_port_delayed(serio, THIS_MODULE);
+}
 
-static __inline__ int serio_write(struct serio *serio, unsigned char data)
+void __serio_register_driver(struct serio_driver *drv, struct module *owner);
+static inline void serio_register_driver(struct serio_driver *drv)
+{
+       __serio_register_driver(drv, THIS_MODULE);
+}
+
+void serio_unregister_driver(struct serio_driver *drv);
+
+static inline int serio_write(struct serio *serio, unsigned char data)
 {
        if (serio->write)
                return serio->write(serio, data);
@@ -79,18 +107,65 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data)
                return -1;
 }
 
-static __inline__ void serio_dev_write_wakeup(struct serio *serio)
+static inline void serio_drv_write_wakeup(struct serio *serio)
+{
+       if (serio->drv && serio->drv->write_wakeup)
+               serio->drv->write_wakeup(serio);
+}
+
+static inline void serio_cleanup(struct serio *serio)
+{
+       if (serio->drv && serio->drv->cleanup)
+               serio->drv->cleanup(serio);
+}
+
+/*
+ * Use the following functions to manipulate serio's per-port
+ * driver-specific data.
+ */
+static inline void *serio_get_drvdata(struct serio *serio)
 {
-       if (serio->dev && serio->dev->write_wakeup)
-               serio->dev->write_wakeup(serio);
+       return dev_get_drvdata(&serio->dev);
 }
 
-static __inline__ void serio_cleanup(struct serio *serio)
+static inline void serio_set_drvdata(struct serio *serio, void *data)
 {
-       if (serio->dev && serio->dev->cleanup)
-               serio->dev->cleanup(serio);
+       dev_set_drvdata(&serio->dev, data);
 }
 
+/*
+ * Use the following functions to protect critical sections in
+ * driver code from port's interrupt handler
+ */
+static inline void serio_pause_rx(struct serio *serio)
+{
+       spin_lock_irq(&serio->lock);
+}
+
+static inline void serio_continue_rx(struct serio *serio)
+{
+       spin_unlock_irq(&serio->lock);
+}
+
+/*
+ * Use the following functions to pin serio's driver in process context
+ */
+static inline int serio_pin_driver(struct serio *serio)
+{
+       return mutex_lock_interruptible(&serio->drv_mutex);
+}
+
+static inline void serio_pin_driver_uninterruptible(struct serio *serio)
+{
+       mutex_lock(&serio->drv_mutex);
+}
+
+static inline void serio_unpin_driver(struct serio *serio)
+{
+       mutex_unlock(&serio->drv_mutex);
+}
+
+
 #endif
 
 /*
@@ -100,16 +175,20 @@ static __inline__ void serio_cleanup(struct serio *serio)
 #define SERIO_PARITY   2
 #define SERIO_FRAME    4
 
-#define SERIO_TYPE     0xff000000UL
-#define SERIO_XT       0x00000000UL
-#define SERIO_8042     0x01000000UL
-#define SERIO_RS232    0x02000000UL
-#define SERIO_HIL_MLC  0x03000000UL
-#define SERIO_PC9800   0x04000000UL
-#define SERIO_PS_PSTHRU        0x05000000UL
-#define SERIO_8042_XL  0x06000000UL
+/*
+ * Serio types
+ */
+#define SERIO_XT       0x00
+#define SERIO_8042     0x01
+#define SERIO_RS232    0x02
+#define SERIO_HIL_MLC  0x03
+#define SERIO_PS_PSTHRU        0x05
+#define SERIO_8042_XL  0x06
 
-#define SERIO_PROTO    0xFFUL
+/*
+ * Serio types
+ */
+#define SERIO_UNKNOWN  0x00
 #define SERIO_MSC      0x01
 #define SERIO_SUN      0x02
 #define SERIO_MS       0x03
@@ -136,8 +215,7 @@ static __inline__ void serio_cleanup(struct serio *serio)
 #define SERIO_SNES232  0x26
 #define SERIO_SEMTECH  0x27
 #define SERIO_LKKBD    0x28
-
-#define SERIO_ID       0xff00UL
-#define SERIO_EXTRA    0xff0000UL
+#define SERIO_ELO      0x29
+#define SERIO_MICROTOUCH       0x30
 
 #endif