Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 14 Mar 2010 18:15:45 +0000 (11:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 14 Mar 2010 18:15:45 +0000 (11:15 -0700)
* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86/mce: Fix build bug with CONFIG_PROVE_LOCKING=y && CONFIG_X86_MCE_INTEL=y

67 files changed:
drivers/hid/hid-input.c
drivers/i2c/Kconfig
drivers/i2c/Makefile
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/busses/i2c-xiic.c
drivers/i2c/chips/Kconfig [deleted file]
drivers/i2c/chips/Makefile [deleted file]
drivers/i2c/i2c-smbus.c
drivers/input/evdev.c
drivers/input/input.c
drivers/input/joystick/gamecon.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/ati_remote2.c
drivers/input/misc/twl4030-vibra.c [new file with mode: 0644]
drivers/input/misc/winbond-cir.c
drivers/input/misc/wm831x-on.c
drivers/input/mouse/alps.c
drivers/input/mouse/appletouch.c
drivers/input/mousedev.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/serio/serio_raw.c
drivers/input/sparse-keymap.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/tablet/wacom_wac.h
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/ad7877.c
drivers/input/touchscreen/ads7846.c
drivers/media/IR/ir-keytable.c
drivers/media/dvb/dvb-usb/dvb-usb-remote.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/eeprom/at24.c
drivers/misc/tsl2550.c [moved from drivers/i2c/chips/tsl2550.c with 99% similarity]
drivers/platform/x86/dell-wmi.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/panasonic-laptop.c
drivers/platform/x86/topstar-laptop.c
drivers/platform/x86/toshiba_acpi.c
fs/9p/v9fs.h
fs/9p/vfs_dir.c
fs/9p/vfs_file.c
fs/nilfs2/alloc.h
fs/nilfs2/dat.c
fs/nilfs2/dir.c
fs/nilfs2/gcinode.c
fs/nilfs2/page.c
fs/nilfs2/segbuf.c
fs/nilfs2/segment.c
fs/nilfs2/segment.h
fs/nilfs2/sufile.c
fs/nilfs2/super.c
fs/nilfs2/the_nilfs.c
include/linux/i2c-algo-bit.h
include/linux/i2c-xiic.h [new file with mode: 0644]
include/linux/input.h
include/linux/spi/ads7846.h
include/linux/virtio.h
include/linux/virtio_9p.h
include/net/9p/client.h
net/9p/client.c
net/9p/trans_virtio.c

index 79d9edd..7a0d2e4 100644 (file)
@@ -68,22 +68,25 @@ static const struct {
 #define map_key_clear(c)       hid_map_usage_clear(hidinput, usage, &bit, \
                &max, EV_KEY, (c))
 
-static inline int match_scancode(int code, int scancode)
+static inline int match_scancode(unsigned int code, unsigned int scancode)
 {
        if (scancode == 0)
                return 1;
-       return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode);
+
+       return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
 }
 
-static inline int match_keycode(int code, int keycode)
+static inline int match_keycode(unsigned int code, unsigned int keycode)
 {
        if (keycode == 0)
                return 1;
-       return (code == keycode);
+
+       return code == keycode;
 }
 
 static struct hid_usage *hidinput_find_key(struct hid_device *hid,
-               int scancode, int keycode)
+                                          unsigned int scancode,
+                                          unsigned int keycode)
 {
        int i, j, k;
        struct hid_report *report;
@@ -105,8 +108,8 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid,
        return NULL;
 }
 
-static int hidinput_getkeycode(struct input_dev *dev, int scancode,
-                               int *keycode)
+static int hidinput_getkeycode(struct input_dev *dev,
+                              unsigned int scancode, unsigned int *keycode)
 {
        struct hid_device *hid = input_get_drvdata(dev);
        struct hid_usage *usage;
@@ -119,16 +122,13 @@ static int hidinput_getkeycode(struct input_dev *dev, int scancode,
        return -EINVAL;
 }
 
-static int hidinput_setkeycode(struct input_dev *dev, int scancode,
-                               int keycode)
+static int hidinput_setkeycode(struct input_dev *dev,
+                              unsigned int scancode, unsigned int keycode)
 {
        struct hid_device *hid = input_get_drvdata(dev);
        struct hid_usage *usage;
        int old_keycode;
 
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
        usage = hidinput_find_key(hid, scancode, 0);
        if (usage) {
                old_keycode = usage->code;
index 02ce9cf..d06083f 100644 (file)
@@ -73,7 +73,6 @@ config I2C_SMBUS
 
 source drivers/i2c/algos/Kconfig
 source drivers/i2c/busses/Kconfig
-source drivers/i2c/chips/Kconfig
 
 config I2C_DEBUG_CORE
        bool "I2C Core debugging messages"
@@ -98,12 +97,4 @@ config I2C_DEBUG_BUS
          a problem with I2C support and want to see more of what is going
          on.
 
-config I2C_DEBUG_CHIP
-       bool "I2C Chip debugging messages"
-       help
-         Say Y here if you want the I2C chip drivers to produce a bunch of
-         debug messages to the system log.  Select this if you are having
-         a problem with I2C support and want to see more of what is going
-         on.
-
 endif # I2C
index acd0250..a7d9b4b 100644 (file)
@@ -6,7 +6,7 @@ obj-$(CONFIG_I2C_BOARDINFO)     += i2c-boardinfo.o
 obj-$(CONFIG_I2C)              += i2c-core.o
 obj-$(CONFIG_I2C_SMBUS)                += i2c-smbus.o
 obj-$(CONFIG_I2C_CHARDEV)      += i2c-dev.o
-obj-y                          += busses/ chips/ algos/
+obj-y                          += algos/ busses/
 
 ifeq ($(CONFIG_I2C_DEBUG_CORE),y)
 EXTRA_CFLAGS += -DDEBUG
index e25e139..e8d568c 100644 (file)
@@ -522,6 +522,12 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
        int i, ret;
        unsigned short nak_ok;
 
+       if (adap->pre_xfer) {
+               ret = adap->pre_xfer(i2c_adap);
+               if (ret < 0)
+                       return ret;
+       }
+
        bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
        i2c_start(adap);
        for (i = 0; i < num; i++) {
@@ -570,6 +576,9 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
 bailout:
        bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
        i2c_stop(adap);
+
+       if (adap->post_xfer)
+               adap->post_xfer(i2c_adap);
        return ret;
 }
 
index 9da5b05..299b918 100644 (file)
@@ -416,9 +416,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
                data->block[0] = 32;    /* max for SMBus block reads */
        }
 
+       /* Experience has shown that the block buffer can only be used for
+          SMBus (not I2C) block transactions, even though the datasheet
+          doesn't mention this limitation. */
        if ((i801_features & FEATURE_BLOCK_BUFFER)
-        && !(command == I2C_SMBUS_I2C_BLOCK_DATA
-             && read_write == I2C_SMBUS_READ)
+        && command != I2C_SMBUS_I2C_BLOCK_DATA
         && i801_set_block_buffer_mode() == 0)
                result = i801_block_transaction_by_block(data, read_write,
                                                         hwpec);
index 1c440a7..b289ec9 100644 (file)
@@ -122,9 +122,14 @@ static s32 i2c_powermac_smbus_xfer(        struct i2c_adapter*     adap,
 
        rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len);
        if (rc) {
-               dev_err(&adap->dev,
-                       "I2C transfer at 0x%02x failed, size %d, err %d\n",
-                       addrdir >> 1, size, rc);
+               if (rc == -ENXIO)
+                       dev_dbg(&adap->dev,
+                               "I2C transfer at 0x%02x failed, size %d, "
+                               "err %d\n", addrdir >> 1, size, rc);
+               else
+                       dev_err(&adap->dev,
+                               "I2C transfer at 0x%02x failed, size %d, "
+                               "err %d\n", addrdir >> 1, size, rc);
                goto bail;
        }
 
@@ -175,10 +180,16 @@ static int i2c_powermac_master_xfer(      struct i2c_adapter *adap,
                goto bail;
        }
        rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
-       if (rc < 0)
-               dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
-                       addrdir & 1 ? "read from" : "write to", addrdir >> 1,
-                       rc);
+       if (rc < 0) {
+               if (rc == -ENXIO)
+                       dev_dbg(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
+                               addrdir & 1 ? "read from" : "write to",
+                               addrdir >> 1, rc);
+               else
+                       dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
+                               addrdir & 1 ? "read from" : "write to",
+                               addrdir >> 1, rc);
+       }
  bail:
        pmac_i2c_close(bus);
        return rc < 0 ? rc : 1;
index eece39a..f0ef8da 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
deleted file mode 100644 (file)
index ae4539d..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Miscellaneous I2C chip drivers configuration
-#
-# *** DEPRECATED! Do not add new entries! See Makefile ***
-#
-
-menu "Miscellaneous I2C Chip support"
-
-config SENSORS_TSL2550
-       tristate "Taos TSL2550 ambient light sensor"
-       depends on EXPERIMENTAL
-       help
-         If you say yes here you get support for the Taos TSL2550
-         ambient light sensor.
-
-         This driver can also be built as a module.  If so, the module
-         will be called tsl2550.
-
-endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
deleted file mode 100644 (file)
index fe0af0f..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Makefile for miscellaneous I2C chip drivers.
-#
-# Do not add new drivers to this directory! It is DEPRECATED.
-#
-# Device drivers are better grouped according to the functionality they
-# implement rather than to the bus they are connected to. In particular:
-# * Hardware monitoring chip drivers go to drivers/hwmon
-# * RTC chip drivers go to drivers/rtc
-# * I/O expander drivers go to drivers/gpio
-#
-
-obj-$(CONFIG_SENSORS_TSL2550)  += tsl2550.o
-
-ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
-
index 4212782..7a8201e 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
-#include <linux/semaphore.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
 #include <linux/i2c.h>
@@ -55,7 +54,7 @@ static int smbus_do_alert(struct device *dev, void *addrp)
         * Drivers should either disable alerts, or provide at least
         * a minimal handler.  Lock so client->driver won't change.
         */
-       down(&dev->sem);
+       device_lock(dev);
        if (client->driver) {
                if (client->driver->alert)
                        client->driver->alert(client, data->flag);
@@ -63,7 +62,7 @@ static int smbus_do_alert(struct device *dev, void *addrp)
                        dev_warn(&client->dev, "no driver alert()!\n");
        } else
                dev_dbg(&client->dev, "alert with no driver\n");
-       up(&dev->sem);
+       device_unlock(dev);
 
        /* Stop iterating after we find the device */
        return -EBUSY;
index 9f9816b..2ee6c7a 100644 (file)
@@ -515,7 +515,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
        struct input_absinfo abs;
        struct ff_effect effect;
        int __user *ip = (int __user *)p;
-       int i, t, u, v;
+       unsigned int i, t, u, v;
        int error;
 
        switch (cmd) {
index 41168d5..e2aad0a 100644 (file)
@@ -582,7 +582,8 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode)
 }
 
 static int input_default_getkeycode(struct input_dev *dev,
-                                   int scancode, int *keycode)
+                                   unsigned int scancode,
+                                   unsigned int *keycode)
 {
        if (!dev->keycodesize)
                return -EINVAL;
@@ -596,7 +597,8 @@ static int input_default_getkeycode(struct input_dev *dev,
 }
 
 static int input_default_setkeycode(struct input_dev *dev,
-                                   int scancode, int keycode)
+                                   unsigned int scancode,
+                                   unsigned int keycode)
 {
        int old_keycode;
        int i;
@@ -654,11 +656,9 @@ static int input_default_setkeycode(struct input_dev *dev,
  * This function should be called by anyone interested in retrieving current
  * keymap. Presently keyboard and evdev handlers use it.
  */
-int input_get_keycode(struct input_dev *dev, int scancode, int *keycode)
+int input_get_keycode(struct input_dev *dev,
+                     unsigned int scancode, unsigned int *keycode)
 {
-       if (scancode < 0)
-               return -EINVAL;
-
        return dev->getkeycode(dev, scancode, keycode);
 }
 EXPORT_SYMBOL(input_get_keycode);
@@ -672,16 +672,14 @@ EXPORT_SYMBOL(input_get_keycode);
  * This function should be called by anyone needing to update current
  * keymap. Presently keyboard and evdev handlers use it.
  */
-int input_set_keycode(struct input_dev *dev, int scancode, int keycode)
+int input_set_keycode(struct input_dev *dev,
+                     unsigned int scancode, unsigned int keycode)
 {
        unsigned long flags;
        int old_keycode;
        int retval;
 
-       if (scancode < 0)
-               return -EINVAL;
-
-       if (keycode < 0 || keycode > KEY_MAX)
+       if (keycode > KEY_MAX)
                return -EINVAL;
 
        spin_lock_irqsave(&dev->event_lock, flags);
@@ -1881,35 +1879,37 @@ static int input_open_file(struct inode *inode, struct file *file)
        const struct file_operations *old_fops, *new_fops = NULL;
        int err;
 
-       lock_kernel();
+       err = mutex_lock_interruptible(&input_mutex);
+       if (err)
+               return err;
+
        /* No load-on-demand here? */
        handler = input_table[iminor(inode) >> 5];
-       if (!handler || !(new_fops = fops_get(handler->fops))) {
-               err = -ENODEV;
-               goto out;
-       }
+       if (handler)
+               new_fops = fops_get(handler->fops);
+
+       mutex_unlock(&input_mutex);
 
        /*
         * That's _really_ odd. Usually NULL ->open means "nothing special",
         * not "no device". Oh, well...
         */
-       if (!new_fops->open) {
+       if (!new_fops || !new_fops->open) {
                fops_put(new_fops);
                err = -ENODEV;
                goto out;
        }
+
        old_fops = file->f_op;
        file->f_op = new_fops;
 
        err = new_fops->open(inode, file);
-
        if (err) {
                fops_put(file->f_op);
                file->f_op = fops_get(old_fops);
        }
        fops_put(old_fops);
 out:
-       unlock_kernel();
        return err;
 }
 
index ae998d9..7a55714 100644 (file)
@@ -819,7 +819,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
        int i;
        int err;
 
-       if (pad_type < 1 || pad_type > GC_MAX) {
+       if (pad_type < 1 || pad_type >= GC_MAX) {
                pr_err("Pad type %d unknown\n", pad_type);
                return -EINVAL;
        }
index fe376a2..593c052 100644 (file)
@@ -162,7 +162,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id)
        input_sync(input);
 
        if (bfin_kpad_get_keypressed(bf54x_kpad)) {
-               disable_irq(bf54x_kpad->irq);
+               disable_irq_nosync(bf54x_kpad->irq);
                bf54x_kpad->lastkey = key;
                mod_timer(&bf54x_kpad->timer,
                          jiffies + bf54x_kpad->keyup_test_jiffies);
index 7097bfe..23140a3 100644 (file)
@@ -214,6 +214,17 @@ config INPUT_TWL4030_PWRBUTTON
          To compile this driver as a module, choose M here. The module will
          be called twl4030_pwrbutton.
 
+config INPUT_TWL4030_VIBRA
+       tristate "Support for TWL4030 Vibrator"
+       depends on TWL4030_CORE
+       select TWL4030_CODEC
+       select INPUT_FF_MEMLESS
+       help
+         This option enables support for TWL4030 Vibrator Driver.
+
+         To compile this driver as a module, choose M here. The module will
+         be called twl4030_vibra.
+
 config INPUT_UINPUT
        tristate "User level driver support"
        help
index b611615..7e95a5d 100644 (file)
@@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)       += rotary_encoder.o
 obj-$(CONFIG_INPUT_SGI_BTNS)           += sgi_btns.o
 obj-$(CONFIG_INPUT_SPARCSPKR)          += sparcspkr.o
 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)  += twl4030-pwrbutton.o
+obj-$(CONFIG_INPUT_TWL4030_VIBRA)      += twl4030-vibra.o
 obj-$(CONFIG_INPUT_UINPUT)             += uinput.o
 obj-$(CONFIG_INPUT_WINBOND_CIR)                += winbond-cir.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)       += wistron_btns.o
index 0501f0e..15be543 100644 (file)
@@ -474,10 +474,11 @@ static void ati_remote2_complete_key(struct urb *urb)
 }
 
 static int ati_remote2_getkeycode(struct input_dev *idev,
-                                 int scancode, int *keycode)
+                                 unsigned int scancode, unsigned int *keycode)
 {
        struct ati_remote2 *ar2 = input_get_drvdata(idev);
-       int index, mode;
+       unsigned int mode;
+       int index;
 
        mode = scancode >> 8;
        if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -491,10 +492,12 @@ static int ati_remote2_getkeycode(struct input_dev *idev,
        return 0;
 }
 
-static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode)
+static int ati_remote2_setkeycode(struct input_dev *idev,
+                                 unsigned int scancode, unsigned int keycode)
 {
        struct ati_remote2 *ar2 = input_get_drvdata(idev);
-       int index, mode, old_keycode;
+       unsigned int mode, old_keycode;
+       int index;
 
        mode = scancode >> 8;
        if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -504,9 +507,6 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc
        if (index < 0)
                return -EINVAL;
 
-       if (keycode < KEY_RESERVED || keycode > KEY_MAX)
-               return -EINVAL;
-
        old_keycode = ar2->keycode[mode][index];
        ar2->keycode[mode][index] = keycode;
        __set_bit(keycode, idev->keybit);
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
new file mode 100644 (file)
index 0000000..2fb79e0
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * twl4030-vibra.c - TWL4030 Vibrator driver
+ *
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Written by Henrik Saari <henrik.saari@nokia.com>
+ * Updates by Felipe Balbi <felipe.balbi@nokia.com>
+ * Input by Jari Vanhala <ext-jari.vanhala@nokia.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/i2c/twl.h>
+#include <linux/mfd/twl4030-codec.h>
+#include <linux/input.h>
+
+/* MODULE ID2 */
+#define LEDEN          0x00
+
+/* ForceFeedback */
+#define EFFECT_DIR_180_DEG     0x8000 /* range is 0 - 0xFFFF */
+
+struct vibra_info {
+       struct device           *dev;
+       struct input_dev        *input_dev;
+
+       struct workqueue_struct *workqueue;
+       struct work_struct      play_work;
+
+       bool                    enabled;
+       int                     speed;
+       int                     direction;
+
+       bool                    coexist;
+};
+
+static void vibra_disable_leds(void)
+{
+       u8 reg;
+
+       /* Disable LEDA & LEDB, cannot be used with vibra (PWM) */
+       twl_i2c_read_u8(TWL4030_MODULE_LED, &reg, LEDEN);
+       reg &= ~0x03;
+       twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg);
+}
+
+/* Powers H-Bridge and enables audio clk */
+static void vibra_enable(struct vibra_info *info)
+{
+       u8 reg;
+
+       twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
+
+       /* turn H-Bridge on */
+       twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+                       &reg, TWL4030_REG_VIBRA_CTL);
+       twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+                        (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
+
+       twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
+
+       info->enabled = true;
+}
+
+static void vibra_disable(struct vibra_info *info)
+{
+       u8 reg;
+
+       /* Power down H-Bridge */
+       twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+                       &reg, TWL4030_REG_VIBRA_CTL);
+       twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+                        (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
+
+       twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
+       twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
+
+       info->enabled = false;
+}
+
+static void vibra_play_work(struct work_struct *work)
+{
+       struct vibra_info *info = container_of(work,
+                       struct vibra_info, play_work);
+       int dir;
+       int pwm;
+       u8 reg;
+
+       dir = info->direction;
+       pwm = info->speed;
+
+       twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+                       &reg, TWL4030_REG_VIBRA_CTL);
+       if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) {
+
+               if (!info->enabled)
+                       vibra_enable(info);
+
+               /* set vibra rotation direction */
+               twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+                               &reg, TWL4030_REG_VIBRA_CTL);
+               reg = (dir) ? (reg | TWL4030_VIBRA_DIR) :
+                       (reg & ~TWL4030_VIBRA_DIR);
+               twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+                                reg, TWL4030_REG_VIBRA_CTL);
+
+               /* set PWM, 1 = max, 255 = min */
+               twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+                                256 - pwm, TWL4030_REG_VIBRA_SET);
+       } else {
+               if (info->enabled)
+                       vibra_disable(info);
+       }
+}
+
+/*** Input/ForceFeedback ***/
+
+static int vibra_play(struct input_dev *input, void *data,
+                     struct ff_effect *effect)
+{
+       struct vibra_info *info = input_get_drvdata(input);
+
+       info->speed = effect->u.rumble.strong_magnitude >> 8;
+       if (!info->speed)
+               info->speed = effect->u.rumble.weak_magnitude >> 9;
+       info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1;
+       queue_work(info->workqueue, &info->play_work);
+       return 0;
+}
+
+static int twl4030_vibra_open(struct input_dev *input)
+{
+       struct vibra_info *info = input_get_drvdata(input);
+
+       info->workqueue = create_singlethread_workqueue("vibra");
+       if (info->workqueue == NULL) {
+               dev_err(&input->dev, "couldn't create workqueue\n");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+static void twl4030_vibra_close(struct input_dev *input)
+{
+       struct vibra_info *info = input_get_drvdata(input);
+
+       cancel_work_sync(&info->play_work);
+       INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */
+       destroy_workqueue(info->workqueue);
+       info->workqueue = NULL;
+
+       if (info->enabled)
+               vibra_disable(info);
+}
+
+/*** Module ***/
+#if CONFIG_PM
+static int twl4030_vibra_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct vibra_info *info = platform_get_drvdata(pdev);
+
+       if (info->enabled)
+               vibra_disable(info);
+
+       return 0;
+}
+
+static int twl4030_vibra_resume(struct device *dev)
+{
+       vibra_disable_leds();
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
+                        twl4030_vibra_suspend, twl4030_vibra_resume);
+#endif
+
+static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
+{
+       struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data;
+       struct vibra_info *info;
+       int ret;
+
+       if (!pdata) {
+               dev_dbg(&pdev->dev, "platform_data not available\n");
+               return -EINVAL;
+       }
+
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       info->dev = &pdev->dev;
+       info->coexist = pdata->coexist;
+       INIT_WORK(&info->play_work, vibra_play_work);
+
+       info->input_dev = input_allocate_device();
+       if (info->input_dev == NULL) {
+               dev_err(&pdev->dev, "couldn't allocate input device\n");
+               ret = -ENOMEM;
+               goto err_kzalloc;
+       }
+
+       input_set_drvdata(info->input_dev, info);
+
+       info->input_dev->name = "twl4030:vibrator";
+       info->input_dev->id.version = 1;
+       info->input_dev->dev.parent = pdev->dev.parent;
+       info->input_dev->open = twl4030_vibra_open;
+       info->input_dev->close = twl4030_vibra_close;
+       __set_bit(FF_RUMBLE, info->input_dev->ffbit);
+
+       ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
+       if (ret < 0) {
+               dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
+               goto err_ialloc;
+       }
+
+       ret = input_register_device(info->input_dev);
+       if (ret < 0) {
+               dev_dbg(&pdev->dev, "couldn't register input device\n");
+               goto err_iff;
+       }
+
+       vibra_disable_leds();
+
+       platform_set_drvdata(pdev, info);
+       return 0;
+
+err_iff:
+       input_ff_destroy(info->input_dev);
+err_ialloc:
+       input_free_device(info->input_dev);
+err_kzalloc:
+       kfree(info);
+       return ret;
+}
+
+static int __devexit twl4030_vibra_remove(struct platform_device *pdev)
+{
+       struct vibra_info *info = platform_get_drvdata(pdev);
+
+       /* this also free ff-memless and calls close if needed */
+       input_unregister_device(info->input_dev);
+       kfree(info);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver twl4030_vibra_driver = {
+       .probe          = twl4030_vibra_probe,
+       .remove         = __devexit_p(twl4030_vibra_remove),
+       .driver         = {
+               .name   = "twl4030_codec_vibra",
+               .owner  = THIS_MODULE,
+#ifdef CONFIG_PM
+               .pm     = &twl4030_vibra_pm_ops,
+#endif
+       },
+};
+
+static int __init twl4030_vibra_init(void)
+{
+       return platform_driver_register(&twl4030_vibra_driver);
+}
+module_init(twl4030_vibra_init);
+
+static void __exit twl4030_vibra_exit(void)
+{
+       platform_driver_unregister(&twl4030_vibra_driver);
+}
+module_exit(twl4030_vibra_exit);
+
+MODULE_ALIAS("platform:twl4030_codec_vibra");
+
+MODULE_DESCRIPTION("TWL4030 Vibra driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nokia Corporation");
index cbec3df..9c155a4 100644 (file)
@@ -385,26 +385,24 @@ wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode)
 }
 
 static int
-wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+wbcir_getkeycode(struct input_dev *dev,
+                unsigned int scancode, unsigned int *keycode)
 {
        struct wbcir_data *data = input_get_drvdata(dev);
 
-       *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode);
+       *keycode = wbcir_do_getkeycode(data, scancode);
        return 0;
 }
 
 static int
-wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode)
+wbcir_setkeycode(struct input_dev *dev,
+                unsigned int scancode, unsigned int keycode)
 {
        struct wbcir_data *data = input_get_drvdata(dev);
        struct wbcir_keyentry *keyentry;
        struct wbcir_keyentry *new_keyentry;
        unsigned long flags;
        unsigned int old_keycode = KEY_RESERVED;
-       u32 scancode = (u32)sscancode;
-
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
 
        new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL);
        if (!new_keyentry)
index ba4f5dd..1e54bce 100644 (file)
@@ -97,8 +97,9 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
        wm831x_on->dev->phys = "wm831x_on/input0";
        wm831x_on->dev->dev.parent = &pdev->dev;
 
-       ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq,
-                                IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on);
+       ret = request_threaded_irq(irq, NULL, wm831x_on_irq,
+                                  IRQF_TRIGGER_RISING, "wm831x_on",
+                                  wm831x_on);
        if (ret < 0) {
                dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret);
                goto err_input_dev;
@@ -114,7 +115,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
        return 0;
 
 err_irq:
-       wm831x_free_irq(wm831x, irq, NULL);
+       free_irq(irq, wm831x_on);
 err_input_dev:
        input_free_device(wm831x_on->dev);
 err:
@@ -127,7 +128,7 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev)
        struct wm831x_on *wm831x_on = platform_get_drvdata(pdev);
        int irq = platform_get_irq(pdev, 0);
 
-       wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on);
+       free_irq(irq, wm831x_on);
        cancel_delayed_work_sync(&wm831x_on->work);
        input_unregister_device(wm831x_on->dev);
        kfree(wm831x_on);
index f93c2c0..7490f1d 100644 (file)
@@ -63,6 +63,8 @@ static const struct alps_model_info alps_model_data[] = {
        { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
                ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
        { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },          /* Dell Vostro 1400 */
+       { { 0x52, 0x01, 0x14 }, 0xff, 0xff,
+               ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },      /* Toshiba Tecra A11-11L */
 };
 
 /*
@@ -118,40 +120,27 @@ static void alps_report_buttons(struct psmouse *psmouse,
                                struct input_dev *dev1, struct input_dev *dev2,
                                int left, int right, int middle)
 {
-       struct alps_data *priv = psmouse->private;
-       const struct alps_model_info *model = priv->i;
-
-       if (model->flags & ALPS_PS2_INTERLEAVED) {
-               struct input_dev *dev;
+       struct input_dev *dev;
 
-               /*
-                * If shared button has already been reported on the
-                * other device (dev2) then this event should be also
-                * sent through that device.
-                */
-               dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
-               input_report_key(dev, BTN_LEFT, left);
+       /*
+        * If shared button has already been reported on the
+        * other device (dev2) then this event should be also
+        * sent through that device.
+        */
+       dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
+       input_report_key(dev, BTN_LEFT, left);
 
-               dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
-               input_report_key(dev, BTN_RIGHT, right);
+       dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
+       input_report_key(dev, BTN_RIGHT, right);
 
-               dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
-               input_report_key(dev, BTN_MIDDLE, middle);
+       dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
+       input_report_key(dev, BTN_MIDDLE, middle);
 
-               /*
-                * Sync the _other_ device now, we'll do the first
-                * device later once we report the rest of the events.
-                */
-               input_sync(dev2);
-       } else {
-               /*
-                * For devices with non-interleaved packets we know what
-                * device buttons belong to so we can simply report them.
-                */
-               input_report_key(dev1, BTN_LEFT, left);
-               input_report_key(dev1, BTN_RIGHT, right);
-               input_report_key(dev1, BTN_MIDDLE, middle);
-       }
+       /*
+        * Sync the _other_ device now, we'll do the first
+        * device later once we report the rest of the events.
+        */
+       input_sync(dev2);
 }
 
 static void alps_process_packet(struct psmouse *psmouse)
