Commit 664a393a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'input-for-v5.19-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:

 - a new driver for the Azoteq IQS7222A/B/C capacitive touch controller

 - a new driver for Raspberry Pi Sense HAT joystick

 - sun4i-lradc-keys gained support of R329 and D1 variants, plus it can
   be now used as a wakeup source

 - pm8941-pwrkey can now properly handle PON GEN3 variants; the driver
   also implements software debouncing and has a workaround for missing
   key press events

 - assorted driver fixes and cleanups

* tag 'input-for-v5.19-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (29 commits)
  Input: stmfts - do not leave device disabled in stmfts_input_open
  Input: gpio-keys - cancel delayed work only in case of GPIO
  Input: cypress_ps2 - fix typo in comment
  Input: vmmouse - disable vmmouse before entering suspend mode
  dt-bindings: google,cros-ec-keyb: Fixup bad compatible match
  Input: cros-ec-keyb - allow skipping keyboard registration
  dt-bindings: google,cros-ec-keyb: Introduce switches only compatible
  Input: psmouse-smbus - avoid flush_scheduled_work() usage
  Input: bcm-keypad - remove unneeded NULL check before clk_disable_unprepare
  Input: sparcspkr - fix refcount leak in bbc_beep_probe
  Input: sun4i-lradc-keys - add support for R329 and D1
  Input: sun4i-lradc-keys - add optional clock/reset support
  dt-bindings: input: sun4i-lradc-keys: Add R329 and D1 compatibles
  Input: sun4i-lradc-keys - add wakeup support
  Input: pm8941-pwrkey - simulate missed key press events
  Input: pm8941-pwrkey - add software key press debouncing support
  Input: pm8941-pwrkey - add support for PON GEN3 base addresses
  Input: pm8941-pwrkey - fix error message
  Input: synaptics-rmi4 - remove unnecessary flush_workqueue()
  Input: ep93xx_keypad - use devm_platform_ioremap_resource() helper
  ...
parents 47f15561 1e90e262
...@@ -18,10 +18,20 @@ properties: ...@@ -18,10 +18,20 @@ properties:
- items: - items:
- const: allwinner,sun50i-a64-lradc - const: allwinner,sun50i-a64-lradc
- const: allwinner,sun8i-a83t-r-lradc - const: allwinner,sun8i-a83t-r-lradc
- const: allwinner,sun50i-r329-lradc
- items:
- const: allwinner,sun20i-d1-lradc
- const: allwinner,sun50i-r329-lradc
reg: reg:
maxItems: 1 maxItems: 1
clocks:
maxItems: 1
resets:
maxItems: 1
interrupts: interrupts:
maxItems: 1 maxItems: 1
...@@ -68,6 +78,18 @@ required: ...@@ -68,6 +78,18 @@ required:
- interrupts - interrupts
- vref-supply - vref-supply
if:
properties:
compatible:
contains:
enum:
- allwinner,sun50i-r329-lradc
then:
required:
- clocks
- resets
additionalProperties: false additionalProperties: false
examples: examples:
......
This diff is collapsed.
...@@ -15,14 +15,16 @@ description: | ...@@ -15,14 +15,16 @@ description: |
Google's ChromeOS EC Keyboard is a simple matrix keyboard Google's ChromeOS EC Keyboard is a simple matrix keyboard
implemented on a separate EC (Embedded Controller) device. It provides implemented on a separate EC (Embedded Controller) device. It provides
a message for reading key scans from the EC. These are then converted a message for reading key scans from the EC. These are then converted
into keycodes for processing by the kernel. into keycodes for processing by the kernel. This device also supports
switches/buttons like power and volume buttons.
allOf:
- $ref: "/schemas/input/matrix-keymap.yaml#"
properties: properties:
compatible: compatible:
const: google,cros-ec-keyb oneOf:
- description: ChromeOS EC with only buttons/switches
const: google,cros-ec-keyb-switches
- description: ChromeOS EC with keyboard and possibly buttons/switches
const: google,cros-ec-keyb
google,needs-ghost-filter: google,needs-ghost-filter:
description: description:
...@@ -42,15 +44,31 @@ properties: ...@@ -42,15 +44,31 @@ properties:
where the lower 16 bits are reserved. This property is specified only where the lower 16 bits are reserved. This property is specified only
when the keyboard has a custom design for the top row keys. when the keyboard has a custom design for the top row keys.
dependencies:
function-row-phsymap: [ 'linux,keymap' ]
google,needs-ghost-filter: [ 'linux,keymap' ]
required: required:
- compatible - compatible
if:
properties:
compatible:
contains:
const: google,cros-ec-keyb
then:
$ref: "/schemas/input/matrix-keymap.yaml#"
required:
- keypad,num-rows
- keypad,num-columns
- linux,keymap
unevaluatedProperties: false unevaluatedProperties: false
examples: examples:
- | - |
#include <dt-bindings/input/input.h> #include <dt-bindings/input/input.h>
cros-ec-keyb { keyboard-controller {
compatible = "google,cros-ec-keyb"; compatible = "google,cros-ec-keyb";
keypad,num-rows = <8>; keypad,num-rows = <8>;
keypad,num-columns = <13>; keypad,num-columns = <13>;
...@@ -114,3 +132,9 @@ examples: ...@@ -114,3 +132,9 @@ examples:
/* UP LEFT */ /* UP LEFT */
0x070b0067 0x070c0069>; 0x070b0067 0x070c0069>;
}; };
- |
/* No matrix keyboard, just buttons/switches */
keyboard-controller {
compatible = "google,cros-ec-keyb-switches";
};
...
...@@ -1793,8 +1793,6 @@ EXPORT_SYMBOL(input_reset_device); ...@@ -1793,8 +1793,6 @@ EXPORT_SYMBOL(input_reset_device);
static int input_inhibit_device(struct input_dev *dev) static int input_inhibit_device(struct input_dev *dev)
{ {
int ret = 0;
mutex_lock(&dev->mutex); mutex_lock(&dev->mutex);
if (dev->inhibited) if (dev->inhibited)
...@@ -1816,7 +1814,7 @@ static int input_inhibit_device(struct input_dev *dev) ...@@ -1816,7 +1814,7 @@ static int input_inhibit_device(struct input_dev *dev)
out: out:
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
return ret; return 0;
} }
static int input_uninhibit_device(struct input_dev *dev) static int input_uninhibit_device(struct input_dev *dev)
......
...@@ -399,4 +399,15 @@ config JOYSTICK_N64 ...@@ -399,4 +399,15 @@ config JOYSTICK_N64
Say Y here if you want enable support for the four Say Y here if you want enable support for the four
built-in controller ports on the Nintendo 64 console. built-in controller ports on the Nintendo 64 console.
config JOYSTICK_SENSEHAT
tristate "Raspberry Pi Sense HAT joystick"
depends on INPUT && I2C
select MFD_SIMPLE_MFD_I2C
help
Say Y here if you want to enable the driver for the
the Raspberry Pi Sense HAT.
To compile this driver as a module, choose M here: the
module will be called sensehat_joystick.
endif endif
...@@ -28,6 +28,7 @@ obj-$(CONFIG_JOYSTICK_N64) += n64joy.o ...@@ -28,6 +28,7 @@ obj-$(CONFIG_JOYSTICK_N64) += n64joy.o
obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o
obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o
obj-$(CONFIG_JOYSTICK_QWIIC) += qwiic-joystick.o obj-$(CONFIG_JOYSTICK_QWIIC) += qwiic-joystick.o
obj-$(CONFIG_JOYSTICK_SENSEHAT) += sensehat-joystick.o
obj-$(CONFIG_JOYSTICK_SIDEWINDER) += sidewinder.o obj-$(CONFIG_JOYSTICK_SIDEWINDER) += sidewinder.o
obj-$(CONFIG_JOYSTICK_SPACEBALL) += spaceball.o obj-$(CONFIG_JOYSTICK_SPACEBALL) += spaceball.o
obj-$(CONFIG_JOYSTICK_SPACEORB) += spaceorb.o obj-$(CONFIG_JOYSTICK_SPACEORB) += spaceorb.o
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Raspberry Pi Sense HAT joystick driver
* http://raspberrypi.org
*
* Copyright (C) 2015 Raspberry Pi
* Copyright (C) 2021 Charles Mirabile, Mwesigwa Guma, Joel Savitz
*
* Original Author: Serge Schneider
* Revised for upstream Linux by: Charles Mirabile, Mwesigwa Guma, Joel Savitz
*/
#include <linux/module.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/property.h>
#define JOYSTICK_SMB_REG 0xf2
struct sensehat_joystick {
struct platform_device *pdev;
struct input_dev *keys_dev;
unsigned long prev_states;
struct regmap *regmap;
};
static const unsigned int keymap[] = {
BTN_DPAD_DOWN, BTN_DPAD_RIGHT, BTN_DPAD_UP, BTN_SELECT, BTN_DPAD_LEFT,
};
static irqreturn_t sensehat_joystick_report(int irq, void *cookie)
{
struct sensehat_joystick *sensehat_joystick = cookie;
unsigned long curr_states, changes;
unsigned int keys;
int error;
int i;
error = regmap_read(sensehat_joystick->regmap, JOYSTICK_SMB_REG, &keys);
if (error < 0) {
dev_err(&sensehat_joystick->pdev->dev,
"Failed to read joystick state: %d", error);
return IRQ_NONE;
}
curr_states = keys;
bitmap_xor(&changes, &curr_states, &sensehat_joystick->prev_states,
ARRAY_SIZE(keymap));
for_each_set_bit(i, &changes, ARRAY_SIZE(keymap))
input_report_key(sensehat_joystick->keys_dev, keymap[i],
curr_states & BIT(i));
input_sync(sensehat_joystick->keys_dev);
sensehat_joystick->prev_states = keys;
return IRQ_HANDLED;
}
static int sensehat_joystick_probe(struct platform_device *pdev)
{
struct sensehat_joystick *sensehat_joystick;
int error, i, irq;
sensehat_joystick = devm_kzalloc(&pdev->dev, sizeof(*sensehat_joystick),
GFP_KERNEL);
if (!sensehat_joystick)
return -ENOMEM;
sensehat_joystick->pdev = pdev;
sensehat_joystick->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!sensehat_joystick->regmap) {
dev_err(&pdev->dev, "unable to get sensehat regmap");
return -ENODEV;
}
sensehat_joystick->keys_dev = devm_input_allocate_device(&pdev->dev);
if (!sensehat_joystick->keys_dev) {
dev_err(&pdev->dev, "Could not allocate input device");
return -ENOMEM;
}
sensehat_joystick->keys_dev->name = "Raspberry Pi Sense HAT Joystick";
sensehat_joystick->keys_dev->phys = "sensehat-joystick/input0";
sensehat_joystick->keys_dev->id.bustype = BUS_I2C;
__set_bit(EV_KEY, sensehat_joystick->keys_dev->evbit);
__set_bit(EV_REP, sensehat_joystick->keys_dev->evbit);
for (i = 0; i < ARRAY_SIZE(keymap); i++)
__set_bit(keymap[i], sensehat_joystick->keys_dev->keybit);
error = input_register_device(sensehat_joystick->keys_dev);
if (error) {
dev_err(&pdev->dev, "Could not register input device");
return error;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "Could not retrieve interrupt request");
return irq;
}
error = devm_request_threaded_irq(&pdev->dev, irq,
NULL, sensehat_joystick_report,
IRQF_ONESHOT, "keys",
sensehat_joystick);
if (error) {
dev_err(&pdev->dev, "IRQ request failed");
return error;
}
return 0;
}
static const struct of_device_id sensehat_joystick_device_id[] = {
{ .compatible = "raspberrypi,sensehat-joystick" },
{},
};
MODULE_DEVICE_TABLE(of, sensehat_joystick_device_id);
static struct platform_driver sensehat_joystick_driver = {
.probe = sensehat_joystick_probe,
.driver = {
.name = "sensehat-joystick",
.of_match_table = sensehat_joystick_device_id,
},
};
module_platform_driver(sensehat_joystick_driver);
MODULE_DESCRIPTION("Raspberry Pi Sense HAT joystick driver");
MODULE_AUTHOR("Charles Mirabile <cmirabil@redhat.com>");
MODULE_AUTHOR("Serge Schneider <serge@raspberrypi.org>");
MODULE_LICENSE("GPL");
...@@ -183,8 +183,7 @@ static void bcm_kp_stop(const struct bcm_kp *kp) ...@@ -183,8 +183,7 @@ static void bcm_kp_stop(const struct bcm_kp *kp)
writel(0xFFFFFFFF, kp->base + KPICR0_OFFSET); writel(0xFFFFFFFF, kp->base + KPICR0_OFFSET);
writel(0xFFFFFFFF, kp->base + KPICR1_OFFSET); writel(0xFFFFFFFF, kp->base + KPICR1_OFFSET);
if (kp->clk) clk_disable_unprepare(kp->clk);
clk_disable_unprepare(kp->clk);
} }
static int bcm_kp_open(struct input_dev *dev) static int bcm_kp_open(struct input_dev *dev)
......
...@@ -95,8 +95,7 @@ static int clps711x_keypad_probe(struct platform_device *pdev) ...@@ -95,8 +95,7 @@ static int clps711x_keypad_probe(struct platform_device *pdev)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
priv->syscon = priv->syscon = syscon_regmap_lookup_by_phandle(np, "syscon");
syscon_regmap_lookup_by_compatible("cirrus,ep7209-syscon1");
if (IS_ERR(priv->syscon)) if (IS_ERR(priv->syscon))
return PTR_ERR(priv->syscon); return PTR_ERR(priv->syscon);
......
...@@ -435,10 +435,13 @@ static __maybe_unused int cros_ec_keyb_resume(struct device *dev) ...@@ -435,10 +435,13 @@ static __maybe_unused int cros_ec_keyb_resume(struct device *dev)
* but the ckdev->bs_idev will remain NULL when this function exits. * but the ckdev->bs_idev will remain NULL when this function exits.
* *
* @ckdev: The keyboard device * @ckdev: The keyboard device
* @expect_buttons_switches: Indicates that EC must report button and/or
* switch events
* *
* Returns 0 if no error or -error upon error. * Returns 0 if no error or -error upon error.
*/ */
static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev) static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev,
bool expect_buttons_switches)
{ {
struct cros_ec_device *ec_dev = ckdev->ec; struct cros_ec_device *ec_dev = ckdev->ec;
struct device *dev = ckdev->dev; struct device *dev = ckdev->dev;
...@@ -465,7 +468,7 @@ static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev) ...@@ -465,7 +468,7 @@ static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev)
switches = get_unaligned_le32(&event_data.switches); switches = get_unaligned_le32(&event_data.switches);
if (!buttons && !switches) if (!buttons && !switches)
return 0; return expect_buttons_switches ? -EINVAL : 0;
/* /*
* We call the non-matrix buttons/switches 'input1', if present. * We call the non-matrix buttons/switches 'input1', if present.
...@@ -516,7 +519,7 @@ static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev) ...@@ -516,7 +519,7 @@ static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev)
} }
/** /**
* cros_ec_keyb_register_bs - Register matrix keys * cros_ec_keyb_register_matrix - Register matrix keys
* *
* Handles all the bits of the keyboard driver related to matrix keys. * Handles all the bits of the keyboard driver related to matrix keys.
* *
...@@ -648,12 +651,12 @@ static const struct attribute_group cros_ec_keyb_attr_group = { ...@@ -648,12 +651,12 @@ static const struct attribute_group cros_ec_keyb_attr_group = {
.attrs = cros_ec_keyb_attrs, .attrs = cros_ec_keyb_attrs,
}; };
static int cros_ec_keyb_probe(struct platform_device *pdev) static int cros_ec_keyb_probe(struct platform_device *pdev)
{ {
struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct cros_ec_keyb *ckdev; struct cros_ec_keyb *ckdev;
bool buttons_switches_only = device_get_match_data(dev);
int err; int err;
if (!dev->of_node) if (!dev->of_node)
...@@ -667,13 +670,16 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) ...@@ -667,13 +670,16 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
ckdev->dev = dev; ckdev->dev = dev;
dev_set_drvdata(dev, ckdev); dev_set_drvdata(dev, ckdev);
err = cros_ec_keyb_register_matrix(ckdev); if (!buttons_switches_only) {
if (err) { err = cros_ec_keyb_register_matrix(ckdev);
dev_err(dev, "cannot register matrix inputs: %d\n", err); if (err) {
return err; dev_err(dev, "cannot register matrix inputs: %d\n",
err);
return err;
}
} }
err = cros_ec_keyb_register_bs(ckdev); err = cros_ec_keyb_register_bs(ckdev, buttons_switches_only);
if (err) { if (err) {
dev_err(dev, "cannot register non-matrix inputs: %d\n", err); dev_err(dev, "cannot register non-matrix inputs: %d\n", err);
return err; return err;
...@@ -681,7 +687,7 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) ...@@ -681,7 +687,7 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
err = devm_device_add_group(dev, &cros_ec_keyb_attr_group); err = devm_device_add_group(dev, &cros_ec_keyb_attr_group);
if (err) { if (err) {
dev_err(dev, "failed to create attributes. err=%d\n", err); dev_err(dev, "failed to create attributes: %d\n", err);
return err; return err;
} }
...@@ -710,7 +716,8 @@ static int cros_ec_keyb_remove(struct platform_device *pdev) ...@@ -710,7 +716,8 @@ static int cros_ec_keyb_remove(struct platform_device *pdev)
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id cros_ec_keyb_of_match[] = { static const struct of_device_id cros_ec_keyb_of_match[] = {
{ .compatible = "google,cros-ec-keyb" }, { .compatible = "google,cros-ec-keyb" },
{}, { .compatible = "google,cros-ec-keyb-switches", .data = (void *)true },
{}
}; };
MODULE_DEVICE_TABLE(of, cros_ec_keyb_of_match); MODULE_DEVICE_TABLE(of, cros_ec_keyb_of_match);
#endif #endif
......
...@@ -231,7 +231,6 @@ static int ep93xx_keypad_probe(struct platform_device *pdev) ...@@ -231,7 +231,6 @@ static int ep93xx_keypad_probe(struct platform_device *pdev)
struct ep93xx_keypad *keypad; struct ep93xx_keypad *keypad;
const struct matrix_keymap_data *keymap_data; const struct matrix_keymap_data *keymap_data;
struct input_dev *input_dev; struct input_dev *input_dev;
struct resource *res;
int err; int err;
keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL); keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
...@@ -250,11 +249,7 @@ static int ep93xx_keypad_probe(struct platform_device *pdev) ...@@ -250,11 +249,7 @@ static int ep93xx_keypad_probe(struct platform_device *pdev)
if (keypad->irq < 0) if (keypad->irq < 0)
return keypad->irq; return keypad->irq;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); keypad->mmio_base = devm_platform_ioremap_resource(pdev, 0);
if (!res)
return -ENXIO;
keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(keypad->mmio_base)) if (IS_ERR(keypad->mmio_base))
return PTR_ERR(keypad->mmio_base); return PTR_ERR(keypad->mmio_base);
......
...@@ -131,7 +131,7 @@ static void gpio_keys_quiesce_key(void *data) ...@@ -131,7 +131,7 @@ static void gpio_keys_quiesce_key(void *data)
if (!bdata->gpiod) if (!bdata->gpiod)
hrtimer_cancel(&bdata->release_timer); hrtimer_cancel(&bdata->release_timer);
if (bdata->debounce_use_hrtimer) else if (bdata->debounce_use_hrtimer)
hrtimer_cancel(&bdata->debounce_timer); hrtimer_cancel(&bdata->debounce_timer);
else else
cancel_delayed_work_sync(&bdata->work); cancel_delayed_work_sync(&bdata->work);
......
...@@ -24,7 +24,6 @@ struct mt6779_keypad { ...@@ -24,7 +24,6 @@ struct mt6779_keypad {
struct regmap *regmap; struct regmap *regmap;
struct input_dev *input_dev; struct input_dev *input_dev;
struct clk *clk; struct clk *clk;
void __iomem *base;
u32 n_rows; u32 n_rows;
u32 n_cols; u32 n_cols;
DECLARE_BITMAP(keymap_state, MTK_KPD_NUM_BITS); DECLARE_BITMAP(keymap_state, MTK_KPD_NUM_BITS);
...@@ -91,6 +90,7 @@ static void mt6779_keypad_clk_disable(void *data) ...@@ -91,6 +90,7 @@ static void mt6779_keypad_clk_disable(void *data)
static int mt6779_keypad_pdrv_probe(struct platform_device *pdev) static int mt6779_keypad_pdrv_probe(struct platform_device *pdev)
{ {
struct mt6779_keypad *keypad; struct mt6779_keypad *keypad;
void __iomem *base;
int irq; int irq;
u32 debounce; u32 debounce;
bool wakeup; bool wakeup;
...@@ -100,11 +100,11 @@ static int mt6779_keypad_pdrv_probe(struct platform_device *pdev) ...@@ -100,11 +100,11 @@ static int mt6779_keypad_pdrv_probe(struct platform_device *pdev)
if (!keypad) if (!keypad)
return -ENOMEM; return -ENOMEM;
keypad->base = devm_platform_ioremap_resource(pdev, 0); base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(keypad->base)) if (IS_ERR(base))
return PTR_ERR(keypad->base); return PTR_ERR(base);
keypad->regmap = devm_regmap_init_mmio(&pdev->dev, keypad->base, keypad->regmap = devm_regmap_init_mmio(&pdev->dev, base,
&mt6779_keypad_regmap_cfg); &mt6779_keypad_regmap_cfg);
if (IS_ERR(keypad->regmap)) { if (IS_ERR(keypad->regmap)) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* there are no boards known to use channel 1. * there are no boards known to use channel 1.
*/ */
#include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/input.h> #include <linux/input.h>
...@@ -22,7 +23,10 @@ ...@@ -22,7 +23,10 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_wakeirq.h>
#include <linux/pm_wakeup.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/slab.h> #include <linux/slab.h>
#define LRADC_CTRL 0x00 #define LRADC_CTRL 0x00
...@@ -58,10 +62,12 @@ ...@@ -58,10 +62,12 @@
/* struct lradc_variant - Describe sun4i-a10-lradc-keys hardware variant /* struct lradc_variant - Describe sun4i-a10-lradc-keys hardware variant
* @divisor_numerator: The numerator of lradc Vref internally divisor * @divisor_numerator: The numerator of lradc Vref internally divisor
* @divisor_denominator: The denominator of lradc Vref internally divisor * @divisor_denominator: The denominator of lradc Vref internally divisor
* @has_clock_reset: If the binding requires a clock and reset
*/ */
struct lradc_variant { struct lradc_variant {
u8 divisor_numerator; u8 divisor_numerator;
u8 divisor_denominator; u8 divisor_denominator;
bool has_clock_reset;
}; };
static const struct lradc_variant lradc_variant_a10 = { static const struct lradc_variant lradc_variant_a10 = {
...@@ -74,6 +80,12 @@ static const struct lradc_variant r_lradc_variant_a83t = { ...@@ -74,6 +80,12 @@ static const struct lradc_variant r_lradc_variant_a83t = {
.divisor_denominator = 4 .divisor_denominator = 4
}; };
static const struct lradc_variant lradc_variant_r329 = {
.divisor_numerator = 3,
.divisor_denominator = 4,
.has_clock_reset = true,
};
struct sun4i_lradc_keymap { struct sun4i_lradc_keymap {
u32 voltage; u32 voltage;
u32 keycode; u32 keycode;
...@@ -83,6 +95,8 @@ struct sun4i_lradc_data { ...@@ -83,6 +95,8 @@ struct sun4i_lradc_data {
struct device *dev; struct device *dev;
struct input_dev *input; struct input_dev *input;
void __iomem *base; void __iomem *base;
struct clk *clk;
struct reset_control *reset;
struct regulator *vref_supply; struct regulator *vref_supply;
struct sun4i_lradc_keymap *chan0_map; struct sun4i_lradc_keymap *chan0_map;
const struct lradc_variant *variant; const struct lradc_variant *variant;
...@@ -140,6 +154,14 @@ static int sun4i_lradc_open(struct input_dev *dev) ...@@ -140,6 +154,14 @@ static int sun4i_lradc_open(struct input_dev *dev)
if (error) if (error)
return error; return error;
error = reset_control_deassert(lradc->reset);
if (error)
goto err_disable_reg;
error = clk_prepare_enable(lradc->clk);
if (error)
goto err_assert_reset;
lradc->vref = regulator_get_voltage(lradc->vref_supply) * lradc->vref = regulator_get_voltage(lradc->vref_supply) *
lradc->variant->divisor_numerator / lradc->variant->divisor_numerator /
lradc->variant->divisor_denominator; lradc->variant->divisor_denominator;
...@@ -153,6 +175,13 @@ static int sun4i_lradc_open(struct input_dev *dev) ...@@ -153,6 +175,13 @@ static int sun4i_lradc_open(struct input_dev *dev)
writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC); writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC);
return 0; return 0;
err_assert_reset:
reset_control_assert(lradc->reset);
err_disable_reg:
regulator_disable(lradc->vref_supply);
return error;
} }
static void sun4i_lradc_close(struct input_dev *dev) static void sun4i_lradc_close(struct input_dev *dev)
...@@ -164,6 +193,8 @@ static void sun4i_lradc_close(struct input_dev *dev) ...@@ -164,6 +193,8 @@ static void sun4i_lradc_close(struct input_dev *dev)
SAMPLE_RATE(2), lradc->base + LRADC_CTRL); SAMPLE_RATE(2), lradc->base + LRADC_CTRL);
writel(0, lradc->base + LRADC_INTC); writel(0, lradc->base + LRADC_INTC);
clk_disable_unprepare(lradc->clk);
reset_control_assert(lradc->reset);
regulator_disable(lradc->vref_supply); regulator_disable(lradc->vref_supply);
} }
...@@ -226,8 +257,7 @@ static int sun4i_lradc_probe(struct platform_device *pdev) ...@@ -226,8 +257,7 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
{ {
struct sun4i_lradc_data *lradc; struct sun4i_lradc_data *lradc;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int i; int error, i, irq;
int error;
lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL); lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL);
if (!lradc) if (!lradc)
...@@ -243,6 +273,16 @@ static int sun4i_lradc_probe(struct platform_device *pdev) ...@@ -243,6 +273,16 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
if (lradc->variant->has_clock_reset) {
lradc->clk = devm_clk_get(dev, NULL);
if (IS_ERR(lradc->clk))
return PTR_ERR(lradc->clk);
lradc->reset = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(lradc->reset))
return PTR_ERR(lradc->reset);
}
lradc->vref_supply = devm_regulator_get(dev, "vref"); lradc->vref_supply = devm_regulator_get(dev, "vref");
if (IS_ERR(lradc->vref_supply)) if (IS_ERR(lradc->vref_supply))
return PTR_ERR(lradc->vref_supply); return PTR_ERR(lradc->vref_supply);
...@@ -272,8 +312,11 @@ static int sun4i_lradc_probe(struct platform_device *pdev) ...@@ -272,8 +312,11 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
if (IS_ERR(lradc->base)) if (IS_ERR(lradc->base))
return PTR_ERR(lradc->base); return PTR_ERR(lradc->base);
error = devm_request_irq(dev, platform_get_irq(pdev, 0), irq = platform_get_irq(pdev, 0);
sun4i_lradc_irq, 0, if (irq < 0)
return irq;
error = devm_request_irq(dev, irq, sun4i_lradc_irq, 0,
"sun4i-a10-lradc-keys", lradc); "sun4i-a10-lradc-keys", lradc);
if (error) if (error)
return error; return error;
...@@ -282,6 +325,16 @@ static int sun4i_lradc_probe(struct platform_device *pdev) ...@@ -282,6 +325,16 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
if (error) if (error)
return error; return error;
if (device_property_read_bool(dev, "wakeup-source")) {
error = dev_pm_set_wake_irq(dev, irq);
if (error)
dev_warn(dev,
"Failed to set IRQ %d as a wake IRQ: %d\n",
irq, error);
else
device_set_wakeup_capable(dev, true);
}
return 0; return 0;
} }
...@@ -290,6 +343,8 @@ static const struct of_device_id sun4i_lradc_of_match[] = { ...@@ -290,6 +343,8 @@ static const struct of_device_id sun4i_lradc_of_match[] = {
.data = &lradc_variant_a10 }, .data = &lradc_variant_a10 },
{ .compatible = "allwinner,sun8i-a83t-r-lradc", { .compatible = "allwinner,sun8i-a83t-r-lradc",
.data = &r_lradc_variant_a83t }, .data = &r_lradc_variant_a83t },
{ .compatible = "allwinner,sun50i-r329-lradc",
.data = &lradc_variant_r329 },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match); MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match);
......
...@@ -762,6 +762,16 @@ config INPUT_IQS626A ...@@ -762,6 +762,16 @@ config INPUT_IQS626A
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called iqs626a. module will be called iqs626a.
config INPUT_IQS7222
tristate "Azoteq IQS7222A/B/C capacitive touch controller"
depends on I2C
help
Say Y to enable support for the Azoteq IQS7222A/B/C family
of capacitive touch controllers.
To compile this driver as a module, choose M here: the
module will be called iqs7222.
config INPUT_CMA3000 config INPUT_CMA3000
tristate "VTI CMA3000 Tri-axis accelerometer" tristate "VTI CMA3000 Tri-axis accelerometer"
help help
......
...@@ -44,6 +44,7 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o ...@@ -44,6 +44,7 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o
obj-$(CONFIG_INPUT_IQS269A) += iqs269a.o obj-$(CONFIG_INPUT_IQS269A) += iqs269a.o
obj-$(CONFIG_INPUT_IQS626A) += iqs626a.o obj-$(CONFIG_INPUT_IQS626A) += iqs626a.o
obj-$(CONFIG_INPUT_IQS7222) += iqs7222.o
obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
......
This diff is collapsed.
...@@ -9,9 +9,11 @@ ...@@ -9,9 +9,11 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/ktime.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reboot.h> #include <linux/reboot.h>
...@@ -19,6 +21,16 @@ ...@@ -19,6 +21,16 @@
#define PON_REV2 0x01 #define PON_REV2 0x01
#define PON_SUBTYPE 0x05
#define PON_SUBTYPE_PRIMARY 0x01
#define PON_SUBTYPE_SECONDARY 0x02
#define PON_SUBTYPE_1REG 0x03
#define PON_SUBTYPE_GEN2_PRIMARY 0x04
#define PON_SUBTYPE_GEN2_SECONDARY 0x05
#define PON_SUBTYPE_GEN3_PBS 0x08
#define PON_SUBTYPE_GEN3_HLOS 0x09
#define PON_RT_STS 0x10 #define PON_RT_STS 0x10
#define PON_KPDPWR_N_SET BIT(0) #define PON_KPDPWR_N_SET BIT(0)
#define PON_RESIN_N_SET BIT(1) #define PON_RESIN_N_SET BIT(1)
...@@ -45,6 +57,7 @@ struct pm8941_data { ...@@ -45,6 +57,7 @@ struct pm8941_data {
unsigned int status_bit; unsigned int status_bit;
bool supports_ps_hold_poff_config; bool supports_ps_hold_poff_config;
bool supports_debounce_config; bool supports_debounce_config;
bool has_pon_pbs;
const char *name; const char *name;
const char *phys; const char *phys;
}; };
...@@ -53,13 +66,18 @@ struct pm8941_pwrkey { ...@@ -53,13 +66,18 @@ struct pm8941_pwrkey {
struct device *dev; struct device *dev;
int irq; int irq;
u32 baseaddr; u32 baseaddr;
u32 pon_pbs_baseaddr;
struct regmap *regmap; struct regmap *regmap;
struct input_dev *input; struct input_dev *input;
unsigned int revision; unsigned int revision;
unsigned int subtype;
struct notifier_block reboot_notifier; struct notifier_block reboot_notifier;
u32 code; u32 code;
u32 sw_debounce_time_us;
ktime_t sw_debounce_end_time;
bool last_status;
const struct pm8941_data *data; const struct pm8941_data *data;
}; };
...@@ -129,20 +147,76 @@ static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data) ...@@ -129,20 +147,76 @@ static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
{ {
struct pm8941_pwrkey *pwrkey = _data; struct pm8941_pwrkey *pwrkey = _data;
unsigned int sts; unsigned int sts;
int error; int err;
if (pwrkey->sw_debounce_time_us) {
if (ktime_before(ktime_get(), pwrkey->sw_debounce_end_time)) {
dev_dbg(pwrkey->dev,
"ignoring key event received before debounce end %llu us\n",
pwrkey->sw_debounce_end_time);
return IRQ_HANDLED;
}
}
error = regmap_read(pwrkey->regmap, err = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_RT_STS, &sts);
pwrkey->baseaddr + PON_RT_STS, &sts); if (err)
if (error)
return IRQ_HANDLED; return IRQ_HANDLED;
input_report_key(pwrkey->input, pwrkey->code, sts &= pwrkey->data->status_bit;
sts & pwrkey->data->status_bit);
if (pwrkey->sw_debounce_time_us && !sts)
pwrkey->sw_debounce_end_time = ktime_add_us(ktime_get(),
pwrkey->sw_debounce_time_us);
/*
* Simulate a press event in case a release event occurred without a
* corresponding press event.
*/
if (!pwrkey->last_status && !sts) {
input_report_key(pwrkey->input, pwrkey->code, 1);
input_sync(pwrkey->input);
}
pwrkey->last_status = sts;
input_report_key(pwrkey->input, pwrkey->code, sts);
input_sync(pwrkey->input); input_sync(pwrkey->input);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int pm8941_pwrkey_sw_debounce_init(struct pm8941_pwrkey *pwrkey)
{
unsigned int val, addr, mask;
int error;
if (pwrkey->data->has_pon_pbs && !pwrkey->pon_pbs_baseaddr) {
dev_err(pwrkey->dev,
"PON_PBS address missing, can't read HW debounce time\n");
return 0;
}
if (pwrkey->pon_pbs_baseaddr)
addr = pwrkey->pon_pbs_baseaddr + PON_DBC_CTL;
else
addr = pwrkey->baseaddr + PON_DBC_CTL;
error = regmap_read(pwrkey->regmap, addr, &val);
if (error)
return error;
if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY)
mask = 0xf;
else
mask = 0x7;
pwrkey->sw_debounce_time_us =
2 * USEC_PER_SEC / (1 << (mask - (val & mask)));
dev_dbg(pwrkey->dev, "SW debounce time = %u us\n",
pwrkey->sw_debounce_time_us);
return 0;
}
static int __maybe_unused pm8941_pwrkey_suspend(struct device *dev) static int __maybe_unused pm8941_pwrkey_suspend(struct device *dev)
{ {
struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev); struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
...@@ -171,6 +245,8 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) ...@@ -171,6 +245,8 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
struct pm8941_pwrkey *pwrkey; struct pm8941_pwrkey *pwrkey;
bool pull_up; bool pull_up;
struct device *parent; struct device *parent;
struct device_node *regmap_node;
const __be32 *addr;
u32 req_delay; u32 req_delay;
int error; int error;
...@@ -192,8 +268,10 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) ...@@ -192,8 +268,10 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
pwrkey->data = of_device_get_match_data(&pdev->dev); pwrkey->data = of_device_get_match_data(&pdev->dev);
parent = pdev->dev.parent; parent = pdev->dev.parent;
regmap_node = pdev->dev.of_node;
pwrkey->regmap = dev_get_regmap(parent, NULL); pwrkey->regmap = dev_get_regmap(parent, NULL);
if (!pwrkey->regmap) { if (!pwrkey->regmap) {
regmap_node = parent->of_node;
/* /*
* We failed to get regmap for parent. Let's see if we are * We failed to get regmap for parent. Let's see if we are
* a child of pon node and read regmap and reg from its * a child of pon node and read regmap and reg from its
...@@ -204,15 +282,21 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) ...@@ -204,15 +282,21 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to locate regmap\n"); dev_err(&pdev->dev, "failed to locate regmap\n");
return -ENODEV; return -ENODEV;
} }
}
error = of_property_read_u32(parent->of_node, addr = of_get_address(regmap_node, 0, NULL, NULL);
"reg", &pwrkey->baseaddr); if (!addr) {
} else { dev_err(&pdev->dev, "reg property missing\n");
error = of_property_read_u32(pdev->dev.of_node, "reg", return -EINVAL;
&pwrkey->baseaddr); }
pwrkey->baseaddr = be32_to_cpup(addr);
if (pwrkey->data->has_pon_pbs) {
/* PON_PBS base address is optional */
addr = of_get_address(regmap_node, 1, NULL, NULL);
if (addr)
pwrkey->pon_pbs_baseaddr = be32_to_cpup(addr);
} }
if (error)
return error;
pwrkey->irq = platform_get_irq(pdev, 0); pwrkey->irq = platform_get_irq(pdev, 0);
if (pwrkey->irq < 0) if (pwrkey->irq < 0)
...@@ -221,7 +305,14 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) ...@@ -221,7 +305,14 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2, error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2,
&pwrkey->revision); &pwrkey->revision);
if (error) { if (error) {
dev_err(&pdev->dev, "failed to set debounce: %d\n", error); dev_err(&pdev->dev, "failed to read revision: %d\n", error);
return error;
}
error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_SUBTYPE,
&pwrkey->subtype);
if (error) {
dev_err(&pdev->dev, "failed to read subtype: %d\n", error);
return error; return error;
} }
...@@ -259,6 +350,10 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) ...@@ -259,6 +350,10 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
} }
} }
error = pm8941_pwrkey_sw_debounce_init(pwrkey);
if (error)
return error;
if (pwrkey->data->pull_up_bit) { if (pwrkey->data->pull_up_bit) {
error = regmap_update_bits(pwrkey->regmap, error = regmap_update_bits(pwrkey->regmap,
pwrkey->baseaddr + PON_PULL_CTL, pwrkey->baseaddr + PON_PULL_CTL,
...@@ -320,6 +415,7 @@ static const struct pm8941_data pwrkey_data = { ...@@ -320,6 +415,7 @@ static const struct pm8941_data pwrkey_data = {
.phys = "pm8941_pwrkey/input0", .phys = "pm8941_pwrkey/input0",
.supports_ps_hold_poff_config = true, .supports_ps_hold_poff_config = true,
.supports_debounce_config = true, .supports_debounce_config = true,
.has_pon_pbs = false,
}; };
static const struct pm8941_data resin_data = { static const struct pm8941_data resin_data = {
...@@ -329,6 +425,7 @@ static const struct pm8941_data resin_data = { ...@@ -329,6 +425,7 @@ static const struct pm8941_data resin_data = {
.phys = "pm8941_resin/input0", .phys = "pm8941_resin/input0",
.supports_ps_hold_poff_config = true, .supports_ps_hold_poff_config = true,
.supports_debounce_config = true, .supports_debounce_config = true,
.has_pon_pbs = false,
}; };
static const struct pm8941_data pon_gen3_pwrkey_data = { static const struct pm8941_data pon_gen3_pwrkey_data = {
...@@ -337,6 +434,7 @@ static const struct pm8941_data pon_gen3_pwrkey_data = { ...@@ -337,6 +434,7 @@ static const struct pm8941_data pon_gen3_pwrkey_data = {
.phys = "pmic_pwrkey/input0", .phys = "pmic_pwrkey/input0",
.supports_ps_hold_poff_config = false, .supports_ps_hold_poff_config = false,
.supports_debounce_config = false, .supports_debounce_config = false,
.has_pon_pbs = true,
}; };
static const struct pm8941_data pon_gen3_resin_data = { static const struct pm8941_data pon_gen3_resin_data = {
...@@ -345,6 +443,7 @@ static const struct pm8941_data pon_gen3_resin_data = { ...@@ -345,6 +443,7 @@ static const struct pm8941_data pon_gen3_resin_data = {
.phys = "pmic_resin/input0", .phys = "pmic_resin/input0",
.supports_ps_hold_poff_config = false, .supports_ps_hold_poff_config = false,
.supports_debounce_config = false, .supports_debounce_config = false,
.has_pon_pbs = true,
}; };
static const struct of_device_id pm8941_pwr_key_id_table[] = { static const struct of_device_id pm8941_pwr_key_id_table[] = {
......
...@@ -205,6 +205,7 @@ static int bbc_beep_probe(struct platform_device *op) ...@@ -205,6 +205,7 @@ static int bbc_beep_probe(struct platform_device *op)
info = &state->u.bbc; info = &state->u.bbc;
info->clock_freq = of_getintprop_default(dp, "clock-frequency", 0); info->clock_freq = of_getintprop_default(dp, "clock-frequency", 0);
of_node_put(dp);
if (!info->clock_freq) if (!info->clock_freq)
goto out_free; goto out_free;
......
...@@ -696,7 +696,7 @@ int cypress_init(struct psmouse *psmouse) ...@@ -696,7 +696,7 @@ int cypress_init(struct psmouse *psmouse)
err_exit: err_exit:
/* /*
* Reset Cypress Trackpad as a standard mouse. Then * Reset Cypress Trackpad as a standard mouse. Then
* let psmouse driver commmunicating with it as default PS2 mouse. * let psmouse driver communicating with it as default PS2 mouse.
*/ */
cypress_reset(psmouse); cypress_reset(psmouse);
......
...@@ -26,6 +26,8 @@ struct psmouse_smbus_dev { ...@@ -26,6 +26,8 @@ struct psmouse_smbus_dev {
static LIST_HEAD(psmouse_smbus_list); static LIST_HEAD(psmouse_smbus_list);
static DEFINE_MUTEX(psmouse_smbus_mutex); static DEFINE_MUTEX(psmouse_smbus_mutex);
static struct workqueue_struct *psmouse_smbus_wq;
static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter) static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter)
{ {
struct psmouse_smbus_dev *smbdev; struct psmouse_smbus_dev *smbdev;
...@@ -161,7 +163,7 @@ static void psmouse_smbus_schedule_remove(struct i2c_client *client) ...@@ -161,7 +163,7 @@ static void psmouse_smbus_schedule_remove(struct i2c_client *client)
INIT_WORK(&rwork->work, psmouse_smbus_remove_i2c_device); INIT_WORK(&rwork->work, psmouse_smbus_remove_i2c_device);
rwork->client = client; rwork->client = client;
schedule_work(&rwork->work); queue_work(psmouse_smbus_wq, &rwork->work);
} }
} }
...@@ -305,9 +307,14 @@ int __init psmouse_smbus_module_init(void) ...@@ -305,9 +307,14 @@ int __init psmouse_smbus_module_init(void)
{ {
int error; int error;
psmouse_smbus_wq = alloc_workqueue("psmouse-smbus", 0, 0);
if (!psmouse_smbus_wq)
return -ENOMEM;
error = bus_register_notifier(&i2c_bus_type, &psmouse_smbus_notifier); error = bus_register_notifier(&i2c_bus_type, &psmouse_smbus_notifier);
if (error) { if (error) {
pr_err("failed to register i2c bus notifier: %d\n", error); pr_err("failed to register i2c bus notifier: %d\n", error);
destroy_workqueue(psmouse_smbus_wq);
return error; return error;
} }
...@@ -317,5 +324,5 @@ int __init psmouse_smbus_module_init(void) ...@@ -317,5 +324,5 @@ int __init psmouse_smbus_module_init(void)
void psmouse_smbus_module_exit(void) void psmouse_smbus_module_exit(void)
{ {
bus_unregister_notifier(&i2c_bus_type, &psmouse_smbus_notifier); bus_unregister_notifier(&i2c_bus_type, &psmouse_smbus_notifier);
flush_scheduled_work(); destroy_workqueue(psmouse_smbus_wq);
} }
...@@ -365,6 +365,19 @@ int vmmouse_detect(struct psmouse *psmouse, bool set_properties) ...@@ -365,6 +365,19 @@ int vmmouse_detect(struct psmouse *psmouse, bool set_properties)
return 0; return 0;
} }
/**
* vmmouse_reset - Disable vmmouse and reset
*
* @psmouse: Pointer to the psmouse struct
*
* Tries to disable vmmouse mode before enter suspend.
*/
static void vmmouse_reset(struct psmouse *psmouse)
{
vmmouse_disable(psmouse);
psmouse_reset(psmouse);
}
/** /**
* vmmouse_disconnect - Take down vmmouse driver * vmmouse_disconnect - Take down vmmouse driver
* *
...@@ -472,6 +485,7 @@ int vmmouse_init(struct psmouse *psmouse) ...@@ -472,6 +485,7 @@ int vmmouse_init(struct psmouse *psmouse)
psmouse->protocol_handler = vmmouse_process_byte; psmouse->protocol_handler = vmmouse_process_byte;
psmouse->disconnect = vmmouse_disconnect; psmouse->disconnect = vmmouse_disconnect;
psmouse->reconnect = vmmouse_reconnect; psmouse->reconnect = vmmouse_reconnect;
psmouse->cleanup = vmmouse_reset;
return 0; return 0;
......
...@@ -733,7 +733,6 @@ static int rmi_f54_probe(struct rmi_function *fn) ...@@ -733,7 +733,6 @@ static int rmi_f54_probe(struct rmi_function *fn)
v4l2_device_unregister(&f54->v4l2); v4l2_device_unregister(&f54->v4l2);
remove_wq: remove_wq:
cancel_delayed_work_sync(&f54->work); cancel_delayed_work_sync(&f54->work);
flush_workqueue(f54->workqueue);
destroy_workqueue(f54->workqueue); destroy_workqueue(f54->workqueue);
return ret; return ret;
} }
......
...@@ -931,8 +931,7 @@ aiptek_query(struct aiptek *aiptek, unsigned char command, unsigned char data) ...@@ -931,8 +931,7 @@ aiptek_query(struct aiptek *aiptek, unsigned char command, unsigned char data)
} }
msleep(aiptek->curSetting.programmableDelay); msleep(aiptek->curSetting.programmableDelay);
if ((ret = if (aiptek_get_report(aiptek, 3, 2, buf, sizeof_buf) != sizeof_buf) {
aiptek_get_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) {
dev_dbg(&aiptek->intf->dev, dev_dbg(&aiptek->intf->dev,
"aiptek_query failed: returned 0x%02x 0x%02x 0x%02x\n", "aiptek_query failed: returned 0x%02x 0x%02x 0x%02x\n",
buf[0], buf[1], buf[2]); buf[0], buf[1], buf[2]);
......
...@@ -337,13 +337,15 @@ static int stmfts_input_open(struct input_dev *dev) ...@@ -337,13 +337,15 @@ static int stmfts_input_open(struct input_dev *dev)
struct stmfts_data *sdata = input_get_drvdata(dev); struct stmfts_data *sdata = input_get_drvdata(dev);
int err; int err;
err = pm_runtime_get_sync(&sdata->client->dev); err = pm_runtime_resume_and_get(&sdata->client->dev);
if (err < 0) if (err)
goto out; return err;
err = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_ON); err = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_ON);
if (err) if (err) {
goto out; pm_runtime_put_sync(&sdata->client->dev);
return err;
}
mutex_lock(&sdata->mutex); mutex_lock(&sdata->mutex);
sdata->running = true; sdata->running = true;
...@@ -366,9 +368,7 @@ static int stmfts_input_open(struct input_dev *dev) ...@@ -366,9 +368,7 @@ static int stmfts_input_open(struct input_dev *dev)
"failed to enable touchkey\n"); "failed to enable touchkey\n");
} }
out: return 0;
pm_runtime_put_noidle(&sdata->client->dev);
return err;
} }
static void stmfts_input_close(struct input_dev *dev) static void stmfts_input_close(struct input_dev *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment