From nobody Mon Jun 15 16:31:57 2026 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F16062848BA for ; Sat, 11 Apr 2026 18:04:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775930663; cv=none; b=AKfOC1PgUIwm9rwZrg1qG3Ncuq0JiOTjURe+QAf46+HmGw8zhBmOSnoXE6C7yxJ2A9ypsb/dGxgIDzA1vMAmqoiTmEoitaHIrdccmSvFsOXcbwyYkryihE/Il0rQ/oTl7Lh8dD8NKH338Pfk5UOG+mYXdfH0rkAKOUBuIsEkF+Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775930663; c=relaxed/simple; bh=9aKPv9W66PoQjS1drLRMSLNL5N+3u0CUbWozsmMaGuY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qIVw606t2Z+4cSwNO+vQUTfusH+lD/4VsYE3BUn7W4Ikn9dJLOn9zmph0DEowsL82umJ3veVA8QoOXqE039F/tIFM2wbBe+KtYvjZGpKVuDHFN0Wu2kjiIlPGU8Eto0W1M3He+pTP+M8TCp+bq5zTCGIpqtp+Nq1o9hQ4+KxENY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=qwa3jElP; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qwa3jElP" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-b9825ba7e8dso447290266b.3 for ; Sat, 11 Apr 2026 11:04:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775930660; x=1776535460; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tUEOsnfxXuZLqwLt1IFYC5XjnP8ak+RNfelGDS4bV6g=; b=qwa3jElP+iCMlndVflfYj152Tniir5hai7buLbBMRxoXa+Qn0CAbxYbkDwRQtthxOa 07CsFti7gkzWoIGciMIAdUQRH8l4CMuvb8Zpc+DON5jTCQnlHS4X69ez4h39FD5g6yd/ hsvPV/CjwSb4SfwX8yeUqjWQYK/G3OjPfngzBy0NVpyw+JrJ4PIiIvUDeulcLDbVQRVE KWmagHOxKfddfm/KpoxhKztksiiJfuJyKctEANyK7O69JrAUIO922iYDqwWMo2Te2Z0K UFItX8O4qAYmIQBKDoMF9dso+amNGQgFHYlqNXrCojUfnyhe2Ay+TildKEkli47rBmAl Yhow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775930660; x=1776535460; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=tUEOsnfxXuZLqwLt1IFYC5XjnP8ak+RNfelGDS4bV6g=; b=BBiobRpFVVGOnrDL4P73JVegL249isALxCBp5PgzvDKKP53Ny3FKh+Y/pEqBjQRgwK 4YH3+Ad6Ns0uctfQw0YAjQke0Ek78VmPcyIrvOlFXdjAh2wCWZGYj2jyepPeavyPEcdk HpXKDvKFibEmVw8MPNXATyLhPsveFcUR+JzWCRJ1+JKNzRUetjtHyBZ5yeZXZhiez/nE nkgLzzitYvf8Dfp7NithgtQa/Q904jG5R4ocnl6yjxe7kyrNqSzjehoP0NBqpirR6WPV LsyYIiwzXPIwHhsbK3W2zuHWN5RAFtyDSq3papK/2N2RAB6d2voHQbsry46DsFKzkeXt oI4A== X-Forwarded-Encrypted: i=1; AJvYcCXW+vFk9SwOi8VPeHVxCCrTElENk/vp61cAO9UPNG0OsdSb3v8dnlxUn/TXfywOKYff67r9UWIyAJIt3CI=@vger.kernel.org X-Gm-Message-State: AOJu0Yw+YjigzWNf8pS5HRG25163mqkKwf8q+zF9OOuXV4XTXq8jZvUX ShKVIs/phx30dux8KfNc7JFZhKNyvH/g6OGLTrBekhh6gQctmMhxgAvq X-Gm-Gg: AeBDievQFEdDAqXUMh++/ME3fVPqEzowni25XsorTCm8MJOUqQYnKzkkXnZ11o1kcUz NyEZSqhtG3qE+aYwNjLwOExrz1i7jE9IfI9qZ4vT0qN7/EWvlV8Bd40URCmU0RkLrbn59NRVqF4 EitcdfNRxK6sZn3RCXg7wiQ8OQq0FeMAsOX3ey/kut23h003PIWmWpa4sGPu/dWNw+T28BgpQq8 nWxX4tP70nF9q/o5thsJtUiHmO2rfZuqOTG7eIysq57kQfMUklmaH/gCCTRK20NAg5ZGE+yc9fL XvCc109u8arwl9dhlWvDF5ax83kTm8VhhanyCxmSq9nYWmEZXtZmCxckD2mBVr7eNPc9+iz9hyf 2y6K7daFwpE12EG98J7hxwvAiWhUX2OftvXi2mOHX2ETNFO8Ofh+x96qbcsEzuHBPq39JuVcSrb vTTIhcvY/GLH2y5PsSF5qr62vdMAPLflvp X-Received: by 2002:a17:906:4790:b0:b98:7e30:8129 with SMTP id a640c23a62f3a-b9d7296657fmr412690366b.32.1775930659993; Sat, 11 Apr 2026 11:04:19 -0700 (PDT) Received: from khalil-hp.home ([62.250.67.33]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b9d6e5c56d3sm186160666b.32.2026.04.11.11.04.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Apr 2026 11:04:19 -0700 (PDT) From: Khalil X-Google-Original-From: Khalil To: broonie@kernel.org, hdegoede@kernel.org, ilpo.jarvinen@linux.intel.com Cc: rf@opensource.cirrus.com, linux-spi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Khalil Subject: [PATCH 1/3] spi: Preserve preset cs_gpiod in __spi_add_device() Date: Sat, 11 Apr 2026 20:04:12 +0200 Message-ID: <20260411180414.481427-2-khalil@rentman.nl> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260411180414.481427-1-khalil@rentman.nl> References: <20260215135524.1171065-2-khalil@rentman.nl> <20260411180414.481427-1-khalil@rentman.nl> 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" From: Khalil __spi_add_device() unconditionally overwrites spi->cs_gpiod[] from ctlr->cs_gpiods[cs], even if the caller has already set a GPIO descriptor on the device. This prevents drivers like serial-multi-instantiate from pre-configuring a GPIO chip select acquired from ACPI before adding the device. Skip the overwrite when the device already has a cs_gpiod set for the given index, allowing callers to preset GPIO chip selects that aren't described in the controller's cs-gpios property. This is useful on platforms where the ACPI _DSD cs-gpios property on the SPI controller is incomplete, but the peripheral's ACPI node does contain the correct GpioIo resource for its chip select. Suggested-by: Richard Fitzgerald Signed-off-by: Khalil --- drivers/spi/spi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1148,7 +1148,8 @@ static int __spi_add_device(struct spi_device *spi) if (ctlr->cs_gpiods) { for (idx =3D 0; idx < SPI_CS_CNT_MAX; idx++) { - if (is_valid_cs(cs)) + cs =3D spi_get_chipselect(spi, idx); + if (is_valid_cs(cs) && !spi_get_csgpiod(spi, idx)) spi_set_csgpiod(spi, idx, ctlr->cs_gpiods[cs]); } } -- 2.43.0 From nobody Mon Jun 15 16:31:57 2026 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD45D2F9D98 for ; Sat, 11 Apr 2026 18:04:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775930665; cv=none; b=W7m7JneAmJM4K4YCIJV/GpXFCN2101+Gz7tiihI6ZHA2hkqv38D9uO0SzvCKGF4sgFLAujSaV6n9CKVXoV45MzwWy1XHcck08OeZXSvY7R91dToGC9/Uf40SgAPfNFLSQgwylv5+DltYzQQj/b/KOqx5iix76O6FHuz3HDToQb0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775930665; c=relaxed/simple; bh=JMbU1LiY6wuXSksuSlp7BJlBoX3HJ0Ly6A39E8WxkPQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Xmu28NLdfcQoLcYs1AKF3wfhAdTexP55KWAntrzIfpILSkEkd1FZ7XyQm3Mncb6eoKg8Sil8IIaWRYnlLGokr0SYEtMJDYAKKt+6HPcJqt4XlYWpOKnwILDmHAOjJpC1wKqLxmxy7fkfW0qCdMIqOTrQJROjhYZtsEpXmxHMv0w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FdDcTIxh; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FdDcTIxh" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-b9c01854477so504711266b.0 for ; Sat, 11 Apr 2026 11:04:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775930661; x=1776535461; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hNFOlsMFF9Zt9mirLVUiAvZHEoCOZnIB9bjFggGL4eI=; b=FdDcTIxh/hmfz7QFfVMEO0s8zztgUXD/85DZY5PgYnfd0xZy1nQtyLWFoRENBYMDoE Ph4/jAKwBxzqZPmPifl+mqcJ6m+1e9ll/LXXbZtyBzqXpNvaZeJimP1DRZHqnoCCjj7G cexgLi5ct8mNRCDEre3BfLlVusHh59FZWKGBVrqBRyxBIaoyyCQ59c2kHq80HHhNtkfN g9uSZqZJoBrJ05csuIX+RYD61BFF04oGigGfuj/qsLKZeJAN4inYUwNnkIVPBOhPtqao tkdqF4W2oawmh8P0hSpckEpcSXTlPxipZRHwYY85R4rDs9OxqWr9gc0IxGaqydjox/bt hcpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775930661; x=1776535461; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=hNFOlsMFF9Zt9mirLVUiAvZHEoCOZnIB9bjFggGL4eI=; b=rBr/ydeuj6hsenLWs5AV8O3Jpc+zDg4XwEZbPbEacGUOvFWKuY+I5vfdAL5PjARsS+ zZ2E8r5SpQEFMjo/vCKkwYSk6/vsvwnZYYW1u5R8Jk9evxGVDBNOPN7JSMg+c7mOVg7p Kpu30mEM57V/+UelxOsUKWssvrWuP6hRtPQ+9YB/jr//wgTSwOmGflWsBeMexDTiy5Ck p34zGbrKiDGbzwtH2/sSCeBThGfZgUDR1VHEyJVkGvCCTCrDgWt8UvjM0d90BylxIfF/ 59ezPV3pGTva8gFQ9+vLE/uHPBKiY6bWeeZCzUNl4eTfegze5th/8MrNvw0S5a2YlJg6 hZlw== X-Forwarded-Encrypted: i=1; AJvYcCWIo5Se33wPlbSFM+ideMmeF6cJwoXRf0BFax3iBqQ6P4NkbIa5OKUXBgBcAQmIpJCtLecXfmWSTCgge24=@vger.kernel.org X-Gm-Message-State: AOJu0YymJU2O/22W97nxdwE2ikVwk8Zjl1X2UcNEUOmn+6W2EmIN5Uoz ouA6fIUDM7YjJAzOt+XVd8WXJW9HwLy/iyIuvuZb6MlKLgA+2r8hlbLT X-Gm-Gg: AeBDieuHtGAKonMhYarAHQaCrZQDfg8YbcSYS1bwNvGzUKKs1lalt3B+o45z1bad4cK pKx5gfgRkZekTuZOV+kyFm7q0R0DnB1V5kB7EwrUjzhxJaUdsn554JCpLRbqkyny/3QMJF+LRzP TdIYU0GW82gAJQSbQroiak+MTgg9lnCmvTWM0ElPFRxymPMuv3rYL7cpHbgSJyC2sUMGnxX+oat H7auCAeP+CJDffj7gMC1YLDMA9V/JKZ4q/ld5JlR2r9TXd/nUHTjBW+3feYg/N3HCr7s+6xweW1 //VWY1fK92iC1GC4Od8Z2NkXCk90u3x1yEmZwVt3N2tgLn+1n6ZCKOz8mhYTmil+LCi/KHHdmtl wtw1LaM76PGkiI1M25VHToUZpahhliXMmOVlsDJvAG+9CpJ90nfEMMInNOv1A54CaPeZ/wXtGOA Em8MKsZnt+0N2TKFjUpUvajg== X-Received: by 2002:a17:906:9f87:b0:b9d:6a06:fab1 with SMTP id a640c23a62f3a-b9d7265c9b4mr452730266b.32.1775930660854; Sat, 11 Apr 2026 11:04:20 -0700 (PDT) Received: from khalil-hp.home ([62.250.67.33]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b9d6e5c56d3sm186160666b.32.2026.04.11.11.04.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Apr 2026 11:04:20 -0700 (PDT) From: Khalil X-Google-Original-From: Khalil To: broonie@kernel.org, hdegoede@kernel.org, ilpo.jarvinen@linux.intel.com Cc: rf@opensource.cirrus.com, linux-spi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Khalil Subject: [PATCH 2/3] platform/x86: serial-multi-instantiate: Fix SPI chip select on platforms with incomplete ACPI cs-gpios Date: Sat, 11 Apr 2026 20:04:13 +0200 Message-ID: <20260411180414.481427-3-khalil@rentman.nl> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260411180414.481427-1-khalil@rentman.nl> References: <20260215135524.1171065-2-khalil@rentman.nl> <20260411180414.481427-1-khalil@rentman.nl> 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" From: Khalil Some HP laptops with Intel Lunar Lake and dual Cirrus Logic CS35L56 amplifiers over SPI have an incomplete cs-gpios property in the SPI controller's _DSD - it only declares the first chip select. The remaining chip select GPIOs are defined as GpioIo resources in the peripheral's ACPI node but are not referenced by the controller. This causes the SPI framework to reject devices whose chip select exceeds num_chipselect with -EINVAL, preventing the second amplifier from probing. Fix this on known affected platforms by: 1. Adding a DMI quirk table to identify affected systems 2. For devices with chip selects outside the controller's range, acquiring the GPIO from the peripheral's ACPI GpioIo resource 3. Extending num_chipselect and reallocating the controller's cs_gpiods array to install the GPIO descriptor 4. Setting SPI_CONTROLLER_GPIO_SS so the framework calls both the GPIO toggle and controller->set_cs (needed for clock gating on Intel LPSS controllers) Only chip selects beyond the controller's num_chipselect are fixed up. Chip selects within range with a NULL cs_gpiods entry are left alone, as NULL means "native chip select" which is intentional. Tested on HP EliteBook 8 G1i 16 inch (board 8D8A) with 2x CS35L56 Rev B0 amplifiers. Both amplifiers probe and produce audio. Signed-off-by: Khalil --- drivers/platform/x86/serial-multi-instantiate.c | 163 ++++++++++++++- 1 file changed, 156 insertions(+), 7 deletions(-) diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/plat= form/x86/serial-multi-instantiate.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/platform/x86/serial-multi-instantiate.c +++ b/drivers/platform/x86/serial-multi-instantiate.c @@ -8,6 +8,10 @@ #include #include +#include +#include +#include +#include #include #include #include @@ -46,6 +50,53 @@ struct smi { int spi_num; struct i2c_client **i2c_devs; struct spi_device **spi_devs; + struct gpio_desc *cs_gpio; +}; + +/* + * Quirk data for platforms with broken ACPI SPI chip select descriptions. + * cs_gpio_idx: index of the GpioIo resource in the ACPI _CRS that provides + * the chip select GPIO for devices missing a proper cs-gpios + * entry on the SPI controller. + */ +struct smi_cs_gpio_quirk { + int cs_gpio_idx; +}; + +static const struct smi_cs_gpio_quirk hp_elitebook_8g1i_quirk =3D { + .cs_gpio_idx =3D 0, +}; + +/* + * DMI table of platforms with broken SPI chip select ACPI descriptions. + * + * These systems have multiple SPI peripherals (e.g., dual CS35L56 + * amplifiers) but the SPI controller's _DSD cs-gpios property is + * incomplete - it only declares the first chip select. The remaining + * chip select GPIOs are defined as GpioIo resources in the peripheral's + * ACPI node but are not referenced by the controller. + */ +static const struct dmi_system_id smi_cs_gpio_dmi_table[] =3D { + { + .ident =3D "HP EliteBook 8 G1i 16 inch", + .matches =3D { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_BOARD_NAME, "8D8A"), + }, + .driver_data =3D (void *)&hp_elitebook_8g1i_quirk, + }, + { } +}; + +/* + * ACPI GPIO mapping for the chip select GpioIo resource. + * Maps "cs-gpios" to the GpioIo resource at index 0 of the ACPI _CRS. + */ +static const struct acpi_gpio_params smi_cs_gpio_params =3D { 0, 0, false = }; + +static const struct acpi_gpio_mapping smi_cs_gpio_mapping[] =3D { + { "cs-gpios", &smi_cs_gpio_params, 1 }, + { } }; static int smi_get_irq(struct platform_device *pdev, struct acpi_device *a= dev, @@ -99,6 +150,85 @@ static void smi_devs_unregister(struct smi *smi) } } +/* + * smi_spi_setup_cs_gpio - Fix up chip select for a device on a platform + * with broken ACPI cs-gpios description. + * + * On affected platforms, the SPI controller's cs-gpios property is incomp= lete, + * so the framework has no GPIO descriptor for some chip selects. This cau= ses + * __spi_add_device() to reject the device with -EINVAL (cs >=3D num_chips= elect). + * + * This function: + * 1. Extends num_chipselect if the device's CS is out of range + * 2. Reallocates cs_gpiods to match, preventing out-of-bounds access + * in __spi_add_device() + * 3. Installs the GPIO from the peripheral's ACPI node into the + * controller's cs_gpiods array so __spi_add_device() propagates + * it to the device + * 4. Sets SPI_CONTROLLER_GPIO_SS so the framework calls both the GPIO + * toggle and controller->set_cs (needed for clock gating on Intel + * LPSS controllers) + */ +static int smi_spi_setup_cs_gpio(struct device *dev, + struct spi_device *spi_dev, + struct smi *smi, + const struct smi_cs_gpio_quirk *quirk) +{ + struct spi_controller *ctlr =3D spi_dev->controller; + struct gpio_desc **new_gpiods; + u16 cs =3D spi_get_chipselect(spi_dev, 0); + + /* + * Only fix up chip selects that the controller doesn't know about. + * A NULL cs_gpiods[cs] within the controller's num_chipselect range + * means "native chip select" - that's intentional, not broken. + * The broken case is when cs >=3D num_chipselect, meaning the ACPI + * cs-gpios property on the controller was incomplete. + */ + if (cs < ctlr->num_chipselect) + return 0; + + /* Extend num_chipselect to cover this device */ + dev_info(dev, "Extending num_chipselect from %u to %u for CS%u\n", + ctlr->num_chipselect, cs + 1, cs); + ctlr->num_chipselect =3D cs + 1; + + /* Acquire the CS GPIO from the ACPI GpioIo resource if not yet done */ + if (!smi->cs_gpio) { + int ret; + + ret =3D devm_acpi_dev_add_driver_gpios(dev, smi_cs_gpio_mapping); + if (ret) { + dev_warn(dev, "Failed to add CS GPIO mapping: %d\n", ret); + return ret; + } + + smi->cs_gpio =3D devm_gpiod_get(dev, "cs", GPIOD_OUT_HIGH); + if (IS_ERR(smi->cs_gpio)) { + dev_warn(dev, "Failed to get CS GPIO: %ld\n", + PTR_ERR(smi->cs_gpio)); + smi->cs_gpio =3D NULL; + return -ENOENT; + } + dev_info(dev, "Acquired CS GPIO for CS%u from ACPI GpioIo[%d]\n", + cs, quirk->cs_gpio_idx); + } + + /* + * Reallocate the controller's cs_gpiods array to accommodate the + * new num_chipselect, and install the GPIO descriptor. This is + * necessary because __spi_add_device() unconditionally reads + * ctlr->cs_gpiods[cs] to set the device's cs_gpiod. + */ + new_gpiods =3D devm_kcalloc(&ctlr->dev, ctlr->num_chipselect, + sizeof(*new_gpiods), GFP_KERNEL); + if (!new_gpiods) + return -ENOMEM; + + if (ctlr->cs_gpiods) { + unsigned int i; + + for (i =3D 0; i < cs; i++) + new_gpiods[i] =3D ctlr->cs_gpiods[i]; + } + new_gpiods[cs] =3D smi->cs_gpio; + ctlr->cs_gpiods =3D new_gpiods; + + /* + * SPI_CONTROLLER_GPIO_SS ensures the framework calls both the + * GPIO CS toggle and controller->set_cs(). This is required on + * Intel LPSS controllers where set_cs handles clock gating. + */ + ctlr->flags |=3D SPI_CONTROLLER_GPIO_SS; + + dev_info(dev, "Installed GPIO CS on controller for CS%u\n", cs); + return 0; +} + /** * smi_spi_probe - Instantiate multiple SPI devices from inst array * @pdev: Platform device @@ -112,10 +242,19 @@ static int smi_spi_probe(struct platform_device *pdev= , struct smi *smi, { struct device *dev =3D &pdev->dev; struct acpi_device *adev =3D ACPI_COMPANION(dev); + const struct dmi_system_id *dmi_id; + const struct smi_cs_gpio_quirk *quirk =3D NULL; struct spi_controller *ctlr; struct spi_device *spi_dev; char name[50]; int i, ret, count; + u16 cs; + + dmi_id =3D dmi_first_match(smi_cs_gpio_dmi_table); + if (dmi_id) { + quirk =3D dmi_id->driver_data; + dev_info(dev, "Applying CS GPIO quirk for %s\n", dmi_id->ident); + } ret =3D acpi_spi_count_resources(adev); if (ret < 0) @@ -139,6 +278,19 @@ static int smi_spi_probe(struct platform_device *pdev,= struct smi *smi, } ctlr =3D spi_dev->controller; + cs =3D spi_get_chipselect(spi_dev, 0); + + /* + * On quirked platforms, fix up the chip select GPIO for + * devices that would otherwise fail due to incomplete + * ACPI cs-gpios on the SPI controller. + */ + if (quirk) { + ret =3D smi_spi_setup_cs_gpio(dev, spi_dev, smi, quirk); + if (ret) + dev_dbg(dev, "CS GPIO setup returned %d for CS%u\n", + ret, cs); + } strscpy(spi_dev->modalias, inst_array[i].type); -- 2.43.0 From nobody Mon Jun 15 16:31:57 2026 Received: from mail-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F4D92FD695 for ; Sat, 11 Apr 2026 18:04:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775930665; cv=none; b=YBxGYB4GUpjNimsEm+8pmt7VTl6ARu+A7zbRWGPMUqAqExH0xNxffm4WFz2dzpQiLwy7gExACCLszxZ63NnErpmNFdrOHwUEb+IOFPiPPf2AltmntH5IC49Zdo3CN1DKFI0seLmr2lkNVb5ct46obBLeuqAR7z1ge5JC9zmCAiY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775930665; c=relaxed/simple; bh=F+3unnwfG8mEtF1vJsp3nr2TnWCw5/D1ao7o6rizU7U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s1+ES8mxmbYhrjYZx9LYngFe7JXJYjuKCXqjoVPcOr6+lHLzkus+gBjkXFFbM2JNva8/zDea0i0j8meOaJhgav0c5gpYip9zyYjJz3TrzzTUIGMxTdEv1xPbqxCvsMYVISWUGGp1pqoki5aQyTD9DB45Xk3o/tcdv8dmOAejmGM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=aWL/ACfg; arc=none smtp.client-ip=209.85.208.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="aWL/ACfg" Received: by mail-ed1-f48.google.com with SMTP id 4fb4d7f45d1cf-6712eb9139bso96370a12.3 for ; Sat, 11 Apr 2026 11:04:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775930662; x=1776535462; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sc495D3OguMO7EA5HHUBGx+k9Q7iag37WzE7hUJCoNI=; b=aWL/ACfgEXbM3Z4qVSeRsWua8XmGf8TS6/Y6wl0dvNb48Yni0eu/yzRojixbtOa4GL ERffOal3veCllDf7bj0OA3pwEQtYfw1zjnhJQe9iCRWO3QYPspek2mA9vosxL3ZdgHyM elqohwVSs+QiJ/zHpjZhkVzBjGvgpbf2DGLCgYkSfpc6cqRo+Py4kOoBTBK0RiNYOHCh cY9BA0mEENaeiDlO+AdT3ckU6+LJdWq1BAmPj3OLQ+VP7aOuVR+UhNBpiRg/RGoAjKkq 5aLfYe52YZN1E4Pkh2fGG0TW2DWQY4rQ0t5nlWJjNn7mKya2CyYoafxiT/r7saGnX12N T2Ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775930662; x=1776535462; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=sc495D3OguMO7EA5HHUBGx+k9Q7iag37WzE7hUJCoNI=; b=Er9z0m2r+vZ4OK3n3sJu3dkBuqwl8ruxN/VYBJlDjvc4urmfVx9rW/Zc4uznKId0xy CXZwwziXakNOzzzAsj7D0fHn3mZhsjJ/lTYvaJ3C9tMfSp8Yjl+H35MAkJgyNzLeMBeI i2dtmbfTbKM5oEVe3UgVtFQarpZ3EbKWpfBl2lVay6MvtcVelfrwso/AfNTJWSpfD61a y4HbZkBhysXn/WCMVuZGmxI+yXc6f40YWccmWloBH446BhxIgOc+4f2blc2FvM6Pqh3R N69djJtvNMzGWBjKqsLwXXmkRL9B98o4P4iL5CCqujyswYyvhJzF1R6cOBQCWEs5HkyL 8ldA== X-Forwarded-Encrypted: i=1; AJvYcCXpXiCEvElUm9mOwE8dV/zsDNS9pb0m1ztvxXJMrImSSEM6lCNDYtLuIpR1fOp/lqCMdQQHFe6qVCRQtZc=@vger.kernel.org X-Gm-Message-State: AOJu0Yy3cyUaDLORpRFM96QDJwAsPYcwHUq7ThkA4eNaSrO9fpIo3Idu rmc+gpeKrws3lVS+X0xI4lL7I7aHNk0FpgPVEkh999M1pLFRgxsS+ap6 X-Gm-Gg: AeBDietHFGM/F7666JCCvnLECWbywTuRfITVuEVkK2adya193nSYHNS0GFlave53KVD Bbp8jwXMf0I1Gxf1/HDpxq9vvSW52z5bCBpK67qbZ3m/LDHs6p5wv4csKGkQIfLmtoRpdGJBvbB /HeAtx5jjKWo4pgw1/v+kOepFw/DFkulh9k1cih1ma5noCzftm/qKxwPRuikt5TWBNwqebnzdsv 4pIoq/vlgnxP2T79kzhPmA5E4M8D0xamErq9ZRIL7RxrLJ1Yb+09R0mf0s8qWvf/qkVN67gaKiv zlVdIeg5m24gA5FRKodM5LhKzTqAzUKUmDiYKlHUA7YMoahUQ4qyWDPXGeKh0NLfct2z31bgl7j mKYgnYtM0aVdCvR97BCeyb8XOnMJ/dKwlTZvMthwxzWQ1zxLHnLPPPdU5kzj2sEjasBnshCkTsc eCmY0BwcKpphy9tQ6u13NKWQ== X-Received: by 2002:a17:907:a1a0:b0:b9c:69df:4d8e with SMTP id a640c23a62f3a-b9d7298091fmr310218866b.25.1775930661559; Sat, 11 Apr 2026 11:04:21 -0700 (PDT) Received: from khalil-hp.home ([62.250.67.33]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b9d6e5c56d3sm186160666b.32.2026.04.11.11.04.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Apr 2026 11:04:21 -0700 (PDT) From: Khalil X-Google-Original-From: Khalil To: broonie@kernel.org, hdegoede@kernel.org, ilpo.jarvinen@linux.intel.com Cc: rf@opensource.cirrus.com, linux-spi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Khalil Subject: [PATCH 3/3] spi: pxa2xx: Handle clock gating for GPIO chip select devices Date: Sat, 11 Apr 2026 20:04:14 +0200 Message-ID: <20260411180414.481427-4-khalil@rentman.nl> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260411180414.481427-1-khalil@rentman.nl> References: <20260215135524.1171065-2-khalil@rentman.nl> <20260411180414.481427-1-khalil@rentman.nl> 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" From: Khalil On Intel LPSS SPI controllers (Cannon Lake and later) with dynamic clock gating (cs_clk_stays_gated=3Dtrue), the SPI clock is gated when no native chip select is asserted. When using a GPIO chip select (via SPI_CONTROLLER_GPIO_SS), the SPI framework toggles the GPIO and also calls the controller's set_cs callback. Handle this in the pxa2xx cs_assert/cs_deassert functions: when the device uses a GPIO chip select on an LPSS controller, assert native CS in the control register to enable the clock, and force the clock gate on. On deassert, restore both. This is needed on platforms where serial-multi-instantiate installs a GPIO chip select from the peripheral's ACPI GpioIo resource to work around an incomplete cs-gpios property on the SPI controller. Also remove the unconditional num_chipselect bump to 2 that was added as a temporary workaround - the proper fix is now in serial-multi-instantiate. Signed-off-by: Khalil --- drivers/spi/spi-pxa2xx.c | 78 ++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -419,33 +419,43 @@ static void cs_assert(struct spi_device *spi) { struct driver_data *drv_data =3D spi_controller_get_devdata(spi->controller); - struct gpio_desc *cs_gpio; + const struct lpss_config *config; if (drv_data->ssp_type =3D=3D CE4100_SSP) { pxa2xx_spi_write(drv_data, SSSR, spi_get_chipselect(spi, 0)); return; } - /* - * For devices with GPIO chip select, toggle the GPIO directly. - * This ensures GPIO CS works on Intel LPSS which only has native CS0. - */ - cs_gpio =3D spi_get_csgpiod(spi, 0); - if (cs_gpio) { - /* For ACPI: LOW =3D selected (gpiod_set_value uses logical value) */ - gpiod_set_value_cansleep(cs_gpio, 0); - return; - } - - if (is_lpss_ssp(drv_data)) - lpss_ssp_cs_control(spi, true); + if (is_lpss_ssp(drv_data)) { + config =3D lpss_get_config(drv_data); + + if (spi_is_csgpiod(spi)) { + /* + * GPIO handles the actual chip select to the device. + * On LPSS controllers with dynamic clock gating, the + * SPI clock won't run unless the native CS state says + * "asserted" in the CS control register. Assert native + * CS in the register to enable the clock, and force + * the clock gate on. + */ + lpss_ssp_cs_control(spi, true); + if (config->cs_clk_stays_gated) { + __lpss_ssp_update_priv(drv_data, + LPSS_PRIV_CLOCK_GATE, + LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK, + LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON); + } + } else { + lpss_ssp_cs_control(spi, true); + } + } } static void cs_deassert(struct spi_device *spi) { struct driver_data *drv_data =3D spi_controller_get_devdata(spi->controller); - struct gpio_desc *cs_gpio; + const struct lpss_config *config; unsigned long timeout; if (drv_data->ssp_type =3D=3D CE4100_SSP) @@ -457,19 +467,22 @@ static void cs_deassert(struct spi_device *spi) !time_after(jiffies, timeout)) cpu_relax(); - /* - * For devices with GPIO chip select, toggle the GPIO directly. - * This ensures GPIO CS works on Intel LPSS which only has native CS0. - */ - cs_gpio =3D spi_get_csgpiod(spi, 0); - if (cs_gpio) { - /* For ACPI: HIGH =3D deselected (gpiod_set_value uses logical value) */ - gpiod_set_value_cansleep(cs_gpio, 1); - return; - } - - if (is_lpss_ssp(drv_data)) - lpss_ssp_cs_control(spi, false); + if (is_lpss_ssp(drv_data)) { + config =3D lpss_get_config(drv_data); + + if (spi_is_csgpiod(spi)) { + /* Deassert native CS and restore clock gating */ + lpss_ssp_cs_control(spi, false); + if (config->cs_clk_stays_gated) { + __lpss_ssp_update_priv(drv_data, + LPSS_PRIV_CLOCK_GATE, + LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK, + LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_OFF); + } + } else { + lpss_ssp_cs_control(spi, false); + } + } } static void pxa2xx_spi_set_cs(struct spi_device *spi, bool level) @@ -1454,13 +1467,6 @@ static int pxa2xx_spi_probe(struct device *dev, ...) } } controller->num_chipselect =3D platform_info->num_chipselect; - - /* Fix for HP EliteBook CS35L56 speakers - need at least 2 chip selects */ - if (is_lpss_ssp(drv_data) && controller->num_chipselect < 2) { - dev_info(dev, "Increasing num_chipselect from %d to 2 for LPSS audio\n", - controller->num_chipselect); - controller->num_chipselect =3D 2; - } controller->use_gpio_descriptors =3D true; -- 2.43.0