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 bb698e1f9e42..0b541cdf9b8e 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 d7fc17f11d77..829de43a2427 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 2f090b46e716..f2fbdd88ed20 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 a6666e142a91..cd139cb17e32 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 da05cca8b562..714c68369134 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 6ab3decc86e6..f34beb228d36 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 b40ee4b47f4f..def21dc84522 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 f9179b2585a9..eef41cfc054d 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 0906ca593d5f..d0277a7b1579 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 199db78acc4f..7288b267613d 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 a9da65e41c5b..ec086f6f3cc3 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 4b811be73974..b49b738aa9c6 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 0808868461de..a37f0c909aba 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 aff47b2c38ff..5b1aff825138 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 ad6415ceaf5f..95cf299ef9a3 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 000000000000..0621c367049a --- /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 a53586a7fbdb..65fd3150919b 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; |