Hi Neil, I love your patch! Perhaps something to improve: [auto build test WARNING on linuxtv-media/master] [also build test WARNING on v5.1-rc4 next-20190408] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Neil-Armstrong/media-dt-bindings-media-meson-ao-cec-Add-G12A-AO-CEC-B-Compatible/20190408-233912 base: git://linuxtv.org/media_tree.git master config: sparc64-allmodconfig (attached as .config) compiler: sparc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=sparc64 All warnings (new ones prefixed by >>): drivers/media/platform/meson/ao-cec-g12a.c:206:16: error: field 'hw' has incomplete type struct clk_hw hw; ^~ In file included from include/linux/build_bug.h:5:0, from include/linux/bitfield.h:18, from drivers/media/platform/meson/ao-cec-g12a.c:10: drivers/media/platform/meson/ao-cec-g12a.c: In function 'meson_ao_cec_g12a_dualdiv_clk_recalc_rate': include/linux/kernel.h:979:32: error: dereferencing pointer to incomplete type 'struct clk_hw' BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ ^~~~~~ include/linux/compiler.h:324:9: note: in definition of macro '__compiletime_assert' if (!(condition)) \ ^~~~~~~~~ include/linux/compiler.h:344:2: note: in expansion of macro '_compiletime_assert' _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^~~~~~~~~~~~~~~~~~~ include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert' #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) ^~~~~~~~~~~~~~~~~~ include/linux/kernel.h:979:2: note: in expansion of macro 'BUILD_BUG_ON_MSG' BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ ^~~~~~~~~~~~~~~~ include/linux/kernel.h:979:20: note: in expansion of macro '__same_type' BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ ^~~~~~~~~~~ >> drivers/media/platform/meson/ao-cec-g12a.c:211:2: note: in expansion of macro 'container_of' container_of(_hw, struct meson_ao_cec_g12a_dualdiv_clk, hw) \ ^~~~~~~~~~~~ >> drivers/media/platform/meson/ao-cec-g12a.c:218:3: note: in expansion of macro 'hw_to_meson_ao_cec_g12a_dualdiv_clk' hw_to_meson_ao_cec_g12a_dualdiv_clk(hw); ^ drivers/media/platform/meson/ao-cec-g12a.c: At top level: drivers/media/platform/meson/ao-cec-g12a.c:317:21: error: variable 'meson_ao_cec_g12a_dualdiv_clk_ops' has initializer but incomplete type static const struct clk_ops meson_ao_cec_g12a_dualdiv_clk_ops = { ^~~~~~~ drivers/media/platform/meson/ao-cec-g12a.c:318:3: error: 'const struct clk_ops' has no member named 'recalc_rate' .recalc_rate = meson_ao_cec_g12a_dualdiv_clk_recalc_rate, ^~~~~~~~~~~ drivers/media/platform/meson/ao-cec-g12a.c:318:17: warning: excess elements in struct initializer .recalc_rate = meson_ao_cec_g12a_dualdiv_clk_recalc_rate, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/media/platform/meson/ao-cec-g12a.c:318:17: note: (near initialization for 'meson_ao_cec_g12a_dualdiv_clk_ops') drivers/media/platform/meson/ao-cec-g12a.c:319:3: error: 'const struct clk_ops' has no member named 'is_enabled' .is_enabled = meson_ao_cec_g12a_dualdiv_clk_is_enabled, ^~~~~~~~~~ drivers/media/platform/meson/ao-cec-g12a.c:319:16: warning: excess elements in struct initializer .is_enabled = meson_ao_cec_g12a_dualdiv_clk_is_enabled, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/media/platform/meson/ao-cec-g12a.c:319:16: note: (near initialization for 'meson_ao_cec_g12a_dualdiv_clk_ops') drivers/media/platform/meson/ao-cec-g12a.c:320:3: error: 'const struct clk_ops' has no member named 'enable' .enable = meson_ao_cec_g12a_dualdiv_clk_enable, ^~~~~~ drivers/media/platform/meson/ao-cec-g12a.c:320:13: warning: excess elements in struct initializer .enable = meson_ao_cec_g12a_dualdiv_clk_enable, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/media/platform/meson/ao-cec-g12a.c:320:13: note: (near initialization for 'meson_ao_cec_g12a_dualdiv_clk_ops') drivers/media/platform/meson/ao-cec-g12a.c:321:3: error: 'const struct clk_ops' has no member named 'disable' .disable = meson_ao_cec_g12a_dualdiv_clk_disable, ^~~~~~~ drivers/media/platform/meson/ao-cec-g12a.c:321:13: warning: excess elements in struct initializer .disable = meson_ao_cec_g12a_dualdiv_clk_disable, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/media/platform/meson/ao-cec-g12a.c:321:13: note: (near initialization for 'meson_ao_cec_g12a_dualdiv_clk_ops') drivers/media/platform/meson/ao-cec-g12a.c: In function 'meson_ao_cec_g12a_setup_clk': drivers/media/platform/meson/ao-cec-g12a.c:328:23: error: storage size of 'init' isn't known struct clk_init_data init; ^~~~ drivers/media/platform/meson/ao-cec-g12a.c:341:16: error: implicit declaration of function '__clk_get_name'; did you mean 'clk_get_rate'? [-Werror=implicit-function-declaration] parent_name = __clk_get_name(ao_cec->oscin); ^~~~~~~~~~~~~~ clk_get_rate >> drivers/media/platform/meson/ao-cec-g12a.c:341:14: warning: assignment makes pointer from integer without a cast [-Wint-conversion] parent_name = __clk_get_name(ao_cec->oscin); ^ drivers/media/platform/meson/ao-cec-g12a.c:351:8: error: implicit declaration of function 'devm_clk_register'; did you mean 'device_register'? [-Werror=implicit-function-declaration] clk = devm_clk_register(dev, &dualdiv_clk->hw); ^~~~~~~~~~~~~~~~~ device_register drivers/media/platform/meson/ao-cec-g12a.c:328:23: warning: unused variable 'init' [-Wunused-variable] struct clk_init_data init; ^~~~ drivers/media/platform/meson/ao-cec-g12a.c: At top level: drivers/media/platform/meson/ao-cec-g12a.c:317:29: error: storage size of 'meson_ao_cec_g12a_dualdiv_clk_ops' isn't known static const struct clk_ops meson_ao_cec_g12a_dualdiv_clk_ops = { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +/container_of +211 drivers/media/platform/meson/ao-cec-g12a.c 209 210 #define hw_to_meson_ao_cec_g12a_dualdiv_clk(_hw) \ > 211 container_of(_hw, struct meson_ao_cec_g12a_dualdiv_clk, hw) \ 212 213 static unsigned long 214 meson_ao_cec_g12a_dualdiv_clk_recalc_rate(struct clk_hw *hw, 215 unsigned long parent_rate) 216 { 217 struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk = > 218 hw_to_meson_ao_cec_g12a_dualdiv_clk(hw); 219 unsigned long n1; 220 u32 reg0, reg1; 221 222 regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, ®0); 223 regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, ®1); 224 225 if (reg1 & CECB_CLK_CNTL_BYPASS_EN) 226 return parent_rate; 227 228 if (reg0 & CECB_CLK_CNTL_DUAL_EN) { 229 unsigned long n2, m1, m2, f1, f2, p1, p2; 230 231 n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1; 232 n2 = FIELD_GET(CECB_CLK_CNTL_N2, reg0) + 1; 233 234 m1 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1; 235 m2 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1; 236 237 f1 = DIV_ROUND_CLOSEST(parent_rate, n1); 238 f2 = DIV_ROUND_CLOSEST(parent_rate, n2); 239 240 p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2)); 241 p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2)); 242 243 return DIV_ROUND_UP(100000000, p1 + p2); 244 } 245 246 n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1; 247 248 return DIV_ROUND_CLOSEST(parent_rate, n1); 249 } 250 251 static int meson_ao_cec_g12a_dualdiv_clk_enable(struct clk_hw *hw) 252 { 253 struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk = 254 hw_to_meson_ao_cec_g12a_dualdiv_clk(hw); 255 256 257 /* Disable Input & Output */ 258 regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, 259 CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN, 260 0); 261 262 /* Set N1 & N2 */ 263 regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, 264 CECB_CLK_CNTL_N1, 265 FIELD_PREP(CECB_CLK_CNTL_N1, 733 - 1)); 266 267 regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, 268 CECB_CLK_CNTL_N2, 269 FIELD_PREP(CECB_CLK_CNTL_N2, 732 - 1)); 270 271 /* Set M1 & M2 */ 272 regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1, 273 CECB_CLK_CNTL_M1, 274 FIELD_PREP(CECB_CLK_CNTL_M1, 8 - 1)); 275 276 regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1, 277 CECB_CLK_CNTL_M2, 278 FIELD_PREP(CECB_CLK_CNTL_M2, 11 - 1)); 279 280 /* Enable Dual divisor */ 281 regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, 282 CECB_CLK_CNTL_DUAL_EN, CECB_CLK_CNTL_DUAL_EN); 283 284 /* Disable divisor bypass */ 285 regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1, 286 CECB_CLK_CNTL_BYPASS_EN, 0); 287 288 /* Enable Input & Output */ 289 regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, 290 CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN, 291 CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN); 292 293 return 0; 294 } 295 296 static void meson_ao_cec_g12a_dualdiv_clk_disable(struct clk_hw *hw) 297 { 298 struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk = 299 hw_to_meson_ao_cec_g12a_dualdiv_clk(hw); 300 301 regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, 302 CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN, 303 0); 304 } 305 306 static int meson_ao_cec_g12a_dualdiv_clk_is_enabled(struct clk_hw *hw) 307 { 308 struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk = 309 hw_to_meson_ao_cec_g12a_dualdiv_clk(hw); 310 int val; 311 312 regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &val); 313 314 return !!(val & (CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN)); 315 } 316 317 static const struct clk_ops meson_ao_cec_g12a_dualdiv_clk_ops = { 318 .recalc_rate = meson_ao_cec_g12a_dualdiv_clk_recalc_rate, 319 .is_enabled = meson_ao_cec_g12a_dualdiv_clk_is_enabled, 320 .enable = meson_ao_cec_g12a_dualdiv_clk_enable, > 321 .disable = meson_ao_cec_g12a_dualdiv_clk_disable, 322 }; 323 324 static int meson_ao_cec_g12a_setup_clk(struct meson_ao_cec_g12a_device *ao_cec) 325 { 326 struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk; 327 struct device *dev = &ao_cec->pdev->dev; 328 struct clk_init_data init; 329 const char *parent_name; 330 struct clk *clk; 331 char *name; 332 333 dualdiv_clk = devm_kzalloc(dev, sizeof(*dualdiv_clk), GFP_KERNEL); 334 if (!dualdiv_clk) 335 return -ENOMEM; 336 337 name = kasprintf(GFP_KERNEL, "%s#dualdiv_clk", dev_name(dev)); 338 if (!name) 339 return -ENOMEM; 340 > 341 parent_name = __clk_get_name(ao_cec->oscin); 342 343 init.name = name; 344 init.ops = &meson_ao_cec_g12a_dualdiv_clk_ops; 345 init.flags = 0; 346 init.parent_names = &parent_name; 347 init.num_parents = 1; 348 dualdiv_clk->regmap = ao_cec->regmap; 349 dualdiv_clk->hw.init = &init; 350 351 clk = devm_clk_register(dev, &dualdiv_clk->hw); 352 kfree(name); 353 if (IS_ERR(clk)) { 354 dev_err(dev, "failed to register clock\n"); 355 return PTR_ERR(clk); 356 } 357 358 ao_cec->core = clk; 359 360 return 0; 361 } 362 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation