Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: qualcomm: phy-qcom-eusb2-repeater: Zero out untouched tuning regs

The vendor kernel zeroes out all tuning data outside the init sequence
as part of initialization. Follow suit to avoid UB.

Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Link: https://lore.kernel.org/r/20230830-topic-eusb2_override-v2-3-7d8c893d93f6@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Konrad Dybcio and committed by
Vinod Koul
99a517a5 4ba2e527

+44 -14
+44 -14
drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
··· 24 24 #define EUSB2_FORCE_VAL_5 0xeD 25 25 #define V_CLK_19P2M_EN BIT(6) 26 26 27 + #define EUSB2_TUNE_USB2_CROSSOVER 0x50 27 28 #define EUSB2_TUNE_IUSB2 0x51 29 + #define EUSB2_TUNE_RES_FSDIF 0x52 30 + #define EUSB2_TUNE_HSDISC 0x53 28 31 #define EUSB2_TUNE_SQUELCH_U 0x54 32 + #define EUSB2_TUNE_USB2_SLEW 0x55 33 + #define EUSB2_TUNE_USB2_EQU 0x56 29 34 #define EUSB2_TUNE_USB2_PREEM 0x57 35 + #define EUSB2_TUNE_USB2_HS_COMP_CUR 0x58 36 + #define EUSB2_TUNE_EUSB_SLEW 0x59 37 + #define EUSB2_TUNE_EUSB_EQU 0x5A 38 + #define EUSB2_TUNE_EUSB_HS_COMP_CUR 0x5B 30 39 31 40 #define QCOM_EUSB2_REPEATER_INIT_CFG(r, v) \ 32 41 { \ ··· 44 35 } 45 36 46 37 enum reg_fields { 38 + F_TUNE_EUSB_HS_COMP_CUR, 39 + F_TUNE_EUSB_EQU, 40 + F_TUNE_EUSB_SLEW, 41 + F_TUNE_USB2_HS_COMP_CUR, 47 42 F_TUNE_USB2_PREEM, 43 + F_TUNE_USB2_EQU, 44 + F_TUNE_USB2_SLEW, 48 45 F_TUNE_SQUELCH_U, 46 + F_TUNE_HSDISC, 47 + F_TUNE_RES_FSDIF, 49 48 F_TUNE_IUSB2, 49 + F_TUNE_USB2_CROSSOVER, 50 50 F_NUM_TUNE_FIELDS, 51 51 52 52 F_FORCE_VAL_5 = F_NUM_TUNE_FIELDS, ··· 68 50 }; 69 51 70 52 static struct reg_field eusb2_repeater_tune_reg_fields[F_NUM_FIELDS] = { 53 + [F_TUNE_EUSB_HS_COMP_CUR] = REG_FIELD(EUSB2_TUNE_EUSB_HS_COMP_CUR, 0, 1), 54 + [F_TUNE_EUSB_EQU] = REG_FIELD(EUSB2_TUNE_EUSB_EQU, 0, 1), 55 + [F_TUNE_EUSB_SLEW] = REG_FIELD(EUSB2_TUNE_EUSB_SLEW, 0, 1), 56 + [F_TUNE_USB2_HS_COMP_CUR] = REG_FIELD(EUSB2_TUNE_USB2_HS_COMP_CUR, 0, 1), 71 57 [F_TUNE_USB2_PREEM] = REG_FIELD(EUSB2_TUNE_USB2_PREEM, 0, 2), 58 + [F_TUNE_USB2_EQU] = REG_FIELD(EUSB2_TUNE_USB2_EQU, 0, 1), 59 + [F_TUNE_USB2_SLEW] = REG_FIELD(EUSB2_TUNE_USB2_SLEW, 0, 1), 72 60 [F_TUNE_SQUELCH_U] = REG_FIELD(EUSB2_TUNE_SQUELCH_U, 0, 2), 61 + [F_TUNE_HSDISC] = REG_FIELD(EUSB2_TUNE_HSDISC, 0, 2), 62 + [F_TUNE_RES_FSDIF] = REG_FIELD(EUSB2_TUNE_RES_FSDIF, 0, 2), 73 63 [F_TUNE_IUSB2] = REG_FIELD(EUSB2_TUNE_IUSB2, 0, 3), 64 + [F_TUNE_USB2_CROSSOVER] = REG_FIELD(EUSB2_TUNE_USB2_CROSSOVER, 0, 2), 74 65 75 66 [F_FORCE_VAL_5] = REG_FIELD(EUSB2_FORCE_VAL_5, 0, 7), 76 67 [F_FORCE_EN_5] = REG_FIELD(EUSB2_FORCE_EN_5, 0, 7), ··· 89 62 [F_RPTR_STATUS] = REG_FIELD(EUSB2_RPTR_STATUS, 0, 7), 90 63 }; 91 64 92 - struct eusb2_repeater_init_tbl { 93 - unsigned int reg; 94 - unsigned int val; 95 - }; 96 - 97 65 struct eusb2_repeater_cfg { 98 - const struct eusb2_repeater_init_tbl *init_tbl; 66 + const u32 *init_tbl; 99 67 int init_tbl_num; 100 68 const char * const *vreg_list; 101 69 int num_vregs; ··· 109 87 "vdd18", "vdd3", 110 88 }; 111 89 112 - static const struct eusb2_repeater_init_tbl pm8550b_init_tbl[] = { 113 - QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_IUSB2, 0x8), 114 - QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_SQUELCH_U, 0x3), 115 - QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_USB2_PREEM, 0x5), 90 + static const u32 pm8550b_init_tbl[F_NUM_TUNE_FIELDS] = { 91 + [F_TUNE_IUSB2] = 0x8, 92 + [F_TUNE_SQUELCH_U] = 0x3, 93 + [F_TUNE_USB2_PREEM] = 0x5, 116 94 }; 117 95 118 96 static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { ··· 140 118 141 119 static int eusb2_repeater_init(struct phy *phy) 142 120 { 121 + struct reg_field *regfields = eusb2_repeater_tune_reg_fields; 143 122 struct eusb2_repeater *rptr = phy_get_drvdata(phy); 144 - const struct eusb2_repeater_init_tbl *init_tbl = rptr->cfg->init_tbl; 123 + const u32 *init_tbl = rptr->cfg->init_tbl; 145 124 u32 val; 146 125 int ret; 147 126 int i; ··· 153 130 154 131 regmap_field_update_bits(rptr->regs[F_EN_CTL1], EUSB2_RPTR_EN, EUSB2_RPTR_EN); 155 132 156 - for (i = 0; i < rptr->cfg->init_tbl_num; i++) 157 - regmap_field_update_bits(rptr->regs[init_tbl[i].reg], 158 - init_tbl[i].val, init_tbl[i].val); 133 + for (i = 0; i < F_NUM_TUNE_FIELDS; i++) { 134 + if (init_tbl[i]) { 135 + regmap_field_update_bits(rptr->regs[i], init_tbl[i], init_tbl[i]); 136 + } else { 137 + /* Write 0 if there's no value set */ 138 + u32 mask = GENMASK(regfields[i].msb, regfields[i].lsb); 139 + 140 + regmap_field_update_bits(rptr->regs[i], mask, 0); 141 + } 142 + } 159 143 160 144 ret = regmap_field_read_poll_timeout(rptr->regs[F_RPTR_STATUS], 161 145 val, val & RPTR_OK, 10, 5);