From 6aabcdffd1a5f8f5b906696e58069c4f8fced542 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Thu, 3 Jul 2008 10:45:38 -0400 Subject: Input: serio - offload resume to kseriod When resuming AUX ports psmouse driver calls psmouse_extensions() to determine if the attached mouse is still the same, which may take a while to complete for generic mice. Offload the resume process to kseriod so the rest of the system may continue resuming without waiting for the mouse. Signed-off-by: Shaohua Li Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 55 ++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 18 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 78f2abb5c11..2f12d60eee3 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -63,8 +63,9 @@ static LIST_HEAD(serio_list); static struct bus_type serio_bus; static void serio_add_port(struct serio *serio); -static void serio_reconnect_port(struct serio *serio); +static int serio_reconnect_port(struct serio *serio); static void serio_disconnect_port(struct serio *serio); +static void serio_reconnect_chain(struct serio *serio); static void serio_attach_driver(struct serio_driver *drv); static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) @@ -161,6 +162,7 @@ static void serio_find_driver(struct serio *serio) enum serio_event_type { SERIO_RESCAN_PORT, SERIO_RECONNECT_PORT, + SERIO_RECONNECT_CHAIN, SERIO_REGISTER_PORT, SERIO_ATTACH_DRIVER, }; @@ -315,6 +317,10 @@ static void serio_handle_event(void) serio_find_driver(event->object); break; + case SERIO_RECONNECT_CHAIN: + serio_reconnect_chain(event->object); + break; + case SERIO_ATTACH_DRIVER: serio_attach_driver(event->object); break; @@ -470,7 +476,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * if (!strncmp(buf, "none", count)) { serio_disconnect_port(serio); } else if (!strncmp(buf, "reconnect", count)) { - serio_reconnect_port(serio); + serio_reconnect_chain(serio); } else if (!strncmp(buf, "rescan", count)) { serio_disconnect_port(serio); serio_find_driver(serio); @@ -619,15 +625,31 @@ static void serio_destroy_port(struct serio *serio) put_device(&serio->dev); } +/* + * Reconnect serio port (re-initialize attached device). + * If reconnect fails (old device is no longer attached or + * there was no device to begin with) we do full rescan in + * hope of finding a driver for the port. + */ +static int serio_reconnect_port(struct serio *serio) +{ + int error = serio_reconnect_driver(serio); + + if (error) { + serio_disconnect_port(serio); + serio_find_driver(serio); + } + + return error; +} + /* * Reconnect serio port and all its children (re-initialize attached devices) */ -static void serio_reconnect_port(struct serio *serio) +static void serio_reconnect_chain(struct serio *serio) { do { - if (serio_reconnect_driver(serio)) { - serio_disconnect_port(serio); - serio_find_driver(serio); + if (serio_reconnect_port(serio)) { /* Ok, old children are now gone, we are done */ break; } @@ -673,7 +695,7 @@ void serio_rescan(struct serio *serio) void serio_reconnect(struct serio *serio) { - serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); + serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN); } /* @@ -927,19 +949,16 @@ static int serio_suspend(struct device *dev, pm_message_t state) static int serio_resume(struct device *dev) { - struct serio *serio = to_serio_port(dev); - - if (dev->power.power_state.event != PM_EVENT_ON && - serio_reconnect_driver(serio)) { - /* - * Driver re-probing can take a while, so better let kseriod - * deal with it. - */ - serio_rescan(serio); + /* + * Driver reconnect can take a while, so better let kseriod + * deal with it. + */ + if (dev->power.power_state.event != PM_EVENT_ON) { + dev->power.power_state = PMSG_ON; + serio_queue_event(to_serio_port(dev), NULL, + SERIO_RECONNECT_PORT); } - dev->power.power_state = PMSG_ON; - return 0; } #endif /* CONFIG_PM */ -- cgit v1.2.3-70-g09d2 From 53703659ab559a58a3058e69aeb59c06d4872358 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Wed, 23 Jul 2008 13:57:50 -0400 Subject: Input: uinput - remove duplicate include Remove duplicate include file in drivers/input/misc/uinput.c. Signed-off-by: Huang Weiyi Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 2bcfa0b3506..223d56d5555 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -37,7 +37,6 @@ #include #include #include -#include static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { -- cgit v1.2.3-70-g09d2 From 494f685775ee4c2f3db4081209f00ff0633243fc Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 23 Jul 2008 14:16:19 -0400 Subject: Input: ads7846 - fix sparse endian warnings Also remove the temporary pointer and use ->rx_buf directly. Signed-off-by: Harvey Harrison Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 907a45fe9d4..4d060321514 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -633,19 +633,17 @@ static void ads7846_rx_val(void *ads) struct ads7846 *ts = ads; struct spi_message *m; struct spi_transfer *t; - u16 *rx_val; int val; int action; int status; m = &ts->msg[ts->msg_idx]; t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); - rx_val = t->rx_buf; /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; * built from two 8 bit values written msb-first. */ - val = be16_to_cpu(*rx_val) >> 3; + val = be16_to_cpup((__be16 *)t->rx_buf) >> 3; action = ts->filter(ts->filter_data, ts->msg_idx, &val); switch (action) { @@ -659,7 +657,7 @@ static void ads7846_rx_val(void *ads) m = ts->last_msg; break; case ADS7846_FILTER_OK: - *rx_val = val; + *(u16 *)t->rx_buf = val; ts->tc.ignore = 0; m = &ts->msg[++ts->msg_idx]; break; -- cgit v1.2.3-70-g09d2 From 9460b6529d8a0bfabf241ddda8b0e469d219844c Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Wed, 23 Jul 2008 14:38:27 -0400 Subject: Input: ads7846 - optimize order of calculating Rt in ads7846_rx() Alter the if expression for calculating Rt. The old implementation would run unnecessary code when the ADS7843 device was used. The patch also fixes the code style to kernel standard. Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 4d060321514..ce6f48c695f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -517,7 +517,9 @@ static void ads7846_rx(void *ads) if (x == MAX_12BIT) x = 0; - if (likely(x && z1)) { + if (ts->model == 7843) { + Rt = ts->pressure_max / 2; + } else if (likely(x && z1)) { /* compute touch pressure resistance using equation #2 */ Rt = z2; Rt -= z1; @@ -525,11 +527,9 @@ static void ads7846_rx(void *ads) Rt *= ts->x_plate_ohms; Rt /= z1; Rt = (Rt + 2047) >> 12; - } else + } else { Rt = 0; - - if (ts->model == 7843) - Rt = ts->pressure_max / 2; + } /* Sample found inconsistent by debouncing or pressure is beyond * the maximum. Don't report it to user space, repeat at least -- cgit v1.2.3-70-g09d2 From 72d18a7b9e1a3a9511bae78fc7f0932ae01d5d73 Mon Sep 17 00:00:00 2001 From: Dan Liang Date: Wed, 23 Jul 2008 21:27:25 -0400 Subject: Input: add driver for Atmel integrated touchscreen controller The AT91SAM9RL SoC integrates a Touchscreen Controller which can trigger ADC conversion periodically. Signed-off-by: Justin Waters Signed-off-by: Dan Liang Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 12 ++ drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/atmel_tsadcc.c | 332 +++++++++++++++++++++++++++++++ 3 files changed, 345 insertions(+) create mode 100644 drivers/input/touchscreen/atmel_tsadcc.c (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index e5736652157..6e60a97a234 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -205,6 +205,18 @@ config TOUCHSCREEN_TOUCHWIN To compile this driver as a module, choose M here: the module will be called touchwin. +config TOUCHSCREEN_ATMEL_TSADCC + tristate "Atmel Touchscreen Interface" + depends on ARCH_AT91SAM9RL + help + Say Y here if you have a 4-wire touchscreen connected to the + ADC Controller on your Atmel SoC (such as the AT91SAM9RL). + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called atmel_tsadcc. + config TOUCHSCREEN_UCB1400 tristate "Philips UCB1400 touchscreen" select AC97_BUS diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 39a804cd80f..15cf2907948 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -7,6 +7,7 @@ wm97xx-ts-y := wm97xx-core.o obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o +obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c new file mode 100644 index 00000000000..eee126b19e8 --- /dev/null +++ b/drivers/input/touchscreen/atmel_tsadcc.c @@ -0,0 +1,332 @@ +/* + * Atmel Touch Screen Driver + * + * Copyright (c) 2008 ATMEL + * Copyright (c) 2008 Dan Liang + * Copyright (c) 2008 TimeSys Corporation + * Copyright (c) 2008 Justin Waters + * + * Based on touchscreen code from Atmel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */ + +#define ATMEL_TSADCC_CR 0x00 /* Control register */ +#define ATMEL_TSADCC_SWRST (1 << 0) /* Software Reset*/ +#define ATMEL_TSADCC_START (1 << 1) /* Start conversion */ + +#define ATMEL_TSADCC_MR 0x04 /* Mode register */ +#define ATMEL_TSADCC_TSAMOD (3 << 0) /* ADC mode */ +#define ATMEL_TSADCC_TSAMOD_ADC_ONLY_MODE (0x0) /* ADC Mode */ +#define ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE (0x1) /* Touch Screen Only Mode */ +#define ATMEL_TSADCC_LOWRES (1 << 4) /* Resolution selection */ +#define ATMEL_TSADCC_SLEEP (1 << 5) /* Sleep mode */ +#define ATMEL_TSADCC_PENDET (1 << 6) /* Pen Detect selection */ +#define ATMEL_TSADCC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */ +#define ATMEL_TSADCC_STARTUP (0x7f << 16) /* Start Up time */ +#define ATMEL_TSADCC_SHTIM (0xf << 24) /* Sample & Hold time */ +#define ATMEL_TSADCC_PENDBC (0xf << 28) /* Pen Detect debouncing time */ + +#define ATMEL_TSADCC_TRGR 0x08 /* Trigger register */ +#define ATMEL_TSADCC_TRGMOD (7 << 0) /* Trigger mode */ +#define ATMEL_TSADCC_TRGMOD_NONE (0 << 0) +#define ATMEL_TSADCC_TRGMOD_EXT_RISING (1 << 0) +#define ATMEL_TSADCC_TRGMOD_EXT_FALLING (2 << 0) +#define ATMEL_TSADCC_TRGMOD_EXT_ANY (3 << 0) +#define ATMEL_TSADCC_TRGMOD_PENDET (4 << 0) +#define ATMEL_TSADCC_TRGMOD_PERIOD (5 << 0) +#define ATMEL_TSADCC_TRGMOD_CONTINUOUS (6 << 0) +#define ATMEL_TSADCC_TRGPER (0xffff << 16) /* Trigger period */ + +#define ATMEL_TSADCC_TSR 0x0C /* Touch Screen register */ +#define ATMEL_TSADCC_TSFREQ (0xf << 0) /* TS Frequency in Interleaved mode */ +#define ATMEL_TSADCC_TSSHTIM (0xf << 24) /* Sample & Hold time */ + +#define ATMEL_TSADCC_CHER 0x10 /* Channel Enable register */ +#define ATMEL_TSADCC_CHDR 0x14 /* Channel Disable register */ +#define ATMEL_TSADCC_CHSR 0x18 /* Channel Status register */ +#define ATMEL_TSADCC_CH(n) (1 << (n)) /* Channel number */ + +#define ATMEL_TSADCC_SR 0x1C /* Status register */ +#define ATMEL_TSADCC_EOC(n) (1 << ((n)+0)) /* End of conversion for channel N */ +#define ATMEL_TSADCC_OVRE(n) (1 << ((n)+8)) /* Overrun error for channel N */ +#define ATMEL_TSADCC_DRDY (1 << 16) /* Data Ready */ +#define ATMEL_TSADCC_GOVRE (1 << 17) /* General Overrun Error */ +#define ATMEL_TSADCC_ENDRX (1 << 18) /* End of RX Buffer */ +#define ATMEL_TSADCC_RXBUFF (1 << 19) /* TX Buffer full */ +#define ATMEL_TSADCC_PENCNT (1 << 20) /* Pen contact */ +#define ATMEL_TSADCC_NOCNT (1 << 21) /* No contact */ + +#define ATMEL_TSADCC_LCDR 0x20 /* Last Converted Data register */ +#define ATMEL_TSADCC_DATA (0x3ff << 0) /* Channel data */ + +#define ATMEL_TSADCC_IER 0x24 /* Interrupt Enable register */ +#define ATMEL_TSADCC_IDR 0x28 /* Interrupt Disable register */ +#define ATMEL_TSADCC_IMR 0x2C /* Interrupt Mask register */ +#define ATMEL_TSADCC_CDR0 0x30 /* Channel Data 0 */ +#define ATMEL_TSADCC_CDR1 0x34 /* Channel Data 1 */ +#define ATMEL_TSADCC_CDR2 0x38 /* Channel Data 2 */ +#define ATMEL_TSADCC_CDR3 0x3C /* Channel Data 3 */ +#define ATMEL_TSADCC_CDR4 0x40 /* Channel Data 4 */ +#define ATMEL_TSADCC_CDR5 0x44 /* Channel Data 5 */ + +#define ADC_CLOCK 1000000 + +struct atmel_tsadcc { + struct input_dev *input; + char phys[32]; + struct clk *clk; + int irq; +}; + +static void __iomem *tsc_base; + +#define atmel_tsadcc_read(reg) __raw_readl(tsc_base + (reg)) +#define atmel_tsadcc_write(reg, val) __raw_writel((val), tsc_base + (reg)) + +static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) +{ + struct input_dev *input_dev = ((struct atmel_tsadcc *)dev)->input; + + unsigned int absx; + unsigned int absy; + unsigned int status; + unsigned int reg; + + status = atmel_tsadcc_read(ATMEL_TSADCC_SR); + status &= atmel_tsadcc_read(ATMEL_TSADCC_IMR); + + if (status & ATMEL_TSADCC_NOCNT) { + /* Contact lost */ + reg = atmel_tsadcc_read(ATMEL_TSADCC_MR) | ATMEL_TSADCC_PENDBC; + + atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); + atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); + atmel_tsadcc_write(ATMEL_TSADCC_IDR, + ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT); + atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); + + input_report_key(input_dev, BTN_TOUCH, 0); + input_sync(input_dev); + + } else if (status & ATMEL_TSADCC_PENCNT) { + /* Pen detected */ + reg = atmel_tsadcc_read(ATMEL_TSADCC_MR); + reg &= ~ATMEL_TSADCC_PENDBC; + + atmel_tsadcc_write(ATMEL_TSADCC_IDR, ATMEL_TSADCC_PENCNT); + atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); + atmel_tsadcc_write(ATMEL_TSADCC_IER, + ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT); + atmel_tsadcc_write(ATMEL_TSADCC_TRGR, + ATMEL_TSADCC_TRGMOD_PERIOD | (0x0FFF << 16)); + + } else if (status & ATMEL_TSADCC_EOC(3)) { + /* Conversion finished */ + + absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10; + absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2); + + absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10; + absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0); + + input_report_abs(input_dev, ABS_X, absx); + input_report_abs(input_dev, ABS_Y, absy); + input_report_key(input_dev, BTN_TOUCH, 1); + input_sync(input_dev); + } + + return IRQ_HANDLED; +} + +/* + * The functions for inserting/removing us as a module. + */ + +static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) +{ + struct atmel_tsadcc *ts_dev; + struct input_dev *input_dev; + struct resource *res; + int err = 0; + unsigned int prsc; + unsigned int reg; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no mmio resource defined.\n"); + return -ENXIO; + } + + /* Allocate memory for device */ + ts_dev = kzalloc(sizeof(struct atmel_tsadcc), GFP_KERNEL); + if (!ts_dev) { + dev_err(&pdev->dev, "failed to allocate memory.\n"); + return -ENOMEM; + } + platform_set_drvdata(pdev, ts_dev); + + input_dev = input_allocate_device(); + if (!input_dev) { + dev_err(&pdev->dev, "failed to allocate input device.\n"); + err = -EBUSY; + goto err_free_mem; + } + + ts_dev->irq = platform_get_irq(pdev, 0); + if (ts_dev->irq < 0) { + dev_err(&pdev->dev, "no irq ID is designated.\n"); + err = -ENODEV; + goto err_free_dev; + } + + if (!request_mem_region(res->start, res->end - res->start + 1, + "atmel tsadcc regs")) { + dev_err(&pdev->dev, "resources is unavailable.\n"); + err = -EBUSY; + goto err_free_dev; + } + + tsc_base = ioremap(res->start, res->end - res->start + 1); + if (!tsc_base) { + dev_err(&pdev->dev, "failed to map registers.\n"); + err = -ENOMEM; + goto err_release_mem; + } + + err = request_irq(ts_dev->irq, atmel_tsadcc_interrupt, IRQF_DISABLED, + pdev->dev.driver->name, ts_dev); + if (err) { + dev_err(&pdev->dev, "failed to allocate irq.\n"); + goto err_unmap_regs; + } + + ts_dev->clk = clk_get(&pdev->dev, "tsc_clk"); + if (IS_ERR(ts_dev->clk)) { + dev_err(&pdev->dev, "failed to get ts_clk\n"); + err = PTR_ERR(ts_dev->clk); + goto err_free_irq; + } + + ts_dev->input = input_dev; + + snprintf(ts_dev->phys, sizeof(ts_dev->phys), + "%s/input0", pdev->dev.bus_id); + + input_dev->name = "atmel touch screen controller"; + input_dev->phys = ts_dev->phys; + input_dev->dev.parent = &pdev->dev; + + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + + input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0); + + /* clk_enable() always returns 0, no need to check it */ + clk_enable(ts_dev->clk); + + prsc = clk_get_rate(ts_dev->clk); + dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc); + + prsc = prsc / ADC_CLOCK / 2 - 1; + + reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE | + ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */ + ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */ + ((prsc << 8) & ATMEL_TSADCC_PRESCAL) | /* PRESCAL */ + ((0x13 << 16) & ATMEL_TSADCC_STARTUP) | /* STARTUP */ + ((0x0F << 28) & ATMEL_TSADCC_PENDBC); /* PENDBC */ + + atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST); + atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); + atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); + atmel_tsadcc_write(ATMEL_TSADCC_TSR, (0x3 << 24) & ATMEL_TSADCC_TSSHTIM); + + atmel_tsadcc_read(ATMEL_TSADCC_SR); + atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); + + /* All went ok, so register to the input system */ + err = input_register_device(input_dev); + if (err) + goto err_fail; + + return 0; + +err_fail: + clk_disable(ts_dev->clk); + clk_put(ts_dev->clk); +err_free_irq: + free_irq(ts_dev->irq, ts_dev); +err_unmap_regs: + iounmap(tsc_base); +err_release_mem: + release_mem_region(res->start, res->end - res->start + 1); +err_free_dev: + input_free_device(ts_dev->input); +err_free_mem: + kfree(ts_dev); + return err; +} + +static int __devexit atmel_tsadcc_remove(struct platform_device *pdev) +{ + struct atmel_tsadcc *ts_dev = dev_get_drvdata(&pdev->dev); + struct resource *res; + + free_irq(ts_dev->irq, ts_dev); + + input_unregister_device(ts_dev->input); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + iounmap(tsc_base); + release_mem_region(res->start, res->end - res->start + 1); + + clk_disable(ts_dev->clk); + clk_put(ts_dev->clk); + + kfree(ts_dev); + + return 0; +} + +static struct platform_driver atmel_tsadcc_driver = { + .probe = atmel_tsadcc_probe, + .remove = __devexit_p(atmel_tsadcc_remove), + .driver = { + .name = "atmel_tsadcc", + }, +}; + +static int __init atmel_tsadcc_init(void) +{ + return platform_driver_register(&atmel_tsadcc_driver); +} + +static void __exit atmel_tsadcc_exit(void) +{ + platform_driver_unregister(&atmel_tsadcc_driver); +} + +module_init(atmel_tsadcc_init); +module_exit(atmel_tsadcc_exit); + + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Atmel TouchScreen Driver"); +MODULE_AUTHOR("Dan Liang "); + -- cgit v1.2.3-70-g09d2 From d3aa43a9db3b18e65f91985b5b91f2450d8b4048 Mon Sep 17 00:00:00 2001 From: Tetsuya Mukawa Date: Sat, 19 Jul 2008 07:46:53 +0900 Subject: sh_keysc: remove request_mem_region() and release_mem_region() Remove request_mem_region() and release_mem_region() from sh_keysc driver. Those functions can find resource conflict, but it is already checked in platform_device_add(). Signed-off-by: Tetsuya Mukawa Signed-off-by: Magnus Damm Signed-off-by: Andrew Morton Cc: Dmitry Torokhov Signed-off-by: Paul Mundt --- drivers/input/keyboard/sh_keysc.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 8486abc457e..c600ab7f93e 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -158,25 +158,18 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); pdata = &priv->pdata; - res = request_mem_region(res->start, res_size(res), pdev->name); - if (res == NULL) { - dev_err(&pdev->dev, "failed to request I/O memory\n"); - error = -EBUSY; - goto err1; - } - priv->iomem_base = ioremap_nocache(res->start, res_size(res)); if (priv->iomem_base == NULL) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); error = -ENXIO; - goto err2; + goto err1; } priv->input = input_allocate_device(); if (!priv->input) { dev_err(&pdev->dev, "failed to allocate input device\n"); error = -ENOMEM; - goto err3; + goto err2; } input = priv->input; @@ -194,7 +187,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); if (error) { dev_err(&pdev->dev, "failed to request IRQ\n"); - goto err4; + goto err3; } for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { @@ -206,7 +199,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) error = input_register_device(input); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); - goto err5; + goto err4; } iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | @@ -214,14 +207,12 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); return 0; - err5: - free_irq(irq, pdev); err4: - input_free_device(input); + free_irq(irq, pdev); err3: - iounmap(priv->iomem_base); + input_free_device(input); err2: - release_mem_region(res->start, res_size(res)); + iounmap(priv->iomem_base); err1: platform_set_drvdata(pdev, NULL); kfree(priv); @@ -232,7 +223,6 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) static int __devexit sh_keysc_remove(struct platform_device *pdev) { struct sh_keysc_priv *priv = platform_get_drvdata(pdev); - struct resource *res; iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); @@ -240,9 +230,6 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) free_irq(platform_get_irq(pdev, 0), pdev); iounmap(priv->iomem_base); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, res_size(res)); - platform_set_drvdata(pdev, NULL); kfree(priv); return 0; -- cgit v1.2.3-70-g09d2 From 0764bff445bb13cd17e41b6ab196ef83c23c6c17 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 29 Jul 2008 22:10:01 +0900 Subject: sh: More header path fixups for mach dir refactoring. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-highlander/psw.c | 2 +- arch/sh/boards/mach-landisk/gio.c | 4 ++-- arch/sh/boards/mach-landisk/irq.c | 2 +- arch/sh/boards/mach-landisk/psw.c | 2 +- arch/sh/boards/mach-landisk/setup.c | 2 +- arch/sh/boards/mach-se/7343/io.c | 2 +- arch/sh/boards/mach-sh03/setup.c | 4 ++-- arch/sh/include/mach-dreamcast/mach/pci.h | 2 +- drivers/cdrom/gdrom.c | 4 ++-- drivers/input/keyboard/maple_keyb.c | 1 - drivers/video/pvr2fb.c | 6 +++--- 11 files changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers/input') diff --git a/arch/sh/boards/mach-highlander/psw.c b/arch/sh/boards/mach-highlander/psw.c index 0b3e062e96c..be8d5477fc6 100644 --- a/arch/sh/boards/mach-highlander/psw.c +++ b/arch/sh/boards/mach-highlander/psw.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include static irqreturn_t psw_irq_handler(int irq, void *arg) diff --git a/arch/sh/boards/mach-landisk/gio.c b/arch/sh/boards/mach-landisk/gio.c index edcde082032..25cdf735800 100644 --- a/arch/sh/boards/mach-landisk/gio.c +++ b/arch/sh/boards/mach-landisk/gio.c @@ -20,8 +20,8 @@ #include #include #include -#include -#include +#include +#include #define DEVCOUNT 4 #define GIO_MINOR 2 /* GIO minor no. */ diff --git a/arch/sh/boards/mach-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c index d0f9378f6ff..7b284cde1f5 100644 --- a/arch/sh/boards/mach-landisk/irq.c +++ b/arch/sh/boards/mach-landisk/irq.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include static void disable_landisk_irq(unsigned int irq) { diff --git a/arch/sh/boards/mach-landisk/psw.c b/arch/sh/boards/mach-landisk/psw.c index 4bd502cbaee..e6b0efa098d 100644 --- a/arch/sh/boards/mach-landisk/psw.c +++ b/arch/sh/boards/mach-landisk/psw.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include static irqreturn_t psw_irq_handler(int irq, void *arg) diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c index 470c7811168..db22ea2e6d4 100644 --- a/arch/sh/boards/mach-landisk/setup.c +++ b/arch/sh/boards/mach-landisk/setup.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include void init_landisk_IRQ(void); diff --git a/arch/sh/boards/mach-se/7343/io.c b/arch/sh/boards/mach-se/7343/io.c index e2fae32d27d..8741abc1da7 100644 --- a/arch/sh/boards/mach-se/7343/io.c +++ b/arch/sh/boards/mach-se/7343/io.c @@ -6,7 +6,7 @@ */ #include #include -#include +#include #define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c index cd9cff1ed34..5771219be3f 100644 --- a/arch/sh/boards/mach-sh03/setup.c +++ b/arch/sh/boards/mach-sh03/setup.c @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include +#include #include static void __init init_sh03_IRQ(void) diff --git a/arch/sh/include/mach-dreamcast/mach/pci.h b/arch/sh/include/mach-dreamcast/mach/pci.h index 9264ff46c63..75fc9009e09 100644 --- a/arch/sh/include/mach-dreamcast/mach/pci.h +++ b/arch/sh/include/mach-dreamcast/mach/pci.h @@ -11,7 +11,7 @@ #ifndef __ASM_SH_DREAMCAST_PCI_H #define __ASM_SH_DREAMCAST_PCI_H -#include +#include #define GAPSPCI_REGS 0x01001400 #define GAPSPCI_DMA_BASE 0x01840000 diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 71ec426ecff..1e0455bd6df 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -39,8 +39,8 @@ #include #include #include -#include -#include +#include +#include #define GDROM_DEV_NAME "gdrom" #define GD_SESSION_OFFSET 150 diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 2b404284c28..7797ef6e5e6 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -27,7 +27,6 @@ #include #include #include -#include /* Very simple mutex to ensure proper cleanup */ static DEFINE_MUTEX(maple_keyb_mutex); diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index 8c863a7f654..0a0fd48a856 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -58,18 +58,18 @@ #ifdef CONFIG_SH_DREAMCAST #include -#include +#include #endif #ifdef CONFIG_SH_DMA #include -#include +#include #include #endif #ifdef CONFIG_SH_STORE_QUEUES #include -#include +#include #endif #ifndef PCI_DEVICE_ID_NEC_NEON250 -- cgit v1.2.3-70-g09d2 From 86d9d32c7b17f8145dc8cbc9667e6385bf8ebc67 Mon Sep 17 00:00:00 2001 From: Adrian McMenamin Date: Wed, 30 Jul 2008 12:31:38 -0700 Subject: maple: allow removal and reinsertion of keyboard driver module Allow the removal (and subsequent reinsertion) of the maple_keyb (maple keyboard) driver by adding a working removal function. Also tidy long lines. Signed-off-by: Adrian McMenamin Cc: Dmitry Torokhov Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Paul Mundt --- drivers/input/keyboard/maple_keyb.c | 124 +++++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 43 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 7797ef6e5e6..7d13f55b504 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -2,7 +2,7 @@ * SEGA Dreamcast keyboard driver * Based on drivers/usb/usbkbd.c * Copyright YAEGASHI Takeshi, 2001 - * Porting to 2.6 Copyright Adrian McMenamin, 2007 + * Porting to 2.6 Copyright Adrian McMenamin, 2007, 2008 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,39 +45,51 @@ struct dc_kbd { }; static const unsigned short dc_kbd_keycode[NR_SCANCODES] = { - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_A, KEY_B, KEY_C, KEY_D, - KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, - KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, - KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_1, KEY_2, - KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, - KEY_ENTER, KEY_ESC, KEY_BACKSPACE, KEY_TAB, KEY_SPACE, KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE, - KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_BACKSLASH, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA, - KEY_DOT, KEY_SLASH, KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_A, KEY_B, + KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, + KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, + KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, + KEY_7, KEY_8, KEY_9, KEY_0, KEY_ENTER, KEY_ESC, KEY_BACKSPACE, + KEY_TAB, KEY_SPACE, KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE, + KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_BACKSLASH, KEY_SEMICOLON, + KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA, KEY_DOT, KEY_SLASH, + KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, KEY_SYSRQ, - KEY_SCROLLLOCK, KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP, KEY_DELETE, - KEY_END, KEY_PAGEDOWN, KEY_RIGHT, KEY_LEFT, KEY_DOWN, KEY_UP, - KEY_NUMLOCK, KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS, KEY_KPPLUS, KEY_KPENTER, KEY_KP1, KEY_KP2, - KEY_KP3, KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT, - KEY_102ND, KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL, KEY_F13, KEY_F14, KEY_F15, - KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20, - KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_OPEN, KEY_HELP, KEY_PROPS, KEY_FRONT, - KEY_STOP, KEY_AGAIN, KEY_UNDO, KEY_CUT, KEY_COPY, KEY_PASTE, KEY_FIND, KEY_MUTE, - KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_KPCOMMA, KEY_RESERVED, KEY_RO, KEY_KATAKANAHIRAGANA , KEY_YEN, - KEY_HENKAN, KEY_MUHENKAN, KEY_KPJPCOMMA, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_HANGEUL, KEY_HANJA, KEY_KATAKANA, KEY_HIRAGANA, KEY_ZENKAKUHANKAKU, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, - KEY_LEFTCTRL, KEY_LEFTSHIFT, KEY_LEFTALT, KEY_LEFTMETA, KEY_RIGHTCTRL, KEY_RIGHTSHIFT, KEY_RIGHTALT, KEY_RIGHTMETA, - KEY_PLAYPAUSE, KEY_STOPCD, KEY_PREVIOUSSONG, KEY_NEXTSONG, KEY_EJECTCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE, - KEY_WWW, KEY_BACK, KEY_FORWARD, KEY_STOP, KEY_FIND, KEY_SCROLLUP, KEY_SCROLLDOWN, KEY_EDIT, KEY_SLEEP, - KEY_SCREENLOCK, KEY_REFRESH, KEY_CALC, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED + KEY_SCROLLLOCK, KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP, + KEY_DELETE, KEY_END, KEY_PAGEDOWN, KEY_RIGHT, KEY_LEFT, KEY_DOWN, + KEY_UP, KEY_NUMLOCK, KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS, + KEY_KPPLUS, KEY_KPENTER, KEY_KP1, KEY_KP2, KEY_KP3, KEY_KP4, KEY_KP5, + KEY_KP6, KEY_KP7, KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT, KEY_102ND, + KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL, KEY_F13, KEY_F14, KEY_F15, + KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20, KEY_F21, KEY_F22, + KEY_F23, KEY_F24, KEY_OPEN, KEY_HELP, KEY_PROPS, KEY_FRONT, KEY_STOP, + KEY_AGAIN, KEY_UNDO, KEY_CUT, KEY_COPY, KEY_PASTE, KEY_FIND, KEY_MUTE, + KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_KPCOMMA, KEY_RESERVED, KEY_RO, KEY_KATAKANAHIRAGANA , KEY_YEN, + KEY_HENKAN, KEY_MUHENKAN, KEY_KPJPCOMMA, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_HANGEUL, KEY_HANJA, KEY_KATAKANA, KEY_HIRAGANA, + KEY_ZENKAKUHANKAKU, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_LEFTCTRL, KEY_LEFTSHIFT, KEY_LEFTALT, + KEY_LEFTMETA, KEY_RIGHTCTRL, KEY_RIGHTSHIFT, KEY_RIGHTALT, + KEY_RIGHTMETA, KEY_PLAYPAUSE, KEY_STOPCD, KEY_PREVIOUSSONG, + KEY_NEXTSONG, KEY_EJECTCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE, + KEY_WWW, KEY_BACK, KEY_FORWARD, KEY_STOP, KEY_FIND, KEY_SCROLLUP, + KEY_SCROLLDOWN, KEY_EDIT, KEY_SLEEP, KEY_SCREENLOCK, KEY_REFRESH, + KEY_CALC, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED }; static void dc_scan_kbd(struct dc_kbd *kbd) @@ -151,14 +163,15 @@ static int dc_kbd_connect(struct maple_device *mdev) struct dc_kbd *kbd; struct input_dev *dev; - if (!(mdev->function & MAPLE_FUNC_KEYBOARD)) - return -EINVAL; - kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); + if (!kbd) { + error = -ENOMEM; + goto fail_kbd; + } dev = input_allocate_device(); - if (!kbd || !dev) { + if (!dev) { error = -ENOMEM; - goto fail; + goto fail_dev; } mdev->private_data = kbd; @@ -169,7 +182,7 @@ static int dc_kbd_connect(struct maple_device *mdev) dev->name = mdev->product_name; dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); dev->keycode = kbd->keycode; - dev->keycodesize = sizeof (unsigned short); + dev->keycodesize = sizeof(unsigned short); dev->keycodemax = ARRAY_SIZE(kbd->keycode); dev->id.bustype = BUS_HOST; dev->dev.parent = &mdev->dev; @@ -186,12 +199,15 @@ static int dc_kbd_connect(struct maple_device *mdev) goto fail; /* Maple polling is locked to VBLANK - which may be just 50/s */ - maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, MAPLE_FUNC_KEYBOARD); + maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, + MAPLE_FUNC_KEYBOARD); return 0; - fail: +fail: input_free_device(dev); +fail_dev: kfree(kbd); +fail_kbd: mdev->private_data = NULL; return error; } @@ -201,7 +217,7 @@ static void dc_kbd_disconnect(struct maple_device *mdev) struct dc_kbd *kbd; mutex_lock(&maple_keyb_mutex); - + mdev->callback = NULL; kbd = mdev->private_data; mdev->private_data = NULL; input_unregister_device(kbd->dev); @@ -222,11 +238,18 @@ static int probe_maple_kbd(struct device *dev) return error; mdev->driver = mdrv; - mdev->registered = 1; return 0; } +static int remove_maple_kbd(struct device *dev) +{ + struct maple_device *mdev = to_maple_dev(dev); + + dc_kbd_disconnect(mdev); + return 0; +} + static struct maple_driver dc_kbd_driver = { .function = MAPLE_FUNC_KEYBOARD, .connect = dc_kbd_connect, @@ -234,9 +257,23 @@ static struct maple_driver dc_kbd_driver = { .drv = { .name = "Dreamcast_keyboard", .probe = probe_maple_kbd, + .remove = remove_maple_kbd, }, }; +static int unplug_maple_keyb(struct device *dev, void *ignored) +{ + /* Please DO NOT really unplug your keyboard */ + struct maple_device *mdev; + + mdev = to_maple_dev(dev); + if ((mdev->function & MAPLE_FUNC_KEYBOARD) + && (mdev->driver == &dc_kbd_driver)) + remove_maple_kbd(dev); + + return 0; +} + static int __init dc_kbd_init(void) { return maple_driver_register(&dc_kbd_driver.drv); @@ -244,6 +281,7 @@ static int __init dc_kbd_init(void) static void __exit dc_kbd_exit(void) { + bus_for_each_dev(&maple_bus_type, NULL, NULL, unplug_maple_keyb); driver_unregister(&dc_kbd_driver.drv); } -- cgit v1.2.3-70-g09d2 From 459021fe3627083ea6678a7b29f9f74accf9c6fd Mon Sep 17 00:00:00 2001 From: Adrian McMenamin Date: Mon, 4 Aug 2008 10:09:03 +0900 Subject: input: Clean up maple keyboard driver Have a single probe function instead of a probe and a connect function. Also tidy a comment. Signed-off-by: Adrian McMenamin Signed-off-by: Paul Mundt --- drivers/input/keyboard/maple_keyb.c | 101 ++++++++++++------------------------ 1 file changed, 32 insertions(+), 69 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 7d13f55b504..42f5d4ec39a 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -143,8 +143,8 @@ static void dc_kbd_callback(struct mapleq *mq) unsigned long *buf = mq->recvbuf; /* - * We should always be getting the lock because the only - * time it may be locked if driver is in cleanup phase. + * We should always get the lock because the only + * time it may be locked is if the driver is in the cleanup phase. */ if (likely(mutex_trylock(&maple_keyb_mutex))) { @@ -157,103 +157,80 @@ static void dc_kbd_callback(struct mapleq *mq) } } -static int dc_kbd_connect(struct maple_device *mdev) +static int probe_maple_kbd(struct device *dev) { + struct maple_device *mdev = to_maple_dev(dev); + struct maple_driver *mdrv = to_maple_driver(dev->driver); int i, error; struct dc_kbd *kbd; - struct input_dev *dev; + struct input_dev *idev; + + if (!(mdev->function & MAPLE_FUNC_KEYBOARD)) + return -EINVAL; kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); - if (!kbd) { + idev = input_allocate_device(); + if (!kbd || !idev) { error = -ENOMEM; - goto fail_kbd; - } - dev = input_allocate_device(); - if (!dev) { - error = -ENOMEM; - goto fail_dev; + goto fail; } mdev->private_data = kbd; - kbd->dev = dev; + kbd->dev = idev; memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode)); - dev->name = mdev->product_name; - dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - dev->keycode = kbd->keycode; - dev->keycodesize = sizeof(unsigned short); - dev->keycodemax = ARRAY_SIZE(kbd->keycode); - dev->id.bustype = BUS_HOST; - dev->dev.parent = &mdev->dev; + idev->name = mdev->product_name; + idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + idev->keycode = kbd->keycode; + idev->keycodesize = sizeof(unsigned short); + idev->keycodemax = ARRAY_SIZE(kbd->keycode); + idev->id.bustype = BUS_HOST; + idev->dev.parent = &mdev->dev; for (i = 0; i < NR_SCANCODES; i++) - __set_bit(dc_kbd_keycode[i], dev->keybit); - __clear_bit(KEY_RESERVED, dev->keybit); + __set_bit(dc_kbd_keycode[i], idev->keybit); + __clear_bit(KEY_RESERVED, idev->keybit); - input_set_capability(dev, EV_MSC, MSC_SCAN); - input_set_drvdata(dev, kbd); + input_set_capability(idev, EV_MSC, MSC_SCAN); + input_set_drvdata(idev, kbd); - error = input_register_device(dev); + error = input_register_device(idev); if (error) goto fail; /* Maple polling is locked to VBLANK - which may be just 50/s */ maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, MAPLE_FUNC_KEYBOARD); - return 0; + + mdev->driver = mdrv; + return error; fail: - input_free_device(dev); -fail_dev: + input_free_device(idev); kfree(kbd); -fail_kbd: mdev->private_data = NULL; return error; } -static void dc_kbd_disconnect(struct maple_device *mdev) +static int remove_maple_kbd(struct device *dev) { + struct maple_device *mdev = to_maple_dev(dev); struct dc_kbd *kbd; mutex_lock(&maple_keyb_mutex); - mdev->callback = NULL; + kbd = mdev->private_data; mdev->private_data = NULL; input_unregister_device(kbd->dev); kfree(kbd); mutex_unlock(&maple_keyb_mutex); -} - -/* allow the keyboard to be used */ -static int probe_maple_kbd(struct device *dev) -{ - struct maple_device *mdev = to_maple_dev(dev); - struct maple_driver *mdrv = to_maple_driver(dev->driver); - int error; - - error = dc_kbd_connect(mdev); - if (error) - return error; - - mdev->driver = mdrv; - - return 0; -} - -static int remove_maple_kbd(struct device *dev) -{ - struct maple_device *mdev = to_maple_dev(dev); - - dc_kbd_disconnect(mdev); return 0; } static struct maple_driver dc_kbd_driver = { .function = MAPLE_FUNC_KEYBOARD, - .connect = dc_kbd_connect, - .disconnect = dc_kbd_disconnect, .drv = { .name = "Dreamcast_keyboard", .probe = probe_maple_kbd, @@ -261,19 +238,6 @@ static struct maple_driver dc_kbd_driver = { }, }; -static int unplug_maple_keyb(struct device *dev, void *ignored) -{ - /* Please DO NOT really unplug your keyboard */ - struct maple_device *mdev; - - mdev = to_maple_dev(dev); - if ((mdev->function & MAPLE_FUNC_KEYBOARD) - && (mdev->driver == &dc_kbd_driver)) - remove_maple_kbd(dev); - - return 0; -} - static int __init dc_kbd_init(void) { return maple_driver_register(&dc_kbd_driver.drv); @@ -281,7 +245,6 @@ static int __init dc_kbd_init(void) static void __exit dc_kbd_exit(void) { - bus_for_each_dev(&maple_bus_type, NULL, NULL, unplug_maple_keyb); driver_unregister(&dc_kbd_driver.drv); } -- cgit v1.2.3-70-g09d2 From 63870295de9adb365cd121dab94379b8cfdf986a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 10:39:46 +0900 Subject: maple: Clean up maple_driver_register/unregister routines. These were completely inconsistent. Clean these up to take a maple_driver pointer directly for consistency. Signed-off-by: Paul Mundt --- drivers/input/keyboard/maple_keyb.c | 6 +++--- drivers/sh/maple/maple.c | 37 ++++++++++++++++++++++++++----------- include/linux/maple.h | 4 +++- 3 files changed, 32 insertions(+), 15 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 42f5d4ec39a..3f5151a0fd1 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -235,17 +235,17 @@ static struct maple_driver dc_kbd_driver = { .name = "Dreamcast_keyboard", .probe = probe_maple_kbd, .remove = remove_maple_kbd, - }, + }, }; static int __init dc_kbd_init(void) { - return maple_driver_register(&dc_kbd_driver.drv); + return maple_driver_register(&dc_kbd_driver); } static void __exit dc_kbd_exit(void) { - driver_unregister(&dc_kbd_driver.drv); + maple_driver_unregister(&dc_kbd_driver); } module_init(dc_kbd_init); diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index be97789fa5f..a6b4dc3cfcb 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c @@ -2,6 +2,7 @@ * Core maple bus functionality * * Copyright (C) 2007, 2008 Adrian McMenamin + * Copyright (C) 2001 - 2008 Paul Mundt * * Based on 2.4 code by: * @@ -31,7 +32,7 @@ #include #include -MODULE_AUTHOR("Yaegshi Takeshi, Paul Mundt, M.R. Brown, Adrian McMenamin"); +MODULE_AUTHOR("Yaegashi Takeshi, Paul Mundt, M. R. Brown, Adrian McMenamin"); MODULE_DESCRIPTION("Maple bus driver for Dreamcast"); MODULE_LICENSE("GPL v2"); MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}"); @@ -65,19 +66,35 @@ static bool checked[4]; static struct maple_device *baseunits[4]; /** - * maple_driver_register - register a device driver - * automatically makes the driver bus a maple bus - * @drv: the driver to be registered + * maple_driver_register - register a maple driver + * @drv: maple driver to be registered. + * + * Registers the passed in @drv, while updating the bus type. + * Devices with matching function IDs will be automatically probed. */ -int maple_driver_register(struct device_driver *drv) +int maple_driver_register(struct maple_driver *drv) { if (!drv) return -EINVAL; - drv->bus = &maple_bus_type; - return driver_register(drv); + + drv->drv.bus = &maple_bus_type; + + return driver_register(&drv->drv); } EXPORT_SYMBOL_GPL(maple_driver_register); +/** + * maple_driver_unregister - unregister a maple driver. + * @drv: maple driver to unregister. + * + * Cleans up after maple_driver_register(). To be invoked in the exit + * path of any module drivers. + */ +void maple_driver_unregister(struct maple_driver *drv) +{ + driver_unregister(&drv->drv); +} + /* set hardware registers to enable next round of dma */ static void maplebus_dma_reset(void) { @@ -724,11 +741,9 @@ static int maple_get_dma_buffer(void) static int match_maple_bus_driver(struct device *devptr, struct device_driver *drvptr) { - struct maple_driver *maple_drv; - struct maple_device *maple_dev; + struct maple_driver *maple_drv = to_maple_driver(drvptr); + struct maple_device *maple_dev = to_maple_dev(devptr); - maple_drv = container_of(drvptr, struct maple_driver, drv); - maple_dev = container_of(devptr, struct maple_device, dev); /* Trap empty port case */ if (maple_dev->devinfo.function == 0xFFFFFFFF) return 0; diff --git a/include/linux/maple.h b/include/linux/maple.h index c853b106601..b2b7ce0fb1f 100644 --- a/include/linux/maple.h +++ b/include/linux/maple.h @@ -70,7 +70,9 @@ void maple_getcond_callback(struct maple_device *dev, void (*callback) (struct mapleq * mq), unsigned long interval, unsigned long function); -int maple_driver_register(struct device_driver *drv); +int maple_driver_register(struct maple_driver *); +void maple_driver_unregister(struct maple_driver *); + int maple_add_packet_sleeps(struct maple_device *mdev, u32 function, u32 command, u32 length, void *data); void maple_clear_dev(struct maple_device *mdev); -- cgit v1.2.3-70-g09d2 From 617870632de6739fca0893f3e6648e9ae1bd0ddb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 10:58:24 +0900 Subject: maple: Kill useless private_data pointer. We can simply wrap in to the dev_set/get_drvdata(), there's no reason to track an extra level of private data on top of the struct device. Signed-off-by: Paul Mundt --- drivers/input/keyboard/maple_keyb.c | 15 ++++++++------- drivers/sh/maple/maple.c | 1 + include/linux/maple.h | 4 +++- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 3f5151a0fd1..22f17a593be 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -139,7 +139,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd) static void dc_kbd_callback(struct mapleq *mq) { struct maple_device *mapledev = mq->dev; - struct dc_kbd *kbd = mapledev->private_data; + struct dc_kbd *kbd = maple_get_drvdata(mapledev); unsigned long *buf = mq->recvbuf; /* @@ -175,8 +175,6 @@ static int probe_maple_kbd(struct device *dev) goto fail; } - mdev->private_data = kbd; - kbd->dev = idev; memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode)); @@ -204,27 +202,30 @@ static int probe_maple_kbd(struct device *dev) MAPLE_FUNC_KEYBOARD); mdev->driver = mdrv; + + maple_set_drvdata(mdev, kbd); + return error; fail: input_free_device(idev); kfree(kbd); - mdev->private_data = NULL; + maple_set_drvdata(mdev, NULL); return error; } static int remove_maple_kbd(struct device *dev) { struct maple_device *mdev = to_maple_dev(dev); - struct dc_kbd *kbd; + struct dc_kbd *kbd = maple_get_drvdata(mdev); mutex_lock(&maple_keyb_mutex); - kbd = mdev->private_data; - mdev->private_data = NULL; input_unregister_device(kbd->dev); kfree(kbd); + maple_set_drvdata(mdev, NULL); + mutex_unlock(&maple_keyb_mutex); return 0; } diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index a6b4dc3cfcb..be77a39f224 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c @@ -94,6 +94,7 @@ void maple_driver_unregister(struct maple_driver *drv) { driver_unregister(&drv->drv); } +EXPORT_SYMBOL_GPL(maple_driver_unregister); /* set hardware registers to enable next round of dma */ static void maplebus_dma_reset(void) diff --git a/include/linux/maple.h b/include/linux/maple.h index b2b7ce0fb1f..c23d3f51ba4 100644 --- a/include/linux/maple.h +++ b/include/linux/maple.h @@ -51,7 +51,6 @@ struct maple_devinfo { struct maple_device { struct maple_driver *driver; struct mapleq *mq; - void *private_data; void (*callback) (struct mapleq * mq); unsigned long when, interval, function; struct maple_devinfo devinfo; @@ -80,4 +79,7 @@ void maple_clear_dev(struct maple_device *mdev); #define to_maple_dev(n) container_of(n, struct maple_device, dev) #define to_maple_driver(n) container_of(n, struct maple_driver, drv) +#define maple_get_drvdata(d) dev_get_drvdata(&(d)->dev) +#define maple_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, (p)) + #endif /* __LINUX_MAPLE_H */ -- cgit v1.2.3-70-g09d2