Skip to content

Commit 2de679e

Browse files
arndbvinodkoul
authored andcommitted
phy: stm32: work around constant-value overflow assertion
FIELD_PREP() checks that a constant fits into the available bitfield, but if one of the two lookup tables in stm32_impedance_tune() does not find a matching entry, the index is out of range, which gcc correctly complains about: In file included from <command-line>: In function 'stm32_impedance_tune', inlined from 'stm32_combophy_pll_init' at drivers/phy/st/phy-stm32-combophy.c:247:9: include/linux/compiler_types.h:517:38: error: call to '__compiletime_assert_447' declared with attribute error: FIELD_PREP: value too large for the field 517 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ^ include/linux/bitfield.h:68:3: note: in expansion of macro 'BUILD_BUG_ON_MSG' 68 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ 115 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ | ^~~~~~~~~~~~~~~~ drivers/phy/st/phy-stm32-combophy.c:162:8: note: in expansion of macro 'FIELD_PREP' 162 | FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of)); | ^~~~~~~~~~ Rework this so the field value gets set inside of the loop and otherwise set to zero. Fixes: 47e1bb6 ("phy: stm32: Add support for STM32MP25 COMBOPHY.") Signed-off-by: Arnd Bergmann <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 8886fb3 commit 2de679e

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

drivers/phy/st/phy-stm32-combophy.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,23 +122,28 @@ static int stm32_impedance_tune(struct stm32_combophy *combophy)
122122
u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
123123
u32 min_vswing = imp_lookup[0].vswing[0];
124124
u32 val;
125+
u32 regval;
125126

126127
if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
127128
if (val < min_imp || val > max_imp) {
128129
dev_err(combophy->dev, "Invalid value %u for output ohm\n", val);
129130
return -EINVAL;
130131
}
131132

132-
for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
133-
if (imp_lookup[imp_of].microohm <= val)
133+
regval = 0;
134+
for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++) {
135+
if (imp_lookup[imp_of].microohm <= val) {
136+
regval = FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of);
134137
break;
138+
}
139+
}
135140

136141
dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
137142
imp_lookup[imp_of].microohm);
138143

139144
regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
140145
STM32MP25_PCIEPRG_IMPCTRL_OHM,
141-
FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
146+
regval);
142147
} else {
143148
regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
144149
imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
@@ -150,16 +155,20 @@ static int stm32_impedance_tune(struct stm32_combophy *combophy)
150155
return -EINVAL;
151156
}
152157

153-
for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
154-
if (imp_lookup[imp_of].vswing[vswing_of] >= val)
158+
regval = 0;
159+
for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++) {
160+
if (imp_lookup[imp_of].vswing[vswing_of] >= val) {
161+
regval = FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of);
155162
break;
163+
}
164+
}
156165

157166
dev_dbg(combophy->dev, "Set %u microvolt swing\n",
158167
imp_lookup[imp_of].vswing[vswing_of]);
159168

160169
regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
161170
STM32MP25_PCIEPRG_IMPCTRL_VSWING,
162-
FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
171+
regval);
163172
}
164173

165174
return 0;

0 commit comments

Comments
 (0)