Re: [PATCH v3 2/3] media: platform: meson: Add Amlogic Meson G12A AO CEC Controller driver

From: Neil Armstrong
Date: Tue Apr 09 2019 - 03:26:02 EST


On 08/04/2019 20:08, kbuild test robot wrote:
> Hi Neil,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on linuxtv-media/master]
> [also build test ERROR 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: ia64-allmodconfig (attached as .config)
> compiler: ia64-linux-gcc (GCC) 8.1.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=8.1.0 make.cross ARCH=ia64
>
> All error/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;

Seems I'll need to add CONFIG_COMMON_CLK

Neil

> ^~
> In file included from include/linux/build_bug.h:5,
> 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 to 'const char *' from 'int' 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 +/hw +206 drivers/media/platform/meson/ao-cec-g12a.c
>
> 186
> 187 /*
> 188 * The AO-CECB embeds a dual/divider to generate a more precise
> 189 * 32,768KHz clock for CEC core clock.
> 190 * ______ ______
> 191 * | | | |
> 192 * ______ | Div1 |-| Cnt1 | ______
> 193 * | | /|______| |______|\ | |
> 194 * Xtal-->| Gate |---| ______ ______ X-X--| Gate |-->
> 195 * |______| | \| | | |/ | |______|
> 196 * | | Div2 |-| Cnt2 | |
> 197 * | |______| |______| |
> 198 * |_______________________|
> 199 *
> 200 * The dividing can be switched to single or dual, with a counter
> 201 * for each divider to set when the switching is done.
> 202 * The entire dividing mechanism can be also bypassed.
> 203 */
> 204
> 205 struct meson_ao_cec_g12a_dualdiv_clk {
> > 206 struct clk_hw hw;
> 207 struct regmap *regmap;
> 208 };
> 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, &reg0);
> 223 regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &reg1);
> 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
>