Pablo Greco d6c4c4
From patchwork Wed Oct  2 12:28:24 2019
Pablo Greco d6c4c4
Content-Type: text/plain; charset="utf-8"
Pablo Greco d6c4c4
MIME-Version: 1.0
Pablo Greco d6c4c4
Content-Transfer-Encoding: 7bit
Pablo Greco d6c4c4
X-Patchwork-Submitter: Thierry Reding <thierry.reding@gmail.com>
Pablo Greco d6c4c4
X-Patchwork-Id: 1170635
Pablo Greco d6c4c4
Return-Path: <linux-gpio-owner@vger.kernel.org>
Pablo Greco d6c4c4
X-Original-To: incoming@patchwork.ozlabs.org
Pablo Greco d6c4c4
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
Pablo Greco d6c4c4
Authentication-Results: ozlabs.org;
Pablo Greco d6c4c4
 spf=none (mailfrom) smtp.mailfrom=vger.kernel.org
Pablo Greco d6c4c4
 (client-ip=209.132.180.67; helo=vger.kernel.org;
Pablo Greco d6c4c4
 envelope-from=linux-gpio-owner@vger.kernel.org;
Pablo Greco d6c4c4
 receiver=<unknown>)
Pablo Greco d6c4c4
Authentication-Results: ozlabs.org;
Pablo Greco d6c4c4
 dmarc=pass (p=none dis=none) header.from=gmail.com
Pablo Greco d6c4c4
Authentication-Results: ozlabs.org; dkim=pass (2048-bit key;
Pablo Greco d6c4c4
 unprotected) header.d=gmail.com header.i=@gmail.com
Pablo Greco d6c4c4
 header.b="ZNLKx8UP"; dkim-atps=neutral
Pablo Greco d6c4c4
Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
Pablo Greco d6c4c4
 by ozlabs.org (Postfix) with ESMTP id 46jwRG4D1Dz9sPj
Pablo Greco d6c4c4
 for <incoming@patchwork.ozlabs.org>;
Pablo Greco d6c4c4
 Wed,  2 Oct 2019 22:28:42 +1000 (AEST)
Pablo Greco d6c4c4
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
Pablo Greco d6c4c4
 id S1726684AbfJBM2d (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);
Pablo Greco d6c4c4
 Wed, 2 Oct 2019 08:28:33 -0400
Pablo Greco d6c4c4
Received: from mail-wr1-f66.google.com ([209.85.221.66]:43919 "EHLO
Pablo Greco d6c4c4
 mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
Pablo Greco d6c4c4
 with ESMTP id S1725848AbfJBM2c (ORCPT
Pablo Greco d6c4c4
 <rfc822; linux-gpio@vger.kernel.org="">); Wed, 2 Oct 2019 08:28:32 -0400
Pablo Greco d6c4c4
Received: by mail-wr1-f66.google.com with SMTP id q17so19436519wrx.10;
Pablo Greco d6c4c4
 Wed, 02 Oct 2019 05:28:30 -0700 (PDT)
Pablo Greco d6c4c4
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
Pablo Greco d6c4c4
 h=from:to:cc:subject:date:message-id:in-reply-to:references
Pablo Greco d6c4c4
 :mime-version:content-transfer-encoding;
Pablo Greco d6c4c4
 bh=iB2sFoZ4x2KF5IYNHgeqY98wXl2bB2JULeTFtyoqdVY=;
Pablo Greco d6c4c4
 b=ZNLKx8UP+ukUsboEbPQ9oqLgg5M+37mex1mpr0SgaI7zjToRbmdCJL/chPAEK2r7t8
Pablo Greco d6c4c4
 C+RcBU7oQnbO3L1hTZQh1VyMX84xXmn0x8g7AskW0bydPo29O2lwBgM9BeNJiMt7gaS7
Pablo Greco d6c4c4
 LtCbNGe/ttaTfoTsJSOmpLgAJLVJ7mpN5r3h18HtAYcsB5NqjcgFF1yFZ9FvmXOIhxAm
Pablo Greco d6c4c4
 1MxDJ7tO9pJbc4JQ8iR/yPEsCNibvlX1qtkuBUWdy6aJHG4CkqIbqb+V+84d3R5bsmoe
Pablo Greco d6c4c4
 sDx7f/mMbJ6cF7dCarqOe47Quscz7UkGw/gZywhaYNS/7p6JBvKDCe0bbruzj3MEXMRy
Pablo Greco d6c4c4
 2tlw==
Pablo Greco d6c4c4
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
Pablo Greco d6c4c4
 d=1e100.net; s=20161025;
Pablo Greco d6c4c4
 h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
Pablo Greco d6c4c4
 :references:mime-version:content-transfer-encoding;
Pablo Greco d6c4c4
 bh=iB2sFoZ4x2KF5IYNHgeqY98wXl2bB2JULeTFtyoqdVY=;
Pablo Greco d6c4c4
 b=E8tcBQ6lyFYE0z3JyOT1cT/Bgc194gfYXxSrFLZnHENJjrNz2Ijr9mgmTvanMcmLgs
Pablo Greco d6c4c4
 qvPIH6L5rKKzPpmhxkGCVNMunQuR3U4+g4lCHaJuDE3QikN/dAMpfidmgej7UBcnxYXq
Pablo Greco d6c4c4
 c8yhdhWsg36bVdUYmTdrPVNYayH3WqNj6h3724+nRQnwGs5Y+emoWuhckIBZQR2fJd3Z
Pablo Greco d6c4c4
 jEEmej1F2QBBv4/Cf7RoOd9BVX1DFI3LgOoGADQcGnuCW/+2clFWp860wnWLGdTGqPKI
Pablo Greco d6c4c4
 KCaPoNOzFDkbQCyhebPt8recsiTexB8AmRdTCOszf/TYQwmlvVUUSVqdwY4/P2N0uAGO
Pablo Greco d6c4c4
 8kOA==
Pablo Greco d6c4c4
X-Gm-Message-State: APjAAAVWUbix6mCYosiAjDRWTB69Pz3baQGdU6UKJJJba2d6nCyRFzs3
Pablo Greco d6c4c4
 w1iyx5KVIbR84BwLezjxgUk=
Pablo Greco d6c4c4
X-Google-Smtp-Source: APXvYqylRlhdhO5L5gTZTUh+KEGBPZYsf15BqzctBqRpCy2v75DzIQkOOs8h+NZd8ePk6530OH8SlA==
Pablo Greco d6c4c4
X-Received: by 2002:adf:f112:: with SMTP id r18mr2493221wro.88.1570019309276; 
Pablo Greco d6c4c4
 Wed, 02 Oct 2019 05:28:29 -0700 (PDT)
Pablo Greco d6c4c4
Received: from localhost (p2E5BE2CE.dip0.t-ipconnect.de. [46.91.226.206])
Pablo Greco d6c4c4
 by smtp.gmail.com with ESMTPSA id
Pablo Greco d6c4c4
 h17sm10777194wme.6.2019.10.02.05.28.28
Pablo Greco d6c4c4
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
Pablo Greco d6c4c4
 Wed, 02 Oct 2019 05:28:28 -0700 (PDT)
Pablo Greco d6c4c4
From: Thierry Reding <thierry.reding@gmail.com>
Pablo Greco d6c4c4
To: Linus Walleij <linus.walleij@linaro.org>,
Pablo Greco d6c4c4
 Bartosz Golaszewski <bgolaszewski@baylibre.com>
Pablo Greco d6c4c4
Cc: Timo Alho <talho@nvidia.com>, linux-gpio@vger.kernel.org,
Pablo Greco d6c4c4
 linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org
Pablo Greco d6c4c4
Subject: [PATCH 2/3] gpio: max77620: Do not allocate IRQs upfront
Pablo Greco d6c4c4
Date: Wed,  2 Oct 2019 14:28:24 +0200
Pablo Greco d6c4c4
Message-Id: <20191002122825.3948322-2-thierry.reding@gmail.com>
Pablo Greco d6c4c4
X-Mailer: git-send-email 2.23.0
Pablo Greco d6c4c4
In-Reply-To: <20191002122825.3948322-1-thierry.reding@gmail.com>
Pablo Greco d6c4c4
References: <20191002122825.3948322-1-thierry.reding@gmail.com>
Pablo Greco d6c4c4
MIME-Version: 1.0
Pablo Greco d6c4c4
Sender: linux-gpio-owner@vger.kernel.org
Pablo Greco d6c4c4
Precedence: bulk
Pablo Greco d6c4c4
List-ID: <linux-gpio.vger.kernel.org>
Pablo Greco d6c4c4
X-Mailing-List: linux-gpio@vger.kernel.org
Pablo Greco d6c4c4
Pablo Greco d6c4c4
From: Thierry Reding <treding@nvidia.com>
Pablo Greco d6c4c4
Pablo Greco d6c4c4
regmap_add_irq_chip() will try to allocate all of the IRQ descriptors
Pablo Greco d6c4c4
upfront if passed a non-zero irq_base parameter. However, the intention
Pablo Greco d6c4c4
is to allocate IRQ descriptors on an as-needed basis if possible. Pass 0
Pablo Greco d6c4c4
instead of -1 to fix that use-case.
Pablo Greco d6c4c4
Pablo Greco d6c4c4
Signed-off-by: Thierry Reding <treding@nvidia.com>
Pablo Greco d6c4c4
---
Pablo Greco d6c4c4
 drivers/gpio/gpio-max77620.c | 2 +-
Pablo Greco d6c4c4
 1 file changed, 1 insertion(+), 1 deletion(-)
Pablo Greco d6c4c4
Pablo Greco d6c4c4
diff --git a/drivers/gpio/gpio-max77620.c b/drivers/gpio/gpio-max77620.c
Pablo Greco d6c4c4
index faf86ea9c51a..c58b56e5291e 100644
Pablo Greco d6c4c4
--- a/drivers/gpio/gpio-max77620.c
Pablo Greco d6c4c4
+++ b/drivers/gpio/gpio-max77620.c
Pablo Greco d6c4c4
@@ -304,7 +304,7 @@ static int max77620_gpio_probe(struct platform_device *pdev)
Pablo Greco d6c4c4
 	}
