From patchwork Tue Jan 24 22:59:06 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 6383 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 1DAB623E29 for ; Tue, 24 Jan 2012 22:59:26 +0000 (UTC) Received: from mail-bk0-f52.google.com (mail-bk0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id F2A10A1817A for ; Tue, 24 Jan 2012 22:59:25 +0000 (UTC) Received: by bkar19 with SMTP id r19so4702418bka.11 for ; Tue, 24 Jan 2012 14:59:25 -0800 (PST) Received: by 10.205.139.12 with SMTP id iu12mr5826689bkc.2.1327445965632; Tue, 24 Jan 2012 14:59:25 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.204.130.220 with SMTP id u28cs117216bks; Tue, 24 Jan 2012 14:59:25 -0800 (PST) Received: by 10.14.11.97 with SMTP id 73mr5129293eew.2.1327445964077; Tue, 24 Jan 2012 14:59:24 -0800 (PST) Received: from eu1sys200aog116.obsmtp.com (eu1sys200aog116.obsmtp.com. [207.126.144.141]) by mx.google.com with SMTP id n14si9353595eeh.142.2012.01.24.14.59.19 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 24 Jan 2012 14:59:24 -0800 (PST) Received-SPF: neutral (google.com: 207.126.144.141 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.141; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.141 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob116.postini.com ([207.126.147.11]) with SMTP ID DSNKTx83x9sDlK6B4rcjMlllmuUIlazuOhyf@postini.com; Tue, 24 Jan 2012 22:59:23 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id 20B693F; Tue, 24 Jan 2012 22:59:06 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id 1D7ED50; Tue, 24 Jan 2012 21:59:11 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id 39E2CA8065; Tue, 24 Jan 2012 23:59:05 +0100 (CET) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Tue, 24 Jan 2012 23:59:13 +0100 From: Linus Walleij To: Samuel Ortiz , Cc: Viresh Kumar , Chris Blair , Linus Walleij Subject: [PATCH v2] mfd/stmpe: Add support for no-interrupt config Date: Tue, 24 Jan 2012 23:59:06 +0100 Message-ID: <1327445946-11470-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.8 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQm5T1CEnAa9EbVkZw+dvO6DcDL8AErrgdD4DI2WjjsxvUuRksC8Q68EVPqQ5cT3knp7j4B4 From: Chris Blair Adds support for boards which have an STMPE device without the interrupt pin connected. Cc: Viresh Kumar Signed-off-by: Chris Blair Tested-by: Michel Jaouen Reviewed-by: Srinidhi Kasagar Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - Corrects initialisation, error condition and driver removal cleanup for the no-irq configuration. --- drivers/mfd/stmpe.c | 114 +++++++++++++++++++++++++------------------- include/linux/mfd/stmpe.h | 2 + 2 files changed, 67 insertions(+), 49 deletions(-) diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index e07947e..04bb013 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -864,7 +864,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe) unsigned int irq_trigger = stmpe->pdata->irq_trigger; int autosleep_timeout = stmpe->pdata->autosleep_timeout; struct stmpe_variant_info *variant = stmpe->variant; - u8 icr; + u8 icr = 0; unsigned int id; u8 data[2]; int ret; @@ -887,31 +887,33 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe) if (ret) return ret; - if (id == STMPE801_ID) - icr = STMPE801_REG_SYS_CTRL_INT_EN; - else - icr = STMPE_ICR_LSB_GIM; - - /* STMPE801 doesn't support Edge interrupts */ - if (id != STMPE801_ID) { - if (irq_trigger == IRQF_TRIGGER_FALLING || - irq_trigger == IRQF_TRIGGER_RISING) - icr |= STMPE_ICR_LSB_EDGE; - } - - if (irq_trigger == IRQF_TRIGGER_RISING || - irq_trigger == IRQF_TRIGGER_HIGH) { + if (!stmpe->pdata->no_irq) { if (id == STMPE801_ID) - icr |= STMPE801_REG_SYS_CTRL_INT_HI; + icr = STMPE801_REG_SYS_CTRL_INT_EN; else - icr |= STMPE_ICR_LSB_HIGH; - } + icr = STMPE_ICR_LSB_GIM; - if (stmpe->pdata->irq_invert_polarity) { - if (id == STMPE801_ID) - icr ^= STMPE801_REG_SYS_CTRL_INT_HI; - else - icr ^= STMPE_ICR_LSB_HIGH; + /* STMPE801 doesn't support Edge interrupts */ + if (id != STMPE801_ID) { + if (irq_trigger == IRQF_TRIGGER_FALLING || + irq_trigger == IRQF_TRIGGER_RISING) + icr |= STMPE_ICR_LSB_EDGE; + } + + if (irq_trigger == IRQF_TRIGGER_RISING || + irq_trigger == IRQF_TRIGGER_HIGH) { + if (id == STMPE801_ID) + icr |= STMPE801_REG_SYS_CTRL_INT_HI; + else + icr |= STMPE_ICR_LSB_HIGH; + } + + if (stmpe->pdata->irq_invert_polarity) { + if (id == STMPE801_ID) + icr ^= STMPE801_REG_SYS_CTRL_INT_HI; + else + icr ^= STMPE_ICR_LSB_HIGH; + } } if (stmpe->pdata->autosleep) { @@ -988,32 +990,42 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum) if (ci->init) ci->init(stmpe); - if (pdata->irq_over_gpio) { - ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe"); - if (ret) { - dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", + if (pdata->no_irq) { + dev_info(stmpe->dev, + "board config says IRQs are not supported\n"); + } else { + if (pdata->irq_over_gpio) { + ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, + "stmpe"); + if (ret) { + dev_err(stmpe->dev, + "failed to request IRQ GPIO: %d\n", ret); - goto out_free; - } + goto out_free; + } - stmpe->irq = gpio_to_irq(pdata->irq_gpio); - } else { - stmpe->irq = ci->irq; + stmpe->irq = gpio_to_irq(pdata->irq_gpio); + } else { + stmpe->irq = ci->irq; + } } ret = stmpe_chip_init(stmpe); if (ret) goto free_gpio; - ret = stmpe_irq_init(stmpe); - if (ret) - goto free_gpio; + if (!pdata->no_irq) { + ret = stmpe_irq_init(stmpe); + if (ret) + goto free_gpio; - ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq, - pdata->irq_trigger | IRQF_ONESHOT, "stmpe", stmpe); - if (ret) { - dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret); - goto out_removeirq; + ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq, + pdata->irq_trigger | IRQF_ONESHOT, + "stmpe", stmpe); + if (ret) { + dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret); + goto out_removeirq; + } } ret = stmpe_devices_init(stmpe); @@ -1026,11 +1038,13 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum) out_removedevs: mfd_remove_devices(stmpe->dev); - free_irq(stmpe->irq, stmpe); + if (!pdata->no_irq) + free_irq(stmpe->irq, stmpe); out_removeirq: - stmpe_irq_remove(stmpe); + if (!pdata->no_irq) + stmpe_irq_remove(stmpe); free_gpio: - if (pdata->irq_over_gpio) + if (!pdata->no_irq && pdata->irq_over_gpio) gpio_free(pdata->irq_gpio); out_free: kfree(stmpe); @@ -1041,11 +1055,13 @@ int stmpe_remove(struct stmpe *stmpe) { mfd_remove_devices(stmpe->dev); - free_irq(stmpe->irq, stmpe); - stmpe_irq_remove(stmpe); + if (!stmpe->pdata->no_irq) { + free_irq(stmpe->irq, stmpe); + stmpe_irq_remove(stmpe); - if (stmpe->pdata->irq_over_gpio) - gpio_free(stmpe->pdata->irq_gpio); + if (stmpe->pdata->irq_over_gpio) + gpio_free(stmpe->pdata->irq_gpio); + } kfree(stmpe); @@ -1057,7 +1073,7 @@ static int stmpe_suspend(struct device *dev) { struct stmpe *stmpe = dev_get_drvdata(dev); - if (device_may_wakeup(dev)) + if (!stmpe->pdata->no_irq && device_may_wakeup(dev)) enable_irq_wake(stmpe->irq); return 0; @@ -1067,7 +1083,7 @@ static int stmpe_resume(struct device *dev) { struct stmpe *stmpe = dev_get_drvdata(dev); - if (device_may_wakeup(dev)) + if (!stmpe->pdata->no_irq && device_may_wakeup(dev)) disable_irq_wake(stmpe->irq); return 0; diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h index ca1d7a3..c4b45fd 100644 --- a/include/linux/mfd/stmpe.h +++ b/include/linux/mfd/stmpe.h @@ -188,6 +188,7 @@ struct stmpe_ts_platform_data { * @irq_invert_polarity: IRQ line is connected with reversed polarity * @autosleep: bool to enable/disable stmpe autosleep * @autosleep_timeout: inactivity timeout in milliseconds for autosleep + * @no_irq: IRQs are not supported on this board * @irq_base: base IRQ number. %STMPE_NR_IRQS irqs will be used, or * %STMPE_NR_INTERNAL_IRQS if the GPIO driver is not used. * @irq_over_gpio: true if gpio is used to get irq @@ -200,6 +201,7 @@ struct stmpe_ts_platform_data { struct stmpe_platform_data { int id; unsigned int blocks; + bool no_irq; int irq_base; unsigned int irq_trigger; bool irq_invert_polarity;