--- /dev/null
+From 12c62ca8a30820c53a058976c1e41b2a880ed334 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 17:39:57 +0800
+Subject: Bluetooth: qca: add support for QCA2066
+
+From: Tim Jiang <quic_tjiang@quicinc.com>
+
+[ Upstream commit a7f8dedb4be2cc930a29af24427b885405ecd15d ]
+
+This patch adds support for QCA2066 firmware patch and NVM downloading.
+as the RF performance of QCA2066 SOC chip from different foundries may
+vary. Therefore we use different NVM to configure them based on board ID.
+
+Changes in v2
+ - optimize the function qca_generate_hsp_nvm_name
+ - remove redundant debug code for function qca_read_fw_board_id
+
+Signed-off-by: Tim Jiang <quic_tjiang@quicinc.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 32868e126c78 ("Bluetooth: qca: fix invalid device address check")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 68 +++++++++++++++++++++++++++++++++++++
+ drivers/bluetooth/btqca.h | 5 ++-
+ drivers/bluetooth/hci_qca.c | 11 ++++++
+ 3 files changed, 83 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 5277090c6d6d7..19cfc342fc7bb 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -205,6 +205,44 @@ static int qca_send_reset(struct hci_dev *hdev)
+ return 0;
+ }
+
++static int qca_read_fw_board_id(struct hci_dev *hdev, u16 *bid)
++{
++ u8 cmd;
++ struct sk_buff *skb;
++ struct edl_event_hdr *edl;
++ int err = 0;
++
++ cmd = EDL_GET_BID_REQ_CMD;
++ skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN,
++ &cmd, 0, HCI_INIT_TIMEOUT);
++ if (IS_ERR(skb)) {
++ err = PTR_ERR(skb);
++ bt_dev_err(hdev, "Reading QCA board ID failed (%d)", err);
++ return err;
++ }
++
++ edl = skb_pull_data(skb, sizeof(*edl));
++ if (!edl) {
++ bt_dev_err(hdev, "QCA read board ID with no header");
++ err = -EILSEQ;
++ goto out;
++ }
++
++ if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
++ edl->rtype != EDL_GET_BID_REQ_CMD) {
++ bt_dev_err(hdev, "QCA Wrong packet: %d %d", edl->cresp, edl->rtype);
++ err = -EIO;
++ goto out;
++ }
++
++ *bid = (edl->data[1] << 8) + edl->data[2];
++ bt_dev_dbg(hdev, "%s: bid = %x", __func__, *bid);
++
++out:
++ kfree_skb(skb);
++ return err;
++}
++
+ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
+ {
+ struct sk_buff *skb;
+@@ -574,6 +612,23 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+ }
+ EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
+
++static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,
++ struct qca_btsoc_version ver, u8 rom_ver, u16 bid)
++{
++ const char *variant;
++
++ /* hsp gf chip */
++ if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID)
++ variant = "g";
++ else
++ variant = "";
++
++ if (bid == 0x0)
++ snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant);
++ else
++ snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", rom_ver, variant, bid);
++}
++
+ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+ enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
+ const char *firmware_name)
+@@ -582,6 +637,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+ int err;
+ u8 rom_ver = 0;
+ u32 soc_ver;
++ u16 boardid = 0;
+
+ bt_dev_dbg(hdev, "QCA setup on UART");
+
+@@ -615,6 +671,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+ snprintf(config.fwname, sizeof(config.fwname),
+ "qca/apbtfw%02x.tlv", rom_ver);
+ break;
++ case QCA_QCA2066:
++ snprintf(config.fwname, sizeof(config.fwname),
++ "qca/hpbtfw%02x.tlv", rom_ver);
++ break;
+ case QCA_QCA6390:
+ snprintf(config.fwname, sizeof(config.fwname),
+ "qca/htbtfw%02x.tlv", rom_ver);
+@@ -649,6 +709,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+ /* Give the controller some time to get ready to receive the NVM */
+ msleep(10);
+
++ if (soc_type == QCA_QCA2066)
++ qca_read_fw_board_id(hdev, &boardid);
++
+ /* Download NVM configuration */
+ config.type = TLV_TYPE_NVM;
+ if (firmware_name) {
+@@ -671,6 +734,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+ snprintf(config.fwname, sizeof(config.fwname),
+ "qca/apnv%02x.bin", rom_ver);
+ break;
++ case QCA_QCA2066:
++ qca_generate_hsp_nvm_name(config.fwname,
++ sizeof(config.fwname), ver, rom_ver, boardid);
++ break;
+ case QCA_QCA6390:
+ snprintf(config.fwname, sizeof(config.fwname),
+ "qca/htnv%02x.bin", rom_ver);
+@@ -702,6 +769,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+
+ switch (soc_type) {
+ case QCA_WCN3991:
++ case QCA_QCA2066:
+ case QCA_QCA6390:
+ case QCA_WCN6750:
+ case QCA_WCN6855:
+diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
+index 03bff5c0059de..dc31984f71dc1 100644
+--- a/drivers/bluetooth/btqca.h
++++ b/drivers/bluetooth/btqca.h
+@@ -12,6 +12,7 @@
+ #define EDL_PATCH_VER_REQ_CMD (0x19)
+ #define EDL_PATCH_TLV_REQ_CMD (0x1E)
+ #define EDL_GET_BUILD_INFO_CMD (0x20)
++#define EDL_GET_BID_REQ_CMD (0x23)
+ #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
+ #define EDL_PATCH_CONFIG_CMD (0x28)
+ #define MAX_SIZE_PER_TLV_SEGMENT (243)
+@@ -47,7 +48,8 @@
+ ((le32_to_cpu(soc_id) << 16) | (le16_to_cpu(rom_ver)))
+
+ #define QCA_FW_BUILD_VER_LEN 255
+-
++#define QCA_HSP_GF_SOC_ID 0x1200
++#define QCA_HSP_GF_SOC_MASK 0x0000ff00
+
+ enum qca_baudrate {
+ QCA_BAUDRATE_115200 = 0,
+@@ -146,6 +148,7 @@ enum qca_btsoc_type {
+ QCA_WCN3990,
+ QCA_WCN3998,
+ QCA_WCN3991,
++ QCA_QCA2066,
+ QCA_QCA6390,
+ QCA_WCN6750,
+ QCA_WCN6855,
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index 410f146e3f671..cb825987e7f1a 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -1845,6 +1845,10 @@ static int qca_setup(struct hci_uart *hu)
+ set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+
+ switch (soc_type) {
++ case QCA_QCA2066:
++ soc_name = "qca2066";
++ break;
++
+ case QCA_WCN3988:
+ case QCA_WCN3990:
+ case QCA_WCN3991:
+@@ -2043,6 +2047,11 @@ static const struct qca_device_data qca_soc_data_wcn3998 __maybe_unused = {
+ .num_vregs = 4,
+ };
+
++static const struct qca_device_data qca_soc_data_qca2066 __maybe_unused = {
++ .soc_type = QCA_QCA2066,
++ .num_vregs = 0,
++};
++
+ static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = {
+ .soc_type = QCA_QCA6390,
+ .num_vregs = 0,
+@@ -2582,6 +2591,7 @@ static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume);
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id qca_bluetooth_of_match[] = {
++ { .compatible = "qcom,qca2066-bt", .data = &qca_soc_data_qca2066},
+ { .compatible = "qcom,qca6174-bt" },
+ { .compatible = "qcom,qca6390-bt", .data = &qca_soc_data_qca6390},
+ { .compatible = "qcom,qca9377-bt" },
+@@ -2599,6 +2609,7 @@ MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);
+
+ #ifdef CONFIG_ACPI
+ static const struct acpi_device_id qca_bluetooth_acpi_match[] = {
++ { "QCOM2066", (kernel_ulong_t)&qca_soc_data_qca2066 },
+ { "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 },
+ { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 },
+ { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 },
+--
+2.43.0
+
--- /dev/null
+From 01b624be41457c3e6bc5d0e202fb14838b118031 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Apr 2024 11:15:09 +0200
+Subject: Bluetooth: qca: fix invalid device address check
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 32868e126c78876a8a5ddfcb6ac8cb2fffcf4d27 ]
+
+Qualcomm Bluetooth controllers may not have been provisioned with a
+valid device address and instead end up using the default address
+00:00:00:00:5a:ad.
+
+This was previously believed to be due to lack of persistent storage for
+the address but it may also be due to integrators opting to not use the
+on-chip OTP memory and instead store the address elsewhere (e.g. in
+storage managed by secure world firmware).
+
+According to Qualcomm, at least WCN6750, WCN6855 and WCN7850 have
+on-chip OTP storage for the address.
+
+As the device type alone cannot be used to determine when the address is
+valid, instead read back the address during setup() and only set the
+HCI_QUIRK_USE_BDADDR_PROPERTY flag when needed.
+
+This specifically makes sure that controllers that have been provisioned
+with an address do not start as unconfigured.
+
+Reported-by: Janaki Ramaiah Thota <quic_janathot@quicinc.com>
+Link: https://lore.kernel.org/r/124a7d54-5a18-4be7-9a76-a12017f6cce5@quicinc.com/
+Fixes: 5971752de44c ("Bluetooth: hci_qca: Set HCI_QUIRK_USE_BDADDR_PROPERTY for wcn3990")
+Fixes: e668eb1e1578 ("Bluetooth: hci_core: Don't stop BT if the BD address missing in dts")
+Fixes: 6945795bc81a ("Bluetooth: fix use-bdaddr-property quirk")
+Cc: stable@vger.kernel.org # 6.5
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reported-by: Janaki Ramaiah Thota <quic_janathot@quicinc.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 38 +++++++++++++++++++++++++++++++++++++
+ drivers/bluetooth/hci_qca.c | 2 --
+ 2 files changed, 38 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 19cfc342fc7bb..216826c31ee34 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -15,6 +15,8 @@
+
+ #define VERSION "0.1"
+
++#define QCA_BDADDR_DEFAULT (&(bdaddr_t) {{ 0xad, 0x5a, 0x00, 0x00, 0x00, 0x00 }})
++
+ int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
+ enum qca_btsoc_type soc_type)
+ {
+@@ -612,6 +614,38 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+ }
+ EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
+
++static int qca_check_bdaddr(struct hci_dev *hdev)
++{
++ struct hci_rp_read_bd_addr *bda;
++ struct sk_buff *skb;
++ int err;
++
++ if (bacmp(&hdev->public_addr, BDADDR_ANY))
++ return 0;
++
++ skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
++ HCI_INIT_TIMEOUT);
++ if (IS_ERR(skb)) {
++ err = PTR_ERR(skb);
++ bt_dev_err(hdev, "Failed to read device address (%d)", err);
++ return err;
++ }
++
++ if (skb->len != sizeof(*bda)) {
++ bt_dev_err(hdev, "Device address length mismatch");
++ kfree_skb(skb);
++ return -EIO;
++ }
++
++ bda = (struct hci_rp_read_bd_addr *)skb->data;
++ if (!bacmp(&bda->bdaddr, QCA_BDADDR_DEFAULT))
++ set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
++
++ kfree_skb(skb);
++
++ return 0;
++}
++
+ static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,
+ struct qca_btsoc_version ver, u8 rom_ver, u16 bid)
+ {
+@@ -818,6 +852,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+ break;
+ }
+
++ err = qca_check_bdaddr(hdev);
++ if (err)
++ return err;
++
+ bt_dev_info(hdev, "QCA setup on UART is completed");
+
+ return 0;
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index cb825987e7f1a..92341a87a5da7 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -1890,8 +1890,6 @@ static int qca_setup(struct hci_uart *hu)
+ case QCA_WCN6750:
+ case QCA_WCN6855:
+ case QCA_WCN7850:
+- set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
+-
+ qcadev = serdev_device_get_drvdata(hu->serdev);
+ if (qcadev->bdaddr_property_broken)
+ set_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks);
+--
+2.43.0
+
--- /dev/null
+From ce281908db152ff7eddb246448280efba6f3f187 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 14:50:26 +0900
+Subject: dmaengine: pl330: issue_pending waits until WFP state
+
+From: Bumyong Lee <bumyong.lee@samsung.com>
+
+[ Upstream commit 22a9d9585812440211b0b34a6bc02ade62314be4 ]
+
+According to DMA-330 errata notice[1] 71930, DMAKILL
+cannot clear internal signal, named pipeline_req_active.
+it makes that pl330 would wait forever in WFP state
+although dma already send dma request if pl330 gets
+dma request before entering WFP state.
+
+The errata suggests that polling until entering WFP state
+as workaround and then peripherals allows to issue dma request.
+
+[1]: https://developer.arm.com/documentation/genc008428/latest
+
+Signed-off-by: Bumyong Lee <bumyong.lee@samsung.com>
+Link: https://lore.kernel.org/r/20231219055026.118695-1-bumyong.lee@samsung.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: afc89870ea67 ("dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/pl330.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index 3cf0b38387ae5..c29744bfdf2c2 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -1053,6 +1053,9 @@ static bool _trigger(struct pl330_thread *thrd)
+
+ thrd->req_running = idx;
+
++ if (desc->rqtype == DMA_MEM_TO_DEV || desc->rqtype == DMA_DEV_TO_MEM)
++ UNTIL(thrd, PL330_STATE_WFP);
++
+ return true;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 5325af9194b3af90ef6267063dbd209feeb9414e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Mar 2024 12:21:51 +0530
+Subject: dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP
+ state"
+
+From: Vinod Koul <vkoul@kernel.org>
+
+[ Upstream commit afc89870ea677bd5a44516eb981f7a259b74280c ]
+
+This reverts commit 22a9d9585812 ("dmaengine: pl330: issue_pending waits
+until WFP state") as it seems to cause regression in pl330 driver.
+Note the issue now exists in mainline so a fix to be done.
+
+Cc: stable@vger.kernel.org
+Reported-by: karthikeyan <karthikeyan@linumiz.com>
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/pl330.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index c29744bfdf2c2..3cf0b38387ae5 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -1053,9 +1053,6 @@ static bool _trigger(struct pl330_thread *thrd)
+
+ thrd->req_running = idx;
+
+- if (desc->rqtype == DMA_MEM_TO_DEV || desc->rqtype == DMA_DEV_TO_MEM)
+- UNTIL(thrd, PL330_STATE_WFP);
+-
+ return true;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From f05efac8afe49f576d3e984c4a54d5b322be5981 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Apr 2024 17:43:36 +0000
+Subject: eeprom: at24: fix memory corruption race condition
+
+From: Daniel Okazaki <dtokazaki@google.com>
+
+[ Upstream commit f42c97027fb75776e2e9358d16bf4a99aeb04cf2 ]
+
+If the eeprom is not accessible, an nvmem device will be registered, the
+read will fail, and the device will be torn down. If another driver
+accesses the nvmem device after the teardown, it will reference
+invalid memory.
+
+Move the failure point before registering the nvmem device.
+
+Signed-off-by: Daniel Okazaki <dtokazaki@google.com>
+Fixes: b20eb4c1f026 ("eeprom: at24: drop unnecessary label")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240422174337.2487142-1-dtokazaki@google.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/eeprom/at24.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
+index e6d688817b106..c290e849b2ed8 100644
+--- a/drivers/misc/eeprom/at24.c
++++ b/drivers/misc/eeprom/at24.c
+@@ -781,15 +781,6 @@ static int at24_probe(struct i2c_client *client)
+ }
+ pm_runtime_enable(dev);
+
+- at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
+- if (IS_ERR(at24->nvmem)) {
+- pm_runtime_disable(dev);
+- if (!pm_runtime_status_suspended(dev))
+- regulator_disable(at24->vcc_reg);
+- return dev_err_probe(dev, PTR_ERR(at24->nvmem),
+- "failed to register nvmem\n");
+- }
+-
+ /*
+ * Perform a one-byte test read to verify that the chip is functional,
+ * unless powering on the device is to be avoided during probe (i.e.
+@@ -805,6 +796,15 @@ static int at24_probe(struct i2c_client *client)
+ }
+ }
+
++ at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
++ if (IS_ERR(at24->nvmem)) {
++ pm_runtime_disable(dev);
++ if (!pm_runtime_status_suspended(dev))
++ regulator_disable(at24->vcc_reg);
++ return dev_err_probe(dev, PTR_ERR(at24->nvmem),
++ "failed to register nvmem\n");
++ }
++
+ /* If this a SPD EEPROM, probe for DDR3 thermal sensor */
+ if (cdata == &at24_data_spd)
+ at24_probe_temp_sensor(client);
+--
+2.43.0
+
--- /dev/null
+From 3a1960199c8366183eba1bc80d64a241fc518304 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Dec 2023 13:55:58 +0100
+Subject: eeprom: at24: Probe for DDR3 thermal sensor in the SPD case
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit caba40ec3531b0849f44502a03117796e8c9f4a1 ]
+
+The DDR3 SPD data structure advertises the presence of a thermal
+sensor on a DDR3 module in byte 32, bit 7. Let's use this information
+to explicitly instantiate the thermal sensor I2C client instead of
+having to rely on class-based I2C probing.
+
+The temp sensor i2c address can be derived from the SPD i2c address,
+so we can directly instantiate the device and don't have to probe
+for it. If the temp sensor has been instantiated already by other
+means (e.g. class-based auto-detection), then the busy-check in
+i2c_new_client_device will detect this.
+
+Note: Thermal sensors on DDR4 DIMM's are instantiated from the
+ ee1004 driver.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/68113672-3724-44d5-9ff8-313dd6628f8c@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: f42c97027fb7 ("eeprom: at24: fix memory corruption race condition")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/eeprom/at24.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
+index dbbf7db4ff2f4..e6d688817b106 100644
+--- a/drivers/misc/eeprom/at24.c
++++ b/drivers/misc/eeprom/at24.c
+@@ -581,6 +581,31 @@ static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len)
+ }
+ }
+
++static void at24_probe_temp_sensor(struct i2c_client *client)
++{
++ struct at24_data *at24 = i2c_get_clientdata(client);
++ struct i2c_board_info info = { .type = "jc42" };
++ int ret;
++ u8 val;
++
++ /*
++ * Byte 2 has value 11 for DDR3, earlier versions don't
++ * support the thermal sensor present flag
++ */
++ ret = at24_read(at24, 2, &val, 1);
++ if (ret || val != 11)
++ return;
++
++ /* Byte 32, bit 7 is set if temp sensor is present */
++ ret = at24_read(at24, 32, &val, 1);
++ if (ret || !(val & BIT(7)))
++ return;
++
++ info.addr = 0x18 | (client->addr & 7);
++
++ i2c_new_client_device(client->adapter, &info);
++}
++
+ static int at24_probe(struct i2c_client *client)
+ {
+ struct regmap_config regmap_config = { };
+@@ -780,6 +805,10 @@ static int at24_probe(struct i2c_client *client)
+ }
+ }
+
++ /* If this a SPD EEPROM, probe for DDR3 thermal sensor */
++ if (cdata == &at24_data_spd)
++ at24_probe_temp_sensor(client);
++
+ pm_runtime_idle(dev);
+
+ if (writable)
+--
+2.43.0
+
--- /dev/null
+From 780dc8a8dab57c6b0bc5a918160c381b52d71f0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Apr 2024 12:50:26 +0200
+Subject: mtd: limit OTP NVMEM cell parse to non-NAND devices
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+[ Upstream commit d2d73a6dd17365c43e109263841f7c26da55cfb0 ]
+
+MTD OTP logic is very fragile on parsing NVMEM cell and can be
+problematic with some specific kind of devices.
+
+The problem was discovered by e87161321a40 ("mtd: rawnand: macronix:
+OTP access for MX30LFxG18AC") where OTP support was added to a NAND
+device. With the case of NAND devices, it does require a node where ECC
+info are declared and all the fixed partitions, and this cause the OTP
+codepath to parse this node as OTP NVMEM cells, making probe fail and
+the NAND device registration fail.
+
+MTD OTP parsing should have been limited to always using compatible to
+prevent this error by using node with compatible "otp-user" or
+"otp-factory".
+
+NVMEM across the years had various iteration on how cells could be
+declared in DT, in some old implementation, no_of_node should have been
+enabled but now add_legacy_fixed_of_cells should be used to disable
+NVMEM to parse child node as NVMEM cell.
+
+To fix this and limit any regression with other MTD that makes use of
+declaring OTP as direct child of the dev node, disable
+add_legacy_fixed_of_cells if we detect the MTD type is Nand.
+
+With the following logic, the OTP NVMEM entry is correctly created with
+no cells and the MTD Nand is correctly probed and partitions are
+correctly exposed.
+
+Fixes: 4b361cfa8624 ("mtd: core: add OTP nvmem provider support")
+Cc: <stable@vger.kernel.org> # v6.7+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20240412105030.1598-1-ansuelsmth@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdcore.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index fbf60d1364f0d..5c32208b17a1d 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -899,7 +899,7 @@ static struct nvmem_device *mtd_otp_nvmem_register(struct mtd_info *mtd,
+ config.name = compatible;
+ config.id = NVMEM_DEVID_AUTO;
+ config.owner = THIS_MODULE;
+- config.add_legacy_fixed_of_cells = true;
++ config.add_legacy_fixed_of_cells = !mtd_type_is_nand(mtd);
+ config.type = NVMEM_TYPE_OTP;
+ config.root_only = true;
+ config.ignore_wp = true;
+--
+2.43.0
+
--- /dev/null
+From aa3412edf8d2ff4fb7d268b9395928e7f6e30461 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 14:57:31 -0500
+Subject: nfs: expose /proc/net/sunrpc/nfs in net namespaces
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit d47151b79e3220e72ae323b8b8e9d6da20dc884e ]
+
+We're using nfs mounts inside of containers in production and noticed
+that the nfs stats are not exposed in /proc. This is a problem for us
+as we use these stats for monitoring, and have to do this awkward bind
+mount from the main host into the container in order to get to these
+states.
+
+Add the rpc_proc_register call to the pernet operations entry and exit
+points so these stats can be exposed inside of network namespaces.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/inode.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index e21c073158e5b..d7d937597001d 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -2427,11 +2427,13 @@ EXPORT_SYMBOL_GPL(nfs_net_id);
+ static int nfs_net_init(struct net *net)
+ {
+ nfs_clients_init(net);
++ rpc_proc_register(net, &nfs_rpcstat);
+ return nfs_fs_proc_net_init(net);
+ }
+
+ static void nfs_net_exit(struct net *net)
+ {
++ rpc_proc_unregister(net, "nfs");
+ nfs_fs_proc_net_exit(net);
+ nfs_clients_exit(net);
+ }
+@@ -2486,15 +2488,12 @@ static int __init init_nfs_fs(void)
+ if (err)
+ goto out1;
+
+- rpc_proc_register(&init_net, &nfs_rpcstat);
+-
+ err = register_nfs_fs();
+ if (err)
+ goto out0;
+
+ return 0;
+ out0:
+- rpc_proc_unregister(&init_net, "nfs");
+ nfs_destroy_directcache();
+ out1:
+ nfs_destroy_writepagecache();
+@@ -2524,7 +2523,6 @@ static void __exit exit_nfs_fs(void)
+ nfs_destroy_inodecache();
+ nfs_destroy_nfspagecache();
+ unregister_pernet_subsys(&nfs_net_ops);
+- rpc_proc_unregister(&init_net, "nfs");
+ unregister_nfs_fs();
+ nfs_fs_proc_exit();
+ nfsiod_stop();
+--
+2.43.0
+
--- /dev/null
+From 2f7b1e4de64bb7c01f197b59b5ef0904ad6fc860 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 15:12:00 -0700
+Subject: nfs: Handle error of rpc_proc_register() in nfs_net_init().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 24457f1be29f1e7042e50a7749f5c2dde8c433c8 ]
+
+syzkaller reported a warning [0] triggered while destroying immature
+netns.
+
+rpc_proc_register() was called in init_nfs_fs(), but its error
+has been ignored since at least the initial commit 1da177e4c3f4
+("Linux-2.6.12-rc2").
+
+Recently, commit d47151b79e32 ("nfs: expose /proc/net/sunrpc/nfs
+in net namespaces") converted the procfs to per-netns and made
+the problem more visible.
+
+Even when rpc_proc_register() fails, nfs_net_init() could succeed,
+and thus nfs_net_exit() will be called while destroying the netns.
+
+Then, remove_proc_entry() will be called for non-existing proc
+directory and trigger the warning below.
+
+Let's handle the error of rpc_proc_register() properly in nfs_net_init().
+
+[0]:
+name 'nfs'
+WARNING: CPU: 1 PID: 1710 at fs/proc/generic.c:711 remove_proc_entry+0x1bb/0x2d0 fs/proc/generic.c:711
+Modules linked in:
+CPU: 1 PID: 1710 Comm: syz-executor.2 Not tainted 6.8.0-12822-gcd51db110a7e #12
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+RIP: 0010:remove_proc_entry+0x1bb/0x2d0 fs/proc/generic.c:711
+Code: 41 5d 41 5e c3 e8 85 09 b5 ff 48 c7 c7 88 58 64 86 e8 09 0e 71 02 e8 74 09 b5 ff 4c 89 e6 48 c7 c7 de 1b 80 84 e8 c5 ad 97 ff <0f> 0b eb b1 e8 5c 09 b5 ff 48 c7 c7 88 58 64 86 e8 e0 0d 71 02 eb
+RSP: 0018:ffffc9000c6d7ce0 EFLAGS: 00010286
+RAX: 0000000000000000 RBX: ffff8880422b8b00 RCX: ffffffff8110503c
+RDX: ffff888030652f00 RSI: ffffffff81105045 RDI: 0000000000000001
+RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000
+R10: 0000000000000001 R11: ffffffff81bb62cb R12: ffffffff84807ffc
+R13: ffff88804ad6fcc0 R14: ffffffff84807ffc R15: ffffffff85741ff8
+FS: 00007f30cfba8640(0000) GS:ffff88807dd00000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007ff51afe8000 CR3: 000000005a60a005 CR4: 0000000000770ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ rpc_proc_unregister+0x64/0x70 net/sunrpc/stats.c:310
+ nfs_net_exit+0x1c/0x30 fs/nfs/inode.c:2438
+ ops_exit_list+0x62/0xb0 net/core/net_namespace.c:170
+ setup_net+0x46c/0x660 net/core/net_namespace.c:372
+ copy_net_ns+0x244/0x590 net/core/net_namespace.c:505
+ create_new_namespaces+0x2ed/0x770 kernel/nsproxy.c:110
+ unshare_nsproxy_namespaces+0xae/0x160 kernel/nsproxy.c:228
+ ksys_unshare+0x342/0x760 kernel/fork.c:3322
+ __do_sys_unshare kernel/fork.c:3393 [inline]
+ __se_sys_unshare kernel/fork.c:3391 [inline]
+ __x64_sys_unshare+0x1f/0x30 kernel/fork.c:3391
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0x4f/0x110 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x46/0x4e
+RIP: 0033:0x7f30d0febe5d
+Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48
+RSP: 002b:00007f30cfba7cc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000110
+RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007f30d0febe5d
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000000006c020600
+RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000002
+R13: 000000000000000b R14: 00007f30d104c530 R15: 0000000000000000
+ </TASK>
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/inode.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index e26d892ff4f2d..ca76b0b51b779 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -2429,7 +2429,12 @@ static int nfs_net_init(struct net *net)
+ struct nfs_net *nn = net_generic(net, nfs_net_id);
+
+ nfs_clients_init(net);
+- rpc_proc_register(net, &nn->rpcstats);
++
++ if (!rpc_proc_register(net, &nn->rpcstats)) {
++ nfs_clients_exit(net);
++ return -ENOMEM;
++ }
++
+ return nfs_fs_proc_net_init(net);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From e1c02961dddd276420ba0f0c527e15027d58652a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 14:57:32 -0500
+Subject: nfs: make the rpc_stat per net namespace
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 1548036ef1204df65ca5a16e8b199c858cb80075 ]
+
+Now that we're exposing the rpc stats on a per-network namespace basis,
+move this struct into struct nfs_net and use that to make sure only the
+per-network namespace stats are exposed.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/client.c | 5 ++++-
+ fs/nfs/inode.c | 4 +++-
+ fs/nfs/internal.h | 2 --
+ fs/nfs/netns.h | 2 ++
+ 4 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nfs/client.c b/fs/nfs/client.c
+index 44eca51b28085..4d9249c99989f 100644
+--- a/fs/nfs/client.c
++++ b/fs/nfs/client.c
+@@ -73,7 +73,6 @@ const struct rpc_program nfs_program = {
+ .number = NFS_PROGRAM,
+ .nrvers = ARRAY_SIZE(nfs_version),
+ .version = nfs_version,
+- .stats = &nfs_rpcstat,
+ .pipe_dir_name = NFS_PIPE_DIRNAME,
+ };
+
+@@ -502,6 +501,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
+ const struct nfs_client_initdata *cl_init,
+ rpc_authflavor_t flavor)
+ {
++ struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
+ struct rpc_clnt *clnt = NULL;
+ struct rpc_create_args args = {
+ .net = clp->cl_net,
+@@ -513,6 +513,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
+ .servername = clp->cl_hostname,
+ .nodename = cl_init->nodename,
+ .program = &nfs_program,
++ .stats = &nn->rpcstats,
+ .version = clp->rpc_ops->version,
+ .authflavor = flavor,
+ .cred = cl_init->cred,
+@@ -1175,6 +1176,8 @@ void nfs_clients_init(struct net *net)
+ #endif
+ spin_lock_init(&nn->nfs_client_lock);
+ nn->boot_time = ktime_get_real();
++ memset(&nn->rpcstats, 0, sizeof(nn->rpcstats));
++ nn->rpcstats.program = &nfs_program;
+
+ nfs_netns_sysfs_setup(nn, net);
+ }
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index d7d937597001d..e26d892ff4f2d 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -2426,8 +2426,10 @@ EXPORT_SYMBOL_GPL(nfs_net_id);
+
+ static int nfs_net_init(struct net *net)
+ {
++ struct nfs_net *nn = net_generic(net, nfs_net_id);
++
+ nfs_clients_init(net);
+- rpc_proc_register(net, &nfs_rpcstat);
++ rpc_proc_register(net, &nn->rpcstats);
+ return nfs_fs_proc_net_init(net);
+ }
+
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index b1fa81c9dff6f..c91bce41931fb 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -449,8 +449,6 @@ int nfs_try_get_tree(struct fs_context *);
+ int nfs_get_tree_common(struct fs_context *);
+ void nfs_kill_super(struct super_block *);
+
+-extern struct rpc_stat nfs_rpcstat;
+-
+ extern int __init register_nfs_fs(void);
+ extern void __exit unregister_nfs_fs(void);
+ extern bool nfs_sb_active(struct super_block *sb);
+diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
+index c8374f74dce11..a68b21603ea9a 100644
+--- a/fs/nfs/netns.h
++++ b/fs/nfs/netns.h
+@@ -9,6 +9,7 @@
+ #include <linux/nfs4.h>
+ #include <net/net_namespace.h>
+ #include <net/netns/generic.h>
++#include <linux/sunrpc/stats.h>
+
+ struct bl_dev_msg {
+ int32_t status;
+@@ -34,6 +35,7 @@ struct nfs_net {
+ struct nfs_netns_client *nfs_client;
+ spinlock_t nfs_client_lock;
+ ktime_t boot_time;
++ struct rpc_stat rpcstats;
+ #ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *proc_nfsfs;
+ #endif
+--
+2.43.0
+
--- /dev/null
+From b8f5e8cbf65b50f337ca6e496dfa1321eed5cd97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 11:55:41 +0100
+Subject: nvmem: add explicit config option to read old syntax fixed OF cells
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 2cc3b37f5b6df8189d55d0e812d9658ce256dfec ]
+
+Binding for fixed NVMEM cells defined directly as NVMEM device subnodes
+has been deprecated. It has been replaced by the "fixed-layout" NVMEM
+layout binding.
+
+New syntax is meant to be clearer and should help avoiding imprecise
+bindings.
+
+NVMEM subsystem already supports the new binding. It should be a good
+idea to limit support for old syntax to existing drivers that actually
+support & use it (we can't break backward compatibility!). That way we
+additionally encourage new bindings & drivers to ignore deprecated
+binding.
+
+It wasn't clear (to me) if rtc and w1 code actually uses old syntax
+fixed cells. I enabled them to don't risk any breakage.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+[for meson-{efuse,mx-efuse}.c]
+Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+[for mtk-efuse.c, nvmem/core.c, nvmem-provider.h]
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+[MT8192, MT8195 Chromebooks]
+Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+[for microchip-otpc.c]
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+[SAMA7G5-EK]
+Tested-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20231020105545.216052-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: d2d73a6dd173 ("mtd: limit OTP NVMEM cell parse to non-NAND devices")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdcore.c | 2 ++
+ drivers/nvmem/apple-efuses.c | 1 +
+ drivers/nvmem/core.c | 8 +++++---
+ drivers/nvmem/imx-ocotp-scu.c | 1 +
+ drivers/nvmem/imx-ocotp.c | 1 +
+ drivers/nvmem/meson-efuse.c | 1 +
+ drivers/nvmem/meson-mx-efuse.c | 1 +
+ drivers/nvmem/microchip-otpc.c | 1 +
+ drivers/nvmem/mtk-efuse.c | 1 +
+ drivers/nvmem/qcom-spmi-sdam.c | 1 +
+ drivers/nvmem/qfprom.c | 1 +
+ drivers/nvmem/rave-sp-eeprom.c | 1 +
+ drivers/nvmem/rockchip-efuse.c | 1 +
+ drivers/nvmem/sc27xx-efuse.c | 1 +
+ drivers/nvmem/sec-qfprom.c | 1 +
+ drivers/nvmem/sprd-efuse.c | 1 +
+ drivers/nvmem/stm32-romem.c | 1 +
+ drivers/nvmem/sunplus-ocotp.c | 1 +
+ drivers/nvmem/sunxi_sid.c | 1 +
+ drivers/nvmem/uniphier-efuse.c | 1 +
+ drivers/nvmem/zynqmp_nvmem.c | 1 +
+ drivers/rtc/nvmem.c | 1 +
+ drivers/w1/slaves/w1_ds250x.c | 1 +
+ include/linux/nvmem-provider.h | 2 ++
+ 24 files changed, 30 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index 9bd661be3ae93..fbf60d1364f0d 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -552,6 +552,7 @@ static int mtd_nvmem_add(struct mtd_info *mtd)
+ config.dev = &mtd->dev;
+ config.name = dev_name(&mtd->dev);
+ config.owner = THIS_MODULE;
++ config.add_legacy_fixed_of_cells = of_device_is_compatible(node, "nvmem-cells");
+ config.reg_read = mtd_nvmem_reg_read;
+ config.size = mtd->size;
+ config.word_size = 1;
+@@ -898,6 +899,7 @@ static struct nvmem_device *mtd_otp_nvmem_register(struct mtd_info *mtd,
+ config.name = compatible;
+ config.id = NVMEM_DEVID_AUTO;
+ config.owner = THIS_MODULE;
++ config.add_legacy_fixed_of_cells = true;
+ config.type = NVMEM_TYPE_OTP;
+ config.root_only = true;
+ config.ignore_wp = true;
+diff --git a/drivers/nvmem/apple-efuses.c b/drivers/nvmem/apple-efuses.c
+index 9b7c871021043..d3d49d22338b3 100644
+--- a/drivers/nvmem/apple-efuses.c
++++ b/drivers/nvmem/apple-efuses.c
+@@ -36,6 +36,7 @@ static int apple_efuses_probe(struct platform_device *pdev)
+ struct resource *res;
+ struct nvmem_config config = {
+ .dev = &pdev->dev,
++ .add_legacy_fixed_of_cells = true,
+ .read_only = true,
+ .reg_read = apple_efuses_read,
+ .stride = sizeof(u32),
+diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
+index 5b3955ad40534..e26f79a132bb5 100644
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -1003,9 +1003,11 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
+ if (rval)
+ goto err_remove_cells;
+
+- rval = nvmem_add_cells_from_legacy_of(nvmem);
+- if (rval)
+- goto err_remove_cells;
++ if (config->add_legacy_fixed_of_cells) {
++ rval = nvmem_add_cells_from_legacy_of(nvmem);
++ if (rval)
++ goto err_remove_cells;
++ }
+
+ rval = nvmem_add_cells_from_fixed_layout(nvmem);
+ if (rval)
+diff --git a/drivers/nvmem/imx-ocotp-scu.c b/drivers/nvmem/imx-ocotp-scu.c
+index c38d9c1c3f486..517d83e11af2c 100644
+--- a/drivers/nvmem/imx-ocotp-scu.c
++++ b/drivers/nvmem/imx-ocotp-scu.c
+@@ -220,6 +220,7 @@ static int imx_scu_ocotp_write(void *context, unsigned int offset,
+
+ static struct nvmem_config imx_scu_ocotp_nvmem_config = {
+ .name = "imx-scu-ocotp",
++ .add_legacy_fixed_of_cells = true,
+ .read_only = false,
+ .word_size = 4,
+ .stride = 1,
+diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
+index e8b6f194925df..f1e202efaa497 100644
+--- a/drivers/nvmem/imx-ocotp.c
++++ b/drivers/nvmem/imx-ocotp.c
+@@ -615,6 +615,7 @@ static int imx_ocotp_probe(struct platform_device *pdev)
+ return PTR_ERR(priv->clk);
+
+ priv->params = of_device_get_match_data(&pdev->dev);
++ imx_ocotp_nvmem_config.add_legacy_fixed_of_cells = true;
+ imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
+ imx_ocotp_nvmem_config.dev = dev;
+ imx_ocotp_nvmem_config.priv = priv;
+diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
+index ba2714bef8d0e..33678d0af2c24 100644
+--- a/drivers/nvmem/meson-efuse.c
++++ b/drivers/nvmem/meson-efuse.c
+@@ -74,6 +74,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
+
+ econfig->dev = dev;
+ econfig->name = dev_name(dev);
++ econfig->add_legacy_fixed_of_cells = true;
+ econfig->stride = 1;
+ econfig->word_size = 1;
+ econfig->reg_read = meson_efuse_read;
+diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c
+index d6d7aeda31f92..3ff04d5ca8f85 100644
+--- a/drivers/nvmem/meson-mx-efuse.c
++++ b/drivers/nvmem/meson-mx-efuse.c
+@@ -210,6 +210,7 @@ static int meson_mx_efuse_probe(struct platform_device *pdev)
+ efuse->config.owner = THIS_MODULE;
+ efuse->config.dev = &pdev->dev;
+ efuse->config.priv = efuse;
++ efuse->config.add_legacy_fixed_of_cells = true;
+ efuse->config.stride = drvdata->word_size;
+ efuse->config.word_size = drvdata->word_size;
+ efuse->config.size = SZ_512;
+diff --git a/drivers/nvmem/microchip-otpc.c b/drivers/nvmem/microchip-otpc.c
+index 436e0dc4f3375..7cf81738a3e0a 100644
+--- a/drivers/nvmem/microchip-otpc.c
++++ b/drivers/nvmem/microchip-otpc.c
+@@ -261,6 +261,7 @@ static int mchp_otpc_probe(struct platform_device *pdev)
+ return ret;
+
+ mchp_nvmem_config.dev = otpc->dev;
++ mchp_nvmem_config.add_legacy_fixed_of_cells = true;
+ mchp_nvmem_config.size = size;
+ mchp_nvmem_config.priv = otpc;
+ nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config);
+diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c
+index b36cd0dcc8c7f..87c94686cfd21 100644
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -83,6 +83,7 @@ static int mtk_efuse_probe(struct platform_device *pdev)
+ return PTR_ERR(priv->base);
+
+ pdata = device_get_match_data(dev);
++ econfig.add_legacy_fixed_of_cells = true;
+ econfig.stride = 1;
+ econfig.word_size = 1;
+ econfig.reg_read = mtk_reg_read;
+diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c
+index 70f2d4f2efbf1..9aa8f42faa4c9 100644
+--- a/drivers/nvmem/qcom-spmi-sdam.c
++++ b/drivers/nvmem/qcom-spmi-sdam.c
+@@ -142,6 +142,7 @@ static int sdam_probe(struct platform_device *pdev)
+ sdam->sdam_config.name = "spmi_sdam";
+ sdam->sdam_config.id = NVMEM_DEVID_AUTO;
+ sdam->sdam_config.owner = THIS_MODULE;
++ sdam->sdam_config.add_legacy_fixed_of_cells = true;
+ sdam->sdam_config.stride = 1;
+ sdam->sdam_config.word_size = 1;
+ sdam->sdam_config.reg_read = sdam_read;
+diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
+index 14814cba2dd65..6c554040c6e67 100644
+--- a/drivers/nvmem/qfprom.c
++++ b/drivers/nvmem/qfprom.c
+@@ -357,6 +357,7 @@ static int qfprom_probe(struct platform_device *pdev)
+ {
+ struct nvmem_config econfig = {
+ .name = "qfprom",
++ .add_legacy_fixed_of_cells = true,
+ .stride = 1,
+ .word_size = 1,
+ .id = NVMEM_DEVID_AUTO,
+diff --git a/drivers/nvmem/rave-sp-eeprom.c b/drivers/nvmem/rave-sp-eeprom.c
+index df6a1c594b781..9ecf3873cbb76 100644
+--- a/drivers/nvmem/rave-sp-eeprom.c
++++ b/drivers/nvmem/rave-sp-eeprom.c
+@@ -328,6 +328,7 @@ static int rave_sp_eeprom_probe(struct platform_device *pdev)
+ of_property_read_string(np, "zii,eeprom-name", &config.name);
+ config.priv = eeprom;
+ config.dev = dev;
++ config.add_legacy_fixed_of_cells = true;
+ config.size = size;
+ config.reg_read = rave_sp_eeprom_reg_read;
+ config.reg_write = rave_sp_eeprom_reg_write;
+diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c
+index 4004c5bece423..2b40978ddb18c 100644
+--- a/drivers/nvmem/rockchip-efuse.c
++++ b/drivers/nvmem/rockchip-efuse.c
+@@ -205,6 +205,7 @@ static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
+
+ static struct nvmem_config econfig = {
+ .name = "rockchip-efuse",
++ .add_legacy_fixed_of_cells = true,
+ .stride = 1,
+ .word_size = 1,
+ .read_only = true,
+diff --git a/drivers/nvmem/sc27xx-efuse.c b/drivers/nvmem/sc27xx-efuse.c
+index 2210da40dfbd7..bff27011f4ff2 100644
+--- a/drivers/nvmem/sc27xx-efuse.c
++++ b/drivers/nvmem/sc27xx-efuse.c
+@@ -247,6 +247,7 @@ static int sc27xx_efuse_probe(struct platform_device *pdev)
+ econfig.reg_read = sc27xx_efuse_read;
+ econfig.priv = efuse;
+ econfig.dev = &pdev->dev;
++ econfig.add_legacy_fixed_of_cells = true;
+ nvmem = devm_nvmem_register(&pdev->dev, &econfig);
+ if (IS_ERR(nvmem)) {
+ dev_err(&pdev->dev, "failed to register nvmem config\n");
+diff --git a/drivers/nvmem/sec-qfprom.c b/drivers/nvmem/sec-qfprom.c
+index e48c2dc0c44b3..19799b3fe00aa 100644
+--- a/drivers/nvmem/sec-qfprom.c
++++ b/drivers/nvmem/sec-qfprom.c
+@@ -47,6 +47,7 @@ static int sec_qfprom_probe(struct platform_device *pdev)
+ {
+ struct nvmem_config econfig = {
+ .name = "sec-qfprom",
++ .add_legacy_fixed_of_cells = true,
+ .stride = 1,
+ .word_size = 1,
+ .id = NVMEM_DEVID_AUTO,
+diff --git a/drivers/nvmem/sprd-efuse.c b/drivers/nvmem/sprd-efuse.c
+index 7e6e31db4baae..bb3105f3291fc 100644
+--- a/drivers/nvmem/sprd-efuse.c
++++ b/drivers/nvmem/sprd-efuse.c
+@@ -408,6 +408,7 @@ static int sprd_efuse_probe(struct platform_device *pdev)
+ econfig.read_only = false;
+ econfig.name = "sprd-efuse";
+ econfig.size = efuse->data->blk_nums * SPRD_EFUSE_BLOCK_WIDTH;
++ econfig.add_legacy_fixed_of_cells = true;
+ econfig.reg_read = sprd_efuse_read;
+ econfig.reg_write = sprd_efuse_write;
+ econfig.priv = efuse;
+diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
+index 0f84044bd1ade..1541c20709d25 100644
+--- a/drivers/nvmem/stm32-romem.c
++++ b/drivers/nvmem/stm32-romem.c
+@@ -207,6 +207,7 @@ static int stm32_romem_probe(struct platform_device *pdev)
+ priv->cfg.priv = priv;
+ priv->cfg.owner = THIS_MODULE;
+ priv->cfg.type = NVMEM_TYPE_OTP;
++ priv->cfg.add_legacy_fixed_of_cells = true;
+
+ priv->lower = 0;
+
+diff --git a/drivers/nvmem/sunplus-ocotp.c b/drivers/nvmem/sunplus-ocotp.c
+index f3a18aa0a6c73..38f5d9df39cd5 100644
+--- a/drivers/nvmem/sunplus-ocotp.c
++++ b/drivers/nvmem/sunplus-ocotp.c
+@@ -145,6 +145,7 @@ static int sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t by
+
+ static struct nvmem_config sp_ocotp_nvmem_config = {
+ .name = "sp-ocotp",
++ .add_legacy_fixed_of_cells = true,
+ .read_only = true,
+ .word_size = 1,
+ .size = QAC628_OTP_SIZE,
+diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
+index 5d364d85347fc..ba14a76208ab6 100644
+--- a/drivers/nvmem/sunxi_sid.c
++++ b/drivers/nvmem/sunxi_sid.c
+@@ -153,6 +153,7 @@ static int sunxi_sid_probe(struct platform_device *pdev)
+ nvmem_cfg->dev = dev;
+ nvmem_cfg->name = "sunxi-sid";
+ nvmem_cfg->type = NVMEM_TYPE_OTP;
++ nvmem_cfg->add_legacy_fixed_of_cells = true;
+ nvmem_cfg->read_only = true;
+ nvmem_cfg->size = cfg->size;
+ nvmem_cfg->word_size = 1;
+diff --git a/drivers/nvmem/uniphier-efuse.c b/drivers/nvmem/uniphier-efuse.c
+index 0a1dbb80537ec..6ad3295d31951 100644
+--- a/drivers/nvmem/uniphier-efuse.c
++++ b/drivers/nvmem/uniphier-efuse.c
+@@ -52,6 +52,7 @@ static int uniphier_efuse_probe(struct platform_device *pdev)
+ econfig.size = resource_size(res);
+ econfig.priv = priv;
+ econfig.dev = dev;
++ econfig.add_legacy_fixed_of_cells = true;
+ nvmem = devm_nvmem_register(dev, &econfig);
+
+ return PTR_ERR_OR_ZERO(nvmem);
+diff --git a/drivers/nvmem/zynqmp_nvmem.c b/drivers/nvmem/zynqmp_nvmem.c
+index f49bb9a26d053..7f15aa89a9d09 100644
+--- a/drivers/nvmem/zynqmp_nvmem.c
++++ b/drivers/nvmem/zynqmp_nvmem.c
+@@ -58,6 +58,7 @@ static int zynqmp_nvmem_probe(struct platform_device *pdev)
+
+ priv->dev = dev;
+ econfig.dev = dev;
++ econfig.add_legacy_fixed_of_cells = true;
+ econfig.reg_read = zynqmp_nvmem_read;
+ econfig.priv = priv;
+
+diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c
+index 07ede21cee347..37df7e80525b4 100644
+--- a/drivers/rtc/nvmem.c
++++ b/drivers/rtc/nvmem.c
+@@ -21,6 +21,7 @@ int devm_rtc_nvmem_register(struct rtc_device *rtc,
+
+ nvmem_config->dev = dev;
+ nvmem_config->owner = rtc->owner;
++ nvmem_config->add_legacy_fixed_of_cells = true;
+ nvmem = devm_nvmem_register(dev, nvmem_config);
+ if (IS_ERR(nvmem))
+ dev_err(dev, "failed to register nvmem device for RTC\n");
+diff --git a/drivers/w1/slaves/w1_ds250x.c b/drivers/w1/slaves/w1_ds250x.c
+index 7592c7050d1d7..cb426f7dd23d4 100644
+--- a/drivers/w1/slaves/w1_ds250x.c
++++ b/drivers/w1/slaves/w1_ds250x.c
+@@ -168,6 +168,7 @@ static int w1_eprom_add_slave(struct w1_slave *sl)
+ struct nvmem_device *nvmem;
+ struct nvmem_config nvmem_cfg = {
+ .dev = &sl->dev,
++ .add_legacy_fixed_of_cells = true,
+ .reg_read = w1_nvmem_read,
+ .type = NVMEM_TYPE_OTP,
+ .read_only = true,
+diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
+index dae26295e6bed..1b81adebdb8be 100644
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -82,6 +82,7 @@ struct nvmem_cell_info {
+ * @owner: Pointer to exporter module. Used for refcounting.
+ * @cells: Optional array of pre-defined NVMEM cells.
+ * @ncells: Number of elements in cells.
++ * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax.
+ * @keepout: Optional array of keepout ranges (sorted ascending by start).
+ * @nkeepout: Number of elements in the keepout array.
+ * @type: Type of the nvmem storage
+@@ -112,6 +113,7 @@ struct nvmem_config {
+ struct module *owner;
+ const struct nvmem_cell_info *cells;
+ int ncells;
++ bool add_legacy_fixed_of_cells;
+ const struct nvmem_keepout *keepout;
+ unsigned int nkeepout;
+ enum nvmem_type type;
+--
+2.43.0
+
--- /dev/null
+From 8cb62438a8b272a8e77cecd0866177c70c986a11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Apr 2024 19:50:48 +0200
+Subject: pinctrl: baytrail: Fix selecting gpio pinctrl state
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit fed6d9a8e6a60ecf6506d0ea004040fbaa109927 ]
+
+For all the "score" pin-groups all the intel_pingroup-s to select
+the non GPIO function are re-used for byt_score_gpio_groups[].
+
+But this is incorrect since a pin-group includes the mode setting,
+which for the non GPIO functions generally is 1, where as to select
+the GPIO function mode must be set to 0.
+
+So the GPIO function needs separate intel_pingroup-s with their own mode
+value of 0.
+
+Add a new PIN_GROUP_GPIO macro which adds a foo_gpio entry to each
+pin-group defined this way and update byt_score_gpio_groups[] to point
+to the new foo_gpio entries.
+
+The "sus" usb_oc_grp usb_ulpi_grp and pcu_spi_grp pin-groups are special
+because these have a non 0 mode value to select the GPIO functions and
+these already have matching foo_gpio pin-groups, leave these are unchanged.
+
+The pmu_clk "sus" groups added in commit 2f46d7f7e959 ("pinctrl: baytrail:
+Add pinconf group + function for the pmu_clk") do need to use the new
+PIN_GROUP_GPIO macro.
+
+Fixes: 2f46d7f7e959 ("pinctrl: baytrail: Add pinconf group + function for the pmu_clk")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/intel/pinctrl-baytrail.c | 74 ++++++++++++------------
+ drivers/pinctrl/intel/pinctrl-intel.h | 4 ++
+ 2 files changed, 42 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
+index 95a8a3a22b2b4..0aaeb54a64765 100644
+--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
+@@ -277,33 +277,33 @@ static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
+ static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
+
+ static const struct intel_pingroup byt_score_groups[] = {
+- PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1),
+- PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1),
+- PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1),
+- PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1),
+- PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1),
+- PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1),
+- PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1),
+- PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1),
+- PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1),
+- PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1),
+- PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1),
+- PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1),
+- PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1),
+- PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1),
+- PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1),
+- PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
+- PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1),
+- PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1),
+- PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1),
+- PIN_GROUP("sata_grp", byt_score_sata_pins, 1),
+- PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
+- PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
+- PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
+- PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
+- PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
+- PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
+- PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1),
++ PIN_GROUP_GPIO("uart1_grp", byt_score_uart1_pins, 1),
++ PIN_GROUP_GPIO("uart2_grp", byt_score_uart2_pins, 1),
++ PIN_GROUP_GPIO("pwm0_grp", byt_score_pwm0_pins, 1),
++ PIN_GROUP_GPIO("pwm1_grp", byt_score_pwm1_pins, 1),
++ PIN_GROUP_GPIO("ssp2_grp", byt_score_ssp2_pins, 1),
++ PIN_GROUP_GPIO("sio_spi_grp", byt_score_sio_spi_pins, 1),
++ PIN_GROUP_GPIO("i2c5_grp", byt_score_i2c5_pins, 1),
++ PIN_GROUP_GPIO("i2c6_grp", byt_score_i2c6_pins, 1),
++ PIN_GROUP_GPIO("i2c4_grp", byt_score_i2c4_pins, 1),
++ PIN_GROUP_GPIO("i2c3_grp", byt_score_i2c3_pins, 1),
++ PIN_GROUP_GPIO("i2c2_grp", byt_score_i2c2_pins, 1),
++ PIN_GROUP_GPIO("i2c1_grp", byt_score_i2c1_pins, 1),
++ PIN_GROUP_GPIO("i2c0_grp", byt_score_i2c0_pins, 1),
++ PIN_GROUP_GPIO("ssp0_grp", byt_score_ssp0_pins, 1),
++ PIN_GROUP_GPIO("ssp1_grp", byt_score_ssp1_pins, 1),
++ PIN_GROUP_GPIO("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
++ PIN_GROUP_GPIO("sdio_grp", byt_score_sdio_pins, 1),
++ PIN_GROUP_GPIO("emmc_grp", byt_score_emmc_pins, 1),
++ PIN_GROUP_GPIO("lpc_grp", byt_score_ilb_lpc_pins, 1),
++ PIN_GROUP_GPIO("sata_grp", byt_score_sata_pins, 1),
++ PIN_GROUP_GPIO("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
++ PIN_GROUP_GPIO("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
++ PIN_GROUP_GPIO("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
++ PIN_GROUP_GPIO("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
++ PIN_GROUP_GPIO("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
++ PIN_GROUP_GPIO("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
++ PIN_GROUP_GPIO("smbus_grp", byt_score_smbus_pins, 1),
+ };
+
+ static const char * const byt_score_uart_groups[] = {
+@@ -331,12 +331,14 @@ static const char * const byt_score_plt_clk_groups[] = {
+ };
+ static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
+ static const char * const byt_score_gpio_groups[] = {
+- "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp",
+- "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp",
+- "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp",
+- "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp",
+- "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
+- "plt_clk4_grp", "plt_clk5_grp", "smbus_grp",
++ "uart1_grp_gpio", "uart2_grp_gpio", "pwm0_grp_gpio",
++ "pwm1_grp_gpio", "ssp0_grp_gpio", "ssp1_grp_gpio", "ssp2_grp_gpio",
++ "sio_spi_grp_gpio", "i2c0_grp_gpio", "i2c1_grp_gpio", "i2c2_grp_gpio",
++ "i2c3_grp_gpio", "i2c4_grp_gpio", "i2c5_grp_gpio", "i2c6_grp_gpio",
++ "sdcard_grp_gpio", "sdio_grp_gpio", "emmc_grp_gpio", "lpc_grp_gpio",
++ "sata_grp_gpio", "plt_clk0_grp_gpio", "plt_clk1_grp_gpio",
++ "plt_clk2_grp_gpio", "plt_clk3_grp_gpio", "plt_clk4_grp_gpio",
++ "plt_clk5_grp_gpio", "smbus_grp_gpio",
+ };
+
+ static const struct intel_function byt_score_functions[] = {
+@@ -455,8 +457,8 @@ static const struct intel_pingroup byt_sus_groups[] = {
+ PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values),
+ PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values),
+ PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values),
+- PIN_GROUP("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1),
+- PIN_GROUP("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1),
++ PIN_GROUP_GPIO("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1),
++ PIN_GROUP_GPIO("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1),
+ };
+
+ static const char * const byt_sus_usb_groups[] = {
+@@ -468,7 +470,7 @@ static const char * const byt_sus_pmu_clk_groups[] = {
+ };
+ static const char * const byt_sus_gpio_groups[] = {
+ "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio",
+- "pmu_clk1_grp", "pmu_clk2_grp",
++ "pmu_clk1_grp_gpio", "pmu_clk2_grp_gpio",
+ };
+
+ static const struct intel_function byt_sus_functions[] = {
+diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h
+index cee512f97b566..45216b9e852dc 100644
+--- a/drivers/pinctrl/intel/pinctrl-intel.h
++++ b/drivers/pinctrl/intel/pinctrl-intel.h
+@@ -179,6 +179,10 @@ struct intel_community {
+ .modes = __builtin_choose_expr(__builtin_constant_p((m)), NULL, (m)), \
+ }
+
++#define PIN_GROUP_GPIO(n, p, m) \
++ PIN_GROUP(n, p, m), \
++ PIN_GROUP(n "_gpio", p, 0)
++
+ #define FUNCTION(n, g) \
+ { \
+ .func = PINCTRL_PINFUNCTION((n), (g), ARRAY_SIZE(g)), \
+--
+2.43.0
+
--- /dev/null
+From 04b43fedcaef2a914eabea7a2cdf47a7d4f06306 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2024 09:38:39 +0300
+Subject: pinctrl: core: delete incorrect free in pinctrl_enable()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 5038a66dad0199de60e5671603ea6623eb9e5c79 ]
+
+The "pctldev" struct is allocated in devm_pinctrl_register_and_init().
+It's a devm_ managed pointer that is freed by devm_pinctrl_dev_release(),
+so freeing it in pinctrl_enable() will lead to a double free.
+
+The devm_pinctrl_dev_release() function frees the pindescs and destroys
+the mutex as well.
+
+Fixes: 6118714275f0 ("pinctrl: core: Fix pinctrl_register_and_init() with pinctrl_enable()")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Message-ID: <578fbe56-44e9-487c-ae95-29b695650f7c@moroto.mountain>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/core.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
+index 184ec92241ca8..9e7b3e6c79cb1 100644
+--- a/drivers/pinctrl/core.c
++++ b/drivers/pinctrl/core.c
+@@ -2116,13 +2116,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
+
+ error = pinctrl_claim_hogs(pctldev);
+ if (error) {
+- dev_err(pctldev->dev, "could not claim hogs: %i\n",
+- error);
+- pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
+- pctldev->desc->npins);
+- mutex_destroy(&pctldev->mutex);
+- kfree(pctldev);
+-
++ dev_err(pctldev->dev, "could not claim hogs: %i\n", error);
+ return error;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 7ed2b477430d3bb38cc74e931f03ba6b1a61af65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Apr 2024 18:53:28 +0800
+Subject: pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map()
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit a0cedbcc8852d6c77b00634b81e41f17f29d9404 ]
+
+If we fail to allocate propname buffer, we need to drop the reference
+count we just took. Because the pinctrl_dt_free_maps() includes the
+droping operation, here we call it directly.
+
+Fixes: 91d5c5060ee2 ("pinctrl: devicetree: fix null pointer dereferencing in pinctrl_dt_to_map")
+Suggested-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Message-ID: <20240415105328.3651441-1-zengheng4@huawei.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/devicetree.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
+index 6e0a40962f384..5ee746cb81f59 100644
+--- a/drivers/pinctrl/devicetree.c
++++ b/drivers/pinctrl/devicetree.c
+@@ -220,14 +220,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
+ for (state = 0; ; state++) {
+ /* Retrieve the pinctrl-* property */
+ propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
+- if (!propname)
+- return -ENOMEM;
++ if (!propname) {
++ ret = -ENOMEM;
++ goto err;
++ }
+ prop = of_find_property(np, propname, &size);
+ kfree(propname);
+ if (!prop) {
+ if (state == 0) {
+- of_node_put(np);
+- return -ENODEV;
++ ret = -ENODEV;
++ goto err;
+ }
+ break;
+ }
+--
+2.43.0
+
--- /dev/null
+From c5daa8901b8a161f0c6d102104bb0872ddeac5ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Mar 2024 17:13:33 +0800
+Subject: pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE
+ readback
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 08f66a8edd08f6f7cfa769c81634b29a2b123908 ]
+
+In the generic pin config library, readback of some options are handled
+differently compared to the setting of those options: the argument value
+is used to convey enable/disable of an option in the set path, but
+success or -EINVAL is used to convey if an option is enabled or disabled
+in the debugfs readback path.
+
+PIN_CONFIG_INPUT_SCHMITT_ENABLE is one such option. Fix the readback of
+the option in the mediatek-paris library, so that the debugfs dump is
+not showing "input schmitt enabled" for pins that don't have it enabled.
+
+Fixes: 1bea6afbc842 ("pinctrl: mediatek: Refine mtk_pinconf_get()")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Message-ID: <20240327091336.3434141-2-wenst@chromium.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-paris.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index 33d6c3fb79080..ea60de040e0a0 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -193,6 +193,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+ }
+
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
++ if (!ret)
++ err = -EINVAL;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ if (!hw->soc->drive_get)
+--
+2.43.0
+
--- /dev/null
+From 2378f927336514789a532e053c78d14bb5d934ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Mar 2024 17:13:34 +0800
+Subject: pinctrl: mediatek: paris: Rework support for
+ PIN_CONFIG_{INPUT,OUTPUT}_ENABLE
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit c5d3b64c568a344e998830e0e94a7c04e372f89b ]
+
+There is a misinterpretation of some of the PIN_CONFIG_* options in this
+driver library. PIN_CONFIG_OUTPUT_ENABLE should refer to a buffer or
+switch in the output direction of the electrical path. The MediaTek
+hardware does not have such a thing. The driver incorrectly maps this
+option to the GPIO function's direction.
+
+Likewise, PIN_CONFIG_INPUT_ENABLE should refer to a buffer or switch in
+the input direction. The hardware does have such a mechanism, and is
+mapped to the IES bit. The driver however sets the direction in addition
+to the IES bit, which is incorrect. On readback, the IES bit isn't even
+considered.
+
+Ironically, the driver does not support readback for PIN_CONFIG_OUTPUT,
+while its readback of PIN_CONFIG_{INPUT,OUTPUT}_ENABLE is what it should
+be doing for PIN_CONFIG_OUTPUT.
+
+Rework support for these three options, so that PIN_CONFIG_OUTPUT_ENABLE
+is completely removed, PIN_CONFIG_INPUT_ENABLE is only linked to the IES
+bit, and PIN_CONFIG_OUTPUT is linked to the GPIO function's direction
+and output level.
+
+Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Message-ID: <20240327091336.3434141-3-wenst@chromium.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-paris.c | 38 +++++++-----------------
+ 1 file changed, 11 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index ea60de040e0a0..9cd7fe3c3e0df 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -165,20 +165,21 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
+- case PIN_CONFIG_OUTPUT_ENABLE:
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret);
++ if (!ret)
++ err = -EINVAL;
++ break;
++ case PIN_CONFIG_OUTPUT:
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+ if (err)
+ break;
+- /* CONFIG Current direction return value
+- * ------------- ----------------- ----------------------
+- * OUTPUT_ENABLE output 1 (= HW value)
+- * input 0 (= HW value)
+- * INPUT_ENABLE output 0 (= reverse HW value)
+- * input 1 (= reverse HW value)
+- */
+- if (param == PIN_CONFIG_INPUT_ENABLE)
+- ret = !ret;
+
++ if (!ret) {
++ err = -EINVAL;
++ break;
++ }
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret);
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+@@ -283,26 +284,9 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ break;
+ err = hw->soc->bias_set_combo(hw, desc, 0, arg);
+ break;
+- case PIN_CONFIG_OUTPUT_ENABLE:
+- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
+- MTK_DISABLE);
+- /* Keep set direction to consider the case that a GPIO pin
+- * does not have SMT control
+- */
+- if (err != -ENOTSUPP)
+- break;
+-
+- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+- MTK_OUTPUT);
+- break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ /* regard all non-zero value as enable */
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
+- if (err)
+- break;
+-
+- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+- MTK_INPUT);
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ /* regard all non-zero value as enable */
+--
+2.43.0
+
--- /dev/null
+From 8c62d314d40fd0c60603ca2cc88d6090d67342ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 14:30:58 +0300
+Subject: pinctrl/meson: fix typo in PDM's pin name
+
+From: Jan Dakinevich <jan.dakinevich@salutedevices.com>
+
+[ Upstream commit 368a90e651faeeb7049a876599cf2b0d74954796 ]
+
+Other pins have _a or _x suffix, but this one doesn't have any. Most
+likely this is a typo.
+
+Fixes: dabad1ff8561 ("pinctrl: meson: add pinctrl driver support for Meson-A1 SoC")
+Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Message-ID: <20240325113058.248022-1-jan.dakinevich@salutedevices.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/meson/pinctrl-meson-a1.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pinctrl/meson/pinctrl-meson-a1.c b/drivers/pinctrl/meson/pinctrl-meson-a1.c
+index 79f5d753d7e1a..50a87d9618a8e 100644
+--- a/drivers/pinctrl/meson/pinctrl-meson-a1.c
++++ b/drivers/pinctrl/meson/pinctrl-meson-a1.c
+@@ -250,7 +250,7 @@ static const unsigned int pdm_dclk_x_pins[] = { GPIOX_10 };
+ static const unsigned int pdm_din2_a_pins[] = { GPIOA_6 };
+ static const unsigned int pdm_din1_a_pins[] = { GPIOA_7 };
+ static const unsigned int pdm_din0_a_pins[] = { GPIOA_8 };
+-static const unsigned int pdm_dclk_pins[] = { GPIOA_9 };
++static const unsigned int pdm_dclk_a_pins[] = { GPIOA_9 };
+
+ /* gen_clk */
+ static const unsigned int gen_clk_x_pins[] = { GPIOX_7 };
+@@ -591,7 +591,7 @@ static struct meson_pmx_group meson_a1_periphs_groups[] = {
+ GROUP(pdm_din2_a, 3),
+ GROUP(pdm_din1_a, 3),
+ GROUP(pdm_din0_a, 3),
+- GROUP(pdm_dclk, 3),
++ GROUP(pdm_dclk_a, 3),
+ GROUP(pwm_c_a, 3),
+ GROUP(pwm_b_a, 3),
+
+@@ -755,7 +755,7 @@ static const char * const spi_a_groups[] = {
+
+ static const char * const pdm_groups[] = {
+ "pdm_din0_x", "pdm_din1_x", "pdm_din2_x", "pdm_dclk_x", "pdm_din2_a",
+- "pdm_din1_a", "pdm_din0_a", "pdm_dclk",
++ "pdm_din1_a", "pdm_din0_a", "pdm_dclk_a",
+ };
+
+ static const char * const gen_clk_groups[] = {
+--
+2.43.0
+
--- /dev/null
+From 2a69f1acd8db186da294dda5449364bf9d2ca3fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 17:28:09 +0800
+Subject: pinctrl: pinctrl-aspeed-g6: Fix register offset for pinconf of
+ GPIOR-T
+
+From: Billy Tsai <billy_tsai@aspeedtech.com>
+
+[ Upstream commit c10cd03d69403fa0f00be8631bd4cb4690440ebd ]
+
+The register offset to disable the internal pull-down of GPIOR~T is 0x630
+instead of 0x620, as specified in the Ast2600 datasheet v15
+The datasheet can download from the official Aspeed website.
+
+Fixes: 15711ba6ff19 ("pinctrl: aspeed-g6: Add AST2600 pinconf support")
+Reported-by: Delphine CC Chiu <Delphine_CC_Chiu@wiwynn.com>
+Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au>
+Message-ID: <20240313092809.2596644-1-billy_tsai@aspeedtech.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 34 +++++++++++-----------
+ 1 file changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c
+index 80838dc54b3ab..7938741136a2c 100644
+--- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c
++++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c
+@@ -43,7 +43,7 @@
+ #define SCU614 0x614 /* Disable GPIO Internal Pull-Down #1 */
+ #define SCU618 0x618 /* Disable GPIO Internal Pull-Down #2 */
+ #define SCU61C 0x61c /* Disable GPIO Internal Pull-Down #3 */
+-#define SCU620 0x620 /* Disable GPIO Internal Pull-Down #4 */
++#define SCU630 0x630 /* Disable GPIO Internal Pull-Down #4 */
+ #define SCU634 0x634 /* Disable GPIO Internal Pull-Down #5 */
+ #define SCU638 0x638 /* Disable GPIO Internal Pull-Down #6 */
+ #define SCU690 0x690 /* Multi-function Pin Control #24 */
+@@ -2494,38 +2494,38 @@ static struct aspeed_pin_config aspeed_g6_configs[] = {
+ ASPEED_PULL_DOWN_PINCONF(D14, SCU61C, 0),
+
+ /* GPIOS7 */
+- ASPEED_PULL_DOWN_PINCONF(T24, SCU620, 23),
++ ASPEED_PULL_DOWN_PINCONF(T24, SCU630, 23),
+ /* GPIOS6 */
+- ASPEED_PULL_DOWN_PINCONF(P23, SCU620, 22),
++ ASPEED_PULL_DOWN_PINCONF(P23, SCU630, 22),
+ /* GPIOS5 */
+- ASPEED_PULL_DOWN_PINCONF(P24, SCU620, 21),
++ ASPEED_PULL_DOWN_PINCONF(P24, SCU630, 21),
+ /* GPIOS4 */
+- ASPEED_PULL_DOWN_PINCONF(R26, SCU620, 20),
++ ASPEED_PULL_DOWN_PINCONF(R26, SCU630, 20),
+ /* GPIOS3*/
+- ASPEED_PULL_DOWN_PINCONF(R24, SCU620, 19),
++ ASPEED_PULL_DOWN_PINCONF(R24, SCU630, 19),
+ /* GPIOS2 */
+- ASPEED_PULL_DOWN_PINCONF(T26, SCU620, 18),
++ ASPEED_PULL_DOWN_PINCONF(T26, SCU630, 18),
+ /* GPIOS1 */
+- ASPEED_PULL_DOWN_PINCONF(T25, SCU620, 17),
++ ASPEED_PULL_DOWN_PINCONF(T25, SCU630, 17),
+ /* GPIOS0 */
+- ASPEED_PULL_DOWN_PINCONF(R23, SCU620, 16),
++ ASPEED_PULL_DOWN_PINCONF(R23, SCU630, 16),
+
+ /* GPIOR7 */
+- ASPEED_PULL_DOWN_PINCONF(U26, SCU620, 15),
++ ASPEED_PULL_DOWN_PINCONF(U26, SCU630, 15),
+ /* GPIOR6 */
+- ASPEED_PULL_DOWN_PINCONF(W26, SCU620, 14),
++ ASPEED_PULL_DOWN_PINCONF(W26, SCU630, 14),
+ /* GPIOR5 */
+- ASPEED_PULL_DOWN_PINCONF(T23, SCU620, 13),
++ ASPEED_PULL_DOWN_PINCONF(T23, SCU630, 13),
+ /* GPIOR4 */
+- ASPEED_PULL_DOWN_PINCONF(U25, SCU620, 12),
++ ASPEED_PULL_DOWN_PINCONF(U25, SCU630, 12),
+ /* GPIOR3*/
+- ASPEED_PULL_DOWN_PINCONF(V26, SCU620, 11),
++ ASPEED_PULL_DOWN_PINCONF(V26, SCU630, 11),
+ /* GPIOR2 */
+- ASPEED_PULL_DOWN_PINCONF(V24, SCU620, 10),
++ ASPEED_PULL_DOWN_PINCONF(V24, SCU630, 10),
+ /* GPIOR1 */
+- ASPEED_PULL_DOWN_PINCONF(U24, SCU620, 9),
++ ASPEED_PULL_DOWN_PINCONF(U24, SCU630, 9),
+ /* GPIOR0 */
+- ASPEED_PULL_DOWN_PINCONF(V25, SCU620, 8),
++ ASPEED_PULL_DOWN_PINCONF(V25, SCU630, 8),
+
+ /* GPIOX7 */
+ ASPEED_PULL_DOWN_PINCONF(AB10, SCU634, 31),
+--
+2.43.0
+
--- /dev/null
+From ff607ee316448942d109b634423457951e41b1ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 10:06:27 +0200
+Subject: power: rt9455: hide unused rt9455_boost_voltage_values
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 452d8950db3e839aba1bb13bc5378f4bac11fa04 ]
+
+The rt9455_boost_voltage_values[] array is only used when USB PHY
+support is enabled, causing a W=1 warning otherwise:
+
+drivers/power/supply/rt9455_charger.c:200:18: error: 'rt9455_boost_voltage_values' defined but not used [-Werror=unused-const-variable=]
+
+Enclose the definition in the same #ifdef as the references to it.
+
+Fixes: e86d69dd786e ("power_supply: Add support for Richtek RT9455 battery charger")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20240403080702.3509288-10-arnd@kernel.org
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/rt9455_charger.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/power/supply/rt9455_charger.c b/drivers/power/supply/rt9455_charger.c
+index c345a77f9f78c..e4dbacd50a437 100644
+--- a/drivers/power/supply/rt9455_charger.c
++++ b/drivers/power/supply/rt9455_charger.c
+@@ -192,6 +192,7 @@ static const int rt9455_voreg_values[] = {
+ 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000
+ };
+
++#if IS_ENABLED(CONFIG_USB_PHY)
+ /*
+ * When the charger is in boost mode, REG02[7:2] represent boost output
+ * voltage.
+@@ -207,6 +208,7 @@ static const int rt9455_boost_voltage_values[] = {
+ 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
+ 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
+ };
++#endif
+
+ /* REG07[3:0] (VMREG) in uV */
+ static const int rt9455_vmreg_values[] = {
+--
+2.43.0
+
--- /dev/null
+From 8b6142e655eac1ce9644917c6398197f8aa00136 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Apr 2024 10:44:05 +0200
+Subject: power: supply: mt6360_charger: Fix of_match for usb-otg-vbus
+ regulator
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 1e0fb113646182e073539db96016b00cfeb18ecc ]
+
+The of_match shall correspond to the name of the regulator subnode,
+or the deprecated `regulator-compatible` property must be used:
+failing to do so, the regulator won't probe (and the driver will
+as well not probe).
+
+Since the devicetree binding for this driver is actually correct
+and wants DTs to use the "usb-otg-vbus-regulator" subnode name,
+fix this driver by aligning the `of_match` string to what the DT
+binding wants.
+
+Fixes: 0402e8ebb8b8 ("power: supply: mt6360_charger: add MT6360 charger support")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://lore.kernel.org/r/20240410084405.1389378-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/mt6360_charger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/mt6360_charger.c b/drivers/power/supply/mt6360_charger.c
+index 1305cba61edd4..aca123783efcc 100644
+--- a/drivers/power/supply/mt6360_charger.c
++++ b/drivers/power/supply/mt6360_charger.c
+@@ -588,7 +588,7 @@ static const struct regulator_ops mt6360_chg_otg_ops = {
+ };
+
+ static const struct regulator_desc mt6360_otg_rdesc = {
+- .of_match = "usb-otg-vbus",
++ .of_match = "usb-otg-vbus-regulator",
+ .name = "usb-otg-vbus",
+ .ops = &mt6360_chg_otg_ops,
+ .owner = THIS_MODULE,
+--
+2.43.0
+
--- /dev/null
+From f101269913cef201cae0eed20d35b182073c5ce6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 14:38:28 +0300
+Subject: regulator: change devm_regulator_get_enable_optional() stub to return
+ Ok
+
+From: Matti Vaittinen <mazziesaccount@gmail.com>
+
+[ Upstream commit ff33132605c1a0acea59e4c523cb7c6fabe856b2 ]
+
+The devm_regulator_get_enable_optional() should be a 'call and forget'
+API, meaning, when it is used to enable the regulators, the API does not
+provide a handle to do any further control of the regulators. It gives
+no real benefit to return an error from the stub if CONFIG_REGULATOR is
+not set.
+
+On the contrary, returning an error is causing problems to drivers when
+hardware is such it works out just fine with no regulator control.
+Returning an error forces drivers to specifically handle the case where
+CONFIG_REGULATOR is not set, making the mere existence of the stub
+questionalble.
+
+Change the stub implementation for the
+devm_regulator_get_enable_optional() to return Ok so drivers do not
+separately handle the case where the CONFIG_REGULATOR is not set.
+
+Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Fixes: da279e6965b3 ("regulator: Add devm helpers for get and enable")
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/ZiedtOE00Zozd3XO@fedora
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/regulator/consumer.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
+index e3e58d5a84e2a..2c526c8d10cc4 100644
+--- a/include/linux/regulator/consumer.h
++++ b/include/linux/regulator/consumer.h
+@@ -371,7 +371,7 @@ static inline int devm_regulator_get_enable(struct device *dev, const char *id)
+ static inline int devm_regulator_get_enable_optional(struct device *dev,
+ const char *id)
+ {
+- return -ENODEV;
++ return 0;
+ }
+
+ static inline struct regulator *__must_check
+--
+2.43.0
+
--- /dev/null
+From be94bd4644d8e8d720ccf52f724916c272b19c7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Apr 2024 09:38:33 +0300
+Subject: regulator: change stubbed devm_regulator_get_enable to return Ok
+
+From: Matti Vaittinen <mazziesaccount@gmail.com>
+
+[ Upstream commit 96e20adc43c4f81e9163a5188cee75a6dd393e09 ]
+
+The devm_regulator_get_enable() should be a 'call and forget' API,
+meaning, when it is used to enable the regulators, the API does not
+provide a handle to do any further control of the regulators. It gives
+no real benefit to return an error from the stub if CONFIG_REGULATOR is
+not set.
+
+On the contrary, returning and error is causing problems to drivers when
+hardware is such it works out just fine with no regulator control.
+Returning an error forces drivers to specifically handle the case where
+CONFIG_REGULATOR is not set, making the mere existence of the stub
+questionalble. Furthermore, the stub of the regulator_enable() seems to
+be returning Ok.
+
+Change the stub implementation for the devm_regulator_get_enable() to
+return Ok so drivers do not separately handle the case where the
+CONFIG_REGULATOR is not set.
+
+Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Reported-by: Aleksander Mazur <deweloper@wp.pl>
+Suggested-by: Guenter Roeck <linux@roeck-us.net>
+Fixes: da279e6965b3 ("regulator: Add devm helpers for get and enable")
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/ZiYF6d1V1vSPcsJS@drtxq0yyyyyyyyyyyyyby-3.rev.dnainternet.fi
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/regulator/consumer.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
+index 39b666b40ea61..e3e58d5a84e2a 100644
+--- a/include/linux/regulator/consumer.h
++++ b/include/linux/regulator/consumer.h
+@@ -365,7 +365,7 @@ devm_regulator_get_exclusive(struct device *dev, const char *id)
+
+ static inline int devm_regulator_get_enable(struct device *dev, const char *id)
+ {
+- return -ENODEV;
++ return 0;
+ }
+
+ static inline int devm_regulator_get_enable_optional(struct device *dev,
+--
+2.43.0
+
--- /dev/null
+From 1983d3272b0672215a4e2a8c6abf00cbe8fa9c32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Apr 2024 16:44:38 +0200
+Subject: regulator: mt6360: De-capitalize devicetree regulator subnodes
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit d3cf8a17498dd9104c04ad28eeac3ef3339f9f9f ]
+
+The MT6360 regulator binding, the example in the MT6360 mfd binding, and
+the devicetree users of those bindings are rightfully declaring MT6360
+regulator subnodes with non-capital names, and luckily without using the
+deprecated regulator-compatible property.
+
+With this driver declaring capitalized BUCKx/LDOx as of_match string for
+the node names, obviously no regulator gets probed: fix that by changing
+the MT6360_REGULATOR_DESC macro to add a "match" parameter which gets
+assigned to the of_match.
+
+Fixes: d321571d5e4c ("regulator: mt6360: Add support for MT6360 regulator")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://msgid.link/r/20240409144438.410060-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/mt6360-regulator.c | 32 +++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/regulator/mt6360-regulator.c b/drivers/regulator/mt6360-regulator.c
+index ad6587a378d09..24cc9fc94e900 100644
+--- a/drivers/regulator/mt6360-regulator.c
++++ b/drivers/regulator/mt6360-regulator.c
+@@ -319,15 +319,15 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
+ }
+ }
+
+-#define MT6360_REGULATOR_DESC(_name, _sname, ereg, emask, vreg, vmask, \
+- mreg, mmask, streg, stmask, vranges, \
+- vcnts, offon_delay, irq_tbls) \
++#define MT6360_REGULATOR_DESC(match, _name, _sname, ereg, emask, vreg, \
++ vmask, mreg, mmask, streg, stmask, \
++ vranges, vcnts, offon_delay, irq_tbls) \
+ { \
+ .desc = { \
+ .name = #_name, \
+ .supply_name = #_sname, \
+ .id = MT6360_REGULATOR_##_name, \
+- .of_match = of_match_ptr(#_name), \
++ .of_match = of_match_ptr(match), \
+ .regulators_node = of_match_ptr("regulator"), \
+ .of_map_mode = mt6360_regulator_of_map_mode, \
+ .owner = THIS_MODULE, \
+@@ -351,21 +351,29 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
+ }
+
+ static const struct mt6360_regulator_desc mt6360_regulator_descs[] = {
+- MT6360_REGULATOR_DESC(BUCK1, BUCK1_VIN, 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
++ MT6360_REGULATOR_DESC("buck1", BUCK1, BUCK1_VIN,
++ 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
+ buck_vout_ranges, 256, 0, buck1_irq_tbls),
+- MT6360_REGULATOR_DESC(BUCK2, BUCK2_VIN, 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
++ MT6360_REGULATOR_DESC("buck2", BUCK2, BUCK2_VIN,
++ 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
+ buck_vout_ranges, 256, 0, buck2_irq_tbls),
+- MT6360_REGULATOR_DESC(LDO6, LDO_VIN3, 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
++ MT6360_REGULATOR_DESC("ldo6", LDO6, LDO_VIN3,
++ 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
+ ldo_vout_ranges1, 256, 0, ldo6_irq_tbls),
+- MT6360_REGULATOR_DESC(LDO7, LDO_VIN3, 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
++ MT6360_REGULATOR_DESC("ldo7", LDO7, LDO_VIN3,
++ 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
+ ldo_vout_ranges1, 256, 0, ldo7_irq_tbls),
+- MT6360_REGULATOR_DESC(LDO1, LDO_VIN1, 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
++ MT6360_REGULATOR_DESC("ldo1", LDO1, LDO_VIN1,
++ 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
+ ldo_vout_ranges2, 256, 0, ldo1_irq_tbls),
+- MT6360_REGULATOR_DESC(LDO2, LDO_VIN1, 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
++ MT6360_REGULATOR_DESC("ldo2", LDO2, LDO_VIN1,
++ 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
+ ldo_vout_ranges2, 256, 0, ldo2_irq_tbls),
+- MT6360_REGULATOR_DESC(LDO3, LDO_VIN1, 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
++ MT6360_REGULATOR_DESC("ldo3", LDO3, LDO_VIN1,
++ 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
+ ldo_vout_ranges2, 256, 100, ldo3_irq_tbls),
+- MT6360_REGULATOR_DESC(LDO5, LDO_VIN2, 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
++ MT6360_REGULATOR_DESC("ldo5", LDO5, LDO_VIN2,
++ 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
+ ldo_vout_ranges3, 128, 100, ldo5_irq_tbls),
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 4631d26efbc10c949e109276c183f7d8ac212a41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Mar 2024 16:54:54 -0300
+Subject: rust: kernel: require `Send` for `Module` implementations
+
+From: Wedson Almeida Filho <walmeida@microsoft.com>
+
+[ Upstream commit 323617f649c0966ad5e741e47e27e06d3a680d8f ]
+
+The thread that calls the module initialisation code when a module is
+loaded is not guaranteed [in fact, it is unlikely] to be the same one
+that calls the module cleanup code on module unload, therefore, `Module`
+implementations must be `Send` to account for them moving from one
+thread to another implicitly.
+
+Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Cc: stable@vger.kernel.org # 6.8.x: df70d04d5697: rust: phy: implement `Send` for `Registration`
+Cc: stable@vger.kernel.org
+Fixes: 247b365dc8dc ("rust: add `kernel` crate")
+Link: https://lore.kernel.org/r/20240328195457.225001-3-wedsonaf@gmail.com
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/lib.rs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
+index e8811700239aa..de54d5fede6f8 100644
+--- a/rust/kernel/lib.rs
++++ b/rust/kernel/lib.rs
+@@ -60,7 +60,7 @@
+ /// The top level entrypoint to implementing a kernel module.
+ ///
+ /// For any teardown or cleanup operations, your type may implement [`Drop`].
+-pub trait Module: Sized + Sync {
++pub trait Module: Sized + Sync + Send {
+ /// Called at module initialization time.
+ ///
+ /// Use this method to perform whatever setup or registration your module
+--
+2.43.0
+
--- /dev/null
+From d529ced135540a4ba8369957ab54951beb9f88f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Apr 2024 18:52:50 +0000
+Subject: rust: macros: fix soundness issue in `module!` macro
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Benno Lossin <benno.lossin@proton.me>
+
+[ Upstream commit 7044dcff8301b29269016ebd17df27c4736140d2 ]
+
+The `module!` macro creates glue code that are called by C to initialize
+the Rust modules using the `Module::init` function. Part of this glue
+code are the local functions `__init` and `__exit` that are used to
+initialize/destroy the Rust module.
+
+These functions are safe and also visible to the Rust mod in which the
+`module!` macro is invoked. This means that they can be called by other
+safe Rust code. But since they contain `unsafe` blocks that rely on only
+being called at the right time, this is a soundness issue.
+
+Wrap these generated functions inside of two private modules, this
+guarantees that the public functions cannot be called from the outside.
+Make the safe functions `unsafe` and add SAFETY comments.
+
+Cc: stable@vger.kernel.org
+Reported-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
+Closes: https://github.com/Rust-for-Linux/linux/issues/629
+Fixes: 1fbde52bde73 ("rust: add `macros` crate")
+Signed-off-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Wedson Almeida Filho <walmeida@microsoft.com>
+Link: https://lore.kernel.org/r/20240401185222.12015-1-benno.lossin@proton.me
+[ Moved `THIS_MODULE` out of the private-in-private modules since it
+ should remain public, as Dirk Behme noticed [1]. Capitalized comments,
+ avoided newline in non-list SAFETY comments and reworded to add
+ Reported-by and newline. ]
+Link: https://rust-for-linux.zulipchat.com/#narrow/stream/291565-Help/topic/x/near/433512583 [1]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/macros/module.rs | 190 +++++++++++++++++++++++++-----------------
+ 1 file changed, 115 insertions(+), 75 deletions(-)
+
+diff --git a/rust/macros/module.rs b/rust/macros/module.rs
+index 27979e582e4b9..acd0393b50957 100644
+--- a/rust/macros/module.rs
++++ b/rust/macros/module.rs
+@@ -199,17 +199,6 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
+ /// Used by the printing macros, e.g. [`info!`].
+ const __LOG_PREFIX: &[u8] = b\"{name}\\0\";
+
+- /// The \"Rust loadable module\" mark.
+- //
+- // This may be best done another way later on, e.g. as a new modinfo
+- // key or a new section. For the moment, keep it simple.
+- #[cfg(MODULE)]
+- #[doc(hidden)]
+- #[used]
+- static __IS_RUST_MODULE: () = ();
+-
+- static mut __MOD: Option<{type_}> = None;
+-
+ // SAFETY: `__this_module` is constructed by the kernel at load time and will not be
+ // freed until the module is unloaded.
+ #[cfg(MODULE)]
+@@ -221,81 +210,132 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
+ kernel::ThisModule::from_ptr(core::ptr::null_mut())
+ }};
+
+- // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
+- /// # Safety
+- ///
+- /// This function must not be called after module initialization, because it may be
+- /// freed after that completes.
+- #[cfg(MODULE)]
+- #[doc(hidden)]
+- #[no_mangle]
+- #[link_section = \".init.text\"]
+- pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{
+- __init()
+- }}
+-
+- #[cfg(MODULE)]
+- #[doc(hidden)]
+- #[no_mangle]
+- pub extern \"C\" fn cleanup_module() {{
+- __exit()
+- }}
++ // Double nested modules, since then nobody can access the public items inside.
++ mod __module_init {{
++ mod __module_init {{
++ use super::super::{type_};
++
++ /// The \"Rust loadable module\" mark.
++ //
++ // This may be best done another way later on, e.g. as a new modinfo
++ // key or a new section. For the moment, keep it simple.
++ #[cfg(MODULE)]
++ #[doc(hidden)]
++ #[used]
++ static __IS_RUST_MODULE: () = ();
++
++ static mut __MOD: Option<{type_}> = None;
++
++ // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
++ /// # Safety
++ ///
++ /// This function must not be called after module initialization, because it may be
++ /// freed after that completes.
++ #[cfg(MODULE)]
++ #[doc(hidden)]
++ #[no_mangle]
++ #[link_section = \".init.text\"]
++ pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{
++ // SAFETY: This function is inaccessible to the outside due to the double
++ // module wrapping it. It is called exactly once by the C side via its
++ // unique name.
++ unsafe {{ __init() }}
++ }}
+
+- // Built-in modules are initialized through an initcall pointer
+- // and the identifiers need to be unique.
+- #[cfg(not(MODULE))]
+- #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
+- #[doc(hidden)]
+- #[link_section = \"{initcall_section}\"]
+- #[used]
+- pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init;
++ #[cfg(MODULE)]
++ #[doc(hidden)]
++ #[no_mangle]
++ pub extern \"C\" fn cleanup_module() {{
++ // SAFETY:
++ // - This function is inaccessible to the outside due to the double
++ // module wrapping it. It is called exactly once by the C side via its
++ // unique name,
++ // - furthermore it is only called after `init_module` has returned `0`
++ // (which delegates to `__init`).
++ unsafe {{ __exit() }}
++ }}
+
+- #[cfg(not(MODULE))]
+- #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
+- core::arch::global_asm!(
+- r#\".section \"{initcall_section}\", \"a\"
+- __{name}_initcall:
+- .long __{name}_init - .
+- .previous
+- \"#
+- );
++ // Built-in modules are initialized through an initcall pointer
++ // and the identifiers need to be unique.
++ #[cfg(not(MODULE))]
++ #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
++ #[doc(hidden)]
++ #[link_section = \"{initcall_section}\"]
++ #[used]
++ pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init;
++
++ #[cfg(not(MODULE))]
++ #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
++ core::arch::global_asm!(
++ r#\".section \"{initcall_section}\", \"a\"
++ __{name}_initcall:
++ .long __{name}_init - .
++ .previous
++ \"#
++ );
++
++ #[cfg(not(MODULE))]
++ #[doc(hidden)]
++ #[no_mangle]
++ pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{
++ // SAFETY: This function is inaccessible to the outside due to the double
++ // module wrapping it. It is called exactly once by the C side via its
++ // placement above in the initcall section.
++ unsafe {{ __init() }}
++ }}
+
+- #[cfg(not(MODULE))]
+- #[doc(hidden)]
+- #[no_mangle]
+- pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{
+- __init()
+- }}
++ #[cfg(not(MODULE))]
++ #[doc(hidden)]
++ #[no_mangle]
++ pub extern \"C\" fn __{name}_exit() {{
++ // SAFETY:
++ // - This function is inaccessible to the outside due to the double
++ // module wrapping it. It is called exactly once by the C side via its
++ // unique name,
++ // - furthermore it is only called after `__{name}_init` has returned `0`
++ // (which delegates to `__init`).
++ unsafe {{ __exit() }}
++ }}
+
+- #[cfg(not(MODULE))]
+- #[doc(hidden)]
+- #[no_mangle]
+- pub extern \"C\" fn __{name}_exit() {{
+- __exit()
+- }}
++ /// # Safety
++ ///
++ /// This function must only be called once.
++ unsafe fn __init() -> core::ffi::c_int {{
++ match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{
++ Ok(m) => {{
++ // SAFETY: No data race, since `__MOD` can only be accessed by this
++ // module and there only `__init` and `__exit` access it. These
++ // functions are only called once and `__exit` cannot be called
++ // before or during `__init`.
++ unsafe {{
++ __MOD = Some(m);
++ }}
++ return 0;
++ }}
++ Err(e) => {{
++ return e.to_errno();
++ }}
++ }}
++ }}
+
+- fn __init() -> core::ffi::c_int {{
+- match <{type_} as kernel::Module>::init(&THIS_MODULE) {{
+- Ok(m) => {{
++ /// # Safety
++ ///
++ /// This function must
++ /// - only be called once,
++ /// - be called after `__init` has been called and returned `0`.
++ unsafe fn __exit() {{
++ // SAFETY: No data race, since `__MOD` can only be accessed by this module
++ // and there only `__init` and `__exit` access it. These functions are only
++ // called once and `__init` was already called.
+ unsafe {{
+- __MOD = Some(m);
++ // Invokes `drop()` on `__MOD`, which should be used for cleanup.
++ __MOD = None;
+ }}
+- return 0;
+- }}
+- Err(e) => {{
+- return e.to_errno();
+ }}
+- }}
+- }}
+
+- fn __exit() {{
+- unsafe {{
+- // Invokes `drop()` on `__MOD`, which should be used for cleanup.
+- __MOD = None;
++ {modinfo}
+ }}
+ }}
+-
+- {modinfo}
+ ",
+ type_ = info.type_,
+ name = info.name,
+--
+2.43.0
+
--- /dev/null
+From 988fd379cb7b5d629bcf4e8960db542d1555a693 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 08:38:06 -0700
+Subject: rust: module: place generated init_module() function in .init.text
+
+From: Thomas Bertschinger <tahbertschinger@gmail.com>
+
+[ Upstream commit 1b6170ff7a203a5e8354f19b7839fe8b897a9c0d ]
+
+Currently Rust kernel modules have their init code placed in the `.text`
+section of the .ko file. I don't think this causes any real problems
+for Rust modules as long as all code called during initialization lives
+in `.text`.
+
+However, if a Rust `init_module()` function (that lives in `.text`)
+calls a function marked with `__init` (in C) or
+`#[link_section = ".init.text"]` (in Rust), then a warning is
+generated by modpost because that function lives in `.init.text`.
+For example:
+
+WARNING: modpost: fs/bcachefs/bcachefs: section mismatch in reference: init_module+0x6 (section: .text) -> _RNvXCsj7d3tFpT5JS_15bcachefs_moduleNtB2_8BcachefsNtCsjDtqRIL3JAG_6kernel6Module4init (section: .init.text)
+
+I ran into this while experimenting with converting the bcachefs kernel
+module from C to Rust. The module's `init()`, written in Rust, calls C
+functions like `bch2_vfs_init()` which are placed in `.init.text`.
+
+This patch places the macro-generated `init_module()` Rust function in
+the `.init.text` section. It also marks `init_module()` as unsafe--now
+it may not be called after module initialization completes because it
+may be freed already.
+
+Note that this is not enough on its own to actually get all the module
+initialization code in that section. The module author must still add
+the `#[link_section = ".init.text"]` attribute to the Rust `init()` in
+the `impl kernel::Module` block in order to then call `__init`
+functions. However, this patch enables module authors do so, when
+previously it would not be possible (without warnings).
+
+Signed-off-by: Thomas Bertschinger <tahbertschinger@gmail.com>
+Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Link: https://lore.kernel.org/r/20240206153806.567055-1-tahbertschinger@gmail.com
+[ Reworded title to add prefix. ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Stable-dep-of: 7044dcff8301 ("rust: macros: fix soundness issue in `module!` macro")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/macros/module.rs | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/rust/macros/module.rs b/rust/macros/module.rs
+index d62d8710d77ab..27979e582e4b9 100644
+--- a/rust/macros/module.rs
++++ b/rust/macros/module.rs
+@@ -222,10 +222,15 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
+ }};
+
+ // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
++ /// # Safety
++ ///
++ /// This function must not be called after module initialization, because it may be
++ /// freed after that completes.
+ #[cfg(MODULE)]
+ #[doc(hidden)]
+ #[no_mangle]
+- pub extern \"C\" fn init_module() -> core::ffi::c_int {{
++ #[link_section = \".init.text\"]
++ pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{
+ __init()
+ }}
+
+--
+2.43.0
+
--- /dev/null
+dmaengine-pl330-issue_pending-waits-until-wfp-state.patch
+dmaengine-revert-dmaengine-pl330-issue_pending-waits.patch
+nvmem-add-explicit-config-option-to-read-old-syntax-.patch
+mtd-limit-otp-nvmem-cell-parse-to-non-nand-devices.patch
+rust-module-place-generated-init_module-function-in-.patch
+rust-macros-fix-soundness-issue-in-module-macro.patch
+wifi-nl80211-don-t-free-null-coalescing-rule.patch
+rust-kernel-require-send-for-module-implementations.patch
+eeprom-at24-probe-for-ddr3-thermal-sensor-in-the-spd.patch
+eeprom-at24-fix-memory-corruption-race-condition.patch
+bluetooth-qca-add-support-for-qca2066.patch
+bluetooth-qca-fix-invalid-device-address-check.patch
+pinctrl-pinctrl-aspeed-g6-fix-register-offset-for-pi.patch
+pinctrl-meson-fix-typo-in-pdm-s-pin-name.patch
+pinctrl-core-delete-incorrect-free-in-pinctrl_enable.patch
+pinctrl-mediatek-paris-fix-pin_config_input_schmitt_.patch
+pinctrl-mediatek-paris-rework-support-for-pin_config.patch
+sunrpc-add-a-struct-rpc_stats-arg-to-rpc_create_args.patch
+nfs-expose-proc-net-sunrpc-nfs-in-net-namespaces.patch
+nfs-make-the-rpc_stat-per-net-namespace.patch
+nfs-handle-error-of-rpc_proc_register-in-nfs_net_ini.patch
+pinctrl-baytrail-fix-selecting-gpio-pinctrl-state.patch
+power-rt9455-hide-unused-rt9455_boost_voltage_values.patch
+power-supply-mt6360_charger-fix-of_match-for-usb-otg.patch
+pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch
+regulator-mt6360-de-capitalize-devicetree-regulator-.patch
+regulator-change-stubbed-devm_regulator_get_enable-t.patch
+regulator-change-devm_regulator_get_enable_optional-.patch
--- /dev/null
+From 6fc82a9ad59e25324b882935e1308b64682a980d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 14:57:30 -0500
+Subject: sunrpc: add a struct rpc_stats arg to rpc_create_args
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 2057a48d0dd00c6a2a94ded7df2bf1d3f2a4a0da ]
+
+We want to be able to have our rpc stats handled in a per network
+namespace manner, so add an option to rpc_create_args to specify a
+different rpc_stats struct instead of using the one on the rpc_program.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sunrpc/clnt.h | 1 +
+ net/sunrpc/clnt.c | 5 ++++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
+index e9d4377d03c6e..17d84b3ee8a01 100644
+--- a/include/linux/sunrpc/clnt.h
++++ b/include/linux/sunrpc/clnt.h
+@@ -139,6 +139,7 @@ struct rpc_create_args {
+ const char *servername;
+ const char *nodename;
+ const struct rpc_program *program;
++ struct rpc_stat *stats;
+ u32 prognumber; /* overrides program->number */
+ u32 version;
+ rpc_authflavor_t authflavor;
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index 339dfc5b92246..f4d32cf2cd16a 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -399,7 +399,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
+ clnt->cl_maxproc = version->nrprocs;
+ clnt->cl_prog = args->prognumber ? : program->number;
+ clnt->cl_vers = version->number;
+- clnt->cl_stats = program->stats;
++ clnt->cl_stats = args->stats ? : program->stats;
+ clnt->cl_metrics = rpc_alloc_iostats(clnt);
+ rpc_init_pipe_dir_head(&clnt->cl_pipedir_objects);
+ err = -ENOMEM;
+@@ -685,6 +685,7 @@ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt)
+ .version = clnt->cl_vers,
+ .authflavor = clnt->cl_auth->au_flavor,
+ .cred = clnt->cl_cred,
++ .stats = clnt->cl_stats,
+ };
+ return __rpc_clone_client(&args, clnt);
+ }
+@@ -707,6 +708,7 @@ rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
+ .version = clnt->cl_vers,
+ .authflavor = flavor,
+ .cred = clnt->cl_cred,
++ .stats = clnt->cl_stats,
+ };
+ return __rpc_clone_client(&args, clnt);
+ }
+@@ -1053,6 +1055,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
+ .version = vers,
+ .authflavor = old->cl_auth->au_flavor,
+ .cred = old->cl_cred,
++ .stats = old->cl_stats,
+ };
+ struct rpc_clnt *clnt;
+ int err;
+--
+2.43.0
+
--- /dev/null
+From d6e174f6148d88419fd1648ff249313353c50e00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Apr 2024 10:52:23 +0200
+Subject: wifi: nl80211: don't free NULL coalescing rule
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 801ea33ae82d6a9d954074fbcf8ea9d18f1543a7 ]
+
+If the parsing fails, we can dereference a NULL pointer here.
+
+Cc: stable@vger.kernel.org
+Fixes: be29b99a9b51 ("cfg80211/nl80211: Add packet coalesce support")
+Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://msgid.link/20240418105220.b328f80406e7.Id75d961050deb05b3e4e354e024866f350c68103@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 9f6d8bcecfebe..c4f08f7eb741d 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -14052,6 +14052,8 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
+ error:
+ for (i = 0; i < new_coalesce.n_rules; i++) {
+ tmp_rule = &new_coalesce.rules[i];
++ if (!tmp_rule)
++ continue;
+ for (j = 0; j < tmp_rule->n_patterns; j++)
+ kfree(tmp_rule->patterns[j].mask);
+ kfree(tmp_rule->patterns);
+--
+2.43.0
+