index 908b5b4..53ec7dd 100644 (file)
@@ -205,8 +205,8 @@ struct atp {
        bool                    overflow_warned;
        int                     x_old;          /* last reported x/y, */
        int                     y_old;          /* used for smoothing */
-       signed char             xy_cur[ATP_XSENSORS + ATP_YSENSORS];
-       signed char             xy_old[ATP_XSENSORS + ATP_YSENSORS];
+       u8                      xy_cur[ATP_XSENSORS + ATP_YSENSORS];
+       u8                      xy_old[ATP_XSENSORS + ATP_YSENSORS];
        int                     xy_acc[ATP_XSENSORS + ATP_YSENSORS];
        int                     idlecount;      /* number of empty packets */
        struct work_struct      work;
@@ -531,7 +531,7 @@ static void atp_complete_geyser_1_2(struct urb *urb)
 
        for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
                /* accumulate the change */
-               signed char change = dev->xy_old[i] - dev->xy_cur[i];
+               int change = dev->xy_old[i] - dev->xy_cur[i];
                dev->xy_acc[i] -= change;
 
                /* prevent down drifting */
index a13d80f..f34b22b 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -542,10 +541,8 @@ static int mousedev_open(struct inode *inode, struct file *file)
        if (i >= MOUSEDEV_MINORS)
                return -ENODEV;
 
-       lock_kernel();
        error = mutex_lock_interruptible(&mousedev_table_mutex);
        if (error) {
-               unlock_kernel();
                return error;
        }
        mousedev = mousedev_table[i];
@@ -554,7 +551,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
        mutex_unlock(&mousedev_table_mutex);
 
        if (!mousedev) {
-               unlock_kernel();
                return -ENODEV;
        }
 
@@ -575,7 +571,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
                goto err_free_client;
 
        file->private_data = client;
-       unlock_kernel();
        return 0;
 
  err_free_client:
@@ -583,7 +578,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
        kfree(client);
  err_put_mousedev:
        put_device(&mousedev->dev);
-       unlock_kernel();
        return error;
 }
 
index 2a5982e..ead0494 100644 (file)
@@ -441,6 +441,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
                },
        },
+       {
+               /* Medion Akoya E1222 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
+               },
+       },
        {
                /* Mivvy M310 */
                .matches = {
@@ -624,6 +631,9 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
                strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
        }
 
+       /* Keyboard ports are always supposed to be wakeup-enabled */
+       device_set_wakeup_enable(&dev->dev, true);
+
        i8042_pnp_kbd_devices++;
        return 0;
 }
index ff4d77c..9302ba0 100644 (file)
@@ -1386,6 +1386,8 @@ static int __init i8042_probe(struct platform_device *dev)
 {
        int error;
 
+       i8042_platform_device = dev;
+
        error = i8042_controller_selftest();
        if (error)
                return error;
@@ -1421,6 +1423,7 @@ static int __init i8042_probe(struct platform_device *dev)
        i8042_free_aux_ports(); /* in case KBD failed but AUX not */
        i8042_free_irqs();
        i8042_controller_reset();
+       i8042_platform_device = NULL;
 
        return error;
 }
@@ -1430,6 +1433,7 @@ static int __devexit i8042_remove(struct platform_device *dev)
        i8042_unregister_ports();
        i8042_free_irqs();
        i8042_controller_reset();
+       i8042_platform_device = NULL;
 
        return 0;
 }
@@ -1448,6 +1452,7 @@ static struct platform_driver i8042_driver = {
 
 static int __init i8042_init(void)
 {
+       struct platform_device *pdev;
        int err;
 
        dbg_init();
@@ -1460,31 +1465,18 @@ static int __init i8042_init(void)
        if (err)
                goto err_platform_exit;
 
-       i8042_platform_device = platform_device_alloc("i8042", -1);
-       if (!i8042_platform_device) {
-               err = -ENOMEM;
+       pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);
+       if (IS_ERR(pdev)) {
+               err = PTR_ERR(pdev);
                goto err_platform_exit;
        }
 
-       err = platform_device_add(i8042_platform_device);
-       if (err)
-               goto err_free_device;
-
-       err = platform_driver_probe(&i8042_driver, i8042_probe);
-       if (err)
-               goto err_del_device;
-
        panic_blink = i8042_panic_blink;
 
        return 0;
 
- err_del_device:
-       platform_device_del(i8042_platform_device);
- err_free_device:
-       platform_device_put(i8042_platform_device);
  err_platform_exit:
        i8042_platform_exit();
-
        return err;
 }
 
index 27fdaaf..9986648 100644 (file)
@@ -81,12 +81,12 @@ static int serio_raw_open(struct inode *inode, struct file *file)
        struct serio_raw_list *list;
        int retval = 0;
 
-       lock_kernel();
        retval = mutex_lock_interruptible(&serio_raw_mutex);
        if (retval)
-               goto out_bkl;
+               return retval;
 
-       if (!(serio_raw = serio_raw_locate(iminor(inode)))) {
+       serio_raw = serio_raw_locate(iminor(inode));
+       if (!serio_raw) {
                retval = -ENODEV;
                goto out;
        }
@@ -96,7 +96,8 @@ static int serio_raw_open(struct inode *inode, struct file *file)
                goto out;
        }
 
-       if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) {
+       list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL);
+       if (!list) {
                retval = -ENOMEM;
                goto out;
        }
@@ -109,8 +110,6 @@ static int serio_raw_open(struct inode *inode, struct file *file)
 
 out:
        mutex_unlock(&serio_raw_mutex);
-out_bkl:
-       unlock_kernel();
        return retval;
 }
 
index fbd3987..e6bde55 100644 (file)
@@ -64,7 +64,8 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
 EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
 
 static int sparse_keymap_getkeycode(struct input_dev *dev,
-                                   int scancode, int *keycode)
+                                   unsigned int scancode,
+                                   unsigned int *keycode)
 {
        const struct key_entry *key =
                        sparse_keymap_entry_from_scancode(dev, scancode);
@@ -78,7 +79,8 @@ static int sparse_keymap_getkeycode(struct input_dev *dev,
 }
 
 static int sparse_keymap_setkeycode(struct input_dev *dev,
-                                   int scancode, int keycode)
+                                   unsigned int scancode,
+                                   unsigned int keycode)
 {
        struct key_entry *key;
        int old_keycode;
index a1770e6..8b5d287 100644 (file)
@@ -371,7 +371,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
                                        } else if (pen) {
                                                /* penabled only accepts exact bytes of data */
                                                if (features->type == TABLETPC2FG)
-                                                       features->pktlen = WACOM_PKGLEN_PENABLED;
+                                                       features->pktlen = WACOM_PKGLEN_GRAPHIRE;
                                                features->device_type = BTN_TOOL_PEN;
                                                features->x_max =
                                                        wacom_le16_to_cpu(&report[i + 3]);
@@ -410,7 +410,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
                                        } else if (pen) {
                                                /* penabled only accepts exact bytes of data */
                                                if (features->type == TABLETPC2FG)
-                                                       features->pktlen = WACOM_PKGLEN_PENABLED;
+                                                       features->pktlen = WACOM_PKGLEN_GRAPHIRE;
                                                features->device_type = BTN_TOOL_PEN;
                                                features->y_max =
                                                        wacom_le16_to_cpu(&report[i + 3]);
index 3d81443..b3ba343 100644 (file)
@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 {
        struct wacom_features *features = &wacom->features;
        unsigned char *data = wacom->data;
-       int x, y, rw;
-       static int penData = 0;
+       int x, y, prox;
+       int rw = 0;
+       int retval = 0;
 
        if (data[0] != WACOM_REPORT_PENABLED) {
                dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
-               return 0;
+               goto exit;
        }
 
-       if (data[1] & 0x80) {
-               /* in prox and not a pad data */
-               penData = 1;
-
-               switch ((data[1] >> 5) & 3) {
+       prox = data[1] & 0x80;
+       if (prox || wacom->id[0]) {
+               if (prox) {
+                       switch ((data[1] >> 5) & 3) {
 
                        case 0: /* Pen */
                                wacom->tool[0] = BTN_TOOL_PEN;
@@ -181,23 +181,13 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 
                        case 2: /* Mouse with wheel */
                                wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
-                               if (features->type == WACOM_G4 || features->type == WACOM_MO) {
-                                       rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
-                                       wacom_report_rel(wcombo, REL_WHEEL, -rw);
-                               } else
-                                       wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]);
                                /* fall through */
 
                        case 3: /* Mouse without wheel */
                                wacom->tool[0] = BTN_TOOL_MOUSE;
                                wacom->id[0] = CURSOR_DEVICE_ID;
-                               wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
-                               wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
-                               if (features->type == WACOM_G4 || features->type == WACOM_MO)
-                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
-                               else
-                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
                                break;
+                       }
                }
                x = wacom_le16_to_cpu(&data[2]);
                y = wacom_le16_to_cpu(&data[4]);
@@ -208,36 +198,32 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
                        wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
                        wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
-               }
-               wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
-               wacom_report_key(wcombo, wacom->tool[0], 1);
-       } else if (wacom->id[0]) {
-               wacom_report_abs(wcombo, ABS_X, 0);
-               wacom_report_abs(wcombo, ABS_Y, 0);
-               if (wacom->tool[0] == BTN_TOOL_MOUSE) {
-                       wacom_report_key(wcombo, BTN_LEFT, 0);
-                       wacom_report_key(wcombo, BTN_RIGHT, 0);
-                       wacom_report_abs(wcombo, ABS_DISTANCE, 0);
                } else {
-                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
-                       wacom_report_key(wcombo, BTN_TOUCH, 0);
-                       wacom_report_key(wcombo, BTN_STYLUS, 0);
-                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+                       wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
+                       wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
+                       if (features->type == WACOM_G4 ||
+                                       features->type == WACOM_MO) {
+                               wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
+                               rw = (signed)(data[7] & 0x04) - (data[7] & 0x03);
+                       } else {
+                               wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
+                               rw = -(signed)data[6];
+                       }
+                       wacom_report_rel(wcombo, REL_WHEEL, rw);
                }
-               wacom->id[0] = 0;
-               wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
-               wacom_report_key(wcombo, wacom->tool[0], 0);
+
+               if (!prox)
+                       wacom->id[0] = 0;
+               wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
+               wacom_report_key(wcombo, wacom->tool[0], prox);
+               wacom_input_sync(wcombo); /* sync last event */
        }
 
        /* send pad data */
        switch (features->type) {
            case WACOM_G4:
-               if (data[7] & 0xf8) {
-                       if (penData) {
-                               wacom_input_sync(wcombo); /* sync last event */
-                               if (!wacom->id[0])
-                                       penData = 0;
-                       }
+               prox = data[7] & 0xf8;
+               if (prox || wacom->id[1]) {
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
                        wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
@@ -245,29 +231,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_rel(wcombo, REL_WHEEL, rw);
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
-                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
-               } else if (wacom->id[1]) {
-                       if (penData) {
-                               wacom_input_sync(wcombo); /* sync last event */
-                               if (!wacom->id[0])
-                                       penData = 0;
-                       }
-                       wacom->id[1] = 0;
-                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
-                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
-                       wacom_report_rel(wcombo, REL_WHEEL, 0);
-                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
-                       wacom_report_abs(wcombo, ABS_MISC, 0);
+                       if (!prox)
+                               wacom->id[1] = 0;
+                       wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
+               retval = 1;
                break;
            case WACOM_MO:
-               if ((data[7] & 0xf8) || (data[8] & 0xff)) {
-                       if (penData) {
-                               wacom_input_sync(wcombo); /* sync last event */
-                               if (!wacom->id[0])
-                                       penData = 0;
-                       }
+               prox = (data[7] & 0xf8) || data[8];
+               if (prox || wacom->id[1]) {
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
                        wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -275,27 +248,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
                        wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
+                       if (!prox)
+                               wacom->id[1] = 0;
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
-               } else if (wacom->id[1]) {
-                       if (penData) {
-                               wacom_input_sync(wcombo); /* sync last event */
-                               if (!wacom->id[0])
-                                       penData = 0;
-                       }
-                       wacom->id[1] = 0;
-                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
-                       wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
-                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
-                       wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
-                       wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
-                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
-                       wacom_report_abs(wcombo, ABS_MISC, 0);
-                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
+               retval = 1;
                break;
        }
-       return 1;
+exit:
+       return retval;
 }
 
 static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
@@ -636,9 +598,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
 static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx)
 {
        wacom_report_abs(wcombo, ABS_X,
-               (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8));
+               data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_Y,
-               (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8));
+               data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
        wacom_report_key(wcombo, wacom->tool[idx], 1);
        if (idx)
@@ -782,31 +744,24 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
 
                touchInProx = 0;
 
-               if (prox) { /* in prox */
-                       if (!wacom->id[0]) {
-                               /* Going into proximity select tool */
-                               wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
-                               if (wacom->tool[0] == BTN_TOOL_PEN)
-                                       wacom->id[0] = STYLUS_DEVICE_ID;
-                               else
-                                       wacom->id[0] = ERASER_DEVICE_ID;
-                       }
-                       wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
-                       wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
-                       wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
-                       wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
-                       pressure = ((data[7] & 0x01) << 8) | data[6];
-                       if (pressure < 0)
-                               pressure = features->pressure_max + pressure + 1;
-                       wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
-                       wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
-               } else {
-                       wacom_report_abs(wcombo, ABS_X, 0);
-                       wacom_report_abs(wcombo, ABS_Y, 0);
-                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
-                       wacom_report_key(wcombo, BTN_STYLUS, 0);
-                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
-                       wacom_report_key(wcombo, BTN_TOUCH, 0);
+               if (!wacom->id[0]) { /* first in prox */
+                       /* Going into proximity select tool */
+                       wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+                       if (wacom->tool[0] == BTN_TOOL_PEN)
+                               wacom->id[0] = STYLUS_DEVICE_ID;
+                       else
+                               wacom->id[0] = ERASER_DEVICE_ID;
+               }
+               wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
+               wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
+               wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
+               wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
+               pressure = ((data[7] & 0x01) << 8) | data[6];
+               if (pressure < 0)
+                       pressure = features->pressure_max + pressure + 1;
+               wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
+               wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
+               if (!prox) { /* out-prox */
                        wacom->id[0] = 0;
                        /* pen is out so touch can be enabled now */
                        touchInProx = 1;
@@ -1028,7 +983,7 @@ static const struct wacom_features wacom_features_0x93 =
 static const struct wacom_features wacom_features_0x9A =
        { "Wacom ISDv4 9A",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC };
 static const struct wacom_features wacom_features_0x9F =
-       { "Wacom ISDv4 9F",       WACOM_PKGLEN_PENABLED,  26202, 16325,  255,  0, TABLETPC };
+       { "Wacom ISDv4 9F",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC };
 static const struct wacom_features wacom_features_0xE2 =
        { "Wacom ISDv4 E2",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG };
 static const struct wacom_features wacom_features_0xE3 =
index 8590b1e..b50cf04 100644 (file)
@@ -17,7 +17,6 @@
 #define WACOM_PKGLEN_GRAPHIRE   8
 #define WACOM_PKGLEN_BBFUN      9
 #define WACOM_PKGLEN_INTUOS    10
-#define WACOM_PKGLEN_PENABLED   8
 #define WACOM_PKGLEN_TPC1FG     5
 #define WACOM_PKGLEN_TPC2FG    14
 
index 7208654..8a8fa4d 100644 (file)
@@ -24,17 +24,18 @@ config TOUCHSCREEN_88PM860X
          module will be called 88pm860x-ts.
 
 config TOUCHSCREEN_ADS7846
-       tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
+       tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens"
        depends on SPI_MASTER
        depends on HWMON = n || HWMON
        help
          Say Y here if you have a touchscreen interface using the
-         ADS7846/TSC2046 or ADS7843 controller, and your board-specific
-         setup code includes that in its table of SPI devices.
+         ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller,
+         and your board-specific setup code includes that in its
+         table of SPI devices.
 
          If HWMON is selected, and the driver is told the reference voltage
          on your board, you will also get hwmon interfaces for the voltage
-         (and on ads7846/tsc2046, temperature) sensors of this chip.
+         (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip.
 
          If unsure, say N (but it's safe to say "Y").
 
index eb83939..e019d53 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/spi/ad7877.h>
 #include <asm/irq.h>
 
-#define        TS_PEN_UP_TIMEOUT       msecs_to_jiffies(50)
+#define        TS_PEN_UP_TIMEOUT       msecs_to_jiffies(100)
 
 #define MAX_SPI_FREQ_HZ                        20000000
 #define        MAX_12BIT                       ((1<<12)-1)
index 8b05d8e..532279c 100644 (file)
@@ -36,6 +36,7 @@
  * TSC2046 is just newer ads7846 silicon.
  * Support for ads7843 tested on Atmel at91sam926x-EK.
  * Support for ads7845 has only been stubbed in.
+ * Support for Analog Devices AD7873 and AD7843 tested.
  *
  * IRQ handling needs a workaround because of a shortcoming in handling
  * edge triggered IRQs on some platforms like the OMAP1/2. These
@@ -821,6 +822,9 @@ static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
 
        spin_unlock_irq(&ts->lock);
 
+       if (device_may_wakeup(&ts->spi->dev))
+               enable_irq_wake(ts->spi->irq);
+
        return 0;
 
 }
@@ -829,6 +833,9 @@ static int ads7846_resume(struct spi_device *spi)
 {
        struct ads7846 *ts = dev_get_drvdata(&spi->dev);
 
+       if (device_may_wakeup(&ts->spi->dev))
+               disable_irq_wake(ts->spi->irq);
+
        spin_lock_irq(&ts->lock);
 
        ts->is_suspended = 0;
@@ -984,6 +991,15 @@ static int __devinit ads7846_probe(struct spi_device *spi)
 
        vref = pdata->keep_vref_on;
 
+       if (ts->model == 7873) {
+               /* The AD7873 is almost identical to the ADS7846
+                * keep VREF off during differential/ratiometric
+                * conversion modes
+                */
+               ts->model = 7846;
+               vref = 0;
+       }
+
        /* set up the transfers to read touchscreen state; this assumes we
         * use formula #2 for pressure, not #3.
         */
@@ -1191,6 +1207,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        if (err)
                goto err_remove_attr_group;
 
+       device_init_wakeup(&spi->dev, pdata->wakeup);
+
        return 0;
 
  err_remove_attr_group:
@@ -1220,6 +1238,8 @@ static int __devexit ads7846_remove(struct spi_device *spi)
 {
        struct ads7846          *ts = dev_get_drvdata(&spi->dev);
 
+       device_init_wakeup(&spi->dev, false);
+
        ads784x_hwmon_unregister(spi, ts);
        input_unregister_device(ts->input);
 
index 0903f53..0a3b4ed 100644 (file)
@@ -123,7 +123,7 @@ static int ir_copy_table(struct ir_scancode_table *destin,
  * If the key is not found, returns -EINVAL, otherwise, returns 0.
  */
 static int ir_getkeycode(struct input_dev *dev,
-                        int scancode, int *keycode)
+                        unsigned int scancode, unsigned int *keycode)
 {
        int elem;
        struct ir_input_dev *ir_dev = input_get_drvdata(dev);
@@ -291,7 +291,7 @@ static int ir_insert_key(struct ir_scancode_table *rc_tab,
  * If the key is not found, returns -EINVAL, otherwise, returns 0.
  */
 static int ir_setkeycode(struct input_dev *dev,
-                        int scancode, int keycode)
+                        unsigned int scancode, unsigned int keycode)
 {
        int rc = 0;
        struct ir_input_dev *ir_dev = input_get_drvdata(dev);
index a03ef7e..852fe89 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/usb/input.h>
 
 static int dvb_usb_getkeycode(struct input_dev *dev,
-                                   int scancode, int *keycode)
+                               unsigned int scancode, unsigned int *keycode)
 {
        struct dvb_usb_device *d = input_get_drvdata(dev);
 
@@ -39,7 +39,7 @@ static int dvb_usb_getkeycode(struct input_dev *dev,
 }
 
 static int dvb_usb_setkeycode(struct input_dev *dev,
-                                   int scancode, int keycode)
+                               unsigned int scancode, unsigned int keycode)
 {
        struct dvb_usb_device *d = input_get_drvdata(dev);
 
index d16af6a..2191c8d 100644 (file)
@@ -268,6 +268,16 @@ config ISL29003
          This driver can also be built as a module.  If so, the module
          will be called isl29003.
 
+config SENSORS_TSL2550
+       tristate "Taos TSL2550 ambient light sensor"
+       depends on I2C && SYSFS
+       help
+         If you say yes here you get support for the Taos TSL2550
+         ambient light sensor.
+
+         This driver can also be built as a module.  If so, the module
+         will be called tsl2550.
+
 config EP93XX_PWM
        tristate "EP93xx PWM support"
        depends on ARCH_EP93XX
index 049ff24..27c4843 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_SGI_GRU)         += sgi-gru/
 obj-$(CONFIG_CS5535_MFGPT)     += cs5535-mfgpt.o
 obj-$(CONFIG_HP_ILO)           += hpilo.o
 obj-$(CONFIG_ISL29003)         += isl29003.o
+obj-$(CONFIG_SENSORS_TSL2550)  += tsl2550.o
 obj-$(CONFIG_EP93XX_PWM)       += ep93xx_pwm.o
 obj-$(CONFIG_DS1682)           += ds1682.o
 obj-$(CONFIG_TI_DAC7512)       += ti_dac7512.o
index 2cb2736..db7d0f2 100644 (file)
@@ -505,6 +505,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
         * Export the EEPROM bytes through sysfs, since that's convenient.
         * By default, only root should see the data (maybe passwords etc)
         */
+       sysfs_bin_attr_init(&at24->bin);
        at24->bin.attr.name = "eeprom";
        at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR;
        at24->bin.read = at24_bin_read;
similarity index 99%
rename from drivers/i2c/chips/tsl2550.c
rename to drivers/misc/tsl2550.c
index a0702f3..483ae5f 100644 (file)
@@ -47,8 +47,8 @@ struct tsl2550_data {
        struct i2c_client *client;
        struct mutex update_lock;
 
-       unsigned int power_state : 1;
-       unsigned int operating_mode : 1;
+       unsigned int power_state:1;
+       unsigned int operating_mode:1;
 };
 
 /*
index 1b1dddb..bed764e 100644 (file)
@@ -142,7 +142,7 @@ static struct key_entry *dell_wmi_keymap = dell_legacy_wmi_keymap;
 
 static struct input_dev *dell_wmi_input_dev;
 
-static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
+static struct key_entry *dell_wmi_get_entry_by_scancode(unsigned int code)
 {
        struct key_entry *key;
 
@@ -153,7 +153,7 @@ static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
        return NULL;
 }
 
-static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
+static struct key_entry *dell_wmi_get_entry_by_keycode(unsigned int keycode)
 {
        struct key_entry *key;
 
@@ -164,8 +164,8 @@ static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
        return NULL;
 }
 
-static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
-                              int *keycode)
+static int dell_wmi_getkeycode(struct input_dev *dev,
+                               unsigned int scancode, unsigned int *keycode)
 {
        struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
 
@@ -177,13 +177,11 @@ static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
        return -EINVAL;
 }
 
-static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int dell_wmi_setkeycode(struct input_dev *dev,
+                               unsigned int scancode, unsigned int keycode)
 {
        struct key_entry *key;
-       int old_keycode;
-
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
+       unsigned int old_keycode;
 
        key = dell_wmi_get_entry_by_scancode(scancode);
        if (key && key->type == KE_KEY) {
index 7ccf33c..5608636 100644 (file)
@@ -278,7 +278,7 @@ static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als);
 static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
 static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
 
-static struct key_entry *hp_wmi_get_entry_by_scancode(int code)
+static struct key_entry *hp_wmi_get_entry_by_scancode(unsigned int code)
 {
        struct key_entry *key;
 
@@ -289,7 +289,7 @@ static struct key_entry *hp_wmi_get_entry_by_scancode(int code)
        return NULL;
 }
 
-static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode)
+static struct key_entry *hp_wmi_get_entry_by_keycode(unsigned int keycode)
 {
        struct key_entry *key;
 
@@ -300,7 +300,8 @@ static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode)
        return NULL;
 }
 
-static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int hp_wmi_getkeycode(struct input_dev *dev,
+                            unsigned int scancode, unsigned int *keycode)
 {
        struct key_entry *key = hp_wmi_get_entry_by_scancode(scancode);
 
@@ -312,13 +313,11 @@ static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode)
        return -EINVAL;
 }
 
-static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int hp_wmi_setkeycode(struct input_dev *dev,
+                            unsigned int scancode, unsigned int keycode)
 {
        struct key_entry *key;
-       int old_keycode;
-
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
+       unsigned int old_keycode;
 
        key = hp_wmi_get_entry_by_scancode(scancode);
        if (key && key->type == KE_KEY) {
index fe7cf01..c9fc479 100644 (file)
@@ -200,7 +200,7 @@ static struct acpi_driver acpi_pcc_driver = {
 };
 
 #define KEYMAP_SIZE            11
-static const int initial_keymap[KEYMAP_SIZE] = {
+static const unsigned int initial_keymap[KEYMAP_SIZE] = {
        /*  0 */ KEY_RESERVED,
        /*  1 */ KEY_BRIGHTNESSDOWN,
        /*  2 */ KEY_BRIGHTNESSUP,
@@ -222,7 +222,7 @@ struct pcc_acpi {
        struct acpi_device      *device;
        struct input_dev        *input_dev;
        struct backlight_device *backlight;
-       int                     keymap[KEYMAP_SIZE];
+       unsigned int            keymap[KEYMAP_SIZE];
 };
 
 struct pcc_keyinput {
@@ -445,7 +445,8 @@ static struct attribute_group pcc_attr_group = {
 
 /* hotkey input device driver */
 
-static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int pcc_getkeycode(struct input_dev *dev,
+                         unsigned int scancode, unsigned int *keycode)
 {
        struct pcc_acpi *pcc = input_get_drvdata(dev);
 
@@ -457,7 +458,7 @@ static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
        return 0;
 }
 
-static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode)
+static int keymap_get_by_keycode(struct pcc_acpi *pcc, unsigned int keycode)
 {
        int i;
 
@@ -469,7 +470,8 @@ static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode)
        return 0;
 }
 
-static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int pcc_setkeycode(struct input_dev *dev,
+                         unsigned int scancode, unsigned int keycode)
 {
        struct pcc_acpi *pcc = input_get_drvdata(dev);
        int oldkeycode;
@@ -477,9 +479,6 @@ static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode)
        if (scancode >= ARRAY_SIZE(pcc->keymap))
                return -EINVAL;
 
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
        oldkeycode = pcc->keymap[scancode];
        pcc->keymap[scancode] = keycode;
 
index 02f3d4e..4d6516f 100644 (file)
@@ -46,7 +46,7 @@ static struct tps_key_entry topstar_keymap[] = {
        { }
 };
 
-static struct tps_key_entry *tps_get_key_by_scancode(int code)
+static struct tps_key_entry *tps_get_key_by_scancode(unsigned int code)
 {
        struct tps_key_entry *key;
 
@@ -57,7 +57,7 @@ static struct tps_key_entry *tps_get_key_by_scancode(int code)
        return NULL;
 }
 
-static struct tps_key_entry *tps_get_key_by_keycode(int code)
+static struct tps_key_entry *tps_get_key_by_keycode(unsigned int code)
 {
        struct tps_key_entry *key;
 
@@ -126,7 +126,8 @@ static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state)
        return 0;
 }
 
-static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int topstar_getkeycode(struct input_dev *dev,
+                               unsigned int scancode, unsigned int *keycode)
 {
        struct tps_key_entry *key = tps_get_key_by_scancode(scancode);
 
@@ -137,14 +138,12 @@ static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode)
        return 0;
 }
 
-static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int topstar_setkeycode(struct input_dev *dev,
+                               unsigned int scancode, unsigned int keycode)
 {
        struct tps_key_entry *key;
        int old_keycode;
 
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
        key = tps_get_key_by_scancode(scancode);
 
        if (!key)
index 405b969..789240d 100644 (file)
@@ -745,7 +745,7 @@ static struct backlight_ops toshiba_backlight_data = {
         .update_status  = set_lcd_status,
 };
 
-static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code)
+static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code)
 {
        struct key_entry *key;
 
@@ -756,7 +756,7 @@ static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code)
        return NULL;
 }
 
-static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code)
+static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code)
 {
        struct key_entry *key;
 
@@ -767,8 +767,8 @@ static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code)
        return NULL;
 }
 
-static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode,
-                                  int *keycode)
+static int toshiba_acpi_getkeycode(struct input_dev *dev,
+                                  unsigned int scancode, unsigned int *keycode)
 {
        struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode);
 
@@ -780,14 +780,11 @@ static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode,
        return -EINVAL;
 }
 
-static int toshiba_acpi_setkeycode(struct input_dev *dev, int scancode,
-                                  int keycode)
+static int toshiba_acpi_setkeycode(struct input_dev *dev,
+                                  unsigned int scancode, unsigned int keycode)
 {
        struct key_entry *key;
-       int old_keycode;
-
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
+       unsigned int old_keycode;
 
        key = toshiba_acpi_get_entry_by_scancode(scancode);
        if (key && key->type == KE_KEY) {
index 79000bf..6b801d1 100644 (file)
@@ -24,7 +24,7 @@
 /**
  * enum p9_session_flags - option flags for each 9P session
  * @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
- * @V9FS_PROTO_2010L: whether or not to use 9P2010.l extensions
+ * @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
  * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
  * @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
  * @V9FS_ACCESS_ANY: use a single attach for all users
@@ -34,7 +34,7 @@
  */
 enum p9_session_flags {
        V9FS_PROTO_2000U        = 0x01,
-       V9FS_PROTO_2010L        = 0x02,
+       V9FS_PROTO_2000L        = 0x02,
        V9FS_ACCESS_SINGLE      = 0x04,
        V9FS_ACCESS_USER        = 0x08,
        V9FS_ACCESS_ANY         = 0x0C,
@@ -130,5 +130,5 @@ static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
 
 static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
 {
-       return v9ses->flags & V9FS_PROTO_2010L;
+       return v9ses->flags & V9FS_PROTO_2000L;
 }
index 6580aa4..d8a3afe 100644 (file)
@@ -76,6 +76,15 @@ static inline int dt_type(struct p9_wstat *mistat)
        return rettype;
 }
 
+static void p9stat_init(struct p9_wstat *stbuf)
+{
+       stbuf->name  = NULL;
+       stbuf->uid   = NULL;
+       stbuf->gid   = NULL;
+       stbuf->muid  = NULL;
+       stbuf->extension = NULL;
+}
+
 /**
  * v9fs_dir_readdir - read a directory
  * @filp: opened file structure
@@ -131,8 +140,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
                        rdir->head = 0;
                        rdir->tail = err;
                }
-
                while (rdir->head < rdir->tail) {
+                       p9stat_init(&st);
                        err = p9stat_read(rdir->buf + rdir->head,
                                                buflen - rdir->head, &st,
                                                fid->clnt->proto_version);
index 3612268..df52d48 100644 (file)
@@ -114,7 +114,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
        P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
 
        /* No mandatory locks */
-       if (__mandatory_lock(inode))
+       if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
                return -ENOLCK;
 
        if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
@@ -215,7 +215,7 @@ v9fs_file_write(struct file *filp, const char __user * data,
        struct p9_fid *fid;
        struct p9_client *clnt;
        struct inode *inode = filp->f_path.dentry->d_inode;
-       int origin = *offset;
+       loff_t origin = *offset;
        unsigned long pg_start, pg_end;
 
        P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data,
index f4543ac..5cccf87 100644 (file)
@@ -42,7 +42,7 @@ void *nilfs_palloc_block_get_entry(const struct inode *, __u64,
                                   const struct buffer_head *, void *);
 
 /**
- * nilfs_palloc_req - persistent alloctor request and reply
+ * nilfs_palloc_req - persistent allocator request and reply
  * @pr_entry_nr: entry number (vblocknr or inode number)
  * @pr_desc_bh: buffer head of the buffer containing block group descriptors
  * @pr_bitmap_bh: buffer head of the buffer containing a block group bitmap
index 9d1e5de..0131467 100644 (file)
@@ -288,7 +288,7 @@ int nilfs_dat_mark_dirty(struct inode *dat, __u64 vblocknr)
  * @vblocknrs and @nitems.
  *
  * Return Value: On success, 0 is returned. On error, one of the following
- * nagative error codes is returned.
+ * negative error codes is returned.
  *
  * %-EIO - I/O error.
  *
index 0092840..85c89df 100644 (file)
@@ -396,7 +396,7 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
                /* next page is past the blocks we've got */
                if (unlikely(n > (dir->i_blocks >> (PAGE_CACHE_SHIFT - 9)))) {
                        nilfs_error(dir->i_sb, __func__,
-                              "dir %lu size %lld exceeds block cout %llu",
+                              "dir %lu size %lld exceeds block count %llu",
                               dir->i_ino, dir->i_size,
                               (unsigned long long)dir->i_blocks);
                        goto out;
index e16a666..8880a9e 100644 (file)
  * gcinodes), and this file provides lookup function of the dummy
  * inodes and their buffer read function.
  *
- * Since NILFS2 keeps up multiple checkpoints/snapshots accross GC, it
+ * Since NILFS2 keeps up multiple checkpoints/snapshots across GC, it
  * has to treat blocks that belong to a same file but have different
  * checkpoint numbers.  To avoid interference among generations, dummy
- * inodes are managed separatly from actual inodes, and their lookup
+ * inodes are managed separately from actual inodes, and their lookup
  * function (nilfs_gc_iget) is designed to be specified with a
  * checkpoint number argument as well as an inode number.
  *
index a2692bb..fc246db 100644 (file)
@@ -292,7 +292,7 @@ void nilfs_free_private_page(struct page *page)
  * @src: source page
  * @copy_dirty: flag whether to copy dirty states on the page's buffer heads.
  *
- * This fuction is for both data pages and btnode pages.  The dirty flag
+ * This function is for both data pages and btnode pages.  The dirty flag
  * should be treated by caller.  The page must not be under i/o.
  * Both src and dst page must be locked
  */
@@ -388,7 +388,7 @@ repeat:
 }
 
 /**
- * nilfs_copy_back_pages -- copy back pages to orignal cache from shadow cache
+ * nilfs_copy_back_pages -- copy back pages to original cache from shadow cache
  * @dmap: destination page cache
  * @smap: source page cache
  *
index ab56fe4..636eaaf 100644 (file)
@@ -32,7 +32,7 @@
 struct nilfs_write_info {
        struct the_nilfs       *nilfs;
        struct bio             *bio;
-       int                     start, end; /* The region to be submitted */
+       int                     start, end; /* The region to be submitted */
        int                     rest_blocks;
        int                     max_pages;
        int                     nr_vecs;
@@ -174,7 +174,7 @@ int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags,
 }
 
 /*
- * Setup segument summary
+ * Setup segment summary
  */
 void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf)
 {
@@ -470,8 +470,8 @@ static int nilfs_segbuf_submit_bh(struct nilfs_segment_buffer *segbuf,
  *
  * %-ENOMEM - Insufficient memory available.
  */
-int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
-                      struct the_nilfs *nilfs)
+static int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
+                             struct the_nilfs *nilfs)
 {
        struct nilfs_write_info wi;
        struct buffer_head *bh;
@@ -514,7 +514,7 @@ int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
  *
  * %-EIO - I/O error
  */
-int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf)
+static int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf)
 {
        int err = 0;
 
index ada2f1b..69576a9 100644 (file)
@@ -141,7 +141,7 @@ int nilfs_init_transaction_cache(void)
 }
 
 /**
- * nilfs_detroy_transaction_cache - destroy the cache for transaction info
+ * nilfs_destroy_transaction_cache - destroy the cache for transaction info
  *
  * nilfs_destroy_transaction_cache() frees the slab cache for the struct
  * nilfs_transaction_info.
@@ -201,7 +201,7 @@ static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti)
  * This function allocates a nilfs_transaction_info struct to keep context
  * information on it.  It is initialized and hooked onto the current task in
  * the outermost call.  If a pre-allocated struct is given to @ti, it is used
- * instead; othewise a new struct is assigned from a slab.
+ * instead; otherwise a new struct is assigned from a slab.
  *
  * When @vacancy_check flag is set, this function will check the amount of
  * free space, and will wait for the GC to reclaim disk space if low capacity.
@@ -2214,7 +2214,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
 }
 
 /**
- * nilfs_secgtor_start_timer - set timer of background write
+ * nilfs_segctor_start_timer - set timer of background write
  * @sci: nilfs_sc_info
  *
  * If the timer has already been set, it ignores the new request.
@@ -2854,7 +2854,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
  * @sbi: nilfs_sb_info
  *
  * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info,
- * initilizes it, and starts the segment constructor.
+ * initializes it, and starts the segment constructor.
  *
  * Return Value: On success, 0 is returned. On error, one of the following
  * negative error code is returned.
index 3155e0c..82dfd6a 100644 (file)
@@ -30,7 +30,7 @@
 #include "sb.h"
 
 /**
- * struct nilfs_recovery_info - Recovery infomation
+ * struct nilfs_recovery_info - Recovery information
  * @ri_need_recovery: Recovery status
  * @ri_super_root: Block number of the last super root
  * @ri_ri_cno: Number of the last checkpoint
@@ -71,7 +71,7 @@ struct nilfs_recovery_info {
  */
 struct nilfs_cstage {
        int                     scnt;
-       unsigned                flags;
+       unsigned                flags;
        struct nilfs_inode_info *dirty_file_ptr;
        struct nilfs_inode_info *gc_inode_ptr;
 };
index b6c36d0..3c6cc60 100644 (file)
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  * Written by Koji Sato <koji@osrg.net>.
- * Rivised by Ryusuke Konishi <ryusuke@osrg.net>.
+ * Revised by Ryusuke Konishi <ryusuke@osrg.net>.
  */
 
 #include <linux/kernel.h>
index 92579cc..0cdbc5e 100644 (file)
@@ -436,7 +436,7 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
        /*
         * Compute the overhead
         *
-        * When distributing meta data blocks outside semgent structure,
+        * When distributing meta data blocks outside segment structure,
         * We must count them as the overhead.
         */
        overhead = 0;
@@ -866,7 +866,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
        if ((*flags & MS_RDONLY) &&
            sbi->s_snapshot_cno != old_opts.snapshot_cno) {
                printk(KERN_WARNING "NILFS (device %s): couldn't "
-                      "remount to a different snapshot. \n",
+                      "remount to a different snapshot.\n",
                       sb->s_id);
                err = -EINVAL;
                goto restore_opts;
index 92733d5..33871f7 100644 (file)
@@ -386,7 +386,7 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
 
        nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
        if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
-               printk(KERN_ERR "NILFS: too short segment. \n");
+               printk(KERN_ERR "NILFS: too short segment.\n");
                return -EINVAL;
        }
 
index 111334f..4f98148 100644 (file)
@@ -36,6 +36,8 @@ struct i2c_algo_bit_data {
        void (*setscl) (void *data, int state);
        int  (*getsda) (void *data);
        int  (*getscl) (void *data);
+       int  (*pre_xfer)  (struct i2c_adapter *);
+       void (*post_xfer) (struct i2c_adapter *);
 
        /* local settings */
        int udelay;             /* half clock cycle time in us,
diff --git a/include/linux/i2c-xiic.h b/include/linux/i2c-xiic.h
new file mode 100644 (file)
index 0000000..4f9f225
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * i2c-xiic.h
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * Xilinx IIC
+ */
+
+#ifndef _LINUX_I2C_XIIC_H
+#define _LINUX_I2C_XIIC_H
+
+/**
+ * struct xiic_i2c_platform_data - Platform data of the Xilinx I2C driver
+ * @num_devices:       Number of devices that shall be added when the driver
+ *                     is probed.
+ * @devices:           The actuall devices to add.
+ *
+ * This purpose of this platform data struct is to be able to provide a number
+ * of devices that should be added to the I2C bus. The reason is that sometimes
+ * the I2C board info is not enough, a new PCI board can for instance be
+ * plugged into a standard PC, and the bus number might be unknown at
+ * early init time.
+ */
+struct xiic_i2c_platform_data {
+       u8                              num_devices;
+       struct i2c_board_info const     *devices;
+};
+
+#endif /* _LINUX_I2C_XIIC_H */
index dc24eff..7ed2251 100644 (file)
@@ -58,10 +58,10 @@ struct input_absinfo {
 
 #define EVIOCGVERSION          _IOR('E', 0x01, int)                    /* get driver version */
 #define EVIOCGID               _IOR('E', 0x02, struct input_id)        /* get device ID */
-#define EVIOCGREP              _IOR('E', 0x03, int[2])                 /* get repeat settings */
-#define EVIOCSREP              _IOW('E', 0x03, int[2])                 /* set repeat settings */
-#define EVIOCGKEYCODE          _IOR('E', 0x04, int[2])                 /* get keycode */
-#define EVIOCSKEYCODE          _IOW('E', 0x04, int[2])                 /* set keycode */
+#define EVIOCGREP              _IOR('E', 0x03, unsigned int[2])        /* get repeat settings */
+#define EVIOCSREP              _IOW('E', 0x03, unsigned int[2])        /* set repeat settings */
+#define EVIOCGKEYCODE          _IOR('E', 0x04, unsigned int[2])        /* get keycode */
+#define EVIOCSKEYCODE          _IOW('E', 0x04, unsigned int[2])        /* set keycode */
 
 #define EVIOCGNAME(len)                _IOC(_IOC_READ, 'E', 0x06, len)         /* get device name */
 #define EVIOCGPHYS(len)                _IOC(_IOC_READ, 'E', 0x07, len)         /* get physical location */
@@ -1142,8 +1142,10 @@ struct input_dev {
        unsigned int keycodemax;
        unsigned int keycodesize;
        void *keycode;
-       int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
-       int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);
+       int (*setkeycode)(struct input_dev *dev,
+                         unsigned int scancode, unsigned int keycode);
+       int (*getkeycode)(struct input_dev *dev,
+                         unsigned int scancode, unsigned int *keycode);
 
        struct ff_device *ff;
 
@@ -1415,8 +1417,10 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
        dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
 }
 
-int input_get_keycode(struct input_dev *dev, int scancode, int *keycode);
-int input_set_keycode(struct input_dev *dev, int scancode, int keycode);
+int input_get_keycode(struct input_dev *dev,
+                     unsigned int scancode, unsigned int *keycode);
+int input_set_keycode(struct input_dev *dev,
+                     unsigned int scancode, unsigned int keycode);
 
 extern struct class input_class;
 
index 51948eb..b4ae570 100644 (file)
@@ -12,7 +12,7 @@ enum ads7846_filter {
 };
 
 struct ads7846_platform_data {
-       u16     model;                  /* 7843, 7845, 7846. */
+       u16     model;                  /* 7843, 7845, 7846, 7873. */
        u16     vref_delay_usecs;       /* 0 for external vref; etc */
        u16     vref_mv;                /* external vref value, milliVolts */
        bool    keep_vref_on;           /* set to keep vref on for differential
@@ -53,5 +53,6 @@ struct ads7846_platform_data {
        int     (*filter)       (void *filter_data, int data_idx, int *val);
        void    (*filter_cleanup)(void *filter_data);
        void    (*wait_for_sync)(void);
+       bool    wakeup;
 };
 
index f508c65..40d1709 100644 (file)
@@ -98,6 +98,7 @@ struct virtio_device {
        void *priv;
 };
 
+#define dev_to_virtio(dev) container_of(dev, struct virtio_device, dev)
 int register_virtio_device(struct virtio_device *dev);
 void unregister_virtio_device(struct virtio_device *dev);
 
index 3322750..5cf1176 100644 (file)
@@ -5,4 +5,16 @@
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 
+/* The feature bitmap for virtio 9P */
+
+/* The mount point is specified in a config variable */
+#define VIRTIO_9P_MOUNT_TAG 0
+
+struct virtio_9p_config {
+       /* length of the tag name */
+       __u16 tag_len;
+       /* non-NULL terminated tag name */
+       __u8 tag[0];
+} __attribute__((packed));
+
 #endif /* _LINUX_VIRTIO_9P_H */
index 52e1fff..f076dfa 100644 (file)
 /** enum p9_proto_versions - 9P protocol versions
  * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u
  * @p9_proto_2000u: 9P2000.u extension
- * @p9_proto_2010L: 9P2010.L extension
+ * @p9_proto_2000L: 9P2000.L extension
  */
 
 enum p9_proto_versions{
        p9_proto_legacy = 0,
        p9_proto_2000u = 1,
-       p9_proto_2010L = 2,
+       p9_proto_2000L = 2,
 };
 
 
index bde9f3d..e3e5bf4 100644 (file)
@@ -60,7 +60,7 @@ static const match_table_t tokens = {
 
 inline int p9_is_proto_dotl(struct p9_client *clnt)
 {
-       return (clnt->proto_version == p9_proto_2010L);
+       return (clnt->proto_version == p9_proto_2000L);
 }
 EXPORT_SYMBOL(p9_is_proto_dotl);
 
@@ -80,9 +80,9 @@ static unsigned char get_protocol_version(const substring_t *name)
        } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) {
                version = p9_proto_2000u;
                P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
-       } else if (!strncmp("9p2010.L", name->from, name->to-name->from)) {
-               version = p9_proto_2010L;
-               P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2010.L\n");
+       } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) {
+               version = p9_proto_2000L;
+               P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
        } else {
                P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ",
                                                        name->from);
@@ -672,9 +672,9 @@ int p9_client_version(struct p9_client *c)
                                                c->msize, c->proto_version);
 
        switch (c->proto_version) {
-       case p9_proto_2010L:
+       case p9_proto_2000L:
                req = p9_client_rpc(c, P9_TVERSION, "ds",
-                                       c->msize, "9P2010.L");
+                                       c->msize, "9P2000.L");
                break;
        case p9_proto_2000u:
                req = p9_client_rpc(c, P9_TVERSION, "ds",
@@ -700,8 +700,8 @@ int p9_client_version(struct p9_client *c)
        }
 
        P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
-       if (!strncmp(version, "9P2010.L", 8))
-               c->proto_version = p9_proto_2010L;
+       if (!strncmp(version, "9P2000.L", 8))
+               c->proto_version = p9_proto_2000L;
        else if (!strncmp(version, "9P2000.u", 8))
                c->proto_version = p9_proto_2000u;
        else if (!strncmp(version, "9P2000", 6))
index 0aaed48..afde1a8 100644 (file)
@@ -78,6 +78,12 @@ struct virtio_chan {
        /* Scatterlist: can be too big for stack. */
        struct scatterlist sg[VIRTQUEUE_NUM];
 
+       int tag_len;
+       /*
+        * tag name to identify a mount Non-null terminated
+        */
+       char *tag;
+
        struct list_head chan_list;
 };
 
@@ -214,6 +220,20 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
        return 0;
 }
 
+static ssize_t p9_mount_tag_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct virtio_chan *chan;
+       struct virtio_device *vdev;
+
+       vdev = dev_to_virtio(dev);
+       chan = vdev->priv;
+
+       return snprintf(buf, chan->tag_len + 1, "%s", chan->tag);
+}
+
+static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL);
+
 /**
  * p9_virtio_probe - probe for existence of 9P virtio channels
  * @vdev: virtio device to probe
@@ -224,6 +244,8 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
 
 static int p9_virtio_probe(struct virtio_device *vdev)
 {
+       __u16 tag_len;
+       char *tag;
        int err;
        struct virtio_chan *chan;
 
@@ -248,6 +270,28 @@ static int p9_virtio_probe(struct virtio_device *vdev)
        sg_init_table(chan->sg, VIRTQUEUE_NUM);
 
        chan->inuse = false;
+       if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
+               vdev->config->get(vdev,
+                               offsetof(struct virtio_9p_config, tag_len),
+                               &tag_len, sizeof(tag_len));
+       } else {
+               err = -EINVAL;
+               goto out_free_vq;
+       }
+       tag = kmalloc(tag_len, GFP_KERNEL);
+       if (!tag) {
+               err = -ENOMEM;
+               goto out_free_vq;
+       }
+       vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag),
+                       tag, tag_len);
+       chan->tag = tag;
+       chan->tag_len = tag_len;
+       err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
+       if (err) {
+               kfree(tag);
+               goto out_free_vq;
+       }
        mutex_lock(&virtio_9p_lock);
        list_add_tail(&chan->chan_list, &virtio_chan_list);
        mutex_unlock(&virtio_9p_lock);
@@ -284,7 +328,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
 
        mutex_lock(&virtio_9p_lock);
        list_for_each_entry(chan, &virtio_chan_list, chan_list) {
-               if (!strcmp(devname, dev_name(&chan->vdev->dev))) {
+               if (!strncmp(devname, chan->tag, chan->tag_len)) {
                        if (!chan->inuse) {
                                chan->inuse = true;
                                found = 1;
@@ -323,6 +367,8 @@ static void p9_virtio_remove(struct virtio_device *vdev)
        mutex_lock(&virtio_9p_lock);
        list_del(&chan->chan_list);
        mutex_unlock(&virtio_9p_lock);
+       sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
+       kfree(chan->tag);
        kfree(chan);
 
 }
@@ -332,13 +378,19 @@ static struct virtio_device_id id_table[] = {
        { 0 },
 };
 
+static unsigned int features[] = {
+       VIRTIO_9P_MOUNT_TAG,
+};
+
 /* The standard "struct lguest_driver": */
 static struct virtio_driver p9_virtio_drv = {
-       .driver.name =  KBUILD_MODNAME,
-       .driver.owner = THIS_MODULE,
-       .id_table =     id_table,
-       .probe =        p9_virtio_probe,
-       .remove =       p9_virtio_remove,
+       .feature_table  = features,
+       .feature_table_size = ARRAY_SIZE(features),
+       .driver.name    = KBUILD_MODNAME,
+       .driver.owner   = THIS_MODULE,
+       .id_table       = id_table,
+       .probe          = p9_virtio_probe,
+       .remove         = p9_virtio_remove,
 };
 
 static struct p9_trans_module p9_virtio_trans = {