From nobody Tue Apr 7 23:43:58 2026 Received: from smtp2-g21.free.fr (smtp2-g21.free.fr [212.27.42.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 41896361DAE; Wed, 11 Mar 2026 14:31:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.27.42.2 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773239516; cv=none; b=WD77dXyo3KVUgEIxbOLQQpXuJUIB7nmbFh2vQaxT6xfiYCHwaNB//0KL7FN87fZjJN+BcdAm6g5nlbBCc5OMAmiA4ribWV/15MHak/ZQAhJfr3RuFME24K+4i1QmMMg+lQ3qbK1rwTr/yaMkR9hYFhh7soDGH/j2MED1T4qFHT8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773239516; c=relaxed/simple; bh=xwzDJldw2ScjgAZdF++yq28RL5rFT7+4YXOLSPkJCW4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=MvaXHBpBraDq7SsItQBAzM0klub/kvt6DtqdUgblzHOgT4Uu15osCMJ+A5W0wCotarzWQ8ZUB32SE+RuPKguJf3O572fg4GXmDh1/0y29cYyunJs9jt6nWtw1BpqUtodLaccQx9cI3iaZf5Bv/hRTIklDBVaFTa3qfqxttfOXA4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=lht.dlh.de; spf=pass smtp.mailfrom=free.fr; arc=none smtp.client-ip=212.27.42.2 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=lht.dlh.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=free.fr Received: from albans-vm.. (unknown [213.61.141.186]) (Authenticated sender: albeu@free.fr) by smtp2-g21.free.fr (Postfix) with ESMTPSA id E41A72003F6; Wed, 11 Mar 2026 15:31:45 +0100 (CET) From: Alban Bedel To: linux-gpio@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Lee Jones , Bartosz Golaszewski , Linus Walleij , Alban Bedel Subject: [PATCH 3/4] gpio: kempld: Add support for get/set multiple Date: Wed, 11 Mar 2026 15:31:19 +0100 Message-Id: <20260311143120.2179347-4-alban.bedel@lht.dlh.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260311143120.2179347-1-alban.bedel@lht.dlh.de> References: <20260311143120.2179347-1-alban.bedel@lht.dlh.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" As the bus accesses are quiet slow with this device, supporting the get/set multiple API can help with performences. The implementation tries to keep the number of bus access to a minimum by checking the mask to only read or write the needed bytes. Signed-off-by: Alban Bedel --- drivers/gpio/gpio-kempld.c | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/gpio/gpio-kempld.c b/drivers/gpio/gpio-kempld.c index 2263de77d40e9..7dd94ff6f2df4 100644 --- a/drivers/gpio/gpio-kempld.c +++ b/drivers/gpio/gpio-kempld.c @@ -65,6 +65,33 @@ static int kempld_gpio_get(struct gpio_chip *chip, unsig= ned offset) return !!kempld_gpio_get_bit(pld, KEMPLD_GPIO_LVL, offset); } =20 +static int kempld_gpio_get_multiple(struct gpio_chip *chip, unsigned long = *mask, + unsigned long *bits) +{ + struct kempld_gpio_data *gpio =3D gpiochip_get_data(chip); + struct kempld_device_data *pld =3D gpio->pld; + u8 reg =3D KEMPLD_GPIO_LVL; + unsigned int shift; + + bits[0] &=3D ~mask[0]; + + kempld_get_mutex(pld); + + /* Try to reduce to a single 8 bits access if possible */ + for (shift =3D 0; shift < gpio->chip.ngpio; shift +=3D 8, reg++) { + unsigned long msk =3D (mask[0] >> shift) & 0xff; + + if (!msk) + continue; + + bits[0] |=3D (kempld_read8(pld, reg) & msk) << shift; + } + + kempld_release_mutex(pld); + + return 0; +} + static int kempld_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { @@ -78,6 +105,37 @@ static int kempld_gpio_set(struct gpio_chip *chip, unsi= gned int offset, return 0; } =20 +static int kempld_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, unsigned long *bits) +{ + struct kempld_gpio_data *gpio =3D gpiochip_get_data(chip); + struct kempld_device_data *pld =3D gpio->pld; + u8 reg =3D gpio->out_lvl_reg; + unsigned int shift; + + kempld_get_mutex(pld); + + /* Try to reduce to a single 8 bits access if possible */ + for (shift =3D 0; shift < gpio->chip.ngpio; shift +=3D 8, reg++) { + u8 val, msk =3D mask[0] >> shift; + + if (!msk) + continue; + + if (msk !=3D 0xFF) + val =3D kempld_read8(pld, reg) & ~msk; + else + val =3D 0; + + val |=3D (bits[0] >> shift) & msk; + kempld_write8(pld, reg, val); + } + + kempld_release_mutex(pld); + + return 0; +} + static int kempld_gpio_direction_input(struct gpio_chip *chip, unsigned of= fset) { struct kempld_gpio_data *gpio =3D gpiochip_get_data(chip); @@ -180,7 +238,9 @@ static int kempld_gpio_probe(struct platform_device *pd= ev) chip->direction_output =3D kempld_gpio_direction_output; chip->get_direction =3D kempld_gpio_get_direction; chip->get =3D kempld_gpio_get; + chip->get_multiple =3D kempld_gpio_get_multiple; chip->set =3D kempld_gpio_set; + chip->set_multiple =3D kempld_gpio_set_multiple; chip->ngpio =3D kempld_gpio_pincount(pld); if (chip->ngpio =3D=3D 0) { dev_err(dev, "No GPIO pins detected\n"); --=20 2.39.5