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