From patchwork Mon Mar 3 19:51:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Warren X-Patchwork-Id: 3757151 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CD364BF13A for ; Mon, 3 Mar 2014 19:53:22 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D5D482041A for ; Mon, 3 Mar 2014 19:53:21 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CA4B420412 for ; Mon, 3 Mar 2014 19:53:20 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WKYuh-0002JG-Ec; Mon, 03 Mar 2014 19:52:35 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WKYuY-0003NE-Pa; Mon, 03 Mar 2014 19:52:26 +0000 Received: from avon.wwwdotorg.org ([70.85.31.133]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WKYuL-0003KG-0H for linux-arm-kernel@lists.infradead.org; Mon, 03 Mar 2014 19:52:14 +0000 Received: from severn.wwwdotorg.org (unknown [192.168.65.5]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by avon.wwwdotorg.org (Postfix) with ESMTPS id 787886314; Mon, 3 Mar 2014 12:51:50 -0700 (MST) Received: from swarren-lx1.nvidia.com (localhost [127.0.0.1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by severn.wwwdotorg.org (Postfix) with ESMTPSA id D4F12E40E6; Mon, 3 Mar 2014 12:51:47 -0700 (MST) From: Stephen Warren To: Thomas Gleixner , Samuel Ortiz , Lee Jones , Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala Subject: [PATCH V3 1/5] genirq: define flag IRQ_SRC_DST_INVERTED, and accessors Date: Mon, 3 Mar 2014 12:51:36 -0700 Message-Id: <1393876300-3061-1-git-send-email-swarren@wwwdotorg.org> X-Mailer: git-send-email 1.8.1.5 X-NVConfidentiality: public X-Virus-Scanned: clamav-milter 0.97.8 at avon.wwwdotorg.org X-Virus-Status: Clean X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140303_145213_175263_F064B9D6 X-CRM114-Status: GOOD ( 16.72 ) X-Spam-Score: 1.1 (+) Cc: linux-tegra@vger.kernel.org, devicetree@vger.kernel.org, Stephen Warren , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00,KHOP_BIG_TO_CC, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stephen Warren Some devices have configurable IRQ output polarities. Software might use IRQ_TYPE_* to determine how to configure such a device's IRQ output polarity in order to match how the IRQ controller input is configured. If the board or SoC inverts the signal between the device's IRQ output and controller's IRQ output, software must be aware of this fact, in order to program the IRQ output to the correct (i.e. opposite) polarity. This flag provides that information. Signed-off-by: Stephen Warren --- v3: New patch. --- include/linux/irq.h | 12 ++++++++++++ kernel/irq/chip.c | 24 ++++++++++++++++++++++++ kernel/irq/irqdomain.c | 4 ++++ 3 files changed, 40 insertions(+) diff --git a/include/linux/irq.h b/include/linux/irq.h index 7dc10036eff5..535f3937e99e 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -73,6 +73,11 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * IRQ_IS_POLLED - Always polled by another interrupt. Exclude * it from the spurious interrupt detection * mechanism and from core side polling. + * IRQ_SRC_DST_INVERTED - An inverter exists between the source's IRQ + * output, and the IRQ controller's input. + * For devices with programmable output polarity + * this helps the driver match the device output + * to the controller's input polarity. */ enum { IRQ_TYPE_NONE = 0x00000000, @@ -98,6 +103,7 @@ enum { IRQ_NOTHREAD = (1 << 16), IRQ_PER_CPU_DEVID = (1 << 17), IRQ_IS_POLLED = (1 << 18), + IRQ_SRC_DST_INVERTED = (1 << 19), }; #define IRQF_MODIFY_MASK \ @@ -218,6 +224,11 @@ static inline u32 irqd_get_trigger_type(struct irq_data *d) return d->state_use_accessors & IRQD_TRIGGER_MASK; } +static inline u32 irqd_get_src_dst_inverted(struct irq_data *d) +{ + return d->state_use_accessors & IRQ_SRC_DST_INVERTED; +} + /* * Must only be called inside irq_chip.irq_set_type() functions. */ @@ -538,6 +549,7 @@ extern int irq_set_chip(unsigned int irq, struct irq_chip *chip); extern int irq_set_handler_data(unsigned int irq, void *data); extern int irq_set_chip_data(unsigned int irq, void *data); extern int irq_set_irq_type(unsigned int irq, unsigned int type); +extern int irq_set_src_dst_inverted(unsigned int irq, unsigned int inverted); extern int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry); extern int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset, struct msi_desc *entry); diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index dc04c166c54d..ff9e13fa1170 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -70,6 +70,30 @@ int irq_set_irq_type(unsigned int irq, unsigned int type) EXPORT_SYMBOL(irq_set_irq_type); /** + * irq_set_src_dst_inverted(unsigned int irq, u32 inverted) + * @irq: irq number + * @inverted: IRQ_SRC_DST_INVERTED value - see include/linux/irq.h + */ +int irq_set_src_dst_inverted(unsigned int irq, unsigned int inverted) +{ + unsigned long flags; + struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL); + int ret = 0; + + if (!desc) + return -EINVAL; + + inverted &= IRQ_SRC_DST_INVERTED; + if (inverted) + irqd_set(&desc->irq_data, inverted); + else + irqd_clear(&desc->irq_data, inverted); + irq_put_desc_busunlock(desc, flags); + return ret; +} +EXPORT_SYMBOL(irq_set_src_dst_inverted); + +/** * irq_set_handler_data - set irq handler data for an irq * @irq: Interrupt number * @data: Pointer to interrupt specific data diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index f14033700c25..f9cee747424e 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -471,6 +471,7 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data) struct irq_domain *domain; irq_hw_number_t hwirq; unsigned int type = IRQ_TYPE_NONE; + unsigned int inverted = 0; unsigned int virq; domain = irq_data->np ? irq_find_host(irq_data->np) : irq_default_domain; @@ -487,6 +488,8 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data) if (domain->ops->xlate(domain, irq_data->np, irq_data->args, irq_data->args_count, &hwirq, &type)) return 0; + inverted = type & IRQ_SRC_DST_INVERTED; + type &= IRQ_TYPE_SENSE_MASK; } /* Create mapping */ @@ -498,6 +501,7 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data) if (type != IRQ_TYPE_NONE && type != irq_get_trigger_type(virq)) irq_set_irq_type(virq, type); + irq_set_src_dst_inverted(virq, inverted); return virq; } EXPORT_SYMBOL_GPL(irq_create_of_mapping);