From patchwork Fri Nov 23 15:19:09 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 13162 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 1548323FCD for ; Fri, 23 Nov 2012 15:19:18 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id A3E41A18A44 for ; Fri, 23 Nov 2012 15:19:17 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id c10so1943492ieb.11 for ; Fri, 23 Nov 2012 07:19:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:x-gm-message-state; bh=MnMa/Sw+ccqU3v4ebHJAZFcLLo7AqaQleniX8dSUsqM=; b=YUYtBEBiGMcC5nfw7mQuT4y95iH3Bkbu14m0ngnR9l2WnxVDhorwh/8DpJ1yd5QM2w FeeyPPxhwVvOEn53KAl9mbM1OJr1Eja7GVcHNGz6WMkRNW3dogAkUoP5sw7DL2YnCCyI zlfxn79TKurKgWofeye++GFRVOZ7LIz5EArwcCTct0QX2tYVPfQqTRPj1G4iZD9TTCcD X9hFDKV2uLCS71XRvknlsyBIcVDpZVM/bnPnHV4Pu+WQxrbhnbgkxCbta4OTesVVu6J/ zFZPBov0aLPzzaecoc/DArDnAfdLu4AYXgiDk1pA1R9gCTAC8tFxiE3aHcnTw1lso1/K Z83A== Received: by 10.43.125.133 with SMTP id gs5mr3361749icc.54.1353683957082; Fri, 23 Nov 2012 07:19:17 -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.50.67.148 with SMTP id n20csp366716igt; Fri, 23 Nov 2012 07:19:16 -0800 (PST) Received: by 10.216.143.105 with SMTP id k83mr759299wej.15.1353683955556; Fri, 23 Nov 2012 07:19:15 -0800 (PST) Received: from mail-we0-f169.google.com (mail-we0-f169.google.com [74.125.82.169]) by mx.google.com with ESMTPS id o61si3658997wed.28.2012.11.23.07.19.15 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 23 Nov 2012 07:19:15 -0800 (PST) Received-SPF: neutral (google.com: 74.125.82.169 is neither permitted nor denied by best guess record for domain of lee.jones@linaro.org) client-ip=74.125.82.169; Authentication-Results: mx.google.com; spf=neutral (google.com: 74.125.82.169 is neither permitted nor denied by best guess record for domain of lee.jones@linaro.org) smtp.mail=lee.jones@linaro.org Received: by mail-we0-f169.google.com with SMTP id t49so1456160wey.28 for ; Fri, 23 Nov 2012 07:19:15 -0800 (PST) Received: by 10.180.83.97 with SMTP id p1mr6494069wiy.2.1353683954865; Fri, 23 Nov 2012 07:19:14 -0800 (PST) Received: from localhost.localdomain (cpc1-aztw13-0-0-cust473.18-1.cable.virginmedia.com. [77.102.241.218]) by mx.google.com with ESMTPS id dm3sm7095243wib.9.2012.11.23.07.19.13 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 23 Nov 2012 07:19:14 -0800 (PST) From: Lee Jones To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: arnd@arndb.de, linus.walleij@stericsson.com, viresh.kumar@linaro.org, Lee Jones , Grant Likely Subject: [PATCH 1/1] gpio: Provide the STMPE GPIO driver with its own IRQ Domain Date: Fri, 23 Nov 2012 15:19:09 +0000 Message-Id: <1353683949-9275-1-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 1.7.9.5 X-Gm-Message-State: ALoCoQn5fHbFQ2zrbAZImwlbfXX7Vk5kHhhXiybfEHYqpufoyu9MD7cT6uRU2xCMT1tD0iJo451t The STMPE GPIO driver can be used as an IRQ controller by some related devices. Here we provide it with its very own IRQ Domain so that IRQs can be issued dynamically. This will stand the driver in good stead when it is enabled for Device Tree, as this it a prerequisite. Cc: Grant Likely Reviewed-by: Viresh Kumar Signed-off-by: Lee Jones --- drivers/gpio/gpio-stmpe.c | 67 +++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index dce3472..5a87ed6 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,7 @@ struct stmpe_gpio { struct stmpe *stmpe; struct device *dev; struct mutex irq_lock; + struct irq_domain *domain; int irq_base; unsigned norequest_mask; @@ -267,38 +269,55 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) return IRQ_HANDLED; } -static int __devinit stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) +int stmpe_gpio_irq_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hwirq) { - int base = stmpe_gpio->irq_base; - int irq; + struct stmpe_gpio *stmpe_gpio = d->host_data; + + if (!stmpe_gpio) + return -EINVAL; - for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) { - irq_set_chip_data(irq, stmpe_gpio); - irq_set_chip_and_handler(irq, &stmpe_gpio_irq_chip, - handle_simple_irq); - irq_set_nested_thread(irq, 1); + irq_set_chip_data(hwirq, stmpe_gpio); + irq_set_chip_and_handler(hwirq, &stmpe_gpio_irq_chip, + handle_simple_irq); + irq_set_nested_thread(hwirq, 1); #ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); + set_irq_flags(hwirq, IRQF_VALID); #else - irq_set_noprobe(irq); + irq_set_noprobe(hwirq); #endif - } return 0; } -static void stmpe_gpio_irq_remove(struct stmpe_gpio *stmpe_gpio) +void stmpe_gpio_irq_unmap(struct irq_domain *d, unsigned int virq) { - int base = stmpe_gpio->irq_base; - int irq; - - for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) { #ifdef CONFIG_ARM - set_irq_flags(irq, 0); + set_irq_flags(virq, 0); #endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); + irq_set_chip_and_handler(virq, NULL, NULL); + irq_set_chip_data(virq, NULL); +} + +static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = { + .unmap = stmpe_gpio_irq_unmap, + .map = stmpe_gpio_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +static int __devinit stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) +{ + int base = stmpe_gpio->irq_base; + + stmpe_gpio->domain = irq_domain_add_simple(NULL, + stmpe_gpio->chip.ngpio, base, + &stmpe_gpio_irq_simple_ops, stmpe_gpio); + if (!stmpe_gpio->domain) { + dev_err(stmpe_gpio->dev, "failed to create irqdomain\n"); + return -ENOSYS; } + + return 0; } static int __devinit stmpe_gpio_probe(struct platform_device *pdev) @@ -348,7 +367,7 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio); if (ret) { dev_err(&pdev->dev, "unable to get irq: %d\n", ret); - goto out_removeirq; + goto out_disable; } } @@ -368,9 +387,6 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) out_freeirq: if (irq >= 0) free_irq(irq, stmpe_gpio); -out_removeirq: - if (irq >= 0) - stmpe_gpio_irq_remove(stmpe_gpio); out_disable: stmpe_disable(stmpe, STMPE_BLOCK_GPIO); out_free: @@ -398,10 +414,9 @@ static int __devexit stmpe_gpio_remove(struct platform_device *pdev) stmpe_disable(stmpe, STMPE_BLOCK_GPIO); - if (irq >= 0) { + if (irq >= 0) free_irq(irq, stmpe_gpio); - stmpe_gpio_irq_remove(stmpe_gpio); - } + platform_set_drvdata(pdev, NULL); kfree(stmpe_gpio);