From patchwork Mon Dec 1 07:26:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 416315 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id D740D14017C for ; Mon, 1 Dec 2014 18:23:55 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752619AbaLAHXy (ORCPT ); Mon, 1 Dec 2014 02:23:54 -0500 Received: from webbox1416.server-home.net ([77.236.96.61]:57071 "EHLO webbox1416.server-home.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752608AbaLAHXy (ORCPT ); Mon, 1 Dec 2014 02:23:54 -0500 Received: from imapserver.systec-electronic.com (unknown [212.185.67.148]) by webbox1416.server-home.net (Postfix) with ESMTPA id 32BE627A4CF; Mon, 1 Dec 2014 08:23:52 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by imapserver.systec-electronic.com (Postfix) with ESMTP id 02C78DA0C5F; Mon, 1 Dec 2014 08:23:52 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at imapserver.systec-electronic.com Received: from imapserver.systec-electronic.com ([127.0.0.1]) by localhost (imapserver.systec-electronic.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nhm3o1glbB_d; Mon, 1 Dec 2014 08:23:49 +0100 (CET) Received: from ws-stein.systec-electronic.de (unknown [192.168.10.109]) by imapserver.systec-electronic.com (Postfix) with ESMTP id 7AFFDDA0C3E; Mon, 1 Dec 2014 08:23:49 +0100 (CET) From: Alexander Stein To: Linus Walleij , Rob Herring , Pawel Moll Cc: Alexander Stein , devicetree@vger.kernel.org, linux-gpio@vger.kernel.org Subject: [PATCH v2 1/1] gpio: mcp23s08: Add option to configure IRQ output polarity as active high Date: Mon, 1 Dec 2014 08:26:00 +0100 Message-Id: <1417418760-17368-1-git-send-email-alexander.stein@systec-electronic.com> X-Mailer: git-send-email 2.0.4 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Default is active low, but if property is specified in DT set INTPOL flag. Signed-off-by: Alexander Stein --- Changes in v2: * Modified the commit message and binding text slightly to indicate that this features changes the IRQ output polarity. .../devicetree/bindings/gpio/gpio-mcp23s08.txt | 2 ++ drivers/gpio/gpio-mcp23s08.c | 30 +++++++++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt b/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt index c306a2d0..f3332b9 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt @@ -57,6 +57,8 @@ Optional device specific properties: occurred on. If it is not set, the interrupt are only generated for the bank they belong to. On devices with only one interrupt output this property is useless. +- microchip,irq-active-high: Sets the INTPOL flag in the IOCON register. This + configures the IRQ output polarity as active high. Example I2C (with interrupt): gpiom1: gpio@20 { diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 529025e..1d5ffb4 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -65,6 +65,7 @@ struct mcp23s08_ops { struct mcp23s08 { u8 addr; + bool irq_active_high; u16 cache[11]; u16 irq_rise; @@ -476,6 +477,7 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp) { struct gpio_chip *chip = &mcp->chip; int err, irq, j; + unsigned long irqflags = IRQF_ONESHOT | IRQF_SHARED; mutex_init(&mcp->irq_lock); @@ -484,10 +486,13 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp) if (!mcp->irq_domain) return -ENODEV; + if (mcp->irq_active_high) + irqflags |= IRQF_TRIGGER_HIGH; + else + irqflags |= IRQF_TRIGGER_LOW; + err = devm_request_threaded_irq(chip->dev, mcp->irq, NULL, mcp23s08_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT | - IRQF_SHARED, - dev_name(chip->dev), mcp); + irqflags, dev_name(chip->dev), mcp); if (err != 0) { dev_err(chip->dev, "unable to request IRQ#%d: %d\n", mcp->irq, err); @@ -589,6 +594,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, mcp->data = data; mcp->addr = addr; + mcp->irq_active_high = false; mcp->chip.direction_input = mcp23s08_direction_input; mcp->chip.get = mcp23s08_get; @@ -648,14 +654,24 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, goto fail; mcp->irq_controller = pdata->irq_controller; - if (mcp->irq && mcp->irq_controller && (type == MCP_TYPE_017)) - mirror = pdata->mirror; + if (mcp->irq && mcp->irq_controller) { + mcp->irq_active_high = of_property_read_bool(mcp->chip.of_node, + "microchip,irq-active-high"); - if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror) { + if (type == MCP_TYPE_017) + mirror = pdata->mirror; + } + + if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror || + mcp->irq_active_high) { /* mcp23s17 has IOCON twice, make sure they are in sync */ status &= ~(IOCON_SEQOP | (IOCON_SEQOP << 8)); status |= IOCON_HAEN | (IOCON_HAEN << 8); - status &= ~(IOCON_INTPOL | (IOCON_INTPOL << 8)); + if (mcp->irq_active_high) + status |= IOCON_INTPOL | (IOCON_INTPOL << 8); + else + status &= ~(IOCON_INTPOL | (IOCON_INTPOL << 8)); + if (mirror) status |= IOCON_MIRROR | (IOCON_MIRROR << 8);