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