From patchwork Mon Nov 5 15:10:31 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 12667 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 72EE923EF8 for ; Mon, 5 Nov 2012 15:10:57 +0000 (UTC) Received: from mail-ia0-f180.google.com (mail-ia0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id CC2E4A19A0B for ; Mon, 5 Nov 2012 15:10:56 +0000 (UTC) Received: by mail-ia0-f180.google.com with SMTP id f6so4196858iag.11 for ; Mon, 05 Nov 2012 07:10:56 -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:in-reply-to:references :x-gm-message-state; bh=p5rTTdb3vulrwZePWfbqjkQMYaAUUPimGQVTnoOQLyQ=; b=fds7ZE7Tbzz6ikfpHFeqIYLXtGJFQGd6AxDUzIsCthWi2wGpKnffv/6mNb7i8fn/pM S6qzbdMcaiYEhTs8FiRM/15e13oeM2gbTuojBH4MCj8HvakBhyKBCWfqTeuS++Vt1ZOC hLOACGydmjOxYvMxoQO4y6lOrKAfwPLLe2Fsl1o1DOBMpORBrgmh/j9iuFL2w9OWbjPC Kzn4ZSEsAVfwSleoPFHOsZKu4Cj5uw6NJoxXlRibYdq4HcEmnqAal3rYq4yaYjAOZO8r GnSaJmIcfQG9zXEjpz1aOObYq8O9rIk8tHL/8wGQtl0VTRjR4teX5VhMOHb6GhIfCppY JaLQ== Received: by 10.42.57.10 with SMTP id b10mr8522968ich.54.1352128256576; Mon, 05 Nov 2012 07:10:56 -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 n20csp231238igt; Mon, 5 Nov 2012 07:10:55 -0800 (PST) Received: by 10.216.210.1 with SMTP id t1mr3560415weo.16.1352128255238; Mon, 05 Nov 2012 07:10:55 -0800 (PST) Received: from mail-wg0-f49.google.com (mail-wg0-f49.google.com [74.125.82.49]) by mx.google.com with ESMTPS id fi1si4301332wib.14.2012.11.05.07.10.54 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 05 Nov 2012 07:10:55 -0800 (PST) Received-SPF: neutral (google.com: 74.125.82.49 is neither permitted nor denied by best guess record for domain of lee.jones@linaro.org) client-ip=74.125.82.49; Authentication-Results: mx.google.com; spf=neutral (google.com: 74.125.82.49 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-wg0-f49.google.com with SMTP id gg4so3499621wgb.6 for ; Mon, 05 Nov 2012 07:10:54 -0800 (PST) Received: by 10.180.87.40 with SMTP id u8mr6739775wiz.3.1352128254704; Mon, 05 Nov 2012 07:10:54 -0800 (PST) Received: from laptop.vlan14.pylonone.local (78.Red-88-2-49.staticIP.rima-tde.net. [88.2.49.78]) by mx.google.com with ESMTPS id ea9sm12275388wib.11.2012.11.05.07.10.53 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 05 Nov 2012 07:10:54 -0800 (PST) From: Lee Jones To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, sameo@linux.intel.com Cc: arnd@arndb.de, linus.walleij@stericsson.com, Lee Jones Subject: [PATCH 3/8] mfd: Provide the STMPE driver with its own IRQ domain Date: Mon, 5 Nov 2012 16:10:31 +0100 Message-Id: <1352128236-11554-4-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1352128236-11554-1-git-send-email-lee.jones@linaro.org> References: <1352128236-11554-1-git-send-email-lee.jones@linaro.org> X-Gm-Message-State: ALoCoQnISMnyN/BJ3nbGvVf1cjc8f4gce2P/Qxw4ZEPW3JdpjZMAvs3dJ4IvkBTXmVX7S/oQJL+J The STMPE driver is yet another IRQ controller which requires its own IRQ domain. So, we provide it with one. Cc: Samuel Ortiz Acked-by: Arnd Bergmann Acked-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/stmpe.c | 82 +++++++++++++++++++++++++++------------------ include/linux/mfd/stmpe.h | 2 ++ 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index ad13cb0..5c8d8f2 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -757,7 +758,9 @@ static irqreturn_t stmpe_irq(int irq, void *data) int i; if (variant->id_val == STMPE801_ID) { - handle_nested_irq(stmpe->irq_base); + int base = irq_create_mapping(stmpe->domain, 0); + + handle_nested_irq(base); return IRQ_HANDLED; } @@ -778,8 +781,9 @@ static irqreturn_t stmpe_irq(int irq, void *data) while (status) { int bit = __ffs(status); int line = bank * 8 + bit; + int nestedirq = irq_create_mapping(stmpe->domain, line); - handle_nested_irq(stmpe->irq_base + line); + handle_nested_irq(nestedirq); status &= ~(1 << bit); } @@ -820,7 +824,7 @@ static void stmpe_irq_sync_unlock(struct irq_data *data) static void stmpe_irq_mask(struct irq_data *data) { struct stmpe *stmpe = irq_data_get_irq_chip_data(data); - int offset = data->irq - stmpe->irq_base; + int offset = data->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -830,7 +834,7 @@ static void stmpe_irq_mask(struct irq_data *data) static void stmpe_irq_unmask(struct irq_data *data) { struct stmpe *stmpe = irq_data_get_irq_chip_data(data); - int offset = data->irq - stmpe->irq_base; + int offset = data->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -845,43 +849,62 @@ static struct irq_chip stmpe_irq_chip = { .irq_unmask = stmpe_irq_unmask, }; -static int __devinit stmpe_irq_init(struct stmpe *stmpe) +static int stmpe_irq_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hwirq) { + struct stmpe *stmpe = d->host_data; struct irq_chip *chip = NULL; - int num_irqs = stmpe->variant->num_irqs; - int base = stmpe->irq_base; - int irq; if (stmpe->variant->id_val != STMPE801_ID) chip = &stmpe_irq_chip; - for (irq = base; irq < base + num_irqs; irq++) { - irq_set_chip_data(irq, stmpe); - irq_set_chip_and_handler(irq, chip, handle_edge_irq); - irq_set_nested_thread(irq, 1); + irq_set_chip_data(virq, stmpe); + irq_set_chip_and_handler(virq, chip, handle_edge_irq); + irq_set_nested_thread(virq, 1); #ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); + set_irq_flags(virq, IRQF_VALID); #else - irq_set_noprobe(irq); + irq_set_noprobe(virq); #endif - } return 0; } -static void stmpe_irq_remove(struct stmpe *stmpe) +static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq) { - int num_irqs = stmpe->variant->num_irqs; - int base = stmpe->irq_base; - int irq; - - for (irq = base; irq < base + num_irqs; 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 struct irq_domain_ops stmpe_irq_ops = { + .map = stmpe_irq_map, + .unmap = stmpe_irq_unmap, + .xlate = irq_domain_xlate_twocell, +}; + +static int __devinit stmpe_irq_init(struct stmpe *stmpe) +{ + int base = stmpe->irq_base; + int num_irqs = stmpe->variant->num_irqs; + + if (base) { + stmpe->domain = irq_domain_add_legacy( + NULL, num_irqs, base, 0, &stmpe_irq_ops, stmpe); + } + else { + stmpe->domain = irq_domain_add_linear( + NULL, num_irqs, &stmpe_irq_ops, stmpe); + } + + if (!stmpe->domain) { + dev_err(stmpe->dev, "Failed to create irqdomain\n"); + return -ENOSYS; } + + return 0; } static int __devinit stmpe_chip_init(struct stmpe *stmpe) @@ -954,7 +977,7 @@ static int __devinit stmpe_add_device(struct stmpe *stmpe, struct mfd_cell *cell) { return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, - NULL, stmpe->irq_base, NULL); + NULL, stmpe->irq_base, stmpe->domain); } static int __devinit stmpe_devices_init(struct stmpe *stmpe) @@ -1067,7 +1090,7 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum) if (ret) { dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret); - goto out_removeirq; + goto free_gpio; } } @@ -1083,9 +1106,6 @@ out_removedevs: mfd_remove_devices(stmpe->dev); if (stmpe->irq >= 0) free_irq(stmpe->irq, stmpe); -out_removeirq: - if (stmpe->irq >= 0) - stmpe_irq_remove(stmpe); free_gpio: if (pdata->irq_over_gpio) gpio_free(pdata->irq_gpio); @@ -1098,10 +1118,8 @@ int stmpe_remove(struct stmpe *stmpe) { mfd_remove_devices(stmpe->dev); - if (stmpe->irq >= 0) { + if (stmpe->irq >= 0) free_irq(stmpe->irq, stmpe); - stmpe_irq_remove(stmpe); - } if (stmpe->pdata->irq_over_gpio) gpio_free(stmpe->pdata->irq_gpio); diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h index f8d5b4d..15dac79 100644 --- a/include/linux/mfd/stmpe.h +++ b/include/linux/mfd/stmpe.h @@ -62,6 +62,7 @@ struct stmpe_client_info; * @lock: lock protecting I/O operations * @irq_lock: IRQ bus lock * @dev: device, mostly for dev_dbg() + * @irq_domain: IRQ domain * @client: client - i2c or spi * @ci: client specific information * @partnum: part number @@ -79,6 +80,7 @@ struct stmpe { struct mutex lock; struct mutex irq_lock; struct device *dev; + struct irq_domain *domain; void *client; struct stmpe_client_info *ci; enum stmpe_partnum partnum;