From patchwork Fri Nov 23 12:44:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 13156 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 BACFD23FC2 for ; Fri, 23 Nov 2012 12:44:36 +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 4693EA1871B for ; Fri, 23 Nov 2012 12:44:36 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id c10so1756213ieb.11 for ; Fri, 23 Nov 2012 04:44:35 -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=Sn1VvkRBuPcgxK2LVgKeedU7b0i/+Qb3vCy6xV9U0fs=; b=HMyKG7RhAuiz6MxRUfuLHaDoPTPJikgROnV63AQGfAnZSHWF+eSPLlxwfcU7rOw3NF ororiuaiiCbAwUbtfWUX3ntusfs2GRLwUUyShB6gke7A8rN0KQLQX7VgoL48vOHxLnu+ WXtd23XMHAexrvbogkbNKY4WZuMFO5Vbup9eQpgPS3P/CJPTm00MvXjRvq6g27dReTO8 J8s4VSKXUebRb/E0iukon3IadK2BkMMekDvNLjaY4/3pm5IebuRAtvaFzuCW2u7aNwIx jX2BDbuHpJKPPPIi5bsaolekHU3sjLs9inYFNVRxO80P8aOZvAJ/81Pq4dnUNZHfADFg EujA== Received: by 10.50.173.34 with SMTP id bh2mr3313945igc.70.1353674675617; Fri, 23 Nov 2012 04:44:35 -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 n20csp346504igt; Fri, 23 Nov 2012 04:44:34 -0800 (PST) Received: by 10.180.86.7 with SMTP id l7mr6048371wiz.5.1353674674255; Fri, 23 Nov 2012 04:44:34 -0800 (PST) Received: from mail-wi0-f178.google.com (mail-wi0-f178.google.com [209.85.212.178]) by mx.google.com with ESMTPS id g2si5757745wie.11.2012.11.23.04.44.33 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 23 Nov 2012 04:44:34 -0800 (PST) Received-SPF: neutral (google.com: 209.85.212.178 is neither permitted nor denied by best guess record for domain of lee.jones@linaro.org) client-ip=209.85.212.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.178 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-wi0-f178.google.com with SMTP id hm6so1576383wib.1 for ; Fri, 23 Nov 2012 04:44:33 -0800 (PST) Received: by 10.180.83.97 with SMTP id p1mr5719179wiy.2.1353674673244; Fri, 23 Nov 2012 04:44:33 -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 p2sm9432175wic.7.2012.11.23.04.44.31 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 23 Nov 2012 04:44:32 -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 12:44:25 +0000 Message-Id: <1353674665-31905-1-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 1.7.9.5 X-Gm-Message-State: ALoCoQl8ljfnuvZfW1mWFBbT14WjhYmjNN1z2EbAUP/rLpt5LCcsLOEiOZMAmG0zr5ijUfyyQlIz 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 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..0e0471b 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); +} + +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);