diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-07 13:38:46 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-07 13:38:46 -0400 |
| commit | 8b8a7df9a1d87ba413fce246b11f54c636bb456a (patch) | |
| tree | 797265037b52117fa633b32cbe3feacb1b1b0f07 /drivers/input/touchscreen | |
| parent | b04c99e3b845892d754ee8052d6324c39c4040de (diff) | |
| parent | 07176b988ebb20f46a317a60ee1d983fe1630203 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
"A new driver for slidebar on Ideapad laptops and a bunch of assorted
driver fixes"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (32 commits)
Input: add SYN_MAX and SYN_CNT constants
Input: max11801_ts - convert to devm
Input: egalax-ts - fix typo and improve text
Input: MAINTAINERS - change maintainer for cyttsp driver
Input: cyttsp4 - kill 'defined but not used' compiler warnings
Input: add driver for slidebar on Lenovo IdeaPad laptops
Input: omap-keypad - set up irq type from DT
Input: omap-keypad - enable wakeup capability for keypad.
Input: omap-keypad - clear interrupts on open
Input: omap-keypad - convert to threaded IRQ
Input: omap-keypad - use bitfiled instead of hardcoded values
Input: cyttsp4 - remove useless NULL test from cyttsp4_watchdog_timer()
Input: wacom - fix error return code in wacom_probe()
Input: as5011 - fix error return code in as5011_probe()
Input: keyboard, serio - simplify use of devm_ioremap_resource
Input: tegra-kbc - simplify use of devm_ioremap_resource
Input: htcpen - fix incorrect placement of __initdata
Input: qt1070 - add power management ops
Input: wistron_btns - add MODULE_DEVICE_TABLE
Input: wistron_btns - mark the Medion MD96500 keymap as tested
...
Diffstat (limited to 'drivers/input/touchscreen')
| -rw-r--r-- | drivers/input/touchscreen/cy8ctmg110_ts.c | 6 | ||||
| -rw-r--r-- | drivers/input/touchscreen/cyttsp4_core.c | 203 | ||||
| -rw-r--r-- | drivers/input/touchscreen/eeti_ts.c | 6 | ||||
| -rw-r--r-- | drivers/input/touchscreen/htcpen.c | 2 | ||||
| -rw-r--r-- | drivers/input/touchscreen/max11801_ts.c | 37 |
5 files changed, 114 insertions, 140 deletions
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 96e0eedcc7e5..8c651985a5c4 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c | |||
| @@ -291,7 +291,7 @@ err_free_mem: | |||
| 291 | return err; | 291 | return err; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | #ifdef CONFIG_PM | 294 | #ifdef CONFIG_PM_SLEEP |
| 295 | static int cy8ctmg110_suspend(struct device *dev) | 295 | static int cy8ctmg110_suspend(struct device *dev) |
| 296 | { | 296 | { |
| 297 | struct i2c_client *client = to_i2c_client(dev); | 297 | struct i2c_client *client = to_i2c_client(dev); |
| @@ -319,9 +319,9 @@ static int cy8ctmg110_resume(struct device *dev) | |||
| 319 | } | 319 | } |
| 320 | return 0; | 320 | return 0; |
| 321 | } | 321 | } |
| 322 | #endif | ||
| 322 | 323 | ||
| 323 | static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); | 324 | static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); |
| 324 | #endif | ||
| 325 | 325 | ||
| 326 | static int cy8ctmg110_remove(struct i2c_client *client) | 326 | static int cy8ctmg110_remove(struct i2c_client *client) |
| 327 | { | 327 | { |
| @@ -351,9 +351,7 @@ static struct i2c_driver cy8ctmg110_driver = { | |||
| 351 | .driver = { | 351 | .driver = { |
| 352 | .owner = THIS_MODULE, | 352 | .owner = THIS_MODULE, |
| 353 | .name = CY8CTMG110_DRIVER_NAME, | 353 | .name = CY8CTMG110_DRIVER_NAME, |
| 354 | #ifdef CONFIG_PM | ||
| 355 | .pm = &cy8ctmg110_pm, | 354 | .pm = &cy8ctmg110_pm, |
| 356 | #endif | ||
| 357 | }, | 355 | }, |
| 358 | .id_table = cy8ctmg110_idtable, | 356 | .id_table = cy8ctmg110_idtable, |
| 359 | .probe = cy8ctmg110_probe, | 357 | .probe = cy8ctmg110_probe, |
diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c index edcf7993034b..d038575f49db 100644 --- a/drivers/input/touchscreen/cyttsp4_core.c +++ b/drivers/input/touchscreen/cyttsp4_core.c | |||
| @@ -1246,9 +1246,6 @@ static void cyttsp4_watchdog_timer(unsigned long handle) | |||
| 1246 | 1246 | ||
| 1247 | dev_vdbg(cd->dev, "%s: Watchdog timer triggered\n", __func__); | 1247 | dev_vdbg(cd->dev, "%s: Watchdog timer triggered\n", __func__); |
| 1248 | 1248 | ||
| 1249 | if (!cd) | ||
| 1250 | return; | ||
| 1251 | |||
| 1252 | if (!work_pending(&cd->watchdog_work)) | 1249 | if (!work_pending(&cd->watchdog_work)) |
| 1253 | schedule_work(&cd->watchdog_work); | 1250 | schedule_work(&cd->watchdog_work); |
| 1254 | 1251 | ||
| @@ -1552,106 +1549,6 @@ exit: | |||
| 1552 | return rc; | 1549 | return rc; |
| 1553 | } | 1550 | } |
| 1554 | 1551 | ||
| 1555 | static int cyttsp4_core_sleep(struct cyttsp4 *cd) | ||
| 1556 | { | ||
| 1557 | int rc; | ||
| 1558 | |||
| 1559 | rc = cyttsp4_request_exclusive(cd, cd->dev, | ||
| 1560 | CY_CORE_SLEEP_REQUEST_EXCLUSIVE_TIMEOUT); | ||
| 1561 | if (rc < 0) { | ||
| 1562 | dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n", | ||
| 1563 | __func__, cd->exclusive_dev, cd->dev); | ||
| 1564 | return 0; | ||
| 1565 | } | ||
| 1566 | |||
| 1567 | rc = cyttsp4_core_sleep_(cd); | ||
| 1568 | |||
| 1569 | if (cyttsp4_release_exclusive(cd, cd->dev) < 0) | ||
| 1570 | dev_err(cd->dev, "%s: fail to release exclusive\n", __func__); | ||
| 1571 | else | ||
| 1572 | dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__); | ||
| 1573 | |||
| 1574 | return rc; | ||
| 1575 | } | ||
| 1576 | |||
| 1577 | static int cyttsp4_core_wake_(struct cyttsp4 *cd) | ||
| 1578 | { | ||
| 1579 | struct device *dev = cd->dev; | ||
| 1580 | int rc; | ||
| 1581 | u8 mode; | ||
| 1582 | int t; | ||
| 1583 | |||
| 1584 | /* Already woken? */ | ||
| 1585 | mutex_lock(&cd->system_lock); | ||
| 1586 | if (cd->sleep_state == SS_SLEEP_OFF) { | ||
| 1587 | mutex_unlock(&cd->system_lock); | ||
| 1588 | return 0; | ||
| 1589 | } | ||
| 1590 | cd->int_status &= ~CY_INT_IGNORE; | ||
| 1591 | cd->int_status |= CY_INT_AWAKE; | ||
| 1592 | cd->sleep_state = SS_WAKING; | ||
| 1593 | |||
| 1594 | if (cd->cpdata->power) { | ||
| 1595 | dev_dbg(dev, "%s: Power up HW\n", __func__); | ||
| 1596 | rc = cd->cpdata->power(cd->cpdata, 1, dev, &cd->ignore_irq); | ||
| 1597 | } else { | ||
| 1598 | dev_dbg(dev, "%s: No power function\n", __func__); | ||
| 1599 | rc = -ENOSYS; | ||
| 1600 | } | ||
| 1601 | if (rc < 0) { | ||
| 1602 | dev_err(dev, "%s: HW Power up fails r=%d\n", | ||
| 1603 | __func__, rc); | ||
| 1604 | |||
| 1605 | /* Initiate a read transaction to wake up */ | ||
| 1606 | cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(mode), &mode); | ||
| 1607 | } else | ||
| 1608 | dev_vdbg(cd->dev, "%s: HW power up succeeds\n", | ||
| 1609 | __func__); | ||
| 1610 | mutex_unlock(&cd->system_lock); | ||
| 1611 | |||
| 1612 | t = wait_event_timeout(cd->wait_q, | ||
| 1613 | (cd->int_status & CY_INT_AWAKE) == 0, | ||
| 1614 | msecs_to_jiffies(CY_CORE_WAKEUP_TIMEOUT)); | ||
| 1615 | if (IS_TMO(t)) { | ||
| 1616 | dev_err(dev, "%s: TMO waiting for wakeup\n", __func__); | ||
| 1617 | mutex_lock(&cd->system_lock); | ||
| 1618 | cd->int_status &= ~CY_INT_AWAKE; | ||
| 1619 | /* Try starting up */ | ||
| 1620 | cyttsp4_queue_startup_(cd); | ||
| 1621 | mutex_unlock(&cd->system_lock); | ||
| 1622 | } | ||
| 1623 | |||
| 1624 | mutex_lock(&cd->system_lock); | ||
| 1625 | cd->sleep_state = SS_SLEEP_OFF; | ||
| 1626 | mutex_unlock(&cd->system_lock); | ||
| 1627 | |||
| 1628 | cyttsp4_start_wd_timer(cd); | ||
| 1629 | |||
| 1630 | return 0; | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | static int cyttsp4_core_wake(struct cyttsp4 *cd) | ||
| 1634 | { | ||
| 1635 | int rc; | ||
| 1636 | |||
| 1637 | rc = cyttsp4_request_exclusive(cd, cd->dev, | ||
| 1638 | CY_CORE_REQUEST_EXCLUSIVE_TIMEOUT); | ||
| 1639 | if (rc < 0) { | ||
| 1640 | dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n", | ||
| 1641 | __func__, cd->exclusive_dev, cd->dev); | ||
| 1642 | return 0; | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | rc = cyttsp4_core_wake_(cd); | ||
| 1646 | |||
| 1647 | if (cyttsp4_release_exclusive(cd, cd->dev) < 0) | ||
| 1648 | dev_err(cd->dev, "%s: fail to release exclusive\n", __func__); | ||
| 1649 | else | ||
| 1650 | dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__); | ||
| 1651 | |||
| 1652 | return rc; | ||
| 1653 | } | ||
| 1654 | |||
| 1655 | static int cyttsp4_startup_(struct cyttsp4 *cd) | 1552 | static int cyttsp4_startup_(struct cyttsp4 *cd) |
| 1656 | { | 1553 | { |
| 1657 | int retry = CY_CORE_STARTUP_RETRY_COUNT; | 1554 | int retry = CY_CORE_STARTUP_RETRY_COUNT; |
| @@ -1821,6 +1718,106 @@ static void cyttsp4_free_si_ptrs(struct cyttsp4 *cd) | |||
| 1821 | } | 1718 | } |
| 1822 | 1719 | ||
| 1823 | #if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME) | 1720 | #if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME) |
| 1721 | static int cyttsp4_core_sleep(struct cyttsp4 *cd) | ||
| 1722 | { | ||
| 1723 | int rc; | ||
| 1724 | |||
| 1725 | rc = cyttsp4_request_exclusive(cd, cd->dev, | ||
| 1726 | CY_CORE_SLEEP_REQUEST_EXCLUSIVE_TIMEOUT); | ||
| 1727 | if (rc < 0) { | ||
| 1728 | dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n", | ||
| 1729 | __func__, cd->exclusive_dev, cd->dev); | ||
| 1730 | return 0; | ||
| 1731 | } | ||
| 1732 | |||
| 1733 | rc = cyttsp4_core_sleep_(cd); | ||
| 1734 | |||
| 1735 | if (cyttsp4_release_exclusive(cd, cd->dev) < 0) | ||
| 1736 | dev_err(cd->dev, "%s: fail to release exclusive\n", __func__); | ||
| 1737 | else | ||
| 1738 | dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__); | ||
| 1739 | |||
| 1740 | return rc; | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | static int cyttsp4_core_wake_(struct cyttsp4 *cd) | ||
| 1744 | { | ||
| 1745 | struct device *dev = cd->dev; | ||
| 1746 | int rc; | ||
| 1747 | u8 mode; | ||
| 1748 | int t; | ||
| 1749 | |||
| 1750 | /* Already woken? */ | ||
| 1751 | mutex_lock(&cd->system_lock); | ||
| 1752 | if (cd->sleep_state == SS_SLEEP_OFF) { | ||
| 1753 | mutex_unlock(&cd->system_lock); | ||
| 1754 | return 0; | ||
| 1755 | } | ||
| 1756 | cd->int_status &= ~CY_INT_IGNORE; | ||
| 1757 | cd->int_status |= CY_INT_AWAKE; | ||
| 1758 | cd->sleep_state = SS_WAKING; | ||
| 1759 | |||
| 1760 | if (cd->cpdata->power) { | ||
| 1761 | dev_dbg(dev, "%s: Power up HW\n", __func__); | ||
| 1762 | rc = cd->cpdata->power(cd->cpdata, 1, dev, &cd->ignore_irq); | ||
| 1763 | } else { | ||
| 1764 | dev_dbg(dev, "%s: No power function\n", __func__); | ||
| 1765 | rc = -ENOSYS; | ||
| 1766 | } | ||
| 1767 | if (rc < 0) { | ||
| 1768 | dev_err(dev, "%s: HW Power up fails r=%d\n", | ||
| 1769 | __func__, rc); | ||
| 1770 | |||
| 1771 | /* Initiate a read transaction to wake up */ | ||
| 1772 | cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(mode), &mode); | ||
| 1773 | } else | ||
| 1774 | dev_vdbg(cd->dev, "%s: HW power up succeeds\n", | ||
| 1775 | __func__); | ||
| 1776 | mutex_unlock(&cd->system_lock); | ||
| 1777 | |||
| 1778 | t = wait_event_timeout(cd->wait_q, | ||
| 1779 | (cd->int_status & CY_INT_AWAKE) == 0, | ||
| 1780 | msecs_to_jiffies(CY_CORE_WAKEUP_TIMEOUT)); | ||
| 1781 | if (IS_TMO(t)) { | ||
| 1782 | dev_err(dev, "%s: TMO waiting for wakeup\n", __func__); | ||
| 1783 | mutex_lock(&cd->system_lock); | ||
| 1784 | cd->int_status &= ~CY_INT_AWAKE; | ||
| 1785 | /* Try starting up */ | ||
| 1786 | cyttsp4_queue_startup_(cd); | ||
| 1787 | mutex_unlock(&cd->system_lock); | ||
| 1788 | } | ||
| 1789 | |||
| 1790 | mutex_lock(&cd->system_lock); | ||
| 1791 | cd->sleep_state = SS_SLEEP_OFF; | ||
| 1792 | mutex_unlock(&cd->system_lock); | ||
| 1793 | |||
| 1794 | cyttsp4_start_wd_timer(cd); | ||
| 1795 | |||
| 1796 | return 0; | ||
| 1797 | } | ||
| 1798 | |||
| 1799 | static int cyttsp4_core_wake(struct cyttsp4 *cd) | ||
| 1800 | { | ||
| 1801 | int rc; | ||
| 1802 | |||
| 1803 | rc = cyttsp4_request_exclusive(cd, cd->dev, | ||
| 1804 | CY_CORE_REQUEST_EXCLUSIVE_TIMEOUT); | ||
| 1805 | if (rc < 0) { | ||
| 1806 | dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n", | ||
| 1807 | __func__, cd->exclusive_dev, cd->dev); | ||
| 1808 | return 0; | ||
| 1809 | } | ||
| 1810 | |||
| 1811 | rc = cyttsp4_core_wake_(cd); | ||
| 1812 | |||
| 1813 | if (cyttsp4_release_exclusive(cd, cd->dev) < 0) | ||
| 1814 | dev_err(cd->dev, "%s: fail to release exclusive\n", __func__); | ||
| 1815 | else | ||
| 1816 | dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__); | ||
| 1817 | |||
| 1818 | return rc; | ||
| 1819 | } | ||
| 1820 | |||
| 1824 | static int cyttsp4_core_suspend(struct device *dev) | 1821 | static int cyttsp4_core_suspend(struct device *dev) |
| 1825 | { | 1822 | { |
| 1826 | struct cyttsp4 *cd = dev_get_drvdata(dev); | 1823 | struct cyttsp4 *cd = dev_get_drvdata(dev); |
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 8fe5086c8d2e..1ce3d29ffca5 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
| @@ -264,7 +264,7 @@ static int eeti_ts_remove(struct i2c_client *client) | |||
| 264 | return 0; | 264 | return 0; |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | #ifdef CONFIG_PM | 267 | #ifdef CONFIG_PM_SLEEP |
| 268 | static int eeti_ts_suspend(struct device *dev) | 268 | static int eeti_ts_suspend(struct device *dev) |
| 269 | { | 269 | { |
| 270 | struct i2c_client *client = to_i2c_client(dev); | 270 | struct i2c_client *client = to_i2c_client(dev); |
| @@ -302,9 +302,9 @@ static int eeti_ts_resume(struct device *dev) | |||
| 302 | 302 | ||
| 303 | return 0; | 303 | return 0; |
| 304 | } | 304 | } |
| 305 | #endif | ||
| 305 | 306 | ||
| 306 | static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); | 307 | static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); |
| 307 | #endif | ||
| 308 | 308 | ||
| 309 | static const struct i2c_device_id eeti_ts_id[] = { | 309 | static const struct i2c_device_id eeti_ts_id[] = { |
| 310 | { "eeti_ts", 0 }, | 310 | { "eeti_ts", 0 }, |
| @@ -315,9 +315,7 @@ MODULE_DEVICE_TABLE(i2c, eeti_ts_id); | |||
| 315 | static struct i2c_driver eeti_ts_driver = { | 315 | static struct i2c_driver eeti_ts_driver = { |
| 316 | .driver = { | 316 | .driver = { |
| 317 | .name = "eeti_ts", | 317 | .name = "eeti_ts", |
| 318 | #ifdef CONFIG_PM | ||
| 319 | .pm = &eeti_ts_pm, | 318 | .pm = &eeti_ts_pm, |
| 320 | #endif | ||
| 321 | }, | 319 | }, |
| 322 | .probe = eeti_ts_probe, | 320 | .probe = eeti_ts_probe, |
| 323 | .remove = eeti_ts_remove, | 321 | .remove = eeti_ts_remove, |
diff --git a/drivers/input/touchscreen/htcpen.c b/drivers/input/touchscreen/htcpen.c index 6c4fb8436957..66500852341b 100644 --- a/drivers/input/touchscreen/htcpen.c +++ b/drivers/input/touchscreen/htcpen.c | |||
| @@ -221,7 +221,7 @@ static struct isa_driver htcpen_isa_driver = { | |||
| 221 | } | 221 | } |
| 222 | }; | 222 | }; |
| 223 | 223 | ||
| 224 | static struct dmi_system_id __initdata htcshift_dmi_table[] = { | 224 | static struct dmi_system_id htcshift_dmi_table[] __initdata = { |
| 225 | { | 225 | { |
| 226 | .ident = "Shift", | 226 | .ident = "Shift", |
| 227 | .matches = { | 227 | .matches = { |
diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c index 00bc6caa27f5..9f84fcd08732 100644 --- a/drivers/input/touchscreen/max11801_ts.c +++ b/drivers/input/touchscreen/max11801_ts.c | |||
| @@ -181,12 +181,11 @@ static int max11801_ts_probe(struct i2c_client *client, | |||
| 181 | struct input_dev *input_dev; | 181 | struct input_dev *input_dev; |
| 182 | int error; | 182 | int error; |
| 183 | 183 | ||
| 184 | data = kzalloc(sizeof(struct max11801_data), GFP_KERNEL); | 184 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); |
| 185 | input_dev = input_allocate_device(); | 185 | input_dev = devm_input_allocate_device(&client->dev); |
| 186 | if (!data || !input_dev) { | 186 | if (!data || !input_dev) { |
| 187 | dev_err(&client->dev, "Failed to allocate memory\n"); | 187 | dev_err(&client->dev, "Failed to allocate memory\n"); |
| 188 | error = -ENOMEM; | 188 | return -ENOMEM; |
| 189 | goto err_free_mem; | ||
| 190 | } | 189 | } |
| 191 | 190 | ||
| 192 | data->client = client; | 191 | data->client = client; |
| @@ -205,38 +204,21 @@ static int max11801_ts_probe(struct i2c_client *client, | |||
| 205 | 204 | ||
| 206 | max11801_ts_phy_init(data); | 205 | max11801_ts_phy_init(data); |
| 207 | 206 | ||
| 208 | error = request_threaded_irq(client->irq, NULL, max11801_ts_interrupt, | 207 | error = devm_request_threaded_irq(&client->dev, client->irq, NULL, |
| 209 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 208 | max11801_ts_interrupt, |
| 210 | "max11801_ts", data); | 209 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
| 210 | "max11801_ts", data); | ||
| 211 | if (error) { | 211 | if (error) { |
| 212 | dev_err(&client->dev, "Failed to register interrupt\n"); | 212 | dev_err(&client->dev, "Failed to register interrupt\n"); |
| 213 | goto err_free_mem; | 213 | return error; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | error = input_register_device(data->input_dev); | 216 | error = input_register_device(data->input_dev); |
| 217 | if (error) | 217 | if (error) |
| 218 | goto err_free_irq; | 218 | return error; |
| 219 | 219 | ||
| 220 | i2c_set_clientdata(client, data); | 220 | i2c_set_clientdata(client, data); |
| 221 | return 0; | 221 | return 0; |
| 222 | |||
| 223 | err_free_irq: | ||
| 224 | free_irq(client->irq, data); | ||
| 225 | err_free_mem: | ||
| 226 | input_free_device(input_dev); | ||
| 227 | kfree(data); | ||
| 228 | return error; | ||
| 229 | } | ||
| 230 | |||
| 231 | static int max11801_ts_remove(struct i2c_client *client) | ||
| 232 | { | ||
| 233 | struct max11801_data *data = i2c_get_clientdata(client); | ||
| 234 | |||
| 235 | free_irq(client->irq, data); | ||
| 236 | input_unregister_device(data->input_dev); | ||
| 237 | kfree(data); | ||
| 238 | |||
| 239 | return 0; | ||
| 240 | } | 222 | } |
| 241 | 223 | ||
| 242 | static const struct i2c_device_id max11801_ts_id[] = { | 224 | static const struct i2c_device_id max11801_ts_id[] = { |
| @@ -252,7 +234,6 @@ static struct i2c_driver max11801_ts_driver = { | |||
| 252 | }, | 234 | }, |
| 253 | .id_table = max11801_ts_id, | 235 | .id_table = max11801_ts_id, |
| 254 | .probe = max11801_ts_probe, | 236 | .probe = max11801_ts_probe, |
| 255 | .remove = max11801_ts_remove, | ||
| 256 | }; | 237 | }; |
| 257 | 238 | ||
| 258 | module_i2c_driver(max11801_ts_driver); | 239 | module_i2c_driver(max11801_ts_driver); |
