Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: ads7846 - fix unsafe disable_irq Input: mainstone-wm97xx - fix condition in pen_up Input: pc110pad - remove unused variable dev Input: bf54x-keys - remove depreciated IRQF_SAMPLE_RANDOM flag Input: ad7877, ad7879 - remove depreciated IRQF_SAMPLE_RANDOM flag Input: da9034-ts - make pen {down,up} events more reliable Input: da9034-ts - add Bin Yang as co-author of the driver Input: atkbd - add forced release keys quirk for Samsung NC20 Input: atkbd - add forced release keys quirk for Samsung Q45 Input: gameport - fix attach driver code Input: hp_sdc_rtc should depend on serio Input: wm97xx - don't specify IRQF_SAMPLE_RANDOM Input: ads7846 - introduce platform specific way to synchronize sampling Input: remove unnecessary synchronize_rcu() call Input: i8042 - add a DMI table for the i8042.reset option Input: i8042 - introduce a tougher reset
This commit is contained in:
Коммит
91ec65ba33
|
@ -50,9 +50,8 @@ static LIST_HEAD(gameport_list);
|
|||
|
||||
static struct bus_type gameport_bus;
|
||||
|
||||
static void gameport_add_driver(struct gameport_driver *drv);
|
||||
static void gameport_add_port(struct gameport *gameport);
|
||||
static void gameport_destroy_port(struct gameport *gameport);
|
||||
static void gameport_attach_driver(struct gameport_driver *drv);
|
||||
static void gameport_reconnect_port(struct gameport *gameport);
|
||||
static void gameport_disconnect_port(struct gameport *gameport);
|
||||
|
||||
|
@ -230,7 +229,6 @@ static void gameport_find_driver(struct gameport *gameport)
|
|||
|
||||
enum gameport_event_type {
|
||||
GAMEPORT_REGISTER_PORT,
|
||||
GAMEPORT_REGISTER_DRIVER,
|
||||
GAMEPORT_ATTACH_DRIVER,
|
||||
};
|
||||
|
||||
|
@ -374,8 +372,8 @@ static void gameport_handle_event(void)
|
|||
gameport_add_port(event->object);
|
||||
break;
|
||||
|
||||
case GAMEPORT_REGISTER_DRIVER:
|
||||
gameport_add_driver(event->object);
|
||||
case GAMEPORT_ATTACH_DRIVER:
|
||||
gameport_attach_driver(event->object);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -706,14 +704,14 @@ static int gameport_driver_remove(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void gameport_add_driver(struct gameport_driver *drv)
|
||||
static void gameport_attach_driver(struct gameport_driver *drv)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = driver_register(&drv->driver);
|
||||
error = driver_attach(&drv->driver);
|
||||
if (error)
|
||||
printk(KERN_ERR
|
||||
"gameport: driver_register() failed for %s, error: %d\n",
|
||||
"gameport: driver_attach() failed for %s, error: %d\n",
|
||||
drv->driver.name, error);
|
||||
}
|
||||
|
||||
|
|
|
@ -1549,7 +1549,6 @@ int input_register_handle(struct input_handle *handle)
|
|||
return error;
|
||||
list_add_tail_rcu(&handle->d_node, &dev->h_list);
|
||||
mutex_unlock(&dev->mutex);
|
||||
synchronize_rcu();
|
||||
|
||||
/*
|
||||
* Since we are supposed to be called from ->connect()
|
||||
|
|
|
@ -880,7 +880,7 @@ static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
|
|||
};
|
||||
|
||||
/*
|
||||
* Samsung NC10 with Fn+F? key release not working
|
||||
* Samsung NC10,NC20 with Fn+F? key release not working
|
||||
*/
|
||||
static unsigned int atkbd_samsung_forced_release_keys[] = {
|
||||
0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U
|
||||
|
@ -1533,6 +1533,24 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
|
|||
.callback = atkbd_setup_forced_release,
|
||||
.driver_data = atkbd_samsung_forced_release_keys,
|
||||
},
|
||||
{
|
||||
.ident = "Samsung NC20",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "NC20"),
|
||||
},
|
||||
.callback = atkbd_setup_forced_release,
|
||||
.driver_data = atkbd_samsung_forced_release_keys,
|
||||
},
|
||||
{
|
||||
.ident = "Samsung SQ45S70S",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
|
||||
},
|
||||
.callback = atkbd_setup_forced_release,
|
||||
.driver_data = atkbd_samsung_forced_release_keys,
|
||||
},
|
||||
{
|
||||
.ident = "Fujitsu Amilo PA 1510",
|
||||
.matches = {
|
||||
|
|
|
@ -252,7 +252,7 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
error = request_irq(bf54x_kpad->irq, bfin_kpad_isr,
|
||||
IRQF_SAMPLE_RANDOM, DRV_NAME, pdev);
|
||||
0, DRV_NAME, pdev);
|
||||
if (error) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
": unable to claim irq %d; error %d\n",
|
||||
|
|
|
@ -214,7 +214,7 @@ config INPUT_SGI_BTNS
|
|||
|
||||
config HP_SDC_RTC
|
||||
tristate "HP SDC Real Time Clock"
|
||||
depends on GSC || HP300
|
||||
depends on (GSC || HP300) && SERIO
|
||||
select HP_SDC
|
||||
help
|
||||
Say Y here if you want to support the built-in real time clock
|
||||
|
|
|
@ -108,7 +108,6 @@ static int pc110pad_open(struct input_dev *dev)
|
|||
*/
|
||||
static int __init pc110pad_init(void)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
int err;
|
||||
|
||||
if (!no_pci_devices())
|
||||
|
|
|
@ -377,6 +377,24 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
|
||||
{
|
||||
.ident = "MSI Wind U-100",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "U-100"),
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "LG Electronics X110",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X110"),
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
|
||||
{
|
||||
|
@ -386,6 +404,13 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
|
|||
DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "MSI Wind U-100",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "U-100"),
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
@ -698,6 +723,9 @@ static int __init i8042_platform_init(void)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
if (dmi_check_system(i8042_dmi_reset_table))
|
||||
i8042_reset = 1;
|
||||
|
||||
if (dmi_check_system(i8042_dmi_noloop_table))
|
||||
i8042_noloop = 1;
|
||||
|
||||
|
|
|
@ -712,22 +712,43 @@ static int i8042_controller_check(void)
|
|||
static int i8042_controller_selftest(void)
|
||||
{
|
||||
unsigned char param;
|
||||
int i = 0;
|
||||
|
||||
if (!i8042_reset)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We try this 5 times; on some really fragile systems this does not
|
||||
* take the first time...
|
||||
*/
|
||||
do {
|
||||
|
||||
if (i8042_command(¶m, I8042_CMD_CTL_TEST)) {
|
||||
printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (param != I8042_RET_CTL_TEST) {
|
||||
if (param == I8042_RET_CTL_TEST)
|
||||
return 0;
|
||||
|
||||
printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
|
||||
param, I8042_RET_CTL_TEST);
|
||||
return -EIO;
|
||||
}
|
||||
msleep(50);
|
||||
} while (i++ < 5);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
/*
|
||||
* On x86, we don't fail entire i8042 initialization if controller
|
||||
* reset fails in hopes that keyboard port will still be functional
|
||||
* and user will still get a working keyboard. This is especially
|
||||
* important on netbooks. On other arches we trust hardware more.
|
||||
*/
|
||||
printk(KERN_INFO
|
||||
"i8042: giving up on controller selftest, continuing anyway...\n");
|
||||
return 0;
|
||||
#else
|
||||
return -EIO;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -736,8 +736,8 @@ static int __devinit ad7877_probe(struct spi_device *spi)
|
|||
|
||||
/* Request AD7877 /DAV GPIO interrupt */
|
||||
|
||||
err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING |
|
||||
IRQF_SAMPLE_RANDOM, spi->dev.driver->name, ts);
|
||||
err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING,
|
||||
spi->dev.driver->name, ts);
|
||||
if (err) {
|
||||
dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
|
||||
goto err_free_mem;
|
||||
|
|
|
@ -448,8 +448,7 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
|
|||
ad7879_setup(ts);
|
||||
|
||||
err = request_irq(bus->irq, ad7879_irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_SAMPLE_RANDOM,
|
||||
bus->dev.driver->name, ts);
|
||||
IRQF_TRIGGER_FALLING, bus->dev.driver->name, ts);
|
||||
|
||||
if (err) {
|
||||
dev_err(&bus->dev, "irq %d busy?\n", bus->irq);
|
||||
|
|
|
@ -127,6 +127,8 @@ struct ads7846 {
|
|||
void (*filter_cleanup)(void *data);
|
||||
int (*get_pendown_state)(void);
|
||||
int gpio_pendown;
|
||||
|
||||
void (*wait_for_sync)(void);
|
||||
};
|
||||
|
||||
/* leave chip selected when we're done, for quicker re-select? */
|
||||
|
@ -511,6 +513,10 @@ static int get_pendown_state(struct ads7846 *ts)
|
|||
return !gpio_get_value(ts->gpio_pendown);
|
||||
}
|
||||
|
||||
static void null_wait_for_sync(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* PENIRQ only kicks the timer. The timer only reissues the SPI transfer,
|
||||
* to retrieve touchscreen status.
|
||||
|
@ -686,6 +692,7 @@ static void ads7846_rx_val(void *ads)
|
|||
default:
|
||||
BUG();
|
||||
}
|
||||
ts->wait_for_sync();
|
||||
status = spi_async(ts->spi, m);
|
||||
if (status)
|
||||
dev_err(&ts->spi->dev, "spi_async --> %d\n",
|
||||
|
@ -723,6 +730,7 @@ static enum hrtimer_restart ads7846_timer(struct hrtimer *handle)
|
|||
} else {
|
||||
/* pen is still down, continue with the measurement */
|
||||
ts->msg_idx = 0;
|
||||
ts->wait_for_sync();
|
||||
status = spi_async(ts->spi, &ts->msg[0]);
|
||||
if (status)
|
||||
dev_err(&ts->spi->dev, "spi_async --> %d\n", status);
|
||||
|
@ -746,7 +754,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle)
|
|||
* that here. (The "generic irq" framework may help...)
|
||||
*/
|
||||
ts->irq_disabled = 1;
|
||||
disable_irq(ts->spi->irq);
|
||||
disable_irq_nosync(ts->spi->irq);
|
||||
ts->pending = 1;
|
||||
hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
|
||||
HRTIMER_MODE_REL);
|
||||
|
@ -947,6 +955,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
|
|||
ts->penirq_recheck_delay_usecs =
|
||||
pdata->penirq_recheck_delay_usecs;
|
||||
|
||||
ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync;
|
||||
|
||||
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
|
||||
|
||||
input_dev->name = "ADS784x Touchscreen";
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2006-2008 Marvell International Ltd.
|
||||
* Fengwei Yin <fengwei.yin@marvell.com>
|
||||
* Bin Yang <bin.yang@marvell.com>
|
||||
* Eric Miao <eric.miao@marvell.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -175,6 +176,16 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
|
|||
goto err_reset;
|
||||
|
||||
touch->state = STATE_STOP;
|
||||
|
||||
/* FIXME: PEN_{UP/DOWN} events are expected to be
|
||||
* available by stopping TSI, but this is found not
|
||||
* always true, delay and simulate such an event
|
||||
* here is more reliable
|
||||
*/
|
||||
mdelay(1);
|
||||
da9034_event_handler(touch,
|
||||
is_pen_down(touch) ? EVENT_PEN_DOWN :
|
||||
EVENT_PEN_UP);
|
||||
break;
|
||||
|
||||
case STATE_STOP:
|
||||
|
@ -189,8 +200,6 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
|
|||
report_pen_up(touch);
|
||||
touch->state = STATE_IDLE;
|
||||
}
|
||||
|
||||
input_sync(touch->input_dev);
|
||||
break;
|
||||
|
||||
case STATE_WAIT:
|
||||
|
@ -200,8 +209,10 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
|
|||
if (is_pen_down(touch)) {
|
||||
start_tsi(touch);
|
||||
touch->state = STATE_BUSY;
|
||||
} else
|
||||
} else {
|
||||
report_pen_up(touch);
|
||||
touch->state = STATE_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
@ -226,16 +237,12 @@ static int da9034_touch_notifier(struct notifier_block *nb,
|
|||
struct da9034_touch *touch =
|
||||
container_of(nb, struct da9034_touch, notifier);
|
||||
|
||||
if (event & DA9034_EVENT_PEN_DOWN) {
|
||||
if (is_pen_down(touch))
|
||||
da9034_event_handler(touch, EVENT_PEN_DOWN);
|
||||
else
|
||||
da9034_event_handler(touch, EVENT_PEN_UP);
|
||||
}
|
||||
|
||||
if (event & DA9034_EVENT_TSI_READY)
|
||||
da9034_event_handler(touch, EVENT_TSI_READY);
|
||||
|
||||
if ((event & DA9034_EVENT_PEN_DOWN) && touch->state == STATE_IDLE)
|
||||
da9034_event_handler(touch, EVENT_PEN_DOWN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -385,6 +392,6 @@ static void __exit da9034_touch_exit(void)
|
|||
module_exit(da9034_touch_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034");
|
||||
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
|
||||
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>, Bin Yang <bin.yang@marvell.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:da9034-touch");
|
||||
|
|
|
@ -111,13 +111,12 @@ static void wm97xx_acc_pen_up(struct wm97xx *wm)
|
|||
#else
|
||||
static void wm97xx_acc_pen_up(struct wm97xx *wm)
|
||||
{
|
||||
int count = 16;
|
||||
unsigned int count;
|
||||
|
||||
schedule_timeout_uninterruptible(1);
|
||||
|
||||
while (count < 16) {
|
||||
for (count = 0; count < 16; count++)
|
||||
MODR;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -370,8 +370,7 @@ static int wm97xx_init_pen_irq(struct wm97xx *wm)
|
|||
* provided. */
|
||||
BUG_ON(!wm->mach_ops->irq_enable);
|
||||
|
||||
if (request_irq(wm->pen_irq, wm97xx_pen_interrupt,
|
||||
IRQF_SHARED | IRQF_SAMPLE_RANDOM,
|
||||
if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED,
|
||||
"wm97xx-pen", wm)) {
|
||||
dev_err(wm->dev,
|
||||
"Failed to register pen down interrupt, polling");
|
||||
|
|
|
@ -51,5 +51,6 @@ struct ads7846_platform_data {
|
|||
void **filter_data);
|
||||
int (*filter) (void *filter_data, int data_idx, int *val);
|
||||
void (*filter_cleanup)(void *filter_data);
|
||||
void (*wait_for_sync)(void);
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче