[rdkb][common][bsp][Refactor and sync kernel from openwrt]
[Description]
0dd31333 [kernel][common][mt7988][Enable MIB read feature for the Aquantia PHY driver]
659abbdf [kernel][pinctrl][Backport pinconf setting combo mode]
02a6f8ff [kernel][pinctrl][Upgrade mt7988 pinconf setting using combo]
[Release-log]
Change-Id: I53e20e8fe8a768f6324a8a0fb13761a0a0987c0f
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7981.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7981.c
index 2e91034..4f0f145 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7981.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7981.c
@@ -436,6 +436,39 @@
PIN_FIELD_BASE(39, 39, 3, 0x40, 0x10, 1, 1),
};
+static const unsigned int mt7981_pull_type[] = {
+ MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PUPD_R1R0_TYPE,/*7*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*8*/ MTK_PULL_PUPD_R1R0_TYPE,/*9*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PUPD_R1R0_TYPE,/*13*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*14*/ MTK_PULL_PUPD_R1R0_TYPE,/*15*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*16*/ MTK_PULL_PUPD_R1R0_TYPE,/*17*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
+ MTK_PULL_PU_PD_TYPE,/*40*/ MTK_PULL_PU_PD_TYPE,/*41*/
+ MTK_PULL_PU_PD_TYPE,/*42*/ MTK_PULL_PU_PD_TYPE,/*43*/
+ MTK_PULL_PU_PD_TYPE,/*44*/ MTK_PULL_PU_PD_TYPE,/*45*/
+ MTK_PULL_PU_PD_TYPE,/*46*/ MTK_PULL_PU_PD_TYPE,/*47*/
+ MTK_PULL_PU_PD_TYPE,/*48*/ MTK_PULL_PU_PD_TYPE,/*49*/
+ MTK_PULL_PU_PD_TYPE,/*50*/ MTK_PULL_PU_PD_TYPE,/*51*/
+ MTK_PULL_PU_PD_TYPE,/*52*/ MTK_PULL_PU_PD_TYPE,/*53*/
+ MTK_PULL_PU_PD_TYPE,/*54*/ MTK_PULL_PU_PD_TYPE,/*55*/
+ MTK_PULL_PU_PD_TYPE,/*56*/
+};
+
+
static const struct mtk_pin_reg_calc mt7981_reg_cals[] = {
[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7981_pin_mode_range),
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7981_pin_dir_range),
@@ -964,6 +997,9 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
+ .pull_type = mt7981_pull_type,
+ .bias_set_combo = mtk_pinconf_bias_set_combo,
+ .bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_rev1,
.drive_get = mtk_pinconf_drive_get_rev1,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7986.c
index b0f4c95..215642a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7986.c
@@ -633,6 +633,60 @@
PIN_FIELD_BASE(68, 68, 4, 0x60, 0x10, 4, 1),
};
+static const unsigned int mt7986_pull_type[] = {
+ MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PUPD_R1R0_TYPE,/*7*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*8*/ MTK_PULL_PUPD_R1R0_TYPE,/*9*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PUPD_R1R0_TYPE,/*13*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*14*/ MTK_PULL_PUPD_R1R0_TYPE,/*15*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*16*/ MTK_PULL_PUPD_R1R0_TYPE,/*17*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PUPD_R1R0_TYPE,/*63*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PU_PD_TYPE,/*69*/
+ MTK_PULL_PU_PD_TYPE,/*70*/ MTK_PULL_PU_PD_TYPE,/*71*/
+ MTK_PULL_PU_PD_TYPE,/*72*/ MTK_PULL_PU_PD_TYPE,/*73*/
+ MTK_PULL_PU_PD_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,/*75*/
+ MTK_PULL_PU_PD_TYPE,/*76*/ MTK_PULL_PU_PD_TYPE,/*77*/
+ MTK_PULL_PU_PD_TYPE,/*78*/ MTK_PULL_PU_PD_TYPE,/*79*/
+ MTK_PULL_PU_PD_TYPE,/*80*/ MTK_PULL_PU_PD_TYPE,/*81*/
+ MTK_PULL_PU_PD_TYPE,/*82*/ MTK_PULL_PU_PD_TYPE,/*83*/
+ MTK_PULL_PU_PD_TYPE,/*84*/ MTK_PULL_PU_PD_TYPE,/*85*/
+ MTK_PULL_PU_PD_TYPE,/*86*/ MTK_PULL_PU_PD_TYPE,/*87*/
+ MTK_PULL_PU_PD_TYPE,/*88*/ MTK_PULL_PU_PD_TYPE,/*89*/
+ MTK_PULL_PU_PD_TYPE,/*90*/ MTK_PULL_PU_PD_TYPE,/*91*/
+ MTK_PULL_PU_PD_TYPE,/*92*/ MTK_PULL_PU_PD_TYPE,/*93*/
+ MTK_PULL_PU_PD_TYPE,/*94*/ MTK_PULL_PU_PD_TYPE,/*95*/
+ MTK_PULL_PU_PD_TYPE,/*96*/ MTK_PULL_PU_PD_TYPE,/*97*/
+ MTK_PULL_PU_PD_TYPE,/*98*/ MTK_PULL_PU_PD_TYPE,/*99*/
+ MTK_PULL_PU_PD_TYPE,/*100*/
+};
+
static const struct mtk_pin_reg_calc mt7986_reg_cals[] = {
[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range),
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range),
@@ -1065,6 +1119,9 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
+ .pull_type = mt7986_pull_type,
+ .bias_set_combo = mtk_pinconf_bias_set_combo,
+ .bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_rev1,
.drive_get = mtk_pinconf_drive_get_rev1,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c
index 49c0be1..2fe1746 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c
@@ -596,6 +596,51 @@
PIN_FIELD_BASE(83, 83, 1, 0x90, 0x10, 15, 1),
};
+static const unsigned int mt7988_pull_type[] = {
+ MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PU_PD_TYPE, /*7*/
+ MTK_PULL_PU_PD_TYPE, /*8*/ MTK_PULL_PU_PD_TYPE, /*9*/
+ MTK_PULL_PU_PD_TYPE, /*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PU_PD_TYPE, /*13*/
+ MTK_PULL_PU_PD_TYPE, /*14*/ MTK_PULL_PD_TYPE, /*15*/
+ MTK_PULL_PD_TYPE, /*16*/ MTK_PULL_PD_TYPE, /*17*/
+ MTK_PULL_PD_TYPE, /*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PU_PD_TYPE, /*63*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PUPD_R1R0_TYPE,/*69*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*70*/ MTK_PULL_PD_TYPE, /*71*/
+ MTK_PULL_PD_TYPE, /*72*/ MTK_PULL_PUPD_R1R0_TYPE,/*73*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE, /*75*/
+ MTK_PULL_PU_PD_TYPE, /*76*/ MTK_PULL_PU_PD_TYPE, /*77*/
+ MTK_PULL_PU_PD_TYPE, /*78*/ MTK_PULL_PU_PD_TYPE, /*79*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*80*/ MTK_PULL_PUPD_R1R0_TYPE,/*81*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*82*/ MTK_PULL_PUPD_R1R0_TYPE,/*83*/
+};
+
static const struct mtk_pin_reg_calc mt7988_reg_cals[] = {
[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7988_pin_mode_range),
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7988_pin_dir_range),
@@ -1433,6 +1478,9 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
+ .pull_type = mt7988_pull_type,
+ .bias_set_combo = mtk_pinconf_bias_set_combo,
+ .bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_rev1,
.drive_get = mtk_pinconf_drive_get_rev1,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
index d661a18..fb27f0d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
@@ -7,6 +7,7 @@
CONFIG_AQUANTIA_PHY_FW_DOWNLOAD_GANG=y
# CONFIG_AQUANTIA_PHY_FW_DOWNLOAD_SINGLE is not set
CONFIG_AQUANTIA_PHY_FW_FILE="Rhe-05.06-Candidate9-AQR_Mediatek_23B_P5_ID45824_LCLVER1.cld"
+CONFIG_AQUANTIA_PHY_MIB=y
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1000-backport-pinctrl-pinconf-setting-combo.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1000-backport-pinctrl-pinconf-setting-combo.patch
new file mode 100644
index 0000000..43ca0c5
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1000-backport-pinctrl-pinconf-setting-combo.patch
@@ -0,0 +1,632 @@
+--- a/drivers/pinctrl/mediatek/pinctrl-moore.c
++++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
+@@ -99,14 +99,22 @@ static int mtk_pinconf_get(struct pinctr
+ {
+ struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+ u32 param = pinconf_to_config_param(*config);
+- int val, val2, err, reg, ret = 1;
++ int val, val2, err, pullup, reg, ret = 1;
+ const struct mtk_pin_desc *desc;
+
+ desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
++ if (!desc->name)
++ return -ENOTSUPP;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+- if (hw->soc->bias_disable_get) {
++ if (hw->soc->bias_get_combo) {
++ err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
++ if (err)
++ return err;
++ if (ret != MTK_PUPD_SET_R1R0_00 && ret != MTK_DISABLE)
++ return -EINVAL;
++ } else if (hw->soc->bias_disable_get) {
+ err = hw->soc->bias_disable_get(hw, desc, &ret);
+ if (err)
+ return err;
+@@ -115,7 +123,15 @@ static int mtk_pinconf_get(struct pinctr
+ }
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+- if (hw->soc->bias_get) {
++ if (hw->soc->bias_get_combo) {
++ err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
++ if (err)
++ return err;
++ if (ret == MTK_PUPD_SET_R1R0_00 || ret == MTK_DISABLE)
++ return -EINVAL;
++ if (!pullup)
++ return -EINVAL;
++ } else if (hw->soc->bias_get) {
+ err = hw->soc->bias_get(hw, desc, 1, &ret);
+ if (err)
+ return err;
+@@ -124,7 +140,15 @@ static int mtk_pinconf_get(struct pinctr
+ }
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+- if (hw->soc->bias_get) {
++ if (hw->soc->bias_get_combo) {
++ err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
++ if (err)
++ return err;
++ if (ret == MTK_PUPD_SET_R1R0_00 || ret == MTK_DISABLE)
++ return -EINVAL;
++ if (pullup)
++ return -EINVAL;
++ } else if (hw->soc->bias_get) {
+ err = hw->soc->bias_get(hw, desc, 0, &ret);
+ if (err)
+ return err;
+@@ -218,14 +242,19 @@ static int mtk_pinconf_set(struct pinctr
+ int cfg, err = 0;
+
+ desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
++ if (!desc->name)
++ return -ENOTSUPP;
+
+ for (cfg = 0; cfg < num_configs; cfg++) {
+ param = pinconf_to_config_param(configs[cfg]);
+ arg = pinconf_to_config_argument(configs[cfg]);
+-
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+- if (hw->soc->bias_disable_set) {
++ if (hw->soc->bias_set_combo) {
++ err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
++ if (err)
++ return err;
++ } else if (hw->soc->bias_disable_set) {
+ err = hw->soc->bias_disable_set(hw, desc);
+ if (err)
+ return err;
+@@ -234,7 +263,11 @@ static int mtk_pinconf_set(struct pinctr
+ }
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+- if (hw->soc->bias_set) {
++ if (hw->soc->bias_set_combo) {
++ err = hw->soc->bias_set_combo(hw, desc, 1, arg);
++ if (err)
++ return err;
++ } else if (hw->soc->bias_set) {
+ err = hw->soc->bias_set(hw, desc, 1);
+ if (err)
+ return err;
+@@ -243,7 +276,11 @@ static int mtk_pinconf_set(struct pinctr
+ }
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+- if (hw->soc->bias_set) {
++ if (hw->soc->bias_set_combo) {
++ err = hw->soc->bias_set_combo(hw, desc, 0, arg);
++ if (err)
++ return err;
++ } else if (hw->soc->bias_set) {
+ err = hw->soc->bias_set(hw, desc, 0);
+ if (err)
+ return err;
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -506,6 +506,404 @@ int mtk_pinconf_bias_get_rev1(struct mtk
+ return 0;
+ }
+
++/* Combo for the following pull register type:
++ * 1. PU + PD
++ * 2. PULLSEL + PULLEN
++ * 3. PUPD + R0 + R1
++ */
++static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 pullup, u32 arg)
++{
++ int err, pu, pd;
++
++ if (arg == MTK_DISABLE) {
++ pu = 0;
++ pd = 0;
++ } else if ((arg == MTK_ENABLE) && pullup) {
++ pu = 1;
++ pd = 0;
++ } else if ((arg == MTK_ENABLE) && !pullup) {
++ pu = 0;
++ pd = 1;
++ } else {
++ err = -EINVAL;
++ goto out;
++ }
++
++ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
++ if (err)
++ goto out;
++
++ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
++
++out:
++ return err;
++}
++
++static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 pullup, u32 arg)
++{
++ int err, enable;
++
++ if (arg == MTK_DISABLE)
++ enable = 0;
++ else if (arg == MTK_ENABLE)
++ enable = 1;
++ else {
++ err = -EINVAL;
++ goto out;
++ }
++
++ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
++ if (err)
++ goto out;
++
++ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
++
++out:
++ return err;
++}
++
++static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 pullup, u32 arg)
++{
++ int err, r0, r1;
++
++ if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
++ pullup = 0;
++ r0 = 0;
++ r1 = 0;
++ } else if (arg == MTK_PUPD_SET_R1R0_01) {
++ r0 = 1;
++ r1 = 0;
++ } else if (arg == MTK_PUPD_SET_R1R0_10) {
++ r0 = 0;
++ r1 = 1;
++ } else if (arg == MTK_PUPD_SET_R1R0_11) {
++ r0 = 1;
++ r1 = 1;
++ } else {
++ err = -EINVAL;
++ goto out;
++ }
++
++ /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
++ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
++ if (err)
++ goto out;
++
++ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
++ if (err)
++ goto out;
++
++ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
++
++out:
++ return err;
++}
++
++static int mtk_hw_pin_rsel_lookup(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 pullup, u32 arg, u32 *rsel_val)
++{
++ const struct mtk_pin_rsel *rsel;
++ int check;
++ bool found = false;
++
++ rsel = hw->soc->pin_rsel;
++
++ for (check = 0; check <= hw->soc->npin_rsel - 1; check++) {
++ if (desc->number >= rsel[check].s_pin &&
++ desc->number <= rsel[check].e_pin) {
++ if (pullup) {
++ if (rsel[check].up_rsel == arg) {
++ found = true;
++ *rsel_val = rsel[check].rsel_index;
++ break;
++ }
++ } else {
++ if (rsel[check].down_rsel == arg) {
++ found = true;
++ *rsel_val = rsel[check].rsel_index;
++ break;
++ }
++ }
++ }
++ }
++
++ if (!found) {
++ dev_err(hw->dev, "Not support rsel value %d Ohm for pin = %d (%s)\n",
++ arg, desc->number, desc->name);
++ return -ENOTSUPP;
++ }
++
++ return 0;
++}
++
++static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 pullup, u32 arg)
++{
++ int err, rsel_val;
++
++ if (!pullup && arg == MTK_DISABLE)
++ return 0;
++
++ if (hw->rsel_si_unit) {
++ /* find pin rsel_index from pin_rsel array*/
++ err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val);
++ if (err)
++ goto out;
++ } else {
++ if (arg < MTK_PULL_SET_RSEL_000 ||
++ arg > MTK_PULL_SET_RSEL_111) {
++ err = -EINVAL;
++ goto out;
++ }
++
++ rsel_val = arg - MTK_PULL_SET_RSEL_000;
++ }
++
++ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
++ if (err)
++ goto out;
++
++ err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, MTK_ENABLE);
++
++out:
++ return err;
++}
++
++int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 pullup, u32 arg)
++{
++ int err = -ENOTSUPP;
++ u32 try_all_type;
++
++ if (hw->soc->pull_type)
++ try_all_type = hw->soc->pull_type[desc->number];
++ else
++ try_all_type = MTK_PULL_TYPE_MASK;
++
++ if (try_all_type & MTK_PULL_RSEL_TYPE) {
++ err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
++ if (!err)
++ return err;
++ }
++
++ if (try_all_type & MTK_PULL_PU_PD_TYPE) {
++ err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
++ if (!err)
++ return err;
++ }
++
++ if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
++ err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc,
++ pullup, arg);
++ if (!err)
++ return err;
++ }
++
++ if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
++ err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
++
++ if (err)
++ dev_err(hw->dev, "Invalid pull argument\n");
++
++ return err;
++}
++EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
++
++static int mtk_rsel_get_si_unit(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 pullup, u32 rsel_val, u32 *si_unit)
++{
++ const struct mtk_pin_rsel *rsel;
++ int check;
++
++ rsel = hw->soc->pin_rsel;
++
++ for (check = 0; check <= hw->soc->npin_rsel - 1; check++) {
++ if (desc->number >= rsel[check].s_pin &&
++ desc->number <= rsel[check].e_pin) {
++ if (rsel_val == rsel[check].rsel_index) {
++ if (pullup)
++ *si_unit = rsel[check].up_rsel;
++ else
++ *si_unit = rsel[check].down_rsel;
++ break;
++ }
++ }
++ }
++
++ return 0;
++}
++
++static int mtk_pinconf_bias_get_rsel(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 *pullup, u32 *enable)
++{
++ int pu, pd, rsel, err;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_RSEL, &rsel);
++ if (err)
++ goto out;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
++ if (err)
++ goto out;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
++ if (err)
++ goto out;
++
++ if (pu == 0 && pd == 0) {
++ *pullup = 0;
++ *enable = MTK_DISABLE;
++ } else if (pu == 1 && pd == 0) {
++ *pullup = 1;
++ if (hw->rsel_si_unit)
++ mtk_rsel_get_si_unit(hw, desc, *pullup, rsel, enable);
++ else
++ *enable = rsel + MTK_PULL_SET_RSEL_000;
++ } else if (pu == 0 && pd == 1) {
++ *pullup = 0;
++ if (hw->rsel_si_unit)
++ mtk_rsel_get_si_unit(hw, desc, *pullup, rsel, enable);
++ else
++ *enable = rsel + MTK_PULL_SET_RSEL_000;
++ } else {
++ err = -EINVAL;
++ goto out;
++ }
++
++out:
++ return err;
++}
++
++static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 *pullup, u32 *enable)
++{
++ int err, pu, pd;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
++ if (err)
++ goto out;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
++ if (err)
++ goto out;
++
++ if (pu == 0 && pd == 0) {
++ *pullup = 0;
++ *enable = MTK_DISABLE;
++ } else if (pu == 1 && pd == 0) {
++ *pullup = 1;
++ *enable = MTK_ENABLE;
++ } else if (pu == 0 && pd == 1) {
++ *pullup = 0;
++ *enable = MTK_ENABLE;
++ } else
++ err = -EINVAL;
++
++out:
++ return err;
++}
++
++static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 *pullup, u32 *enable)
++{
++ int err;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
++ if (err)
++ goto out;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
++
++out:
++ return err;
++}
++
++static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 *pullup, u32 *enable)
++{
++ int err, r0, r1;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
++ if (err)
++ goto out;
++ /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
++ *pullup = !(*pullup);
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
++ if (err)
++ goto out;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
++ if (err)
++ goto out;
++
++ if ((r1 == 0) && (r0 == 0))
++ *enable = MTK_PUPD_SET_R1R0_00;
++ else if ((r1 == 0) && (r0 == 1))
++ *enable = MTK_PUPD_SET_R1R0_01;
++ else if ((r1 == 1) && (r0 == 0))
++ *enable = MTK_PUPD_SET_R1R0_10;
++ else if ((r1 == 1) && (r0 == 1))
++ *enable = MTK_PUPD_SET_R1R0_11;
++ else
++ err = -EINVAL;
++
++out:
++ return err;
++}
++
++int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 *pullup, u32 *enable)
++{
++ int err = -ENOTSUPP;
++ u32 try_all_type;
++
++ if (hw->soc->pull_type)
++ try_all_type = hw->soc->pull_type[desc->number];
++ else
++ try_all_type = MTK_PULL_TYPE_MASK;
++
++ if (try_all_type & MTK_PULL_RSEL_TYPE) {
++ err = mtk_pinconf_bias_get_rsel(hw, desc, pullup, enable);
++ if (!err)
++ return err;
++ }
++
++ if (try_all_type & MTK_PULL_PU_PD_TYPE) {
++ err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
++ if (!err)
++ return err;
++ }
++
++ if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
++ err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc,
++ pullup, enable);
++ if (!err)
++ return err;
++ }
++
++ if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
++ err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
++
++ return err;
++}
++EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
++
+ /* Revision 0 */
+ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 arg)
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+@@ -17,6 +17,34 @@
+ #define MTK_ENABLE 1
+ #define MTK_PULLDOWN 0
+ #define MTK_PULLUP 1
++#define MTK_PULL_PU_PD_TYPE BIT(0)
++#define MTK_PULL_PULLSEL_TYPE BIT(1)
++#define MTK_PULL_PUPD_R1R0_TYPE BIT(2)
++/* MTK_PULL_RSEL_TYPE can select resistance and can be
++ * turned on/off itself. But it can't be selected pull up/down
++ */
++#define MTK_PULL_RSEL_TYPE BIT(3)
++/* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by
++ * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE.
++ */
++#define MTK_PULL_PU_PD_RSEL_TYPE (MTK_PULL_PU_PD_TYPE \
++ | MTK_PULL_RSEL_TYPE)
++#define MTK_PULL_TYPE_MASK (MTK_PULL_PU_PD_TYPE |\
++ MTK_PULL_PULLSEL_TYPE |\
++ MTK_PULL_PUPD_R1R0_TYPE |\
++ MTK_PULL_RSEL_TYPE)
++#define MTK_PUPD_SET_R1R0_00 100
++#define MTK_PUPD_SET_R1R0_01 101
++#define MTK_PUPD_SET_R1R0_10 102
++#define MTK_PUPD_SET_R1R0_11 103
++#define MTK_PULL_SET_RSEL_000 200
++#define MTK_PULL_SET_RSEL_001 201
++#define MTK_PULL_SET_RSEL_010 202
++#define MTK_PULL_SET_RSEL_011 203
++#define MTK_PULL_SET_RSEL_100 204
++#define MTK_PULL_SET_RSEL_101 205
++#define MTK_PULL_SET_RSEL_110 206
++#define MTK_PULL_SET_RSEL_111 207
+
+ #define EINT_NA U16_MAX
+ #define NO_EINT_SUPPORT EINT_NA
+@@ -66,6 +94,8 @@ enum {
+ PINCTRL_PIN_REG_DRV_EN,
+ PINCTRL_PIN_REG_DRV_E0,
+ PINCTRL_PIN_REG_DRV_E1,
++ PINCTRL_PIN_REG_DRV_ADV,
++ PINCTRL_PIN_REG_RSEL,
+ PINCTRL_PIN_REG_MAX,
+ };
+
+@@ -101,6 +131,22 @@ struct mtk_pin_field {
+ u8 next;
+ };
+
++/**
++ * struct mtk_pin_rsel - the structure that provides bias resistance selection.
++ * @s_pin: the start pin within the rsel range
++ * @e_pin: the end pin within the rsel range
++ * @rsel_index: the rsel bias resistance index
++ * @up_rsel: the pullup rsel bias resistance value
++ * @down_rsel: the pulldown rsel bias resistance value
++ */
++struct mtk_pin_rsel {
++ u16 s_pin;
++ u16 e_pin;
++ u16 rsel_index;
++ u32 up_rsel;
++ u32 down_rsel;
++};
++
+ /* struct mtk_pin_field_calc - the structure that holds the range providing
+ * the guide used to look up the relevant field
+ * @s_pin: the start pin within the range
+@@ -205,6 +251,9 @@ struct mtk_pin_soc {
+ bool ies_present;
+ const char * const *base_names;
+ unsigned int nbase_names;
++ const unsigned int *pull_type;
++ const struct mtk_pin_rsel *pin_rsel;
++ unsigned int npin_rsel;
+
+ /* Specific pinconfig operations */
+ int (*bias_disable_set)(struct mtk_pinctrl *hw,
+@@ -215,7 +264,10 @@ struct mtk_pin_soc {
+ const struct mtk_pin_desc *desc, bool pullup);
+ int (*bias_get)(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, bool pullup, int *res);
+-
++ int (*bias_set_combo)(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
++ int (*bias_get_combo)(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
+ int (*drive_set)(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 arg);
+ int (*drive_get)(struct mtk_pinctrl *hw,
+@@ -246,6 +298,10 @@ struct mtk_pinctrl {
+ struct mtk_eint *eint;
+ struct mtk_pinctrl_group *groups;
+ const char **grp_names;
++ /* lock pin's register resource to avoid multiple threads issue*/
++ spinlock_t lock;
++ /* identify rsel setting by si unit or rsel define in dts node */
++ bool rsel_si_unit;
+ };
+
+ void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set);
+@@ -282,7 +338,12 @@ int mtk_pinconf_drive_set(struct mtk_pin
+ const struct mtk_pin_desc *desc, u32 arg);
+ int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, int *val);
+-
++int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 pullup, u32 enable);
++int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 *pullup, u32 *enable);
+ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 arg);
+ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2023-pinctrl-add-mt7988-pd-pulltype-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2023-pinctrl-add-mt7988-pd-pulltype-support.patch
new file mode 100644
index 0000000..6ef9357
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2023-pinctrl-add-mt7988-pd-pulltype-support.patch
@@ -0,0 +1,99 @@
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -541,6 +541,30 @@ out:
+ return err;
+ }
+
++static int mtk_pinconf_bias_set_pd(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 pullup, u32 arg)
++{
++ int err, pd;
++
++ if (arg == MTK_DISABLE)
++ pd = 0;
++ else if ((arg == MTK_ENABLE) && pullup)
++ pd = 0;
++ else if ((arg == MTK_ENABLE) && !pullup)
++ pd = 1;
++ else {
++ err = -EINVAL;
++ goto out;
++ }
++
++ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
++
++out:
++ return err;
++
++}
++
+ static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+@@ -695,6 +719,12 @@ int mtk_pinconf_bias_set_combo(struct mt
+ return err;
+ }
+
++ if (try_all_type & MTK_PULL_PD_TYPE) {
++ err = mtk_pinconf_bias_set_pd(hw, desc, pullup, arg);
++ if (!err)
++ return err;
++ }
++
+ if (try_all_type & MTK_PULL_PU_PD_TYPE) {
+ err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+ if (!err)
+@@ -815,6 +845,29 @@ out:
+ return err;
+ }
+
++static int mtk_pinconf_bias_get_pd(struct mtk_pinctrl *hw,
++ const struct mtk_pin_desc *desc,
++ u32 *pullup, u32 *enable)
++{
++ int err, pd;
++
++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
++ if (err)
++ goto out;
++
++ if (pd == 0) {
++ *pullup = 0;
++ *enable = MTK_DISABLE;
++ } else if (pd == 1) {
++ *pullup = 0;
++ *enable = MTK_ENABLE;
++ } else
++ err = -EINVAL;
++
++out:
++ return err;
++}
++
+ static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
+@@ -883,6 +936,12 @@ int mtk_pinconf_bias_get_combo(struct mt
+ if (!err)
+ return err;
+ }
++
++ if (try_all_type & MTK_PULL_PD_TYPE) {
++ err = mtk_pinconf_bias_get_pd(hw, desc, pullup, enable);
++ if (!err)
++ return err;
++ }
+
+ if (try_all_type & MTK_PULL_PU_PD_TYPE) {
+ err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+@@ -24,6 +24,7 @@
+ * turned on/off itself. But it can't be selected pull up/down
+ */
+ #define MTK_PULL_RSEL_TYPE BIT(3)
++#define MTK_PULL_PD_TYPE BIT(4)
+ /* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by
+ * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE.
+ */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
index 3fce397..1fe0212 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
@@ -35,6 +35,7 @@
file://1010-pcie-mediatek-fix-clearing-interrupt-status.patch \
file://1020-spi-nor-w25q512jv.patch \
file://1021-ubnt-ledbar-driver.patch \
+ file://999-1000-backport-pinctrl-pinconf-setting-combo.patch \
file://999-1600-mdiobus-add-c45.patch \
file://999-1700-macsec-revert-async-support.patch \
file://999-1701-add-default-setting-to-dsa-unused-port.patch \
@@ -58,6 +59,7 @@
file://999-2020-pinctrl-add-mt7986-driver.patch \
file://999-2021-pinctrl-enable-mt7988-pinctrl-config.patch \
file://999-2022-pinctrl-add-mt7981-driver.patch \
+ file://999-2023-pinctrl-add-mt7988-pd-pulltype-support.patch \
file://999-2040-powerdomain-add-mt7988-support.patch \
file://999-2050-watchdog-add-mt7986-assert.patch \
file://999-2100-mt7986-trng-add-rng-support.patch \