diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-04 15:35:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-04 15:35:08 -0700 |
commit | f5b63ac0f77ecab46796ba5d368ea5dd51834e6e (patch) | |
tree | 66788b3327afa62aa7f8fe05951945a2ee1e9e4e /drivers/input/misc | |
parent | 98f486f18d16e2214728d101ed8b6a12dce75539 (diff) | |
parent | 57961e3ba72f4a8a1aa52e978020ecc2ca03a79f (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
"First round of updates for the input subsystem.
You will get a new touchsreen driver for Cypress 4th generation
devices, a driver for a special controller implementing PS/2 protocol
in OLPC devices, and a driver for power key for SiRFprimaII PWRC.
HID and bcm5497 now support for the 2013 MacBook Air.
EVIOCGKEY and the rest of evdev ioctls now flush events of matching
type from the client's event queue so that clients can be sure any
events received after issuing EVIOCG* ioctl are new events.
And a host of cleanups and improvements in other drivers"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (87 commits)
Input: cyttsp4 - kfree xfer_buf on error path in probe()
Input: tps6507x-ts - select INPUT_POLLDEV
Input: bcm5974 - add support for the 2013 MacBook Air
HID: apple: Add support for the 2013 Macbook Air
Input: cyttsp4 - leak on error path in probe()
Input: cyttsp4 - silence NULL dereference warning
Input: cyttsp4 - silence shift wrap warning
Input: tps6507x-ts - convert to polled input device infrastructure
ARM: davinci: da850-evm: remove vref from touchscreen platform data
Input: cyttsp4 - SPI driver for Cypress TMA4XX touchscreen devices
Input: cyttsp4 - I2C driver for Cypress TMA4XX touchscreen devices
Input: cyttsp4 - add core driver for Cypress TMA4XX touchscreen devices
Input: cyttsp - I2C driver split into two modules
Input: add OLPC AP-SP driver
Input: nspire-keypad - remove redundant dev_err call in nspire_keypad_probe()
Input: tps6507x-ts - remove vref from platform data
Input: tps6507x-ts - use bool for booleans
Input: tps6507x-ts - remove bogus unreachable code
Input: samsung-keypad - let device core setup the default pin configuration
Input: wacom_i2c - implement hovering capability
...
Diffstat (limited to 'drivers/input/misc')
-rw-r--r-- | drivers/input/misc/Kconfig | 10 | ||||
-rw-r--r-- | drivers/input/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/misc/ab8500-ponkey.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/bfin_rotary.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/gpio_tilt_polled.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/ixp4xx-beeper.c | 5 | ||||
-rw-r--r-- | drivers/input/misc/m68kspkr.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/max8925_onkey.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/mc13783-pwrbutton.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/pcspkr.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/pm8xxx-vibrator.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/pmic8xxx-pwrkey.c | 4 | ||||
-rw-r--r-- | drivers/input/misc/pwm-beeper.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/rotary_encoder.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/sgi_btns.c | 7 | ||||
-rw-r--r-- | drivers/input/misc/sirfsoc-onkey.c | 165 | ||||
-rw-r--r-- | drivers/input/misc/sparcspkr.c | 14 |
17 files changed, 186 insertions, 35 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index bb698e1f9e4..0b541cdf9b8 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -637,4 +637,14 @@ config INPUT_XEN_KBDDEV_FRONTEND To compile this driver as a module, choose M here: the module will be called xen-kbdfront. +config INPUT_SIRFSOC_ONKEY + bool "CSR SiRFSoC power on/off/suspend key support" + depends on ARCH_SIRF && OF + default y + help + Say Y here if you want to support for the SiRFSoC power on/off/suspend key + in Linux, after you press the onkey, system will suspend. + + If unsure, say N. + endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index d7fc17f11d7..829de43a242 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o +obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index 2f090b46e71..f2fbdd88ed2 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c @@ -127,8 +127,6 @@ static int ab8500_ponkey_remove(struct platform_device *pdev) input_unregister_device(ponkey->idev); kfree(ponkey); - platform_set_drvdata(pdev, NULL); - return 0; } diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index a6666e142a9..cd139cb17e3 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c @@ -208,7 +208,6 @@ static int bfin_rotary_remove(struct platform_device *pdev) peripheral_free_list(per_cnt); kfree(rotary); - platform_set_drvdata(pdev, NULL); return 0; } diff --git a/drivers/input/misc/gpio_tilt_polled.c b/drivers/input/misc/gpio_tilt_polled.c index da05cca8b56..714c6836913 100644 --- a/drivers/input/misc/gpio_tilt_polled.c +++ b/drivers/input/misc/gpio_tilt_polled.c @@ -184,8 +184,6 @@ static int gpio_tilt_polled_remove(struct platform_device *pdev) struct gpio_tilt_polled_dev *tdev = platform_get_drvdata(pdev); const struct gpio_tilt_platform_data *pdata = tdev->pdata; - platform_set_drvdata(pdev, NULL); - input_unregister_polled_device(tdev->poll_dev); input_free_polled_device(tdev->poll_dev); diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index 6ab3decc86e..f34beb228d3 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c @@ -125,7 +125,7 @@ static int ixp4xx_spkr_probe(struct platform_device *dev) return 0; err_free_irq: - free_irq(IRQ_IXP4XX_TIMER2, dev); + free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id); err_free_device: input_free_device(input_dev); @@ -138,13 +138,12 @@ static int ixp4xx_spkr_remove(struct platform_device *dev) unsigned int pin = (unsigned int) input_get_drvdata(input_dev); input_unregister_device(input_dev); - platform_set_drvdata(dev, NULL); /* turn the speaker off */ disable_irq(IRQ_IXP4XX_TIMER2); ixp4xx_spkr_control(pin, 0); - free_irq(IRQ_IXP4XX_TIMER2, dev); + free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id); return 0; } diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c index b40ee4b47f4..def21dc8452 100644 --- a/drivers/input/misc/m68kspkr.c +++ b/drivers/input/misc/m68kspkr.c @@ -85,7 +85,6 @@ static int m68kspkr_remove(struct platform_device *dev) struct input_dev *input_dev = platform_get_drvdata(dev); input_unregister_device(input_dev); - platform_set_drvdata(dev, NULL); /* turn off the speaker */ m68kspkr_event(NULL, EV_SND, SND_BELL, 0); diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c index f9179b2585a..eef41cfc054 100644 --- a/drivers/input/misc/max8925_onkey.c +++ b/drivers/input/misc/max8925_onkey.c @@ -148,8 +148,6 @@ static int max8925_onkey_remove(struct platform_device *pdev) input_unregister_device(info->idev); kfree(info); - platform_set_drvdata(pdev, NULL); - return 0; } diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c index 0906ca593d5..d0277a7b157 100644 --- a/drivers/input/misc/mc13783-pwrbutton.c +++ b/drivers/input/misc/mc13783-pwrbutton.c @@ -250,7 +250,6 @@ static int mc13783_pwrbutton_remove(struct platform_device *pdev) input_unregister_device(priv->pwr); kfree(priv); - platform_set_drvdata(pdev, NULL); return 0; } diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 199db78acc4..7288b267613 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -100,7 +100,6 @@ static int pcspkr_remove(struct platform_device *dev) struct input_dev *pcspkr_dev = platform_get_drvdata(dev); input_unregister_device(pcspkr_dev); - platform_set_drvdata(dev, NULL); /* turn off the speaker */ pcspkr_event(NULL, EV_SND, SND_BELL, 0); diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c index a9da65e41c5..ec086f6f3cc 100644 --- a/drivers/input/misc/pm8xxx-vibrator.c +++ b/drivers/input/misc/pm8xxx-vibrator.c @@ -249,8 +249,6 @@ static int pm8xxx_vib_remove(struct platform_device *pdev) input_unregister_device(vib->vib_input_dev); kfree(vib); - platform_set_drvdata(pdev, NULL); - return 0; } diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index 4b811be7397..b49b738aa9c 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c @@ -175,9 +175,8 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev) return 0; free_press_irq: - free_irq(key_press_irq, NULL); + free_irq(key_press_irq, pwrkey); unreg_input_dev: - platform_set_drvdata(pdev, NULL); input_unregister_device(pwr); pwr = NULL; free_input_dev: @@ -198,7 +197,6 @@ static int pmic8xxx_pwrkey_remove(struct platform_device *pdev) free_irq(key_press_irq, pwrkey); free_irq(key_release_irq, pwrkey); input_unregister_device(pwrkey->pwr); - platform_set_drvdata(pdev, NULL); kfree(pwrkey); return 0; diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 0808868461d..a37f0c909ab 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -133,7 +133,6 @@ static int pwm_beeper_remove(struct platform_device *pdev) { struct pwm_beeper *beeper = platform_get_drvdata(pdev); - platform_set_drvdata(pdev, NULL); input_unregister_device(beeper->input); pwm_disable(beeper->pwm); diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index aff47b2c38f..5b1aff82513 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -317,8 +317,6 @@ static int rotary_encoder_remove(struct platform_device *pdev) if (!dev_get_platdata(&pdev->dev)) kfree(pdata); - platform_set_drvdata(pdev, NULL); - return 0; } diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c index ad6415ceaf5..95cf299ef9a 100644 --- a/drivers/input/misc/sgi_btns.c +++ b/drivers/input/misc/sgi_btns.c @@ -128,7 +128,7 @@ static int sgi_buttons_probe(struct platform_device *pdev) __clear_bit(KEY_RESERVED, input->keybit); bdev->poll_dev = poll_dev; - dev_set_drvdata(&pdev->dev, bdev); + platform_set_drvdata(pdev, bdev); error = input_register_polled_device(poll_dev); if (error) @@ -139,19 +139,16 @@ static int sgi_buttons_probe(struct platform_device *pdev) err_free_mem: input_free_polled_device(poll_dev); kfree(bdev); - dev_set_drvdata(&pdev->dev, NULL); return error; } static int sgi_buttons_remove(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct buttons_dev *bdev = dev_get_drvdata(dev); + struct buttons_dev *bdev = platform_get_drvdata(pdev); input_unregister_polled_device(bdev->poll_dev); input_free_polled_device(bdev->poll_dev); kfree(bdev); - dev_set_drvdata(dev, NULL); return 0; } diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c new file mode 100644 index 00000000000..0621c367049 --- /dev/null +++ b/drivers/input/misc/sirfsoc-onkey.c @@ -0,0 +1,165 @@ +/* + * Power key driver for SiRF PrimaII + * + * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/input.h> +#include <linux/rtc/sirfsoc_rtciobrg.h> +#include <linux/of.h> + +struct sirfsoc_pwrc_drvdata { + u32 pwrc_base; + struct input_dev *input; +}; + +#define PWRC_ON_KEY_BIT (1 << 0) + +#define PWRC_INT_STATUS 0xc +#define PWRC_INT_MASK 0x10 + +static irqreturn_t sirfsoc_pwrc_isr(int irq, void *dev_id) +{ + struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_id; + u32 int_status; + + int_status = sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base + + PWRC_INT_STATUS); + sirfsoc_rtc_iobrg_writel(int_status & ~PWRC_ON_KEY_BIT, + pwrcdrv->pwrc_base + PWRC_INT_STATUS); + + /* + * For a typical Linux system, we report KEY_SUSPEND to trigger apm-power.c + * to queue a SUSPEND APM event + */ + input_event(pwrcdrv->input, EV_PWR, KEY_SUSPEND, 1); + input_sync(pwrcdrv->input); + + /* + * Todo: report KEY_POWER event for Android platforms, Android PowerManager + * will handle the suspend and powerdown/hibernation + */ + + return IRQ_HANDLED; +} + +static const struct of_device_id sirfsoc_pwrc_of_match[] = { + { .compatible = "sirf,prima2-pwrc" }, + {}, +} +MODULE_DEVICE_TABLE(of, sirfsoc_pwrc_of_match); + +static int sirfsoc_pwrc_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct sirfsoc_pwrc_drvdata *pwrcdrv; + int irq; + int error; + + pwrcdrv = devm_kzalloc(&pdev->dev, sizeof(struct sirfsoc_pwrc_drvdata), + GFP_KERNEL); + if (!pwrcdrv) { + dev_info(&pdev->dev, "Not enough memory for the device data\n"); + return -ENOMEM; + } + + /* + * we can't use of_iomap because pwrc is not mapped in memory, + * the so-called base address is only offset in rtciobrg + */ + error = of_property_read_u32(np, "reg", &pwrcdrv->pwrc_base); + if (error) { + dev_err(&pdev->dev, + "unable to find base address of pwrc node in dtb\n"); + return error; + } + + pwrcdrv->input = devm_input_allocate_device(&pdev->dev); + if (!pwrcdrv->input) + return -ENOMEM; + + pwrcdrv->input->name = "sirfsoc pwrckey"; + pwrcdrv->input->phys = "pwrc/input0"; + pwrcdrv->input->evbit[0] = BIT_MASK(EV_PWR); + + irq = platform_get_irq(pdev, 0); + error = devm_request_irq(&pdev->dev, irq, + sirfsoc_pwrc_isr, IRQF_SHARED, + "sirfsoc_pwrc_int", pwrcdrv); + if (error) { + dev_err(&pdev->dev, "unable to claim irq %d, error: %d\n", + irq, error); + return error; + } + + sirfsoc_rtc_iobrg_writel( + sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base + PWRC_INT_MASK) | + PWRC_ON_KEY_BIT, + pwrcdrv->pwrc_base + PWRC_INT_MASK); + + error = input_register_device(pwrcdrv->input); + if (error) { + dev_err(&pdev->dev, + "unable to register input device, error: %d\n", + error); + return error; + } + + platform_set_drvdata(pdev, pwrcdrv); + device_init_wakeup(&pdev->dev, 1); + + return 0; +} + +static int sirfsoc_pwrc_remove(struct platform_device *pdev) +{ + device_init_wakeup(&pdev->dev, 0); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int pwrc_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct sirfsoc_pwrc_drvdata *pwrcdrv = platform_get_drvdata(pdev); + + /* + * Do not mask pwrc interrupt as we want pwrc work as a wakeup source + * if users touch X_ONKEY_B, see arch/arm/mach-prima2/pm.c + */ + sirfsoc_rtc_iobrg_writel( + sirfsoc_rtc_iobrg_readl( + pwrcdrv->pwrc_base + PWRC_INT_MASK) | PWRC_ON_KEY_BIT, + pwrcdrv->pwrc_base + PWRC_INT_MASK); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, pwrc_resume); + +static struct platform_driver sirfsoc_pwrc_driver = { + .probe = sirfsoc_pwrc_probe, + .remove = sirfsoc_pwrc_remove, + .driver = { + .name = "sirfsoc-pwrc", + .owner = THIS_MODULE, + .pm = &sirfsoc_pwrc_pm_ops, + .of_match_table = of_match_ptr(sirfsoc_pwrc_of_match), + } +}; + +module_platform_driver(sirfsoc_pwrc_driver); + +MODULE_LICENSE("GPLv2"); +MODULE_AUTHOR("Binghua Duan <Binghua.Duan@csr.com>, Xianglong Du <Xianglong.Du@csr.com>"); +MODULE_DESCRIPTION("CSR Prima2 PWRC Driver"); +MODULE_ALIAS("platform:sirfsoc-pwrc"); diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index a53586a7fbd..65fd3150919 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -175,7 +175,7 @@ static int sparcspkr_probe(struct device *dev) static void sparcspkr_shutdown(struct platform_device *dev) { - struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); + struct sparcspkr_state *state = platform_get_drvdata(dev); struct input_dev *input_dev = state->input_dev; /* turn off the speaker */ @@ -211,7 +211,7 @@ static int bbc_beep_probe(struct platform_device *op) if (!info->regs) goto out_free; - dev_set_drvdata(&op->dev, state); + platform_set_drvdata(op, state); err = sparcspkr_probe(&op->dev); if (err) @@ -220,7 +220,6 @@ static int bbc_beep_probe(struct platform_device *op) return 0; out_clear_drvdata: - dev_set_drvdata(&op->dev, NULL); of_iounmap(&op->resource[0], info->regs, 6); out_free: @@ -231,7 +230,7 @@ out_err: static int bbc_remove(struct platform_device *op) { - struct sparcspkr_state *state = dev_get_drvdata(&op->dev); + struct sparcspkr_state *state = platform_get_drvdata(op); struct input_dev *input_dev = state->input_dev; struct bbc_beep_info *info = &state->u.bbc; @@ -242,7 +241,6 @@ static int bbc_remove(struct platform_device *op) of_iounmap(&op->resource[0], info->regs, 6); - dev_set_drvdata(&op->dev, NULL); kfree(state); return 0; @@ -290,7 +288,7 @@ static int grover_beep_probe(struct platform_device *op) if (!info->enable_reg) goto out_unmap_freq_regs; - dev_set_drvdata(&op->dev, state); + platform_set_drvdata(op, state); err = sparcspkr_probe(&op->dev); if (err) @@ -299,7 +297,6 @@ static int grover_beep_probe(struct platform_device *op) return 0; out_clear_drvdata: - dev_set_drvdata(&op->dev, NULL); of_iounmap(&op->resource[3], info->enable_reg, 1); out_unmap_freq_regs: @@ -312,7 +309,7 @@ out_err: static int grover_remove(struct platform_device *op) { - struct sparcspkr_state *state = dev_get_drvdata(&op->dev); + struct sparcspkr_state *state = platform_get_drvdata(op); struct grover_beep_info *info = &state->u.grover; struct input_dev *input_dev = state->input_dev; @@ -324,7 +321,6 @@ static int grover_remove(struct platform_device *op) of_iounmap(&op->resource[3], info->enable_reg, 1); of_iounmap(&op->resource[2], info->freq_regs, 2); - dev_set_drvdata(&op->dev, NULL); kfree(state); return 0; |