Merge tag 'v3.7-rc4' into next to sync up Wacom bits
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 8 Nov 2012 16:51:52 +0000 (08:51 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 8 Nov 2012 16:51:52 +0000 (08:51 -0800)
Linux 3.7-rc4

21 files changed:
Documentation/devicetree/bindings/input/pwm-beeper.txt [new file with mode: 0644]
Documentation/devicetree/bindings/input/touchscreen/mms114.txt [new file with mode: 0644]
drivers/input/input-mt.c
drivers/input/input.c
drivers/input/joystick/as5011.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/qt2160.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/da9055_onkey.c [new file with mode: 0644]
drivers/input/misc/pwm-beeper.c
drivers/input/misc/wm831x-on.c
drivers/input/mouse/alps.c
drivers/input/serio/Kconfig
drivers/input/serio/Makefile
drivers/input/serio/arc_ps2.c [new file with mode: 0644]
drivers/input/serio/i8042-io.h
drivers/input/touchscreen/cy8ctmg110_ts.c
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/mms114.c
drivers/input/touchscreen/wm831x-ts.c

diff --git a/Documentation/devicetree/bindings/input/pwm-beeper.txt b/Documentation/devicetree/bindings/input/pwm-beeper.txt
new file mode 100644 (file)
index 0000000..be332ae
--- /dev/null
@@ -0,0 +1,7 @@
+* PWM beeper device tree bindings
+
+Registers a PWM device as beeper.
+
+Required properties:
+- compatible: should be "pwm-beeper"
+- pwms: phandle to the physical PWM device
diff --git a/Documentation/devicetree/bindings/input/touchscreen/mms114.txt b/Documentation/devicetree/bindings/input/touchscreen/mms114.txt
new file mode 100644 (file)
index 0000000..89d4c56
--- /dev/null
@@ -0,0 +1,34 @@
+* MELFAS MMS114 touchscreen controller
+
+Required properties:
+- compatible: must be "melfas,mms114"
+- reg: I2C address of the chip
+- interrupts: interrupt to which the chip is connected
+- x-size: horizontal resolution of touchscreen
+- y-size: vertical resolution of touchscreen
+
+Optional properties:
+- contact-threshold:
+- moving-threshold:
+- x-invert: invert X axis
+- y-invert: invert Y axis
+
+Example:
+
+       i2c@00000000 {
+               /* ... */
+
+               touchscreen@48 {
+                       compatible = "melfas,mms114";
+                       reg = <0x48>;
+                       interrupts = <39 0>;
+                       x-size = <720>;
+                       y-size = <1280>;
+                       contact-threshold = <10>;
+                       moving-threshold = <10>;
+                       x-invert;
+                       y-invert;
+               };
+
+               /* ... */
+       };
index c0ec7d4..bf2f30c 100644 (file)
@@ -190,7 +190,7 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
        if (!mt)
                return;
 
-       oldest = 0;
+       oldest = NULL;
        oldid = mt->trkid;
        count = 0;
 
index 53a0dde..f1be1a7 100644 (file)
@@ -534,8 +534,11 @@ EXPORT_SYMBOL(input_grab_device);
 static void __input_release_device(struct input_handle *handle)
 {
        struct input_dev *dev = handle->dev;
+       struct input_handle *grabber;
 
-       if (dev->grab == handle) {
+       grabber = rcu_dereference_protected(dev->grab,
+                                           lockdep_is_held(&dev->mutex));
+       if (grabber == handle) {
                rcu_assign_pointer(dev->grab, NULL);
                /* Make sure input_pass_event() notices that grab is gone */
                synchronize_rcu();
index c96653b..9d869e2 100644 (file)
@@ -85,7 +85,10 @@ static int as5011_i2c_write(struct i2c_client *client,
 {
        uint8_t data[2] = { aregaddr, avalue };
        struct i2c_msg msg = {
-               client->addr, I2C_M_IGNORE_NAK, 2, (uint8_t *)data
+               .addr = client->addr,
+               .flags = I2C_M_IGNORE_NAK,
+               .len = 2,
+               .buf = (uint8_t *)data
        };
        int error;
 
@@ -98,8 +101,18 @@ static int as5011_i2c_read(struct i2c_client *client,
 {
        uint8_t data[2] = { aregaddr };
        struct i2c_msg msg_set[2] = {
-               { client->addr, I2C_M_REV_DIR_ADDR, 1, (uint8_t *)data },
-               { client->addr, I2C_M_RD | I2C_M_NOSTART, 1, (uint8_t *)data }
+               {
+                       .addr = client->addr,
+                       .flags = I2C_M_REV_DIR_ADDR,
+                       .len = 1,
+                       .buf = (uint8_t *)data
+               },
+               {
+                       .addr = client->addr,
+                       .flags = I2C_M_RD | I2C_M_NOSTART,
+                       .len = 1,
+                       .buf = (uint8_t *)data
+               }
        };
        int error;
 
index de08740..4830964 100644 (file)
@@ -134,7 +134,7 @@ config KEYBOARD_QT1070
 
 config KEYBOARD_QT2160
        tristate "Atmel AT42QT2160 Touch Sensor Chip"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for Atmel AT42QT2160 Touch
          Sensor chip as a keyboard input.
index 76b7d43..031eed7 100644 (file)
@@ -206,23 +206,14 @@ static int __devinit qt2160_read(struct i2c_client *client, u8 reg)
 
 static int __devinit qt2160_write(struct i2c_client *client, u8 reg, u8 data)
 {
-       int error;
-
-       error = i2c_smbus_write_byte(client, reg);
-       if (error) {
-               dev_err(&client->dev,
-                       "couldn't send request. Returned %d\n", error);
-               return error;
-       }
+       int ret;
 
-       error = i2c_smbus_write_byte(client, data);
-       if (error) {
+       ret = i2c_smbus_write_byte_data(client, reg, data);
+       if (ret < 0)
                dev_err(&client->dev,
-                       "couldn't write data. Returned %d\n", error);
-               return error;
-       }
+                       "couldn't write data. Returned %d\n", ret);
 
-       return error;
+       return ret;
 }
 
 
index 7c0f1ec..0f959d7 100644 (file)
@@ -290,8 +290,7 @@ config INPUT_ATI_REMOTE2
          called ati_remote2.
 
 config INPUT_KEYSPAN_REMOTE
-       tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       tristate "Keyspan DMR USB remote control"
        depends on USB_ARCH_HAS_HCD
        select USB
        help
@@ -340,7 +339,6 @@ config INPUT_POWERMATE
 
 config INPUT_YEALINK
        tristate "Yealink usb-p1k voip phone"
-       depends on EXPERIMENTAL
        depends on USB_ARCH_HAS_HCD
        select USB
        help
@@ -356,7 +354,6 @@ config INPUT_YEALINK
 
 config INPUT_CM109
        tristate "C-Media CM109 USB I/O Controller"
-       depends on EXPERIMENTAL
        depends on USB_ARCH_HAS_HCD
        select USB
        help
@@ -434,7 +431,7 @@ config INPUT_PCF50633_PMU
 
 config INPUT_PCF8574
        tristate "PCF8574 Keypad input device"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          Say Y here if you want to support a keypad connected via I2C
          with a PCF8574.
@@ -444,7 +441,7 @@ config INPUT_PCF8574
 
 config INPUT_PWM_BEEPER
        tristate "PWM beeper support"
-       depends on HAVE_PWM
+       depends on HAVE_PWM || PWM
        help
          Say Y here to get support for PWM based beeper devices.
 
@@ -486,6 +483,16 @@ config INPUT_DA9052_ONKEY
          To compile this driver as a module, choose M here: the
          module will be called da9052_onkey.
 
+config INPUT_DA9055_ONKEY
+       tristate "Dialog Semiconductor DA9055 ONKEY"
+       depends on MFD_DA9055
+       help
+         Support the ONKEY of DA9055 PMICs as an input device
+         reporting power button status.
+
+         To compile this driver as a module, choose M here: the module
+         will be called da9055_onkey.
+
 config INPUT_DM355EVM
        tristate "TI DaVinci DM355 EVM Keypad and IR Remote"
        depends on MFD_DM355EVM_MSP
index 83fe6f5..23347e3 100644 (file)
@@ -23,6 +23,7 @@ obj-$(CONFIG_INPUT_CMA3000)           += cma3000_d0x.o
 obj-$(CONFIG_INPUT_CMA3000_I2C)                += cma3000_d0x_i2c.o
 obj-$(CONFIG_INPUT_COBALT_BTNS)                += cobalt_btns.o
 obj-$(CONFIG_INPUT_DA9052_ONKEY)       += da9052_onkey.o
+obj-$(CONFIG_INPUT_DA9055_ONKEY)       += da9055_onkey.o
 obj-$(CONFIG_INPUT_DM355EVM)           += dm355evm_keys.o
 obj-$(CONFIG_INPUT_GP2A)               += gp2ap002a00f.o
 obj-$(CONFIG_INPUT_GPIO_TILT_POLLED)   += gpio_tilt_polled.o
diff --git a/drivers/input/misc/da9055_onkey.c b/drivers/input/misc/da9055_onkey.c
new file mode 100644 (file)
index 0000000..10ebf15
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * ON pin driver for Dialog DA9055 PMICs
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/da9055/core.h>
+#include <linux/mfd/da9055/reg.h>
+
+struct da9055_onkey {
+       struct da9055 *da9055;
+       struct input_dev *input;
+       struct delayed_work work;
+};
+
+static void da9055_onkey_query(struct da9055_onkey *onkey)
+{
+       int key_stat;
+
+       key_stat = da9055_reg_read(onkey->da9055, DA9055_REG_STATUS_A);
+       if (key_stat < 0) {
+               dev_err(onkey->da9055->dev,
+                       "Failed to read onkey event %d\n", key_stat);
+       } else {
+               key_stat &= DA9055_NOKEY_STS;
+               /*
+                * Onkey status bit is cleared when onkey button is relased.
+                */
+               if (!key_stat) {
+                       input_report_key(onkey->input, KEY_POWER, 0);
+                       input_sync(onkey->input);
+               }
+       }
+
+       /*
+        * Interrupt is generated only when the ONKEY pin is asserted.
+        * Hence the deassertion of the pin is simulated through work queue.
+        */
+       if (key_stat)
+               schedule_delayed_work(&onkey->work, msecs_to_jiffies(10));
+
+}
+
+static void da9055_onkey_work(struct work_struct *work)
+{
+       struct da9055_onkey *onkey = container_of(work, struct da9055_onkey,
+                                                 work.work);
+
+       da9055_onkey_query(onkey);
+}
+
+static irqreturn_t da9055_onkey_irq(int irq, void *data)
+{
+       struct da9055_onkey *onkey = data;
+
+       input_report_key(onkey->input, KEY_POWER, 1);
+       input_sync(onkey->input);
+
+       da9055_onkey_query(onkey);
+
+       return IRQ_HANDLED;
+}
+
+static int __devinit da9055_onkey_probe(struct platform_device *pdev)
+{
+       struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent);
+       struct da9055_onkey *onkey;
+       struct input_dev *input_dev;
+       int irq, err;
+
+       irq = platform_get_irq_byname(pdev, "ONKEY");
+       if (irq < 0) {
+               dev_err(&pdev->dev,
+                       "Failed to get an IRQ for input device, %d\n", irq);
+               return -EINVAL;
+       }
+
+       onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
+       if (!onkey) {
+               dev_err(&pdev->dev, "Failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       input_dev = input_allocate_device();
+       if (!input_dev) {
+               dev_err(&pdev->dev, "Failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       onkey->input = input_dev;
+       onkey->da9055 = da9055;
+       input_dev->name = "da9055-onkey";
+       input_dev->phys = "da9055-onkey/input0";
+       input_dev->dev.parent = &pdev->dev;
+
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
+       __set_bit(KEY_POWER, input_dev->keybit);
+
+       INIT_DELAYED_WORK(&onkey->work, da9055_onkey_work);
+
+       irq = regmap_irq_get_virq(da9055->irq_data, irq);
+       err = request_threaded_irq(irq, NULL, da9055_onkey_irq,
+                                  IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+                                  "ONKEY", onkey);
+       if (err < 0) {
+               dev_err(&pdev->dev,
+                       "Failed to register ONKEY IRQ %d, error = %d\n",
+                       irq, err);
+               goto err_free_input;
+       }
+
+       err = input_register_device(input_dev);
+       if (err) {
+               dev_err(&pdev->dev, "Unable to register input device, %d\n",
+                       err);
+               goto err_free_irq;
+       }
+
+       platform_set_drvdata(pdev, onkey);
+
+       return 0;
+
+err_free_irq:
+       free_irq(irq, onkey);
+       cancel_delayed_work_sync(&onkey->work);
+err_free_input:
+       input_free_device(input_dev);
+
+       return err;
+}
+
+static int __devexit da9055_onkey_remove(struct platform_device *pdev)
+{
+       struct da9055_onkey *onkey = platform_get_drvdata(pdev);
+       int irq = platform_get_irq_byname(pdev, "ONKEY");
+
+       irq = regmap_irq_get_virq(onkey->da9055->irq_data, irq);
+       free_irq(irq, onkey);
+       cancel_delayed_work_sync(&onkey->work);
+       input_unregister_device(onkey->input);
+
+       return 0;
+}
+
+static struct platform_driver da9055_onkey_driver = {
+       .probe  = da9055_onkey_probe,
+       .remove = __devexit_p(da9055_onkey_remove),
+       .driver = {
+               .name   = "da9055-onkey",
+               .owner  = THIS_MODULE,
+       },
+};
+
+module_platform_driver(da9055_onkey_driver);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("Onkey driver for DA9055");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9055-onkey");
index fc84c8a..502544c 100644 (file)
@@ -75,7 +75,11 @@ static int __devinit pwm_beeper_probe(struct platform_device *pdev)
        if (!beeper)
                return -ENOMEM;
 
-       beeper->pwm = pwm_request(pwm_id, "pwm beeper");
+       beeper->pwm = pwm_get(&pdev->dev, NULL);
+       if (IS_ERR(beeper->pwm)) {
+               dev_dbg(&pdev->dev, "unable to request PWM, trying legacy API\n");
+               beeper->pwm = pwm_request(pwm_id, "pwm beeper");
+       }
 
        if (IS_ERR(beeper->pwm)) {
                error = PTR_ERR(beeper->pwm);
@@ -171,6 +175,13 @@ static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops,
 #define PWM_BEEPER_PM_OPS NULL
 #endif
 
+#ifdef CONFIG_OF
+static const struct of_device_id pwm_beeper_match[] = {
+       { .compatible = "pwm-beeper", },
+       { },
+};
+#endif
+
 static struct platform_driver pwm_beeper_driver = {
        .probe  = pwm_beeper_probe,
        .remove = __devexit_p(pwm_beeper_remove),
@@ -178,6 +189,7 @@ static struct platform_driver pwm_beeper_driver = {
                .name   = "pwm-beeper",
                .owner  = THIS_MODULE,
                .pm     = PWM_BEEPER_PM_OPS,
+               .of_match_table = of_match_ptr(pwm_beeper_match),
        },
 };
 module_platform_driver(pwm_beeper_driver);
index 6790a81..fa8b390 100644 (file)
@@ -76,7 +76,8 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
        int irq = wm831x_irq(wm831x, platform_get_irq(pdev, 0));
        int ret;
 
-       wm831x_on = kzalloc(sizeof(struct wm831x_on), GFP_KERNEL);
+       wm831x_on = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_on),
+                                GFP_KERNEL);
        if (!wm831x_on) {
                dev_err(&pdev->dev, "Can't allocate data\n");
                return -ENOMEM;
@@ -120,7 +121,6 @@ err_irq:
 err_input_dev:
        input_free_device(wm831x_on->dev);
 err:
-       kfree(wm831x_on);
        return ret;
 }
 
@@ -132,7 +132,6 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev)
        free_irq(irq, wm831x_on);
        cancel_delayed_work_sync(&wm831x_on->work);
        input_unregister_device(wm831x_on->dev);
-       kfree(wm831x_on);
 
        return 0;
 }
index cf5af1f..e229fa3 100644 (file)
@@ -767,9 +767,8 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
                      psmouse->packet[5]) & 0x80) ||
                    (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) {
                        psmouse_dbg(psmouse,
-                                   "refusing packet %x %x %x %x (suspected interleaved ps/2)\n",
-                                   psmouse->packet[3], psmouse->packet[4],
-                                   psmouse->packet[5], psmouse->packet[6]);
+                                   "refusing packet %4ph (suspected interleaved ps/2)\n",
+                                   psmouse->packet + 3);
                        return PSMOUSE_BAD_DATA;
                }
 
@@ -831,9 +830,8 @@ static void alps_flush_packet(unsigned long data)
                     psmouse->packet[4] |
                     psmouse->packet[5]) & 0x80) {
                        psmouse_dbg(psmouse,
-                                   "refusing packet %x %x %x (suspected interleaved ps/2)\n",
-                                   psmouse->packet[3], psmouse->packet[4],
-                                   psmouse->packet[5]);
+                                   "refusing packet %3ph (suspected interleaved ps/2)\n",
+                                   psmouse->packet + 3);
                } else {
                        alps_process_packet(psmouse);
                }
index 55f2c22..4a4e182 100644 (file)
@@ -234,4 +234,13 @@ config SERIO_PS2MULT
          To compile this driver as a module, choose M here: the
          module will be called ps2mult.
 
+config SERIO_ARC_PS2
+       tristate "ARC PS/2 support"
+       help
+         Say Y here if you have an ARC FPGA platform with a PS/2
+         controller in it.
+
+         To compile this driver as a module, choose M here; the module
+         will be called arc_ps2.
+
 endif
index dbbe376..4b0c8f8 100644 (file)
@@ -25,3 +25,4 @@ obj-$(CONFIG_SERIO_RAW)               += serio_raw.o
 obj-$(CONFIG_SERIO_AMS_DELTA)  += ams_delta_serio.o
 obj-$(CONFIG_SERIO_XILINX_XPS_PS2)     += xilinx_ps2.o
 obj-$(CONFIG_SERIO_ALTERA_PS2) += altera_ps2.o
+obj-$(CONFIG_SERIO_ARC_PS2)    += arc_ps2.o
diff --git a/drivers/input/serio/arc_ps2.c b/drivers/input/serio/arc_ps2.c
new file mode 100644 (file)
index 0000000..89ad763
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.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.
+ *
+ * Driver is originally developed by Pavel Sokolov <psokolov@synopsys.com>
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#define ARC_PS2_PORTS                   2
+
+#define ARC_ARC_PS2_ID                  0x0001f609
+
+#define STAT_TIMEOUT                    128
+
+#define PS2_STAT_RX_FRM_ERR             (1)
+#define PS2_STAT_RX_BUF_OVER            (1 << 1)
+#define PS2_STAT_RX_INT_EN              (1 << 2)
+#define PS2_STAT_RX_VAL                 (1 << 3)
+#define PS2_STAT_TX_ISNOT_FUL           (1 << 4)
+#define PS2_STAT_TX_INT_EN              (1 << 5)
+
+struct arc_ps2_port {
+       void __iomem *data_addr;
+       void __iomem *status_addr;
+       struct serio *io;
+};
+
+struct arc_ps2_data {
+       struct arc_ps2_port port[ARC_PS2_PORTS];
+       void __iomem *addr;
+       unsigned int frame_error;
+       unsigned int buf_overflow;
+       unsigned int total_int;
+};
+
+static void arc_ps2_check_rx(struct arc_ps2_data *arc_ps2,
+                            struct arc_ps2_port *port)
+{
+       unsigned int timeout = 1000;
+       unsigned int flag, status;
+       unsigned char data;
+
+       do {
+               status = ioread32(port->status_addr);
+               if (!(status & PS2_STAT_RX_VAL))
+                       return;
+
+               data = ioread32(port->data_addr) & 0xff;
+
+               flag = 0;
+               arc_ps2->total_int++;
+               if (status & PS2_STAT_RX_FRM_ERR) {
+                       arc_ps2->frame_error++;
+                       flag |= SERIO_PARITY;
+               } else if (status & PS2_STAT_RX_BUF_OVER) {
+                       arc_ps2->buf_overflow++;
+                       flag |= SERIO_FRAME;
+               }
+
+               serio_interrupt(port->io, data, flag);
+       } while (--timeout);
+
+       dev_err(&port->io->dev, "PS/2 hardware stuck\n");
+}
+
+static irqreturn_t arc_ps2_interrupt(int irq, void *dev)
+{
+       struct arc_ps2_data *arc_ps2 = dev;
+       int i;
+
+       for (i = 0; i < ARC_PS2_PORTS; i++)
+               arc_ps2_check_rx(arc_ps2, &arc_ps2->port[i]);
+
+       return IRQ_HANDLED;
+}
+
+static int arc_ps2_write(struct serio *io, unsigned char val)
+{
+       unsigned status;
+       struct arc_ps2_port *port = io->port_data;
+       int timeout = STAT_TIMEOUT;
+
+       do {
+               status = ioread32(port->status_addr);
+               cpu_relax();
+
+               if (status & PS2_STAT_TX_ISNOT_FUL) {
+                       iowrite32(val & 0xff, port->data_addr);
+                       return 0;
+               }
+
+       } while (--timeout);
+
+       dev_err(&io->dev, "write timeout\n");
+       return -ETIMEDOUT;
+}
+
+static int arc_ps2_open(struct serio *io)
+{
+       struct arc_ps2_port *port = io->port_data;
+
+       iowrite32(PS2_STAT_RX_INT_EN, port->status_addr);
+
+       return 0;
+}
+
+static void arc_ps2_close(struct serio *io)
+{
+       struct arc_ps2_port *port = io->port_data;
+
+       iowrite32(ioread32(port->status_addr) & ~PS2_STAT_RX_INT_EN,
+                 port->status_addr);
+}
+
+static void __iomem * __devinit arc_ps2_calc_addr(struct arc_ps2_data *arc_ps2,
+                                                 int index, bool status)
+{
+       void __iomem *addr;
+
+       addr = arc_ps2->addr + 4 + 4 * index;
+       if (status)
+               addr += ARC_PS2_PORTS * 4;
+
+       return addr;
+}
+
+static void __devinit arc_ps2_inhibit_ports(struct arc_ps2_data *arc_ps2)
+{
+       void __iomem *addr;
+       u32 val;
+       int i;
+
+       for (i = 0; i < ARC_PS2_PORTS; i++) {
+               addr = arc_ps2_calc_addr(arc_ps2, i, true);
+               val = ioread32(addr);
+               val &= ~(PS2_STAT_RX_INT_EN | PS2_STAT_TX_INT_EN);
+               iowrite32(val, addr);
+       }
+}
+
+static int __devinit arc_ps2_create_port(struct platform_device *pdev,
+                                        struct arc_ps2_data *arc_ps2,
+                                        int index)
+{
+       struct arc_ps2_port *port = &arc_ps2->port[index];
+       struct serio *io;
+
+       io = kzalloc(sizeof(struct serio), GFP_KERNEL);
+       if (!io)
+               return -ENOMEM;
+
+       io->id.type = SERIO_8042;
+       io->write = arc_ps2_write;
+       io->open = arc_ps2_open;
+       io->close = arc_ps2_close;
+       snprintf(io->name, sizeof(io->name), "ARC PS/2 port%d", index);
+       snprintf(io->phys, sizeof(io->phys), "arc/serio%d", index);
+       io->port_data = port;
+
+       port->io = io;
+
+       port->data_addr = arc_ps2_calc_addr(arc_ps2, index, false);
+       port->status_addr = arc_ps2_calc_addr(arc_ps2, index, true);
+
+       dev_dbg(&pdev->dev, "port%d is allocated (data = 0x%p, status = 0x%p)\n",
+               index, port->data_addr, port->status_addr);
+
+       serio_register_port(port->io);
+       return 0;
+}
+
+static int __devinit arc_ps2_probe(struct platform_device *pdev)
+{
+       struct arc_ps2_data *arc_ps2;
+       struct resource *res;
+       int irq;
+       int error, id, i;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "no IO memory defined\n");
+               return -EINVAL;
+       }
+
+       irq = platform_get_irq_byname(pdev, "arc_ps2_irq");
+       if (irq < 0) {
+               dev_err(&pdev->dev, "no IRQ defined\n");
+               return -EINVAL;
+       }
+
+       arc_ps2 = devm_kzalloc(&pdev->dev, sizeof(struct arc_ps2_data),
+                               GFP_KERNEL);
+       if (!arc_ps2) {
+               dev_err(&pdev->dev, "out of memory\n");
+               return -ENOMEM;
+       }
+
+       arc_ps2->addr = devm_request_and_ioremap(&pdev->dev, res);
+       if (!arc_ps2->addr)
+               return -EBUSY;
+
+       dev_info(&pdev->dev, "irq = %d, address = 0x%p, ports = %i\n",
+                irq, arc_ps2->addr, ARC_PS2_PORTS);
+
+       id = ioread32(arc_ps2->addr);
+       if (id != ARC_ARC_PS2_ID) {
+               dev_err(&pdev->dev, "device id does not match\n");
+               return -ENXIO;
+       }
+
+       arc_ps2_inhibit_ports(arc_ps2);
+
+       error = devm_request_irq(&pdev->dev, irq, arc_ps2_interrupt,
+                                0, "arc_ps2", arc_ps2);
+       if (error) {
+               dev_err(&pdev->dev, "Could not allocate IRQ\n");
+               return error;
+       }
+
+       for (i = 0; i < ARC_PS2_PORTS; i++) {
+               error = arc_ps2_create_port(pdev, arc_ps2, i);
+               if (error) {
+                       while (--i >= 0)
+                               serio_unregister_port(arc_ps2->port[i].io);
+                       return error;
+               }
+       }
+
+       platform_set_drvdata(pdev, arc_ps2);
+
+       return 0;
+}
+
+static int __devexit arc_ps2_remove(struct platform_device *pdev)
+{
+       struct arc_ps2_data *arc_ps2 = platform_get_drvdata(pdev);
+       int i;
+
+       for (i = 0; i < ARC_PS2_PORTS; i++)
+               serio_unregister_port(arc_ps2->port[i].io);
+
+       dev_dbg(&pdev->dev, "interrupt count = %i\n", arc_ps2->total_int);
+       dev_dbg(&pdev->dev, "frame error count = %i\n", arc_ps2->frame_error);
+       dev_dbg(&pdev->dev, "buffer overflow count = %i\n",
+               arc_ps2->buf_overflow);
+
+       return 0;
+}
+
+static struct platform_driver arc_ps2_driver = {
+       .driver = {
+               .name   = "arc_ps2",
+               .owner  = THIS_MODULE,
+       },
+       .probe  = arc_ps2_probe,
+       .remove = __devexit_p(arc_ps2_remove),
+};
+
+module_platform_driver(arc_ps2_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Pavel Sokolov <psokolov@synopsys.com>");
+MODULE_DESCRIPTION("ARC PS/2 Driver");
index 5d48bb6..a5eed2a 100644 (file)
@@ -76,7 +76,7 @@ static inline int i8042_platform_init(void)
        if (check_legacy_ioport(I8042_DATA_REG))
                return -ENODEV;
 #endif
-#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__)
+#if !defined(__sh__) && !defined(__alpha__)
        if (!request_region(I8042_DATA_REG, 16, "i8042"))
                return -EBUSY;
 #endif
index 464f1bf..ad6a664 100644 (file)
@@ -99,9 +99,18 @@ static int cy8ctmg110_read_regs(struct cy8ctmg110 *tsc,
        int ret;
        struct i2c_msg msg[2] = {
                /* first write slave position to i2c devices */
-               { client->addr, 0, 1, &cmd },
+               {
+                       .addr = client->addr,
+                       .len = 1,
+                       .buf = &cmd
+               },
                /* Second read data from position */
-               { client->addr, I2C_M_RD, len, data }
+               {
+                       .addr = client->addr,
+                       .flags = I2C_M_RD,
+                       .len = len,
+                       .buf = data
+               }
        };
 
        ret = i2c_transfer(client->adapter, msg, 2);
index 099d144..d9c6007 100644 (file)
@@ -491,14 +491,6 @@ static int edt_ft5x06_debugfs_mode_set(void *data, u64 mode)
 DEFINE_SIMPLE_ATTRIBUTE(debugfs_mode_fops, edt_ft5x06_debugfs_mode_get,
                        edt_ft5x06_debugfs_mode_set, "%llu\n");
 
-static int edt_ft5x06_debugfs_raw_data_open(struct inode *inode,
-                                           struct file *file)
-{
-       file->private_data = inode->i_private;
-
-       return 0;
-}
-
 static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
                                char __user *buf, size_t count, loff_t *off)
 {
@@ -579,7 +571,7 @@ out:
 
 
 static const struct file_operations debugfs_raw_data_fops = {
-       .open = edt_ft5x06_debugfs_raw_data_open,
+       .open = simple_open,
        .read = edt_ft5x06_debugfs_raw_data_read,
 };
 
index 560cf09..3426d2e 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/of.h>
 #include <linux/i2c.h>
 #include <linux/i2c/mms114.h>
 #include <linux/input/mt.h>
@@ -360,14 +361,63 @@ static void mms114_input_close(struct input_dev *dev)
        mms114_stop(data);
 }
 
+#ifdef CONFIG_OF
+static struct mms114_platform_data * __devinit mms114_parse_dt(struct device *dev)
+{
+       struct mms114_platform_data *pdata;
+       struct device_node *np = dev->of_node;
+
+       if (!np)
+               return NULL;
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata) {
+               dev_err(dev, "failed to allocate platform data\n");
+               return NULL;
+       }
+
+       if (of_property_read_u32(np, "x-size", &pdata->x_size)) {
+               dev_err(dev, "failed to get x-size property\n");
+               return NULL;
+       };
+
+       if (of_property_read_u32(np, "y-size", &pdata->y_size)) {
+               dev_err(dev, "failed to get y-size property\n");
+               return NULL;
+       };
+
+       of_property_read_u32(np, "contact-threshold",
+                               &pdata->contact_threshold);
+       of_property_read_u32(np, "moving-threshold",
+                               &pdata->moving_threshold);
+
+       if (of_find_property(np, "x-invert", NULL))
+               pdata->x_invert = true;
+       if (of_find_property(np, "y-invert", NULL))
+               pdata->y_invert = true;
+
+       return pdata;
+}
+#else
+static inline struct mms114_platform_data *mms114_parse_dt(struct device *dev)
+{
+       return NULL;
+}
+#endif
+
 static int __devinit mms114_probe(struct i2c_client *client,
                                  const struct i2c_device_id *id)
 {
+       const struct mms114_platform_data *pdata;
        struct mms114_data *data;
        struct input_dev *input_dev;
        int error;
 
-       if (!client->dev.platform_data) {
+       pdata = dev_get_platdata(&client->dev);
+       if (!pdata)
+               pdata = mms114_parse_dt(&client->dev);
+
+       if (!pdata) {
                dev_err(&client->dev, "Need platform data\n");
                return -EINVAL;
        }
@@ -389,7 +439,7 @@ static int __devinit mms114_probe(struct i2c_client *client,
 
        data->client = client;
        data->input_dev = input_dev;
-       data->pdata = client->dev.platform_data;
+       data->pdata = pdata;
 
        input_dev->name = "MELPAS MMS114 Touchscreen";
        input_dev->id.bustype = BUS_I2C;
@@ -525,11 +575,19 @@ static const struct i2c_device_id mms114_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, mms114_id);
 
+#ifdef CONFIG_OF
+static struct of_device_id __devinitdata mms114_dt_match[] = {
+       { .compatible = "melfas,mms114" },
+       { }
+};
+#endif
+
 static struct i2c_driver mms114_driver = {
        .driver = {
                .name   = "mms114",
                .owner  = THIS_MODULE,
                .pm     = &mms114_pm_ops,
+               .of_match_table = of_match_ptr(mms114_dt_match),
        },
        .probe          = mms114_probe,
        .remove         = __devexit_p(mms114_remove),
index 52abb98..c7eee56 100644 (file)
@@ -245,7 +245,8 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
        if (core_pdata)
                pdata = core_pdata->touch;
 
-       wm831x_ts = kzalloc(sizeof(struct wm831x_ts), GFP_KERNEL);
+       wm831x_ts = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ts),
+                                GFP_KERNEL);
        input_dev = input_allocate_device();
        if (!wm831x_ts || !input_dev) {
                error = -ENOMEM;
@@ -376,7 +377,6 @@ err_data_irq:
        free_irq(wm831x_ts->data_irq, wm831x_ts);
 err_alloc:
        input_free_device(input_dev);
-       kfree(wm831x_ts);
 
        return error;
 }
@@ -388,9 +388,7 @@ static __devexit int wm831x_ts_remove(struct platform_device *pdev)
        free_irq(wm831x_ts->pd_irq, wm831x_ts);
        free_irq(wm831x_ts->data_irq, wm831x_ts);
        input_unregister_device(wm831x_ts->input_dev);
-       kfree(wm831x_ts);
 
-       platform_set_drvdata(pdev, NULL);
        return 0;
 }