Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen
2025-07-11 14:37:33 +08:00
60 changed files with 816 additions and 551 deletions
+2 -2
View File
@@ -1,2 +1,2 @@
LINUX_VERSION-6.6 = .94
LINUX_KERNEL_HASH-6.6.94 = 713981ea26b20b476ba4ce880b76b21294576788d5db1c2188b167bcb06ecc56
LINUX_VERSION-6.6 = .95
LINUX_KERNEL_HASH-6.6.95 = 18640ae9a2c952f8f8868324378df1a9e138ad29e6b93a9c38155764ea67ea85
@@ -0,0 +1,29 @@
From ee6dac9b6b765e8aab5727688463880c52f6193d Mon Sep 17 00:00:00 2001
From: David Bauer <mail@david-bauer.net>
Date: Wed, 2 Apr 2025 02:45:26 +0200
Subject: [PATCH] wifi: mt76: mt7915: mcu: increase eeprom command timeout
Increase the timeout for MCU_EXT_CMD_EFUSE_BUFFER_MODE command.
Regular retries upon hardware-recovery have been observed. Increasing
the timeout slightly remedies this problem.
Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20250402004528.1036715-2-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
mt7915/mcu.c | 3 +++
1 file changed, 3 insertions(+)
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -208,6 +208,9 @@ mt7915_mcu_set_timeout(struct mt76_dev *
case MCU_EXT_CMD_BSS_INFO_UPDATE:
mdev->mcu.timeout = 2 * HZ;
return;
+ case MCU_EXT_CMD_EFUSE_BUFFER_MODE:
+ mdev->mcu.timeout = 10 * HZ;
+ return;
default:
break;
}
@@ -0,0 +1,29 @@
From 0534761b76e1b2e3390b345e524ce959f3fa50fb Mon Sep 17 00:00:00 2001
From: David Bauer <mail@david-bauer.net>
Date: Wed, 2 Apr 2025 02:45:25 +0200
Subject: [PATCH] wifi: mt76: mt7915: mcu: lower default timeout
The default timeout set in mt76_connac2_mcu_fill_message of 20 seconds
leads to excessive stalling in case messages are lost.
Testing showed that a smaller timeout of 5 seconds is sufficient in
normal operation.
Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20250402004528.1036715-1-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
mt7915/mcu.c | 2 ++
1 file changed, 2 insertions(+)
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -197,6 +197,8 @@ mt7915_mcu_parse_response(struct mt76_de
static void
mt7915_mcu_set_timeout(struct mt76_dev *mdev, int cmd)
{
+ mdev->mcu.timeout = 5 * HZ;
+
if ((cmd & __MCU_CMD_FIELD_ID) != MCU_CMD_EXT_CID)
return;
@@ -0,0 +1,56 @@
From 79dd14f2e8161b656341b6653261779199aedbe4 Mon Sep 17 00:00:00 2001
From: David Bauer <mail@david-bauer.net>
Date: Wed, 2 Apr 2025 02:45:27 +0200
Subject: [PATCH] wifi: mt76: mt7915: mcu: re-init MCU before loading FW patch
Restart the MCU and release the patch semaphore before loading the MCU
patch firmware from the host.
This fixes failures upon error recovery in case the semaphore was
previously taken and never released by the host.
This happens from time to time upon triggering a full-chip error
recovery. Under this circumstance, the hardware restart fails and the
radio is rendered inoperational.
Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20250402004528.1036715-3-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
mt7915/mcu.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -2097,16 +2097,21 @@ static int mt7915_load_firmware(struct m
{
int ret;
- /* make sure fw is download state */
- if (mt7915_firmware_state(dev, false)) {
- /* restart firmware once */
- mt76_connac_mcu_restart(&dev->mt76);
- ret = mt7915_firmware_state(dev, false);
- if (ret) {
- dev_err(dev->mt76.dev,
- "Firmware is not ready for download\n");
- return ret;
- }
+ /* Release Semaphore if taken by previous failed attempt */
+ ret = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, false);
+ if (ret != PATCH_REL_SEM_SUCCESS) {
+ dev_err(dev->mt76.dev, "Could not release semaphore\n");
+ /* Continue anyways */
+ }
+
+ /* Always restart MCU firmware */
+ mt76_connac_mcu_restart(&dev->mt76);
+
+ /* Check if MCU is ready */
+ ret = mt7915_firmware_state(dev, false);
+ if (ret) {
+ dev_err(dev->mt76.dev, "Firmware did not enter download state\n");
+ return ret;
}
ret = mt76_connac2_load_patch(&dev->mt76, fw_name_var(dev, ROM_PATCH));
+2 -2
View File
@@ -8,13 +8,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mbedtls
PKG_VERSION:=3.6.3
PKG_VERSION:=3.6.4
PKG_RELEASE:=1
PKG_BUILD_FLAGS:=no-mips16 gc-sections no-lto
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL=https://github.com/Mbed-TLS/$(PKG_NAME)/releases/download/$(PKG_NAME)-$(PKG_VERSION)
PKG_HASH:=64cd73842cdc05e101172f7b437c65e7312e476206e1dbfd644433d11bc56327
PKG_HASH:=ec35b18a6c593cf98c3e30db8b98ff93e8940a8c4e690e66b41dfc011d678110
PKG_LICENSE:=GPL-2.0-or-later
PKG_LICENSE_FILES:=LICENSE
+2 -2
View File
@@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=openssl
PKG_VERSION:=3.0.16
PKG_VERSION:=3.0.17
PKG_RELEASE:=1
PKG_BUILD_FLAGS:=no-mips16 gc-sections no-lto
@@ -21,7 +21,7 @@ PKG_SOURCE_URL:= \
https://www.openssl.org/source/old/$(PKG_BASE)/ \
https://github.com/openssl/openssl/releases/download/$(PKG_NAME)-$(PKG_VERSION)/
PKG_HASH:=57e03c50feab5d31b152af2b764f10379aecd8ee92f16c985983ce4a99f7ef86
PKG_HASH:=dfdd77e4ea1b57ff3a6dbde6b0bdc3f31db5ac99e7fdd4eaf9e1fbb6ec2db8ce
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
@@ -10,7 +10,7 @@ Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
--- a/Configure
+++ b/Configure
@@ -1677,7 +1677,9 @@ $config{CFLAGS} = [ map { $_ eq '--ossl-
@@ -1678,7 +1678,9 @@ $config{CFLAGS} = [ map { $_ eq '--ossl-
unless ($disabled{afalgeng}) {
$config{afalgeng}="";
@@ -44,7 +44,7 @@
usb_power {
gpio-export,name = "usb-power";
gpio-export,output = <0>;
gpio-export,output = <1>;
gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
};
};
@@ -751,7 +751,7 @@ SVN-Revision: 35130
EXPORT_SYMBOL(xfrm_parse_spi);
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4276,14 +4276,16 @@ static bool tcp_parse_aligned_timestamp(
@@ -4283,14 +4283,16 @@ static bool tcp_parse_aligned_timestamp(
{
const __be32 *ptr = (const __be32 *)(th + 1);
@@ -344,7 +344,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
}
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
@@ -143,6 +143,14 @@ static const struct mmc_fixup __maybe_un
@@ -153,6 +153,14 @@ static const struct mmc_fixup __maybe_un
MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd,
MMC_QUIRK_BROKEN_SD_DISCARD),
@@ -2013,10 +2013,10 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
sdhci_dumpregs(host);
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -297,6 +297,7 @@ struct mmc_card {
#define MMC_QUIRK_BROKEN_SD_CACHE (1<<15) /* Disable broken SD cache support */
@@ -298,6 +298,7 @@ struct mmc_card {
#define MMC_QUIRK_BROKEN_CACHE_FLUSH (1<<16) /* Don't flush cache until the write has occurred */
#define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY (1<<17) /* Disable broken SD poweroff notify support */
#define MMC_QUIRK_NO_UHS_DDR50_TUNING (1<<18) /* Disable DDR50 tuning */
+#define MMC_QUIRK_ERASE_BROKEN (1<<31) /* Skip erase */
bool written_flag; /* Indicates eMMC has been written since power on */
@@ -367,7 +367,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
spin_lock_init(&bp->lock);
spin_lock_init(&bp->stats_lock);
@@ -5118,6 +5237,21 @@ static int macb_probe(struct platform_de
@@ -5122,6 +5241,21 @@ static int macb_probe(struct platform_de
else
bp->phy_interface = interface;
@@ -389,7 +389,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/* IP specific init */
err = init(pdev);
if (err)
@@ -5194,6 +5328,19 @@ static int macb_remove(struct platform_d
@@ -5198,6 +5332,19 @@ static int macb_remove(struct platform_d
return 0;
}
@@ -409,7 +409,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static int __maybe_unused macb_suspend(struct device *dev)
{
struct net_device *netdev = dev_get_drvdata(dev);
@@ -5408,6 +5555,7 @@ static const struct dev_pm_ops macb_pm_o
@@ -5412,6 +5559,7 @@ static const struct dev_pm_ops macb_pm_o
static struct platform_driver macb_driver = {
.probe = macb_probe,
.remove = macb_remove,
@@ -23,33 +23,40 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
#define for_each_registered_fb(i) \
for (i = 0; i < FB_MAX; i++) \
if (!registered_fb[i]) {} else
@@ -938,10 +939,12 @@ static int do_register_framebuffer(struc
@@ -939,9 +940,12 @@ static int do_register_framebuffer(struc
if (num_registered_fb == FB_MAX)
return -ENXIO;
num_registered_fb++;
- for (i = 0 ; i < FB_MAX; i++)
- if (!registered_fb[i])
- break;
- fb_info->node = i;
+ if (!fb_info->custom_fb_num || fb_info->node >= FB_MAX || registered_fb[fb_info->node]) {
+ for (i = min_dynamic_fb ; i < FB_MAX; i++)
+ if (!registered_fb[i])
+ break;
+ fb_info->node = i;
+ }
if (!fb_info->modelist.prev || !fb_info->modelist.next)
INIT_LIST_HEAD(&fb_info->modelist);
@@ -951,7 +955,6 @@ static int do_register_framebuffer(struc
if (err < 0)
return err;
- fb_info->node = i;
refcount_set(&fb_info->count, 1);
mutex_init(&fb_info->lock);
mutex_init(&fb_info->mm_lock);
@@ -976,7 +979,7 @@ static int do_register_framebuffer(struc
@@ -982,7 +985,7 @@ static int do_register_framebuffer(struc
pm_vt_switch_required(fb_info->device, true);
fb_var_to_videomode(&mode, &fb_info->var);
fb_add_videomode(&mode, &fb_info->modelist);
num_registered_fb++;
- registered_fb[i] = fb_info;
+ registered_fb[fb_info->node] = fb_info;
#ifdef CONFIG_GUMSTIX_AM200EPD
{
@@ -1037,6 +1040,12 @@ static void do_unregister_framebuffer(st
@@ -1043,6 +1046,12 @@ static void do_unregister_framebuffer(st
put_fb_info(fb_info);
}
@@ -91,7 +91,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1016,8 +1016,8 @@ static bool mmc_sd_card_using_v18(struct
@@ -1032,8 +1032,8 @@ static bool mmc_sd_card_using_v18(struct
(SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50);
}
@@ -102,7 +102,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
{
struct mmc_host *host = card->host;
struct mmc_request mrq = {};
@@ -1175,8 +1175,14 @@ static int sd_parse_ext_reg_perf(struct
@@ -1191,8 +1191,14 @@ static int sd_parse_ext_reg_perf(struct
card->ext_perf.feature_support |= SD_EXT_PERF_CACHE;
/* Command queue support indicated via queue depth bits (0 to 4). */
@@ -118,7 +118,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
card->ext_perf.fno = fno;
card->ext_perf.page = page;
@@ -1563,13 +1569,41 @@ cont:
@@ -1579,13 +1585,41 @@ cont:
goto free_card;
}
@@ -30,7 +30,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
kfree(card);
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1026,9 +1026,8 @@ int sd_write_ext_reg(struct mmc_card *ca
@@ -1042,9 +1042,8 @@ int sd_write_ext_reg(struct mmc_card *ca
struct scatterlist sg;
u8 *reg_buf;
@@ -42,7 +42,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
mrq.cmd = &cmd;
mrq.data = &data;
@@ -1060,8 +1059,6 @@ int sd_write_ext_reg(struct mmc_card *ca
@@ -1076,8 +1075,6 @@ int sd_write_ext_reg(struct mmc_card *ca
mmc_set_data_timeout(&data, card);
mmc_wait_for_req(host, &mrq);
@@ -51,7 +51,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* Note that, the SD card is allowed to signal busy on DAT0 up to 1s
* after the CMD49. Although, let's leave this to be managed by the
@@ -1102,9 +1099,7 @@ static int sd_parse_ext_reg_power(struct
@@ -1118,9 +1115,7 @@ static int sd_parse_ext_reg_power(struct
int err;
u8 *reg_buf;
@@ -62,7 +62,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/* Read the extension register for power management function. */
err = sd_read_ext_reg(card, fno, page, offset, 512, reg_buf);
@@ -1134,7 +1129,6 @@ static int sd_parse_ext_reg_power(struct
@@ -1150,7 +1145,6 @@ static int sd_parse_ext_reg_power(struct
card->ext_power.offset = offset;
out:
@@ -70,7 +70,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
return err;
}
@@ -1144,9 +1138,7 @@ static int sd_parse_ext_reg_perf(struct
@@ -1160,9 +1154,7 @@ static int sd_parse_ext_reg_perf(struct
int err;
u8 *reg_buf;
@@ -81,7 +81,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
err = sd_read_ext_reg(card, fno, page, offset, 512, reg_buf);
if (err) {
@@ -1189,7 +1181,6 @@ static int sd_parse_ext_reg_perf(struct
@@ -1205,7 +1197,6 @@ static int sd_parse_ext_reg_perf(struct
card->ext_perf.offset = offset;
out:
@@ -89,7 +89,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
return err;
}
@@ -1260,6 +1251,12 @@ static int sd_read_ext_regs(struct mmc_c
@@ -1276,6 +1267,12 @@ static int sd_read_ext_regs(struct mmc_c
if (!gen_info_buf)
return -ENOMEM;
@@ -102,7 +102,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* Read 512 bytes of general info, which is found at function number 0,
* at page 0 and with no offset.
@@ -1326,9 +1323,7 @@ static int sd_flush_cache(struct mmc_hos
@@ -1342,9 +1339,7 @@ static int sd_flush_cache(struct mmc_hos
if (!sd_cache_enabled(host))
return 0;
@@ -113,7 +113,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* Set Flush Cache at bit 0 in the performance enhancement register at
@@ -1364,21 +1359,15 @@ static int sd_flush_cache(struct mmc_hos
@@ -1380,21 +1375,15 @@ static int sd_flush_cache(struct mmc_hos
if (reg_buf[0] & BIT(0))
err = -ETIMEDOUT;
out:
@@ -135,7 +135,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
* Set Cache Enable at bit 0 in the performance enhancement register at
* 260 bytes offset.
@@ -1397,7 +1386,6 @@ static int sd_enable_cache(struct mmc_ca
@@ -1413,7 +1402,6 @@ static int sd_enable_cache(struct mmc_ca
card->ext_perf.feature_enabled |= SD_EXT_PERF_CACHE;
out:
@@ -145,7 +145,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -321,6 +321,7 @@ struct mmc_card {
@@ -322,6 +322,7 @@ struct mmc_card {
struct sd_switch_caps sw_caps; /* switch (CMD6) caps */
struct sd_ext_reg ext_power; /* SD extension reg for PM */
struct sd_ext_reg ext_perf; /* SD extension reg for PERF */
@@ -16,7 +16,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1016,83 +1016,6 @@ static bool mmc_sd_card_using_v18(struct
@@ -1032,83 +1032,6 @@ static bool mmc_sd_card_using_v18(struct
(SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50);
}
@@ -100,7 +100,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static int sd_parse_ext_reg_power(struct mmc_card *card, u8 fno, u8 page,
u16 offset)
{
@@ -1102,7 +1025,7 @@ static int sd_parse_ext_reg_power(struct
@@ -1118,7 +1041,7 @@ static int sd_parse_ext_reg_power(struct
reg_buf = card->ext_reg_buf;
/* Read the extension register for power management function. */
@@ -109,7 +109,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_warn("%s: error %d reading PM func of ext reg\n",
mmc_hostname(card->host), err);
@@ -1140,7 +1063,7 @@ static int sd_parse_ext_reg_perf(struct
@@ -1156,7 +1079,7 @@ static int sd_parse_ext_reg_perf(struct
reg_buf = card->ext_reg_buf;
@@ -118,7 +118,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_warn("%s: error %d reading PERF func of ext reg\n",
mmc_hostname(card->host), err);
@@ -1235,7 +1158,7 @@ static int sd_parse_ext_reg(struct mmc_c
@@ -1251,7 +1174,7 @@ static int sd_parse_ext_reg(struct mmc_c
return 0;
}
@@ -127,7 +127,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
{
int err, i;
u8 num_ext, *gen_info_buf;
@@ -1261,7 +1184,7 @@ static int sd_read_ext_regs(struct mmc_c
@@ -1277,7 +1200,7 @@ static int sd_read_ext_regs(struct mmc_c
* Read 512 bytes of general info, which is found at function number 0,
* at page 0 and with no offset.
*/
@@ -136,7 +136,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_err("%s: error %d reading general info of SD ext reg\n",
mmc_hostname(card->host), err);
@@ -1333,7 +1256,7 @@ static int sd_flush_cache(struct mmc_hos
@@ -1349,7 +1272,7 @@ static int sd_flush_cache(struct mmc_hos
page = card->ext_perf.page;
offset = card->ext_perf.offset + 261;
@@ -145,7 +145,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_warn("%s: error %d writing Cache Flush bit\n",
mmc_hostname(host), err);
@@ -1349,7 +1272,7 @@ static int sd_flush_cache(struct mmc_hos
@@ -1365,7 +1288,7 @@ static int sd_flush_cache(struct mmc_hos
* Read the Flush Cache bit. The card shall reset it, to confirm that
* it's has completed the flushing of the cache.
*/
@@ -154,7 +154,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err) {
pr_warn("%s: error %d reading Cache Flush bit\n",
mmc_hostname(host), err);
@@ -1372,7 +1295,7 @@ static int sd_enable_cache(struct mmc_ca
@@ -1388,7 +1311,7 @@ static int sd_enable_cache(struct mmc_ca
* Set Cache Enable at bit 0 in the performance enhancement register at
* 260 bytes offset.
*/
@@ -163,7 +163,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
card->ext_perf.offset + 260, BIT(0));
if (err) {
pr_warn("%s: error %d writing Cache Enable bit\n",
@@ -1545,7 +1468,7 @@ retry:
@@ -1561,7 +1484,7 @@ retry:
cont:
if (!oldcard) {
/* Read/parse the extension registers. */
@@ -172,7 +172,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (err)
goto free_card;
}
@@ -1672,7 +1595,7 @@ static int sd_busy_poweroff_notify_cb(vo
@@ -1688,7 +1611,7 @@ static int sd_busy_poweroff_notify_cb(vo
* one byte offset and is one byte long. The Power Off Notification
* Ready is bit 0.
*/
@@ -181,7 +181,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
card->ext_power.offset + 1, 1, data->reg_buf);
if (err) {
pr_warn("%s: error %d reading status reg of PM func\n",
@@ -1698,7 +1621,7 @@ static int sd_poweroff_notify(struct mmc
@@ -1714,7 +1637,7 @@ static int sd_poweroff_notify(struct mmc
* Set the Power Off Notification bit in the power management settings
* register at 2 bytes offset.
*/
@@ -17,7 +17,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1089,8 +1089,12 @@ static int sd_parse_ext_reg_perf(struct
@@ -1105,8 +1105,12 @@ static int sd_parse_ext_reg_perf(struct
if ((reg_buf[4] & BIT(0)) && !mmc_card_broken_sd_cache(card))
card->ext_perf.feature_support |= SD_EXT_PERF_CACHE;
@@ -27,7 +27,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
pr_info("%s: Host Software Queue enabled\n",
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -715,7 +715,8 @@ MMC_DEV_ATTR(oemid, "0x%04x\n", card->ci
@@ -731,7 +731,8 @@ MMC_DEV_ATTR(oemid, "0x%04x\n", card->ci
MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
@@ -37,7 +37,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
static ssize_t mmc_dsr_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -777,6 +778,8 @@ static struct attribute *sd_std_attrs[]
@@ -793,6 +794,8 @@ static struct attribute *sd_std_attrs[]
&dev_attr_ocr.attr,
&dev_attr_rca.attr,
&dev_attr_dsr.attr,
@@ -46,7 +46,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
NULL,
};
@@ -1512,8 +1515,8 @@ cont:
@@ -1528,8 +1531,8 @@ cont:
host->cqe_enabled = true;
if (card->ext_csd.cmdq_en) {
@@ -14,7 +14,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1177,7 +1177,7 @@ static int mmc_sd_read_ext_regs(struct m
@@ -1193,7 +1193,7 @@ static int mmc_sd_read_ext_regs(struct m
if (!(card->scr.cmds & SD_SCR_CMD48_SUPPORT))
return 0;
@@ -23,7 +23,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (!gen_info_buf)
return -ENOMEM;
@@ -1208,14 +1208,23 @@ static int mmc_sd_read_ext_regs(struct m
@@ -1224,14 +1224,23 @@ static int mmc_sd_read_ext_regs(struct m
num_ext = gen_info_buf[4];
/*
@@ -129,7 +129,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
bool busy;
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1104,6 +1104,14 @@ static int sd_parse_ext_reg_perf(struct
@@ -1120,6 +1120,14 @@ static int sd_parse_ext_reg_perf(struct
pr_debug("%s: Command Queue supported depth %u\n",
mmc_hostname(card->host),
card->ext_csd.cmdq_depth);
@@ -146,7 +146,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
card->ext_perf.fno = fno;
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -344,6 +344,8 @@ struct mmc_card {
@@ -345,6 +345,8 @@ struct mmc_card {
unsigned int nr_parts;
struct workqueue_struct *complete_wq; /* Private workqueue */
@@ -39,7 +39,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
return BLK_STS_RESOURCE;
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1105,13 +1105,14 @@ static int sd_parse_ext_reg_perf(struct
@@ -1121,13 +1121,14 @@ static int sd_parse_ext_reg_perf(struct
mmc_hostname(card->host),
card->ext_csd.cmdq_depth);
/*
@@ -60,7 +60,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
}
card->ext_perf.fno = fno;
@@ -1375,6 +1376,7 @@ retry:
@@ -1391,6 +1392,7 @@ retry:
card->ocr = ocr;
card->type = MMC_TYPE_SD;
@@ -26,13 +26,13 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
#define CID_MANFID_SAMSUNG 0x15
+#define CID_MANFID_SAMSUNG_SD 0x1b
#define CID_MANFID_APACER 0x27
#define CID_MANFID_SWISSBIT 0x5D
#define CID_MANFID_KINGSTON 0x70
#define CID_MANFID_HYNIX 0x90
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
@@ -34,6 +34,14 @@ static const struct mmc_fixup __maybe_un
MMC_QUIRK_BROKEN_SD_CACHE | MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY,
EXT_CSD_REV_ANY),
@@ -44,6 +44,14 @@ static const struct mmc_fixup __maybe_un
0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
MMC_QUIRK_NO_UHS_DDR50_TUNING, EXT_CSD_REV_ANY),
+ /*
+ * Samsung Pro Plus/EVO Plus/Pro Ultimate SD cards (2023) claim to cache
@@ -14,7 +14,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
@@ -42,6 +42,18 @@ static const struct mmc_fixup __maybe_un
@@ -52,6 +52,18 @@ static const struct mmc_fixup __maybe_un
0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
@@ -15,7 +15,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
@@ -171,6 +171,15 @@ static const struct mmc_fixup __maybe_un
@@ -181,6 +181,15 @@ static const struct mmc_fixup __maybe_un
MMC_FIXUP("SD32G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),
MMC_FIXUP("SD64G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),
@@ -22,8 +22,8 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/card.h
+++ b/drivers/mmc/core/card.h
@@ -292,4 +292,9 @@ static inline int mmc_card_broken_sd_pow
return c->quirks & MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY;
@@ -298,4 +298,9 @@ static inline int mmc_card_no_uhs_ddr50_
return c->quirks & MMC_QUIRK_NO_UHS_DDR50_TUNING;
}
+static inline int mmc_card_working_sd_cq(const struct mmc_card *c)
@@ -34,7 +34,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
#endif
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1506,6 +1506,10 @@ cont:
@@ -1522,6 +1522,10 @@ cont:
goto free_card;
}
@@ -47,10 +47,10 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/*
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -297,6 +297,7 @@ struct mmc_card {
#define MMC_QUIRK_BROKEN_SD_CACHE (1<<15) /* Disable broken SD cache support */
@@ -298,6 +298,7 @@ struct mmc_card {
#define MMC_QUIRK_BROKEN_CACHE_FLUSH (1<<16) /* Don't flush cache until the write has occurred */
#define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY (1<<17) /* Disable broken SD poweroff notify support */
#define MMC_QUIRK_NO_UHS_DDR50_TUNING (1<<18) /* Disable DDR50 tuning */
+#define MMC_QUIRK_WORKING_SD_CQ (1<<30) /* SD card has known-good CQ implementation */
#define MMC_QUIRK_ERASE_BROKEN (1<<31) /* Skip erase */
@@ -16,7 +16,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/mmc/core/card.h
+++ b/drivers/mmc/core/card.h
@@ -90,6 +90,7 @@ struct mmc_fixup {
@@ -91,6 +91,7 @@ struct mmc_fixup {
#define CID_MANFID_KINGSTON 0x70
#define CID_MANFID_HYNIX 0x90
#define CID_MANFID_KINGSTON_SD 0x9F
@@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
#define END_FIXUP { NULL }
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
@@ -66,6 +66,12 @@ static const struct mmc_fixup __maybe_un
@@ -76,6 +76,12 @@ static const struct mmc_fixup __maybe_un
0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
@@ -49,7 +49,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (host->caps & MMC_CAP_NONREMOVABLE)
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1506,8 +1506,8 @@ cont:
@@ -1522,8 +1522,8 @@ cont:
goto free_card;
}
@@ -1,95 +0,0 @@
From 91fb8a7328dda827bc6c0da240a1eb17028416cd Mon Sep 17 00:00:00 2001
From: Linus Walleij <linus.walleij@linaro.org>
Date: Thu, 9 May 2024 23:59:28 +0200
Subject: [PATCH 2/5] net: ethernet: cortina: Use TSO also on common TCP
It is possible to push the segment offloader to also
process non-segmented frames: just pass the skb->len
or desired MSS to the offloader and it will handle them.
This is especially good if the user sets up the MTU
and the frames get big, because the checksumming engine
cannot handle any frames bigger than 1518 bytes, so
segmenting them all to be at max that will be helpful
for the hardware, which only need to quirk odd frames
such as big UDP ping packets.
The vendor driver always uses the TSO like this, and
the driver seems more stable after this, so apparently
the hardware may have been engineered to always use
the TSO on anything it can handle.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/net/ethernet/cortina/gemini.c | 31 +++++++++++++++++++++------
1 file changed, 24 insertions(+), 7 deletions(-)
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1148,6 +1148,7 @@ static int gmac_map_tx_bufs(struct net_d
struct gmac_txdesc *txd;
skb_frag_t *skb_frag;
dma_addr_t mapping;
+ bool tcp = false;
void *buffer;
u16 mss;
int ret;
@@ -1155,6 +1156,13 @@ static int gmac_map_tx_bufs(struct net_d
word1 = skb->len;
word3 = SOF_BIT;
+ /* Determine if we are doing TCP */
+ if (skb->protocol == htons(ETH_P_IP))
+ tcp = (ip_hdr(skb)->protocol == IPPROTO_TCP);
+ else
+ /* IPv6 */
+ tcp = (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP);
+
mss = skb_shinfo(skb)->gso_size;
if (mss) {
/* This means we are dealing with TCP and skb->len is the
@@ -1167,6 +1175,20 @@ static int gmac_map_tx_bufs(struct net_d
mss, skb->len);
word1 |= TSS_MTU_ENABLE_BIT;
word3 |= mss;
+ } else if (tcp) {
+ /* Even if we are not using TSO, use the segment offloader
+ * for transferring the TCP frame: the TSO engine will deal
+ * with chopping up frames that exceed ETH_DATA_LEN which
+ * the checksumming engine cannot handle (see below) into
+ * manageable chunks. It flawlessly deals with quite big
+ * frames and frames containing custom DSA EtherTypes.
+ */
+ mss = netdev->mtu + skb_tcp_all_headers(skb);
+ mss = min(mss, skb->len);
+ netdev_dbg(netdev, "botched TSO len %04x mtu %04x mss %04x\n",
+ skb->len, netdev->mtu, mss);
+ word1 |= TSS_MTU_ENABLE_BIT;
+ word3 |= mss;
} else if (skb->len >= ETH_FRAME_LEN) {
/* Hardware offloaded checksumming isn't working on frames
* bigger than 1514 bytes. A hypothesis about this is that the
@@ -1185,21 +1207,16 @@ static int gmac_map_tx_bufs(struct net_d
}
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- int tcp = 0;
-
/* We do not switch off the checksumming on non TCP/UDP
* frames: as is shown from tests, the checksumming engine
* is smart enough to see that a frame is not actually TCP
* or UDP and then just pass it through without any changes
* to the frame.
*/
- if (skb->protocol == htons(ETH_P_IP)) {
+ if (skb->protocol == htons(ETH_P_IP))
word1 |= TSS_IP_CHKSUM_BIT;
- tcp = ip_hdr(skb)->protocol == IPPROTO_TCP;
- } else { /* IPv6 */
+ else
word1 |= TSS_IPV6_ENABLE_BIT;
- tcp = ipv6_hdr(skb)->nexthdr == IPPROTO_TCP;
- }
word1 |= tcp ? TSS_TCP_CHKSUM_BIT : TSS_UDP_CHKSUM_BIT;
}
@@ -16,7 +16,7 @@ Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -2143,6 +2143,19 @@ static void gmac_get_pauseparam(struct n
@@ -2147,6 +2147,19 @@ static void gmac_get_pauseparam(struct n
pparam->autoneg = true;
}
@@ -36,7 +36,7 @@ Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
static void gmac_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *rp,
struct kernel_ethtool_ringparam *kernel_rp,
@@ -2263,6 +2276,7 @@ static const struct ethtool_ops gmac_351
@@ -2267,6 +2280,7 @@ static const struct ethtool_ops gmac_351
.set_link_ksettings = gmac_set_ksettings,
.nway_reset = gmac_nway_reset,
.get_pauseparam = gmac_get_pauseparam,
@@ -1139,7 +1139,7 @@ Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
};
} link_create;
@@ -6585,6 +6595,10 @@ struct bpf_link_info {
@@ -6587,6 +6597,10 @@ struct bpf_link_info {
__u32 ifindex;
__u32 attach_type;
} tcx;
@@ -1298,7 +1298,7 @@ Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
};
} link_create;
@@ -6588,6 +6598,10 @@ struct bpf_link_info {
@@ -6590,6 +6600,10 @@ struct bpf_link_info {
__u32 ifindex;
__u32 attach_type;
} tcx;
@@ -74,7 +74,7 @@ Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
#include <linux/un.h>
#include <net/xdp_sock_drv.h>
@@ -2482,6 +2483,16 @@ static const struct bpf_func_proto bpf_c
@@ -2483,6 +2484,16 @@ static const struct bpf_func_proto bpf_c
DEFINE_PER_CPU(struct bpf_redirect_info, bpf_redirect_info);
EXPORT_PER_CPU_SYMBOL_GPL(bpf_redirect_info);
@@ -91,7 +91,7 @@ Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
int skb_do_redirect(struct sk_buff *skb)
{
struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
@@ -2495,12 +2506,9 @@ int skb_do_redirect(struct sk_buff *skb)
@@ -2496,12 +2507,9 @@ int skb_do_redirect(struct sk_buff *skb)
if (unlikely(!dev))
goto out_drop;
if (flags & BPF_F_PEER) {
@@ -36,7 +36,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3308,6 +3308,7 @@ static inline void dev_xmit_recursion_de
@@ -3309,6 +3309,7 @@ static inline void dev_xmit_recursion_de
__this_cpu_dec(softnet_data.xmit.recursion);
}
@@ -37,7 +37,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -4580,6 +4580,9 @@ static inline void netif_addr_unlock_bh(
@@ -4581,6 +4581,9 @@ static inline void netif_addr_unlock_bh(
void ether_setup(struct net_device *dev);
@@ -109,7 +109,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
if (ret)
dev_err(dev, "Device failed to enter READY state\n");
}
@@ -1125,7 +1130,8 @@ int mhi_async_power_up(struct mhi_contro
@@ -1141,7 +1146,8 @@ int mhi_async_power_up(struct mhi_contro
if (state == MHI_STATE_SYS_ERR) {
mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET);
ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
@@ -119,7 +119,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
if (ret) {
dev_info(dev, "Failed to reset MHI due to syserr state\n");
goto error_exit;
@@ -1216,14 +1222,18 @@ EXPORT_SYMBOL_GPL(mhi_power_down);
@@ -1232,14 +1238,18 @@ EXPORT_SYMBOL_GPL(mhi_power_down);
int mhi_sync_power_up(struct mhi_controller *mhi_cntrl)
{
int ret = mhi_async_power_up(mhi_cntrl);
@@ -49,7 +49,7 @@
mutex_lock(&mhi_cntrl->pm_mutex);
@@ -820,7 +829,10 @@ void mhi_pm_st_worker(struct work_struct
@@ -836,7 +845,10 @@ void mhi_pm_st_worker(struct work_struct
mhi_pm_sys_error_transition(mhi_cntrl);
break;
case DEV_ST_TRANSITION_DISABLE:
@@ -61,7 +61,7 @@
break;
default:
break;
@@ -1174,7 +1186,8 @@ error_exit:
@@ -1190,7 +1202,8 @@ error_exit:
}
EXPORT_SYMBOL_GPL(mhi_async_power_up);
@@ -71,7 +71,7 @@
{
enum mhi_pm_state cur_state, transition_state;
struct device *dev = &mhi_cntrl->mhi_dev->dev;
@@ -1210,15 +1223,32 @@ void mhi_power_down(struct mhi_controlle
@@ -1226,15 +1239,32 @@ void mhi_power_down(struct mhi_controlle
write_unlock_irq(&mhi_cntrl->pm_lock);
mutex_unlock(&mhi_cntrl->pm_mutex);
@@ -15,7 +15,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
#include "gpiolib.h"
#include "gpiolib-of.h"
@@ -1129,3 +1131,73 @@ void of_gpiochip_remove(struct gpio_chip
@@ -1138,3 +1140,73 @@ void of_gpiochip_remove(struct gpio_chip
{
of_node_put(dev_of_node(&chip->gpiodev->dev));
}
@@ -396,7 +396,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
}
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -381,6 +381,9 @@ static struct pernet_operations ip_rt_pr
@@ -385,6 +385,9 @@ static struct pernet_operations ip_rt_pr
static int __init ip_rt_proc_init(void)
{
@@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (ret < 0)
goto out;
@@ -567,6 +573,17 @@ full_scan:
@@ -569,6 +575,17 @@ full_scan:
return err;
}
@@ -1,10 +1,8 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/dts-v1/;
#include <dt-bindings/leds/common.h>
#include "mt7981.dtsi"
#include "mt7981b.dtsi"
/ {
aliases {
@@ -0,0 +1,19 @@
Force update_cache_variants to use reset for Foresee NAND with bad blocks
Tested on Xiaomi AX3000T + F35SQA001G with bad blocks and without bad blocks
Signed-off-by: Dim Fish <dimfish@gmail.com>
--- a/drivers/mtd/nand/spi/foresee.c
+++ b/drivers/mtd/nand/spi/foresee.c
@@ -22,8 +22,8 @@ static SPINAND_OP_VARIANTS(write_cache_v
SPINAND_PROG_LOAD(true, 0, NULL, 0));
static SPINAND_OP_VARIANTS(update_cache_variants,
- SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
- SPINAND_PROG_LOAD(false, 0, NULL, 0));
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
static int f35sqa002g_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
@@ -18,7 +18,7 @@ Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -432,9 +432,7 @@ static int armada_37xx_gpio_direction_ou
@@ -433,9 +433,7 @@ static int armada_37xx_gpio_direction_ou
reg = OUTPUT_EN;
armada_37xx_update_reg(&reg, &en_offset);
@@ -1,36 +0,0 @@
From 57273ff8bb16f3842c2597b5bbcd49e7fa12edf7 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <j4g8y7@gmail.com>
Date: Wed, 14 May 2025 21:18:35 +0200
Subject: [PATCH 4/7] pinctrl: armada-37xx: propagate error from
armada_37xx_gpio_get()
The regmap_read() function can fail, so propagate its error up to
the stack instead of silently ignoring that.
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-4-07e9ac1ab737@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -440,11 +440,14 @@ static int armada_37xx_gpio_get(struct g
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
unsigned int reg = INPUT_VAL;
unsigned int val, mask;
+ int ret;
armada_37xx_update_reg(&reg, &offset);
mask = BIT(offset);
- regmap_read(info->regmap, reg, &val);
+ ret = regmap_read(info->regmap, reg, &val);
+ if (ret)
+ return ret;
return (val & mask) != 0;
}
@@ -1,42 +0,0 @@
From bfa0ff804ffa8b1246ade8be08de98c9eb19d16f Mon Sep 17 00:00:00 2001
From: Gabor Juhos <j4g8y7@gmail.com>
Date: Wed, 14 May 2025 21:18:36 +0200
Subject: [PATCH 5/7] pinctrl: armada-37xx: propagate error from
armada_37xx_pmx_gpio_set_direction()
The armada_37xx_gpio_direction_{in,out}put() functions can fail, so
propagate their error values back to the stack instead of silently
ignoring those.
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-5-07e9ac1ab737@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -472,16 +472,17 @@ static int armada_37xx_pmx_gpio_set_dire
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct gpio_chip *chip = range->gc;
+ int ret;
dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
offset, range->name, offset, input ? "input" : "output");
if (input)
- armada_37xx_gpio_direction_input(chip, offset);
+ ret = armada_37xx_gpio_direction_input(chip, offset);
else
- armada_37xx_gpio_direction_output(chip, offset, 0);
+ ret = armada_37xx_gpio_direction_output(chip, offset, 0);
- return 0;
+ return ret;
}
static int armada_37xx_gpio_request_enable(struct pinctrl_dev *pctldev,
@@ -1,35 +0,0 @@
From 6481c0a83367b0672951ccc876fbae7ee37b594b Mon Sep 17 00:00:00 2001
From: Gabor Juhos <j4g8y7@gmail.com>
Date: Wed, 14 May 2025 21:18:37 +0200
Subject: [PATCH 6/7] pinctrl: armada-37xx: propagate error from
armada_37xx_gpio_get_direction()
The regmap_read() function can fail, so propagate its error up to
the stack instead of silently ignoring that.
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-6-07e9ac1ab737@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -402,10 +402,13 @@ static int armada_37xx_gpio_get_directio
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
unsigned int reg = OUTPUT_EN;
unsigned int val, mask;
+ int ret;
armada_37xx_update_reg(&reg, &offset);
mask = BIT(offset);
- regmap_read(info->regmap, reg, &val);
+ ret = regmap_read(info->regmap, reg, &val);
+ if (ret)
+ return ret;
if (val & mask)
return GPIO_LINE_DIRECTION_OUT;
@@ -1,31 +0,0 @@
From 4229c28323db141eda69cb99427be75d3edba071 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <j4g8y7@gmail.com>
Date: Wed, 14 May 2025 21:18:38 +0200
Subject: [PATCH 7/7] pinctrl: armada-37xx: propagate error from
armada_37xx_pmx_set_by_name()
The regmap_update_bits() function can fail, so propagate its error
up to the stack instead of silently ignoring that.
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-7-07e9ac1ab737@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -358,9 +358,7 @@ static int armada_37xx_pmx_set_by_name(s
val = grp->val[func];
- regmap_update_bits(info->regmap, reg, mask, val);
-
- return 0;
+ return regmap_update_bits(info->regmap, reg, mask, val);
}
static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev,
@@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -3296,6 +3296,18 @@ static const struct usb_device_id uvc_id
@@ -3307,6 +3307,18 @@ static const struct usb_device_id uvc_id
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
+1 -5
View File
@@ -51,7 +51,6 @@ CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
CONFIG_ARM64_PTR_AUTH_KERNEL=y
CONFIG_ARM64_RAS_EXTN=y
CONFIG_ARM64_SME=y
CONFIG_ARM64_SVE=y
CONFIG_ARM64_TAGGED_ADDR_ABI=y
CONFIG_ARM64_VA_BITS=48
@@ -180,8 +179,6 @@ CONFIG_CPU_THERMAL=y
CONFIG_CRASH_CORE=y
CONFIG_CRASH_DUMP=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CRC64=y
CONFIG_CRC64_ROCKSOFT=y
CONFIG_CRC_T10DIF=y
@@ -271,7 +268,6 @@ CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ARCH_TOPOLOGY=y
@@ -594,6 +590,7 @@ CONFIG_RFKILL_FULL=y
CONFIG_RFKILL_GPIO=y
CONFIG_RFS_ACCEL=y
CONFIG_ROCKCHIP_CPUINFO=y
CONFIG_ROCKCHIP_ERRATUM_3568002=y
CONFIG_ROCKCHIP_ERRATUM_3588001=y
CONFIG_ROCKCHIP_GRF=y
CONFIG_ROCKCHIP_IODOMAIN=y
@@ -718,7 +715,6 @@ CONFIG_TYPEC_TCPM=y
# CONFIG_TYPEC_WUSB3801 is not set
# CONFIG_UCLAMP_TASK is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_UNMAP_KERNEL_AT_EL0=y
CONFIG_USB=y
CONFIG_USB_COMMON=y
@@ -0,0 +1,51 @@
From f15be3d4a0a55db2b50f319c378a2d16ceb21f86 Mon Sep 17 00:00:00 2001
From: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Date: Mon, 17 Feb 2025 01:16:33 +0300
Subject: [PATCH] arm64: dts: rockchip: rk356x: Add MSI controller node
Rockchip 356x SoC's GIC has two hardware integration issues that
affect MSI functionality of the GIC. Previously, both these GIC
issues were worked around by using MBI for MSI instead of ITS
because kernel GIC driver didn't have necessary quirks.
First issue is about RK356x GIC not supporting programmable
shareability, while reporting it as supported in a GIC's feature
register. Rockchip assigned Erratum ID #3568001 for this issue. This
patch adds dma-noncoherent property to the GIC node, denoting that a SW
workaround is required for mitigating the issue.
Second issue is about GIC AXI master interface addressing limited to
the first 4GB of physical address space. Rockchip assigned Erratum
ID #3568002 for this issue.
Now that kernel supports quirks for both of the erratums, add
MSI controller node to RK356x device-tree.
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250216221634.364158-3-dmitry.osipenko@collabora.com
---
arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -364,6 +364,18 @@
mbi-alias = <0x0 0xfd410000>;
mbi-ranges = <296 24>;
msi-controller;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-noncoherent;
+
+ its: msi-controller@fd440000 {
+ compatible = "arm,gic-v3-its";
+ reg = <0x0 0xfd440000 0 0x20000>;
+ dma-noncoherent;
+ msi-controller;
+ #msi-cells = <1>;
+ };
};
usb_host0_ehci: usb@fd800000 {
@@ -0,0 +1,28 @@
From b956c9de91757c9478e24fc9f6a57fd46f0a49f0 Mon Sep 17 00:00:00 2001
From: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Date: Mon, 17 Feb 2025 01:16:34 +0300
Subject: [PATCH] arm64: dts: rockchip: rk356x: Move PCIe MSI to use GIC
ITS instead of MBI
Rockchip 356x device-tree now supports GIC ITS. Move PCIe controller's
MSI to use ITS instead of MBI. This removes extra CPU overhead of handling
PCIe MBIs by letting GIC's ITS to serve the PCIe MSIs.
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250216221634.364158-4-dmitry.osipenko@collabora.com
---
arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -1043,7 +1043,7 @@
num-ib-windows = <6>;
num-ob-windows = <2>;
max-link-speed = <2>;
- msi-map = <0x0 &gic 0x0 0x1000>;
+ msi-map = <0x0 &its 0x0 0x1000>;
num-lanes = <1>;
phys = <&combphy2 PHY_TYPE_PCIE>;
phy-names = "pcie-phy";
@@ -1,3 +1,19 @@
From fbea35a661ed100cee2f3bab8015fb0155508106 Mon Sep 17 00:00:00 2001
From: Chukun Pan <amadeus@jmu.edu.cn>
Date: Sat, 8 Mar 2025 17:30:08 +0800
Subject: [PATCH] arm64: dts: rockchip: Move rk3568 PCIe3 MSI to use GIC ITS
Following commit b956c9de9175 ("arm64: dts: rockchip: rk356x: Move
PCIe MSI to use GIC ITS instead of MBI"), change the PCIe3 controller's
MSI on rk3568 to use ITS, so that all MSI-X can work properly.
Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
Link: https://lore.kernel.org/r/20250308093008.568437-2-amadeus@jmu.edu.cn
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm64/boot/dts/rockchip/rk3568.dtsi | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -64,7 +64,7 @@
@@ -36,42 +52,3 @@
num-lanes = <2>;
phys = <&pcie30phy>;
phy-names = "pcie-phy";
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -362,14 +362,21 @@
gic: interrupt-controller@fd400000 {
compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ interrupt-controller;
+
reg = <0x0 0xfd400000 0 0x10000>, /* GICD */
- <0x0 0xfd460000 0 0x80000>; /* GICR */
+ <0x0 0xfd460000 0 0xc0000>; /* GICR */
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-controller;
- #interrupt-cells = <3>;
- mbi-alias = <0x0 0xfd410000>;
- mbi-ranges = <296 24>;
- msi-controller;
+ its: interrupt-controller@fd440000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x0 0xfd440000 0x0 0x20000>;
+ };
};
usb_host0_ehci: usb@fd800000 {
@@ -1078,7 +1085,7 @@
num-ib-windows = <6>;
num-ob-windows = <2>;
max-link-speed = <2>;
- msi-map = <0x0 &gic 0x0 0x1000>;
+ msi-map = <0x0 &its 0x0 0x1000>;
num-lanes = <1>;
phys = <&combphy2 PHY_TYPE_PCIE>;
phy-names = "pcie-phy";
@@ -0,0 +1,337 @@
From b08e2f42e86b5848add254da45b56fc672e2bced Mon Sep 17 00:00:00 2001
From: Steven Price <steven.price@arm.com>
Date: Wed, 2 Oct 2024 15:16:29 +0100
Subject: [PATCH] irqchip/gic-v3-its: Share ITS tables with a non-trusted
hypervisor
Within a realm guest the ITS is emulated by the host. This means the
allocations must have been made available to the host by a call to
set_memory_decrypted(). Introduce an allocation function which performs
this extra call.
For the ITT use a custom genpool-based allocator that calls
set_memory_decrypted() for each page allocated, but then suballocates the
size needed for each ITT. Note that there is no mechanism implemented to
return pages from the genpool, but it is unlikely that the peak number of
devices will be much larger than the normal level - so this isn't expected
to be an issue.
Co-developed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Will Deacon <will@kernel.org>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/all/20241002141630.433502-2-steven.price@arm.com
---
drivers/irqchip/irq-gic-v3-its.c | 138 +++++++++++++++++++++++++------
1 file changed, 115 insertions(+), 23 deletions(-)
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -12,12 +12,14 @@
#include <linux/crash_dump.h>
#include <linux/delay.h>
#include <linux/efi.h>
+#include <linux/genalloc.h>
#include <linux/interrupt.h>
#include <linux/iommu.h>
#include <linux/iopoll.h>
#include <linux/irqdomain.h>
#include <linux/list.h>
#include <linux/log2.h>
+#include <linux/mem_encrypt.h>
#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/msi.h>
@@ -27,6 +29,7 @@
#include <linux/of_pci.h>
#include <linux/of_platform.h>
#include <linux/percpu.h>
+#include <linux/set_memory.h>
#include <linux/slab.h>
#include <linux/syscore_ops.h>
@@ -163,6 +166,7 @@ struct its_device {
struct its_node *its;
struct event_lpi_map event_map;
void *itt;
+ u32 itt_sz;
u32 nr_ites;
u32 device_id;
bool shared;
@@ -198,6 +202,87 @@ static DEFINE_IDA(its_vpeid_ida);
#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base)
#define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K)
+static struct page *its_alloc_pages_node(int node, gfp_t gfp,
+ unsigned int order)
+{
+ struct page *page;
+ int ret = 0;
+
+ page = alloc_pages_node(node, gfp, order);
+
+ if (!page)
+ return NULL;
+
+ ret = set_memory_decrypted((unsigned long)page_address(page),
+ 1 << order);
+ /*
+ * If set_memory_decrypted() fails then we don't know what state the
+ * page is in, so we can't free it. Instead we leak it.
+ * set_memory_decrypted() will already have WARNed.
+ */
+ if (ret)
+ return NULL;
+
+ return page;
+}
+
+static struct page *its_alloc_pages(gfp_t gfp, unsigned int order)
+{
+ return its_alloc_pages_node(NUMA_NO_NODE, gfp, order);
+}
+
+static void its_free_pages(void *addr, unsigned int order)
+{
+ /*
+ * If the memory cannot be encrypted again then we must leak the pages.
+ * set_memory_encrypted() will already have WARNed.
+ */
+ if (set_memory_encrypted((unsigned long)addr, 1 << order))
+ return;
+ free_pages((unsigned long)addr, order);
+}
+
+static struct gen_pool *itt_pool;
+
+static void *itt_alloc_pool(int node, int size)
+{
+ unsigned long addr;
+ struct page *page;
+
+ if (size >= PAGE_SIZE) {
+ page = its_alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, get_order(size));
+
+ return page ? page_address(page) : NULL;
+ }
+
+ do {
+ addr = gen_pool_alloc(itt_pool, size);
+ if (addr)
+ break;
+
+ page = its_alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 1);
+ if (!page)
+ break;
+
+ gen_pool_add(itt_pool, (unsigned long)page_address(page), PAGE_SIZE, node);
+ } while (!addr);
+
+ return (void *)addr;
+}
+
+static void itt_free_pool(void *addr, int size)
+{
+ if (!addr)
+ return;
+
+ if (size >= PAGE_SIZE) {
+ its_free_pages(addr, get_order(size));
+ return;
+ }
+
+ gen_pool_free(itt_pool, (unsigned long)addr, size);
+}
+
/*
* Skip ITSs that have no vLPIs mapped, unless we're on GICv4.1, as we
* always have vSGIs mapped.
@@ -2192,7 +2277,8 @@ static struct page *its_allocate_prop_ta
{
struct page *prop_page;
- prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
+ prop_page = its_alloc_pages(gfp_flags,
+ get_order(LPI_PROPBASE_SZ));
if (!prop_page)
return NULL;
@@ -2203,8 +2289,7 @@ static struct page *its_allocate_prop_ta
static void its_free_prop_table(struct page *prop_page)
{
- free_pages((unsigned long)page_address(prop_page),
- get_order(LPI_PROPBASE_SZ));
+ its_free_pages(page_address(prop_page), get_order(LPI_PROPBASE_SZ));
}
static bool gic_check_reserved_range(phys_addr_t addr, unsigned long size)
@@ -2326,7 +2411,7 @@ static int its_setup_baser(struct its_no
order = get_order(GITS_BASER_PAGES_MAX * psz);
}
- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
+ page = its_alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
if (!page)
return -ENOMEM;
@@ -2339,7 +2424,7 @@ static int its_setup_baser(struct its_no
/* 52bit PA is supported only when PageSize=64K */
if (psz != SZ_64K) {
pr_err("ITS: no 52bit PA support when psz=%d\n", psz);
- free_pages((unsigned long)base, order);
+ its_free_pages(base, order);
return -ENXIO;
}
@@ -2395,7 +2480,7 @@ retry_baser:
pr_err("ITS@%pa: %s doesn't stick: %llx %llx\n",
&its->phys_base, its_base_type_string[type],
val, tmp);
- free_pages((unsigned long)base, order);
+ its_free_pages(base, order);
return -ENXIO;
}
@@ -2534,8 +2619,7 @@ static void its_free_tables(struct its_n
for (i = 0; i < GITS_BASER_NR_REGS; i++) {
if (its->tables[i].base) {
- free_pages((unsigned long)its->tables[i].base,
- its->tables[i].order);
+ its_free_pages(its->tables[i].base, its->tables[i].order);
its->tables[i].base = NULL;
}
}
@@ -2801,7 +2885,7 @@ static bool allocate_vpe_l2_table(int cp
/* Allocate memory for 2nd level table */
if (!table[idx]) {
- page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(psz));
+ page = its_alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(psz));
if (!page)
return false;
@@ -2920,7 +3004,7 @@ static int allocate_vpe_l1_table(void)
pr_debug("np = %d, npg = %lld, psz = %d, epp = %d, esz = %d\n",
np, npg, psz, epp, esz);
- page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE));
+ page = its_alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE));
if (!page)
return -ENOMEM;
@@ -2966,8 +3050,7 @@ static struct page *its_allocate_pending
{
struct page *pend_page;
- pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
- get_order(LPI_PENDBASE_SZ));
+ pend_page = its_alloc_pages(gfp_flags | __GFP_ZERO, get_order(LPI_PENDBASE_SZ));
if (!pend_page)
return NULL;
@@ -2979,7 +3062,7 @@ static struct page *its_allocate_pending
static void its_free_pending_table(struct page *pt)
{
- free_pages((unsigned long)page_address(pt), get_order(LPI_PENDBASE_SZ));
+ its_free_pages(page_address(pt), get_order(LPI_PENDBASE_SZ));
}
/*
@@ -3314,8 +3397,8 @@ static bool its_alloc_table_entry(struct
/* Allocate memory for 2nd level table */
if (!table[idx]) {
- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
- get_order(baser->psz));
+ page = its_alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
+ get_order(baser->psz));
if (!page)
return false;
@@ -3410,7 +3493,6 @@ static struct its_device *its_create_dev
if (WARN_ON(!is_power_of_2(nvecs)))
nvecs = roundup_pow_of_two(nvecs);
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
/*
* Even if the device wants a single LPI, the ITT must be
* sized as a power of two (and you need at least one bit...).
@@ -3418,7 +3500,11 @@ static struct its_device *its_create_dev
nr_ites = max(2, nvecs);
sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
- itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
+
+ itt = itt_alloc_pool(its->numa_node, sz);
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+
if (alloc_lpis) {
lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis);
if (lpi_map)
@@ -3430,9 +3516,9 @@ static struct its_device *its_create_dev
lpi_base = 0;
}
- if (!dev || !itt || !col_map || (!lpi_map && alloc_lpis)) {
+ if (!dev || !itt || !col_map || (!lpi_map && alloc_lpis)) {
kfree(dev);
- kfree(itt);
+ itt_free_pool(itt, sz);
bitmap_free(lpi_map);
kfree(col_map);
return NULL;
@@ -3442,6 +3528,7 @@ static struct its_device *its_create_dev
dev->its = its;
dev->itt = itt;
+ dev->itt_sz = sz;
dev->nr_ites = nr_ites;
dev->event_map.lpi_map = lpi_map;
dev->event_map.col_map = col_map;
@@ -3469,7 +3556,7 @@ static void its_free_device(struct its_d
list_del(&its_dev->entry);
raw_spin_unlock_irqrestore(&its_dev->its->lock, flags);
kfree(its_dev->event_map.col_map);
- kfree(its_dev->itt);
+ itt_free_pool(its_dev->itt, its_dev->itt_sz);
kfree(its_dev);
}
@@ -5112,8 +5199,9 @@ static int __init its_probe_one(struct i
}
}
- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
- get_order(ITS_CMD_QUEUE_SZ));
+ page = its_alloc_pages_node(its->numa_node,
+ GFP_KERNEL | __GFP_ZERO,
+ get_order(ITS_CMD_QUEUE_SZ));
if (!page) {
err = -ENOMEM;
goto out_unmap_sgir;
@@ -5177,7 +5265,7 @@ static int __init its_probe_one(struct i
out_free_tables:
its_free_tables(its);
out_free_cmd:
- free_pages((unsigned long)its->cmd_base, get_order(ITS_CMD_QUEUE_SZ));
+ its_free_pages(its->cmd_base, get_order(ITS_CMD_QUEUE_SZ));
out_unmap_sgir:
if (its->sgir_base)
iounmap(its->sgir_base);
@@ -5659,6 +5747,10 @@ int __init its_init(struct fwnode_handle
bool has_v4_1 = false;
int err;
+ itt_pool = gen_pool_create(get_order(ITS_ITT_ALIGN), -1);
+ if (!itt_pool)
+ return -ENOMEM;
+
gic_rdists = rdists;
its_parent = parent_domain;
@@ -0,0 +1,33 @@
From bc88d44bd7e45b992cf8c2c2ffbc7bb3e24db4a7 Mon Sep 17 00:00:00 2001
From: Steven Price <steven.price@arm.com>
Date: Mon, 21 Oct 2024 11:41:05 +0100
Subject: [PATCH] irqchip/gic-v3-its: Fix over allocation in
itt_alloc_pool()
itt_alloc_pool() calls its_alloc_pages_node() to allocate an individual
page to add to the pool (for allocations <PAGE_SIZE). However the final
argument of its_alloc_pages_node() is the page order not the number of
pages. Currently it allocates two pages and leaks the second page.
Fix it by passing 0 instead (1 << 0 = 1 page).
Fixes: b08e2f42e86b ("irqchip/gic-v3-its: Share ITS tables with a non-trusted hypervisor")
Reported-by: Shanker Donthineni <sdonthineni@nvidia.com>
Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/1f6e19c4-1fb9-43ab-a8a2-a465c9cff84b@arm.com
Closes: https://lore.kernel.org/r/ed65312a-245c-4fa5-91ad-5d620cab7c6b%40nvidia.com
---
drivers/irqchip/irq-gic-v3-its.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -260,7 +260,7 @@ static void *itt_alloc_pool(int node, in
if (addr)
break;
- page = its_alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 1);
+ page = its_alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0);
if (!page)
break;
@@ -0,0 +1,105 @@
From 2d81e1bb625238d40a686ed909ff3e1abab7556a Mon Sep 17 00:00:00 2001
From: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Date: Mon, 17 Feb 2025 01:16:32 +0300
Subject: [PATCH] irqchip/gic-v3: Add Rockchip 3568002 erratum workaround
Rockchip RK3566/RK3568 GIC600 integration has DDR addressing
limited to the first 32bit of physical address space. Rockchip
assigned Erratum ID #3568002 for this issue. Add driver quirk for
this Rockchip GIC Erratum.
Note, that the 0x0201743b GIC600 ID is not Rockchip-specific and is
common for many ARM GICv3 implementations. Hence, there is an extra
of_machine_is_compatible() check.
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/all/20250216221634.364158-2-dmitry.osipenko@collabora.com
---
Documentation/arch/arm64/silicon-errata.rst | 2 ++
arch/arm64/Kconfig | 9 ++++++++
drivers/irqchip/irq-gic-v3-its.c | 23 ++++++++++++++++++++-
3 files changed, 33 insertions(+), 1 deletion(-)
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -270,6 +270,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| Rockchip | RK3588 | #3588001 | ROCKCHIP_ERRATUM_3588001 |
+----------------+-----------------+-----------------+-----------------------------+
+| Rockchip | RK3568 | #3568002 | ROCKCHIP_ERRATUM_3568002 |
++----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+
| Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 |
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1267,6 +1267,15 @@ config NVIDIA_CARMEL_CNP_ERRATUM
If unsure, say Y.
+config ROCKCHIP_ERRATUM_3568002
+ bool "Rockchip 3568002: GIC600 can not access physical addresses higher than 4GB"
+ default y
+ help
+ The Rockchip RK3566 and RK3568 GIC600 SoC integrations have AXI
+ addressing limited to the first 32bit of physical address space.
+
+ If unsure, say Y.
+
config ROCKCHIP_ERRATUM_3588001
bool "Rockchip 3588001: GIC600 can not support shareability attributes"
default y
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -202,13 +202,15 @@ static DEFINE_IDA(its_vpeid_ida);
#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base)
#define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K)
+static gfp_t gfp_flags_quirk;
+
static struct page *its_alloc_pages_node(int node, gfp_t gfp,
unsigned int order)
{
struct page *page;
int ret = 0;
- page = alloc_pages_node(node, gfp, order);
+ page = alloc_pages_node(node, gfp | gfp_flags_quirk, order);
if (!page)
return NULL;
@@ -4851,6 +4853,17 @@ static bool its_set_non_coherent(void *d
return true;
}
+static bool __maybe_unused its_enable_rk3568002(void *data)
+{
+ if (!of_machine_is_compatible("rockchip,rk3566") &&
+ !of_machine_is_compatible("rockchip,rk3568"))
+ return false;
+
+ gfp_flags_quirk |= GFP_DMA32;
+
+ return true;
+}
+
static const struct gic_quirk its_quirks[] = {
#ifdef CONFIG_CAVIUM_ERRATUM_22375
{
@@ -4910,6 +4923,14 @@ static const struct gic_quirk its_quirks
.property = "dma-noncoherent",
.init = its_set_non_coherent,
},
+#ifdef CONFIG_ROCKCHIP_ERRATUM_3568002
+ {
+ .desc = "ITS: Rockchip erratum RK3568002",
+ .iidr = 0x0201743b,
+ .mask = 0xffffffff,
+ .init = its_enable_rk3568002,
+ },
+#endif
{
}
};
@@ -103,8 +103,8 @@ Change-Id: Ia74d77b68a6303223eaccdc08e882851a917f50f
static int rk3588_otp_read(void *context, unsigned int offset,
void *val, size_t bytes)
{
@@ -274,6 +343,17 @@ static const struct rockchip_data px30_d
.reg_read = px30_otp_read,
@@ -282,6 +351,17 @@ static const struct rockchip_data rk3576
.reg_read = rk3588_otp_read,
};
+static const char * const rk3568_otp_clocks[] = {
@@ -121,8 +121,8 @@ Change-Id: Ia74d77b68a6303223eaccdc08e882851a917f50f
static const char * const rk3588_otp_clocks[] = {
"otp", "apb_pclk", "phy", "arb",
};
@@ -295,6 +375,10 @@ static const struct of_device_id rockchi
.data = &px30_data,
@@ -308,6 +388,10 @@ static const struct of_device_id rockchi
.data = &rk3576_data,
},
{
+ .compatible = "rockchip,rk3568-otp",
@@ -11,7 +11,7 @@ Change-Id: I4ec51ba8d4e1381f787c0137cb475a21e546789d
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -882,6 +882,47 @@
@@ -894,6 +894,47 @@
};
};
@@ -35,7 +35,7 @@ Signed-off-by: jensen <jensenhuang@friendlyarm.com>
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7572,7 +7572,7 @@ int stmmac_dvr_probe(struct device *devi
@@ -7577,7 +7577,7 @@ int stmmac_dvr_probe(struct device *devi
#ifdef STMMAC_VLAN_TAG_USED
/* Both mac100 and gmac support receive VLAN tag detection */
ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;
@@ -46,7 +46,7 @@ Signed-off-by: jensen <jensenhuang@friendlyarm.com>
}
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -589,6 +589,9 @@ stmmac_probe_config_dt(struct platform_d
@@ -596,6 +596,9 @@ stmmac_probe_config_dt(struct platform_d
"force_sf_dma_mode is ignored if force_thresh_dma_mode is set.\n");
}
@@ -8,15 +8,15 @@
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@@ -5381,6 +5382,7 @@ static int rtl_init_one(struct pci_dev *
@@ -5393,6 +5394,7 @@ static int rtl_init_one(struct pci_dev *
struct rtl8169_private *tp;
int jumbo_max, region, rc;
enum mac_version chipset;
struct net_device *dev;
+ const char *devname = of_get_property(pdev->dev.of_node, "label", NULL);
u32 txconfig;
u16 xid;
@@ -5388,6 +5390,9 @@ static int rtl_init_one(struct pci_dev *
@@ -5400,6 +5402,9 @@ static int rtl_init_one(struct pci_dev *
if (!dev)
return -ENOMEM;
@@ -1,6 +1,6 @@
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7398,6 +7398,7 @@ int stmmac_dvr_probe(struct device *devi
@@ -7403,6 +7403,7 @@ int stmmac_dvr_probe(struct device *devi
{
struct net_device *ndev = NULL;
struct stmmac_priv *priv;
@@ -8,7 +8,7 @@
u32 rxq;
int i, ret = 0;
@@ -7406,6 +7407,9 @@ int stmmac_dvr_probe(struct device *devi
@@ -7411,6 +7412,9 @@ int stmmac_dvr_probe(struct device *devi
if (!ndev)
return -ENOMEM;
@@ -1,161 +0,0 @@
From 536378a084c6a4148141e132efee2fa9a464e007 Mon Sep 17 00:00:00 2001
From: Peter Geis <pgwipeout@gmail.com>
Date: Thu, 3 Jun 2021 11:36:35 -0400
Subject: [PATCH] irqchip: gic-v3: add hackaround for rk3568 its
---
drivers/irqchip/irq-gic-v3-its.c | 70 +++++++++++++++++++++++++++++---
1 file changed, 65 insertions(+), 5 deletions(-)
--- a/drivers/irqchip/irq-gic-common.h
+++ b/drivers/irqchip/irq-gic-common.h
@@ -32,5 +32,6 @@ void gic_enable_of_quirks(const struct d
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
#define RDIST_FLAGS_FORCE_NON_SHAREABLE (1 << 2)
+#define RDIST_FLAGS_FORCE_NO_LOCAL_CACHE (1 << 3)
#endif /* _IRQ_GIC_COMMON_H */
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2192,6 +2192,11 @@ static struct page *its_allocate_prop_ta
{
struct page *prop_page;
+ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) {
+ pr_debug("ITS ALLOCATE PROP WORKAROUND\n");
+ gfp_flags |= GFP_DMA;
+ }
+
prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
if (!prop_page)
return NULL;
@@ -2314,6 +2319,7 @@ static int its_setup_baser(struct its_no
u64 baser_phys, tmp;
u32 alloc_pages, psz;
struct page *page;
+ gfp_t gfp_flags;
void *base;
psz = baser->psz;
@@ -2326,7 +2332,10 @@ static int its_setup_baser(struct its_no
order = get_order(GITS_BASER_PAGES_MAX * psz);
}
- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
+ gfp_flags = GFP_KERNEL | __GFP_ZERO;
+ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE)
+ gfp_flags |= GFP_DMA;
+ page = alloc_pages_node(its->numa_node, gfp_flags, order);
if (!page)
return -ENOMEM;
@@ -2966,6 +2975,10 @@ static struct page *its_allocate_pending
{
struct page *pend_page;
+ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) {
+ gfp_flags |= GFP_DMA;
+ }
+
pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
get_order(LPI_PENDBASE_SZ));
if (!pend_page)
@@ -3314,7 +3327,12 @@ static bool its_alloc_table_entry(struct
/* Allocate memory for 2nd level table */
if (!table[idx]) {
- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
+ gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO;
+ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE) {
+ gfp_flags |= GFP_DMA;
+ }
+
+ page = alloc_pages_node(its->numa_node, gfp_flags,
get_order(baser->psz));
if (!page)
return false;
@@ -3398,6 +3416,7 @@ static struct its_device *its_create_dev
unsigned long *lpi_map = NULL;
unsigned long flags;
u16 *col_map = NULL;
+ gfp_t gfp_flags;
void *itt;
int lpi_base;
int nr_lpis;
@@ -3410,7 +3429,11 @@ static struct its_device *its_create_dev
if (WARN_ON(!is_power_of_2(nvecs)))
nvecs = roundup_pow_of_two(nvecs);
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ gfp_flags = GFP_KERNEL;
+ if (gic_rdists->flags & RDIST_FLAGS_FORCE_NO_LOCAL_CACHE)
+ gfp_flags |= GFP_DMA;
+
+ dev = kzalloc(sizeof(*dev), gfp_flags);
/*
* Even if the device wants a single LPI, the ITT must be
* sized as a power of two (and you need at least one bit...).
@@ -3418,7 +3441,7 @@ static struct its_device *its_create_dev
nr_ites = max(2, nvecs);
sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
- itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
+ itt = kzalloc_node(sz, gfp_flags, its->numa_node);
if (alloc_lpis) {
lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis);
if (lpi_map)
@@ -4742,6 +4765,21 @@ static bool __maybe_unused its_enable_qu
return true;
}
+static bool __maybe_unused its_enable_rk3568001(void *data)
+{
+ struct its_node *its = data;
+
+ if (!of_machine_is_compatible("rockchip,rk3566") &&
+ !of_machine_is_compatible("rockchip,rk3568"))
+ return false;
+
+ its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
+ gic_rdists->flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE |
+ RDIST_FLAGS_FORCE_NO_LOCAL_CACHE;
+
+ return true;
+}
+
static bool __maybe_unused its_enable_rk3588001(void *data)
{
struct its_node *its = data;
@@ -4812,6 +4850,12 @@ static const struct gic_quirk its_quirks
#endif
#ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
{
+ .desc = "ITS: Rockchip erratum RK3568001",
+ .iidr = 0x0201743b,
+ .mask = 0xffffffff,
+ .init = its_enable_rk3568001,
+ },
+ {
.desc = "ITS: Rockchip erratum RK3588001",
.iidr = 0x0201743b,
.mask = 0xffffffff,
@@ -5077,6 +5121,7 @@ static int __init its_probe_one(struct i
{
u64 baser, tmp;
struct page *page;
+ gfp_t gfp_flags;
u32 ctlr;
int err;
@@ -5112,7 +5157,9 @@ static int __init its_probe_one(struct i
}
}
- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
+ gfp_flags = GFP_KERNEL | __GFP_ZERO | GFP_DMA;
+
+ page = alloc_pages_node(its->numa_node, gfp_flags,
get_order(ITS_CMD_QUEUE_SZ));
if (!page) {
err = -ENOMEM;
@@ -26,7 +26,7 @@ Signed-off-by: David Wu <david.wu@rock-chips.com>
xin24m: xin24m {
compatible = "fixed-clock";
clock-frequency = <24000000>;
@@ -423,6 +430,12 @@
@@ -428,6 +435,12 @@
status = "disabled";
};
@@ -39,7 +39,7 @@ Signed-off-by: David Wu <david.wu@rock-chips.com>
pmugrf: syscon@fdc20000 {
compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd";
reg = <0x0 0xfdc20000 0x0 0x10000>;
@@ -722,11 +735,13 @@
@@ -727,11 +740,13 @@
clocks = <&cru SCLK_GMAC1>, <&cru SCLK_GMAC1_RX_TX>,
<&cru SCLK_GMAC1_RX_TX>, <&cru CLK_MAC1_REFOUT>,
<&cru ACLK_GMAC1>, <&cru PCLK_GMAC1>,
@@ -24,7 +24,7 @@ Signed-off-by: Lin Jinhan <troy.lin@rock-chips.com>
phy-names = "usb2-phy", "usb3-phy";
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -1123,6 +1123,16 @@
@@ -1128,6 +1128,16 @@
};
};