Pablo Greco d6c4c4
 
Pablo Greco d6c4c4
 	ret = devm_regmap_add_irq_chip(&pdev->dev, chip->rmap, gpio_irq,
Pablo Greco d6c4c4
-				       IRQF_ONESHOT, -1,
Pablo Greco d6c4c4
+				       IRQF_ONESHOT, 0,
Pablo Greco d6c4c4
 				       &max77620_gpio_irq_chip,
Pablo Greco d6c4c4
 				       &chip->gpio_irq_data);
Pablo Greco d6c4c4
 	if (ret < 0) {
Pablo Greco d6c4c4
Pablo Greco d6c4c4
From patchwork Wed Oct  2 12:28:25 2019
Pablo Greco d6c4c4
Content-Type: text/plain; charset="utf-8"
Pablo Greco d6c4c4
MIME-Version: 1.0
Pablo Greco d6c4c4
Content-Transfer-Encoding: 7bit
Pablo Greco d6c4c4
X-Patchwork-Submitter: Thierry Reding <thierry.reding@gmail.com>
Pablo Greco d6c4c4
X-Patchwork-Id: 1170633
Pablo Greco d6c4c4
Return-Path: <linux-gpio-owner@vger.kernel.org>
Pablo Greco d6c4c4
X-Original-To: incoming@patchwork.ozlabs.org
Pablo Greco d6c4c4
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
Pablo Greco d6c4c4
Authentication-Results: ozlabs.org;
Pablo Greco d6c4c4
 spf=none (mailfrom) smtp.mailfrom=vger.kernel.org
Pablo Greco d6c4c4
 (client-ip=209.132.180.67; helo=vger.kernel.org;
Pablo Greco d6c4c4
 envelope-from=linux-gpio-owner@vger.kernel.org;
Pablo Greco d6c4c4
 receiver=<unknown>)
Pablo Greco d6c4c4
Authentication-Results: ozlabs.org;
Pablo Greco d6c4c4
 dmarc=pass (p=none dis=none) header.from=gmail.com
Pablo Greco d6c4c4
Authentication-Results: ozlabs.org; dkim=pass (2048-bit key;
Pablo Greco d6c4c4
 unprotected) header.d=gmail.com header.i=@gmail.com
Pablo Greco d6c4c4
 header.b="TsA9TpB7"; dkim-atps=neutral
Pablo Greco d6c4c4
Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
Pablo Greco d6c4c4
 by ozlabs.org (Postfix) with ESMTP id 46jwRD5mmDz9sPq
Pablo Greco d6c4c4
 for <incoming@patchwork.ozlabs.org>;
Pablo Greco d6c4c4
 Wed,  2 Oct 2019 22:28:40 +1000 (AEST)
Pablo Greco d6c4c4
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
Pablo Greco d6c4c4
 id S1727456AbfJBM2f (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);
Pablo Greco d6c4c4
 Wed, 2 Oct 2019 08:28:35 -0400
Pablo Greco d6c4c4
Received: from mail-wm1-f66.google.com ([209.85.128.66]:34525 "EHLO
Pablo Greco d6c4c4
 mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
Pablo Greco d6c4c4
 with ESMTP id S1726682AbfJBM2e (ORCPT
Pablo Greco d6c4c4
 <rfc822; linux-gpio@vger.kernel.org="">); Wed, 2 Oct 2019 08:28:34 -0400
Pablo Greco d6c4c4
Received: by mail-wm1-f66.google.com with SMTP id y135so4823030wmc.1;
Pablo Greco d6c4c4
 Wed, 02 Oct 2019 05:28:32 -0700 (PDT)
Pablo Greco d6c4c4
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
Pablo Greco d6c4c4
 h=from:to:cc:subject:date:message-id:in-reply-to:references
Pablo Greco d6c4c4
 :mime-version:content-transfer-encoding;
Pablo Greco d6c4c4
 bh=CBafHZOcPLRsPg6HMh6RW3fmvKDiW2MODjit57xEepE=;
Pablo Greco d6c4c4
 b=TsA9TpB72Q02EPmaBqcc4zzucsjsdc5mtjgAgTak5YrKh+mRT2HMioWeCxrLu5Cl+6
Pablo Greco d6c4c4
 66PhcUzrRtOnct3yEqC1hueFX+K8TsDr1bJq2f3L5LqA9rYz5Hdk93jVmwyEKtrPUOa5
Pablo Greco d6c4c4
 DNgu/r4ppuWX/d9nuLpVLcFGOzWYjz/GSfyRm/B0MNSsiIFx/VfjsK6OQk48uN2gyMPf
Pablo Greco d6c4c4
 LsirANA0HYZPyXaUFBkchtTE71HqGFSIzJGUSVGm12Z26puMZ9GiUid1l1XJjdDuFfhU
Pablo Greco d6c4c4
 3k9TQnvLEpZDHArb2G8JrwRI8fRZ/OBDLPyKvH/EEdDYa/FfJOzliZBqMgVFpXpXGTZ6
Pablo Greco d6c4c4
 7YAw==
Pablo Greco d6c4c4
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
Pablo Greco d6c4c4
 d=1e100.net; s=20161025;
Pablo Greco d6c4c4
 h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
Pablo Greco d6c4c4
 :references:mime-version:content-transfer-encoding;
Pablo Greco d6c4c4
 bh=CBafHZOcPLRsPg6HMh6RW3fmvKDiW2MODjit57xEepE=;
Pablo Greco d6c4c4
 b=MVU3M5NDj2W8TitA2MM98hE9Vgb07UODtrRolwf9TaeTgf2XRMgYAWr9v5zaHvBU2q
Pablo Greco d6c4c4
 4q/HPqbn0WAW3OBfSQLW6CFcdiHOkjfR+r8tKHpNMNBbeDrj1DeeKE/A25plLXxg+Ypz
Pablo Greco d6c4c4
 1bKJe6DPvjIqLvrpVmPADaRtsAkgDFTt/h41ti2uTwS5xq4qEf1mwz6lFyJkGyf+Qjb5
Pablo Greco d6c4c4
 pnViJ3Lv89RLBvJwWj0j2t/EzzznPZn9xP663YkNrUNRYrAM7ZBauvK7kMyf8LnKo96E
Pablo Greco d6c4c4
 +niJu7OV4PnRspOC8AS3PPM4DHGctXZl6QMcJ1LyPwBkd8EHJioV1iDJKqHQIbxew46f
Pablo Greco d6c4c4
 AzCA==
Pablo Greco d6c4c4
X-Gm-Message-State: APjAAAWbRYKoHNSgs+vkRdoNeam2jbbuVKAFxN3ysahEdBul5DIjNFsz
Pablo Greco d6c4c4
 JRjkPkilW+LPTwy2EmDLNUE=
Pablo Greco d6c4c4
X-Google-Smtp-Source: APXvYqyfSTFvcH9+iLVzVGJ5KDEauN0ssdr9eBfIIdRWe8prWnP7KBGuKItc0GAk8lMLMDzdLKlWtw==
Pablo Greco d6c4c4
X-Received: by 2002:a1c:7306:: with SMTP id d6mr2864027wmb.62.1570019311374; 
Pablo Greco d6c4c4
 Wed, 02 Oct 2019 05:28:31 -0700 (PDT)
Pablo Greco d6c4c4
Received: from localhost (p2E5BE2CE.dip0.t-ipconnect.de. [46.91.226.206])
Pablo Greco d6c4c4
 by smtp.gmail.com with ESMTPSA id
Pablo Greco d6c4c4
 90sm3179450wrr.1.2019.10.02.05.28.30
Pablo Greco d6c4c4
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
Pablo Greco d6c4c4
 Wed, 02 Oct 2019 05:28:30 -0700 (PDT)
Pablo Greco d6c4c4
From: Thierry Reding <thierry.reding@gmail.com>
Pablo Greco d6c4c4
To: Linus Walleij <linus.walleij@linaro.org>,
Pablo Greco d6c4c4
 Bartosz Golaszewski <bgolaszewski@baylibre.com>
Pablo Greco d6c4c4
Cc: Timo Alho <talho@nvidia.com>, linux-gpio@vger.kernel.org,
Pablo Greco d6c4c4
 linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org
Pablo Greco d6c4c4
Subject: [PATCH 3/3] gpio: max77620: Fix interrupt handling
Pablo Greco d6c4c4
Date: Wed,  2 Oct 2019 14:28:25 +0200
Pablo Greco d6c4c4
Message-Id: <20191002122825.3948322-3-thierry.reding@gmail.com>
Pablo Greco d6c4c4
X-Mailer: git-send-email 2.23.0
Pablo Greco d6c4c4
In-Reply-To: <20191002122825.3948322-1-thierry.reding@gmail.com>
Pablo Greco d6c4c4
References: <20191002122825.3948322-1-thierry.reding@gmail.com>
Pablo Greco d6c4c4
MIME-Version: 1.0
Pablo Greco d6c4c4
Sender: linux-gpio-owner@vger.kernel.org
Pablo Greco d6c4c4
Precedence: bulk
Pablo Greco d6c4c4
List-ID: <linux-gpio.vger.kernel.org>
Pablo Greco d6c4c4
X-Mailing-List: linux-gpio@vger.kernel.org
Pablo Greco d6c4c4
Pablo Greco d6c4c4
From: Timo Alho <talho@nvidia.com>
Pablo Greco d6c4c4
Pablo Greco d6c4c4
The interrupt-related register fields on the MAX77620 GPIO controller
Pablo Greco d6c4c4
share registers with GPIO related fields. If the IRQ chip is implemented
Pablo Greco d6c4c4
with regmap-irq, this causes the IRQ controller code to overwrite fields
Pablo Greco d6c4c4
previously configured by the GPIO controller code.
Pablo Greco d6c4c4
Pablo Greco d6c4c4
Two examples where this causes problems are the NVIDIA Jetson TX1 and
Pablo Greco d6c4c4
Jetson TX2 boards, where some of the GPIOs are used to enable vital
Pablo Greco d6c4c4
power regulators. The MAX77620 GPIO controller also provides the USB OTG
Pablo Greco d6c4c4
ID pin. If configured as an interrupt, this causes some of the
Pablo Greco d6c4c4
regulators to be powered off.
Pablo Greco d6c4c4
Pablo Greco d6c4c4
Signed-off-by: Timo Alho <talho@nvidia.com>
Pablo Greco d6c4c4
Signed-off-by: Thierry Reding <treding@nvidia.com>
Pablo Greco d6c4c4
---
Pablo Greco d6c4c4
 drivers/gpio/gpio-max77620.c | 231 ++++++++++++++++++-----------------
Pablo Greco d6c4c4
 1 file changed, 117 insertions(+), 114 deletions(-)
Pablo Greco d6c4c4
Pablo Greco d6c4c4
diff --git a/drivers/gpio/gpio-max77620.c b/drivers/gpio/gpio-max77620.c
Pablo Greco d6c4c4
index c58b56e5291e..c5b64a4ac172 100644
Pablo Greco d6c4c4
--- a/drivers/gpio/gpio-max77620.c
Pablo Greco d6c4c4
+++ b/drivers/gpio/gpio-max77620.c
Pablo Greco d6c4c4
@@ -18,109 +18,115 @@ struct max77620_gpio {
Pablo Greco d6c4c4
 	struct gpio_chip	gpio_chip;
Pablo Greco d6c4c4
 	struct regmap		*rmap;
Pablo Greco d6c4c4
 	struct device		*dev;
Pablo Greco d6c4c4
+	struct mutex		buslock; /* irq_bus_lock */
Pablo Greco d6c4c4
+	unsigned int		irq_type[8];
Pablo Greco d6c4c4
+	bool			irq_enabled[8];
Pablo Greco d6c4c4
 };
Pablo Greco d6c4c4
 
Pablo Greco d6c4c4
-static const struct regmap_irq max77620_gpio_irqs[] = {
Pablo Greco d6c4c4
-	[0] = {
Pablo Greco d6c4c4
-		.reg_offset = 0,
Pablo Greco d6c4c4
-		.mask = MAX77620_IRQ_LVL2_GPIO_EDGE0,
Pablo Greco d6c4c4
-		.type = {
Pablo Greco d6c4c4
-			.type_rising_val = MAX77620_CNFG_GPIO_INT_RISING,
Pablo Greco d6c4c4
-			.type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING,
Pablo Greco d6c4c4
-			.type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK,
Pablo Greco d6c4c4
-			.type_reg_offset = 0,
Pablo Greco d6c4c4
-			.types_supported = IRQ_TYPE_EDGE_BOTH,
Pablo Greco d6c4c4
-		},
Pablo Greco d6c4c4
-	},
Pablo Greco d6c4c4
-	[1] = {
Pablo Greco d6c4c4
-		.reg_offset = 0,
Pablo Greco d6c4c4
-		.mask = MAX77620_IRQ_LVL2_GPIO_EDGE1,
Pablo Greco d6c4c4
-		.type = {
Pablo Greco d6c4c4
-			.type_rising_val = MAX77620_CNFG_GPIO_INT_RISING,
Pablo Greco d6c4c4
-			.type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING,
Pablo Greco d6c4c4
-			.type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK,
Pablo Greco d6c4c4
-			.type_reg_offset = 1,
Pablo Greco d6c4c4
-			.types_supported = IRQ_TYPE_EDGE_BOTH,
Pablo Greco d6c4c4
-		},
Pablo Greco d6c4c4
-	},
Pablo Greco d6c4c4
-	[2] = {
Pablo Greco d6c4c4
-		.reg_offset = 0,
Pablo Greco d6c4c4
-		.mask = MAX77620_IRQ_LVL2_GPIO_EDGE2,
Pablo Greco d6c4c4
-		.type = {
Pablo Greco d6c4c4
-			.type_rising_val = MAX77620_CNFG_GPIO_INT_RISING,
Pablo Greco d6c4c4
-			.type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING,
Pablo Greco d6c4c4
-			.type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK,
Pablo Greco d6c4c4
-			.type_reg_offset = 2,
Pablo Greco d6c4c4
-			.types_supported = IRQ_TYPE_EDGE_BOTH,
Pablo Greco d6c4c4
-		},
Pablo Greco d6c4c4
-	},
Pablo Greco d6c4c4
-	[3] = {
Pablo Greco d6c4c4
-		.reg_offset = 0,
Pablo Greco d6c4c4
-		.mask = MAX77620_IRQ_LVL2_GPIO_EDGE3,
Pablo Greco d6c4c4
-		.type = {
Pablo Greco d6c4c4
-			.type_rising_val = MAX77620_CNFG_GPIO_INT_RISING,
Pablo Greco d6c4c4
-			.type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING,
Pablo Greco d6c4c4
-			.type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK,
Pablo Greco d6c4c4
-			.type_reg_offset = 3,
Pablo Greco d6c4c4
-			.types_supported = IRQ_TYPE_EDGE_BOTH,
Pablo Greco d6c4c4
-		},
Pablo Greco d6c4c4
-	},
Pablo Greco d6c4c4
-	[4] = {
Pablo Greco d6c4c4
-		.reg_offset = 0,
Pablo Greco d6c4c4
-		.mask = MAX77620_IRQ_LVL2_GPIO_EDGE4,
Pablo Greco d6c4c4
-		.type = {
Pablo Greco d6c4c4
-			.type_rising_val = MAX77620_CNFG_GPIO_INT_RISING,
Pablo Greco d6c4c4
-			.type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING,
Pablo Greco d6c4c4
-			.type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK,
Pablo Greco d6c4c4
-			.type_reg_offset = 4,
Pablo Greco d6c4c4
-			.types_supported = IRQ_TYPE_EDGE_BOTH,
Pablo Greco d6c4c4
-		},
Pablo Greco d6c4c4
-	},
Pablo Greco d6c4c4
-	[5] = {
Pablo Greco d6c4c4
-		.reg_offset = 0,
Pablo Greco d6c4c4
-		.mask = MAX77620_IRQ_LVL2_GPIO_EDGE5,
Pablo Greco d6c4c4
-		.type = {
Pablo Greco d6c4c4
-			.type_rising_val = MAX77620_CNFG_GPIO_INT_RISING,
Pablo Greco d6c4c4
-			.type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING,
Pablo Greco d6c4c4
-			.type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK,
Pablo Greco d6c4c4
-			.type_reg_offset = 5,
Pablo Greco d6c4c4
-			.types_supported = IRQ_TYPE_EDGE_BOTH,
Pablo Greco d6c4c4
-		},
Pablo Greco d6c4c4
-	},
Pablo Greco d6c4c4
-	[6] = {
Pablo Greco d6c4c4
-		.reg_offset = 0,
Pablo Greco d6c4c4
-		.mask = MAX77620_IRQ_LVL2_GPIO_EDGE6,
Pablo Greco d6c4c4
-		.type = {
Pablo Greco d6c4c4
-			.type_rising_val = MAX77620_CNFG_GPIO_INT_RISING,
Pablo Greco d6c4c4
-			.type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING,
Pablo Greco d6c4c4
-			.type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK,
Pablo Greco d6c4c4
-			.type_reg_offset = 6,
Pablo Greco d6c4c4
-			.types_supported = IRQ_TYPE_EDGE_BOTH,
Pablo Greco d6c4c4
-		},
Pablo Greco d6c4c4
-	},
Pablo Greco d6c4c4
-	[7] = {
Pablo Greco d6c4c4
-		.reg_offset = 0,
Pablo Greco d6c4c4
-		.mask = MAX77620_IRQ_LVL2_GPIO_EDGE7,
Pablo Greco d6c4c4
-		.type = {
Pablo Greco d6c4c4
-			.type_rising_val = MAX77620_CNFG_GPIO_INT_RISING,
Pablo Greco d6c4c4
-			.type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING,
Pablo Greco d6c4c4
-			.type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK,
Pablo Greco d6c4c4
-			.type_reg_offset = 7,
Pablo Greco d6c4c4
-			.types_supported = IRQ_TYPE_EDGE_BOTH,
Pablo Greco d6c4c4
-		},
Pablo Greco d6c4c4
-	},
Pablo Greco d6c4c4
-};
Pablo Greco d6c4c4
+static irqreturn_t max77620_gpio_irqhandler(int irq, void *data)
Pablo Greco d6c4c4
+{
Pablo Greco d6c4c4
+	struct max77620_gpio *gpio = data;
Pablo Greco d6c4c4
+	unsigned int value, offset;
Pablo Greco d6c4c4
+	unsigned long pending;
Pablo Greco d6c4c4
+	int err;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	err = regmap_read(gpio->rmap, MAX77620_REG_IRQ_LVL2_GPIO, &value);
Pablo Greco d6c4c4
+	if (err < 0) {
Pablo Greco d6c4c4
+		dev_err(gpio->dev, "REG_IRQ_LVL2_GPIO read failed: %d\n", err);
Pablo Greco d6c4c4
+		return IRQ_NONE;
Pablo Greco d6c4c4
+	}
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	pending = value;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	for_each_set_bit(offset, &pending, 8) {
Pablo Greco d6c4c4
+		unsigned int virq;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+		virq = irq_find_mapping(gpio->gpio_chip.irq.domain, offset);
Pablo Greco d6c4c4
+		handle_nested_irq(virq);
Pablo Greco d6c4c4
+	}
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	return IRQ_HANDLED;
Pablo Greco d6c4c4
+}
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+static void max77620_gpio_irq_mask(struct irq_data *data)
Pablo Greco d6c4c4
+{
Pablo Greco d6c4c4
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
Pablo Greco d6c4c4
+	struct max77620_gpio *gpio = gpiochip_get_data(chip);
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	gpio->irq_enabled[data->hwirq] = false;
Pablo Greco d6c4c4
+}
Pablo Greco d6c4c4
 
Pablo Greco d6c4c4
-static const struct regmap_irq_chip max77620_gpio_irq_chip = {
Pablo Greco d6c4c4
-	.name = "max77620-gpio",
Pablo Greco d6c4c4
-	.irqs = max77620_gpio_irqs,
Pablo Greco d6c4c4
-	.num_irqs = ARRAY_SIZE(max77620_gpio_irqs),
Pablo Greco d6c4c4
-	.num_regs = 1,
Pablo Greco d6c4c4
-	.num_type_reg = 8,
Pablo Greco d6c4c4
-	.irq_reg_stride = 1,
Pablo Greco d6c4c4
-	.type_reg_stride = 1,
Pablo Greco d6c4c4
-	.status_base = MAX77620_REG_IRQ_LVL2_GPIO,
Pablo Greco d6c4c4
-	.type_base = MAX77620_REG_GPIO0,
Pablo Greco d6c4c4
+static void max77620_gpio_irq_unmask(struct irq_data *data)
Pablo Greco d6c4c4
+{
Pablo Greco d6c4c4
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
Pablo Greco d6c4c4
+	struct max77620_gpio *gpio = gpiochip_get_data(chip);
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	gpio->irq_enabled[data->hwirq] = true;
Pablo Greco d6c4c4
+}
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+static int max77620_gpio_set_irq_type(struct irq_data *data, unsigned int type)
Pablo Greco d6c4c4
+{
Pablo Greco d6c4c4
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
Pablo Greco d6c4c4
+	struct max77620_gpio *gpio = gpiochip_get_data(chip);
Pablo Greco d6c4c4
+	unsigned int irq_type;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	switch (type) {
Pablo Greco d6c4c4
+	case IRQ_TYPE_EDGE_RISING:
Pablo Greco d6c4c4
+		irq_type = MAX77620_CNFG_GPIO_INT_RISING;
Pablo Greco d6c4c4
+		break;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	case IRQ_TYPE_EDGE_FALLING:
Pablo Greco d6c4c4
+		irq_type = MAX77620_CNFG_GPIO_INT_FALLING;
Pablo Greco d6c4c4
+		break;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	case IRQ_TYPE_EDGE_BOTH:
Pablo Greco d6c4c4
+		irq_type = MAX77620_CNFG_GPIO_INT_RISING |
Pablo Greco d6c4c4
+			   MAX77620_CNFG_GPIO_INT_FALLING;
Pablo Greco d6c4c4
+		break;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	default:
Pablo Greco d6c4c4
+		return -EINVAL;
Pablo Greco d6c4c4
+	}
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	gpio->irq_type[data->hwirq] = irq_type;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	return 0;
Pablo Greco d6c4c4
+}
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+static void max77620_gpio_bus_lock(struct irq_data *data)
Pablo Greco d6c4c4
+{
Pablo Greco d6c4c4
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
Pablo Greco d6c4c4
+	struct max77620_gpio *gpio = gpiochip_get_data(chip);
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	mutex_lock(&gpio->buslock);
Pablo Greco d6c4c4
+}
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+static void max77620_gpio_bus_sync_unlock(struct irq_data *data)
Pablo Greco d6c4c4
+{
Pablo Greco d6c4c4
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
Pablo Greco d6c4c4
+	struct max77620_gpio *gpio = gpiochip_get_data(chip);
Pablo Greco d6c4c4
+	unsigned int value, offset = data->hwirq;
Pablo Greco d6c4c4
+	int err;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	value = gpio->irq_enabled[offset] ? gpio->irq_type[offset] : 0;
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	err = regmap_update_bits(gpio->rmap, GPIO_REG_ADDR(offset),
Pablo Greco d6c4c4
+				 MAX77620_CNFG_GPIO_INT_MASK, value);
Pablo Greco d6c4c4
+	if (err < 0)
Pablo Greco d6c4c4
+		dev_err(chip->parent, "failed to update interrupt mask: %d\n",
Pablo Greco d6c4c4
+			err);
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	mutex_unlock(&gpio->buslock);
Pablo Greco d6c4c4
+}
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+static struct irq_chip max77620_gpio_irqchip = {
Pablo Greco d6c4c4
+	.name		= "max77620-gpio",
Pablo Greco d6c4c4
+	.irq_mask	= max77620_gpio_irq_mask,
Pablo Greco d6c4c4
+	.irq_unmask	= max77620_gpio_irq_unmask,
Pablo Greco d6c4c4
+	.irq_set_type	= max77620_gpio_set_irq_type,
Pablo Greco d6c4c4
+	.irq_bus_lock	= max77620_gpio_bus_lock,
Pablo Greco d6c4c4
+	.irq_bus_sync_unlock = max77620_gpio_bus_sync_unlock,
Pablo Greco d6c4c4
+	.flags		= IRQCHIP_MASK_ON_SUSPEND,
Pablo Greco d6c4c4
 };
Pablo Greco d6c4c4
 
Pablo Greco d6c4c4
 static int max77620_gpio_dir_input(struct gpio_chip *gc, unsigned int offset)
Pablo Greco d6c4c4
@@ -254,14 +260,6 @@ static int max77620_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
Pablo Greco d6c4c4
 	return -ENOTSUPP;
Pablo Greco d6c4c4
 }
Pablo Greco d6c4c4
 
Pablo Greco d6c4c4
-static int max77620_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
Pablo Greco d6c4c4
-{
Pablo Greco d6c4c4
-	struct max77620_gpio *mgpio = gpiochip_get_data(gc);
Pablo Greco d6c4c4
-	struct max77620_chip *chip = dev_get_drvdata(mgpio->dev->parent);
Pablo Greco d6c4c4
-
Pablo Greco d6c4c4
-	return regmap_irq_get_virq(chip->gpio_irq_data, offset);
Pablo Greco d6c4c4
-}
Pablo Greco d6c4c4
-
Pablo Greco d6c4c4
 static int max77620_gpio_probe(struct platform_device *pdev)
Pablo Greco d6c4c4
 {
Pablo Greco d6c4c4
 	struct max77620_chip *chip =  dev_get_drvdata(pdev->dev.parent);
Pablo Greco d6c4c4
@@ -287,7 +285,6 @@ static int max77620_gpio_probe(struct platform_device *pdev)
Pablo Greco d6c4c4
 	mgpio->gpio_chip.direction_output = max77620_gpio_dir_output;
Pablo Greco d6c4c4
 	mgpio->gpio_chip.set = max77620_gpio_set;
Pablo Greco d6c4c4
 	mgpio->gpio_chip.set_config = max77620_gpio_set_config;
Pablo Greco d6c4c4
-	mgpio->gpio_chip.to_irq = max77620_gpio_to_irq;
Pablo Greco d6c4c4
 	mgpio->gpio_chip.ngpio = MAX77620_GPIO_NR;
Pablo Greco d6c4c4
 	mgpio->gpio_chip.can_sleep = 1;
Pablo Greco d6c4c4
 	mgpio->gpio_chip.base = -1;
Pablo Greco d6c4c4
@@ -303,15 +300,21 @@ static int max77620_gpio_probe(struct platform_device *pdev)
Pablo Greco d6c4c4
 		return ret;
Pablo Greco d6c4c4
 	}
Pablo Greco d6c4c4
 
Pablo Greco d6c4c4
-	ret = devm_regmap_add_irq_chip(&pdev->dev, chip->rmap, gpio_irq,
Pablo Greco d6c4c4
-				       IRQF_ONESHOT, 0,
Pablo Greco d6c4c4
-				       &max77620_gpio_irq_chip,
Pablo Greco d6c4c4
-				       &chip->gpio_irq_data);
Pablo Greco d6c4c4
+	mutex_init(&mgpio->buslock);
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	gpiochip_irqchip_add_nested(&mgpio->gpio_chip, &max77620_gpio_irqchip,
Pablo Greco d6c4c4
+				    0, handle_edge_irq, IRQ_TYPE_NONE);
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
+	ret = request_threaded_irq(gpio_irq, NULL, max77620_gpio_irqhandler,
Pablo Greco d6c4c4
+				   IRQF_ONESHOT, "max77620-gpio", mgpio);
Pablo Greco d6c4c4
 	if (ret < 0) {
Pablo Greco d6c4c4
-		dev_err(&pdev->dev, "Failed to add gpio irq_chip %d\n", ret);
Pablo Greco d6c4c4
+		dev_err(&pdev->dev, "failed to request IRQ: %d\n", ret);
Pablo Greco d6c4c4
 		return ret;
Pablo Greco d6c4c4
 	}
Pablo Greco d6c4c4
 
Pablo Greco d6c4c4
+	gpiochip_set_nested_irqchip(&mgpio->gpio_chip, &max77620_gpio_irqchip,
Pablo Greco d6c4c4
+				    gpio_irq);
Pablo Greco d6c4c4
+
Pablo Greco d6c4c4
 	return 0;
Pablo Greco d6c4c4
 }
Pablo Greco d6c4c4