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:
Linus Torvalds 2009-04-17 10:08:13 -07:00
commit 91ec65ba33
15 changed files with 121 additions and 43 deletions

View File

@ -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);
}

View File

@ -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()

View File

@ -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 = {

View File

@ -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",

View File

@ -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

View File

@ -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())

View File

@ -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;

View File

@ -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;
if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
return -ENODEV;
}
/*
* We try this 5 times; on some really fragile systems this does not
* take the first time...
*/
do {
if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
return -ENODEV;
}
if (param == I8042_RET_CTL_TEST)
return 0;
if (param != I8042_RET_CTL_TEST) {
printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
param, I8042_RET_CTL_TEST);
return -EIO;
}
param, I8042_RET_CTL_TEST);
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
}
/*

View File

@ -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;

View File

@ -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);

View File

@ -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";

View File

@ -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");

View File

@ -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

View File

@ -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");

View File

@ -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);
};