Hi Marco, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on media-tree/master] [also build test WARNING on robh/for-next linus/master v6.0-rc5 next-20220916] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Marco-Felsch/Add-support-for-Toshiba-TC358746/20220916-214808 base: git://linuxtv.org/media_tree.git master config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20220917/202209170957.eHfxERTT-lkp@xxxxxxxxx/config) compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/8ce1bdf646dd24a8117ed47f47e086ef7011c385 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Marco-Felsch/Add-support-for-Toshiba-TC358746/20220916-214808 git checkout 8ce1bdf646dd24a8117ed47f47e086ef7011c385 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/media/i2c/ drivers/net/wireless/ath/ath11k/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@xxxxxxxxx> All warnings (new ones prefixed by >>): >> drivers/media/i2c/tc358746.c:986:1: warning: no previous prototype for function 'tc358746_g_register' [-Wmissing-prototypes] tc358746_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) ^ drivers/media/i2c/tc358746.c:985:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int __maybe_unused ^ static >> drivers/media/i2c/tc358746.c:1007:1: warning: no previous prototype for function 'tc358746_s_register' [-Wmissing-prototypes] tc358746_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) ^ drivers/media/i2c/tc358746.c:1006:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int __maybe_unused ^ static >> drivers/media/i2c/tc358746.c:1178:15: warning: no previous prototype for function 'tc358746_recalc_rate' [-Wmissing-prototypes] unsigned long tc358746_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) ^ drivers/media/i2c/tc358746.c:1178:1: note: declare 'static' if the function is not intended to be used outside of this translation unit unsigned long tc358746_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) ^ static 3 warnings generated. vim +/tc358746_g_register +986 drivers/media/i2c/tc358746.c 984 985 int __maybe_unused > 986 tc358746_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) 987 { 988 struct tc358746 *tc358746 = to_tc358746(sd); 989 990 /* 32-bit registers starting from CLW_DPHYCONTTX */ 991 reg->size = reg->reg < CLW_DPHYCONTTX_REG ? 2 : 4; 992 993 if (pm_runtime_resume_and_get(sd->dev)) { 994 dev_err(sd->dev, "Failed to resume the device\n"); 995 return 0; 996 } 997 998 tc358746_read(tc358746, reg->reg, (u32 *)®->val); 999 1000 pm_runtime_mark_last_busy(sd->dev); 1001 pm_runtime_put_sync_autosuspend(sd->dev); 1002 1003 return 0; 1004 } 1005 1006 int __maybe_unused > 1007 tc358746_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) 1008 { 1009 struct tc358746 *tc358746 = to_tc358746(sd); 1010 1011 if (pm_runtime_resume_and_get(sd->dev)) { 1012 dev_err(sd->dev, "Failed to resume the device\n"); 1013 return 0; 1014 } 1015 1016 tc358746_write(tc358746, (u32)reg->reg, (u32)reg->val); 1017 1018 pm_runtime_mark_last_busy(sd->dev); 1019 pm_runtime_put_sync_autosuspend(sd->dev); 1020 1021 return 0; 1022 } 1023 1024 static const struct v4l2_subdev_core_ops tc358746_core_ops = { 1025 #ifdef CONFIG_VIDEO_ADV_DEBUG 1026 .g_register = tc358746_g_register, 1027 .s_register = tc358746_s_register, 1028 #endif 1029 }; 1030 1031 static const struct v4l2_subdev_video_ops tc358746_video_ops = { 1032 .s_stream = tc358746_s_stream, 1033 }; 1034 1035 static const struct v4l2_subdev_pad_ops tc358746_pad_ops = { 1036 .init_cfg = tc358746_init_cfg, 1037 .enum_mbus_code = tc358746_enum_mbus_code, 1038 .set_fmt = tc358746_set_fmt, 1039 .get_fmt = v4l2_subdev_get_fmt, 1040 .link_validate = tc358746_link_validate, 1041 .get_mbus_config = tc358746_get_mbus_config, 1042 }; 1043 1044 static const struct v4l2_subdev_ops tc358746_ops = { 1045 .core = &tc358746_core_ops, 1046 .video = &tc358746_video_ops, 1047 .pad = &tc358746_pad_ops, 1048 }; 1049 1050 static const struct media_entity_operations tc358746_entity_ops = { 1051 .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1, 1052 .link_validate = v4l2_subdev_link_validate, 1053 }; 1054 1055 static int tc358746_mclk_enable(struct clk_hw *hw) 1056 { 1057 struct tc358746 *tc358746 = clk_hw_to_tc358746(hw); 1058 unsigned int div; 1059 u32 val; 1060 int err; 1061 1062 div = tc358746->mclk_postdiv / 2; 1063 val = MCLK_HIGH(div - 1) | MCLK_LOW(div - 1); 1064 dev_dbg(tc358746->sd.dev, "MCLKCTL: %u (0x%x)\n", val, val); 1065 err = tc358746_write(tc358746, MCLKCTL_REG, val); 1066 if (err) 1067 return err; 1068 1069 if (tc358746->mclk_prediv == 8) 1070 val = MCLKDIV(MCLKDIV_8); 1071 else if (tc358746->mclk_prediv == 4) 1072 val = MCLKDIV(MCLKDIV_4); 1073 else 1074 val = MCLKDIV(MCLKDIV_2); 1075 1076 dev_dbg(tc358746->sd.dev, "CLKCTL[MCLKDIV]: %u (0x%x)\n", val, val); 1077 return tc358746_update_bits(tc358746, CLKCTL_REG, MCLKDIV_MASK, val); 1078 } 1079 1080 static void tc358746_mclk_disable(struct clk_hw *hw) 1081 { 1082 struct tc358746 *tc358746 = clk_hw_to_tc358746(hw); 1083 1084 tc358746_write(tc358746, MCLKCTL_REG, 0); 1085 } 1086 1087 static long 1088 tc358746_find_mclk_settings(struct tc358746 *tc358746, unsigned long mclk_rate) 1089 { 1090 unsigned long pll_rate = tc358746->pll_rate; 1091 const unsigned char prediv[] = { 2, 4, 8 }; 1092 unsigned int mclk_prediv, mclk_postdiv; 1093 struct device *dev = tc358746->sd.dev; 1094 unsigned int postdiv, mclkdiv; 1095 unsigned long best_mclk_rate; 1096 unsigned int i; 1097 1098 /* 1099 * MCLK-Div 1100 * -------------------´`--------------------- 1101 * ´ ` 1102 * +-------------+ +------------------------+ 1103 * | MCLK-PreDiv | | MCLK-PostDiv | 1104 * PLL --> | (2/4/8) | --> | (mclk_low + mclk_high) | --> MCLK 1105 * +-------------+ +------------------------+ 1106 * 1107 * The register value of mclk_low/high is mclk_low/high+1, i.e.: 1108 * mclk_low/high = 1 --> 2 MCLK-Ref Counts 1109 * mclk_low/high = 255 --> 256 MCLK-Ref Counts == max. 1110 * If mclk_low and mclk_high are 0 then MCLK is disabled. 1111 * 1112 * Keep it simple and support 50/50 duty cycles only for now, 1113 * so the calc will be: 1114 * 1115 * MCLK = PLL / (MCLK-PreDiv * 2 * MCLK-PostDiv) 1116 */ 1117 1118 if (mclk_rate == tc358746->mclk_rate) 1119 return mclk_rate; 1120 1121 /* Highest possible rate */ 1122 mclkdiv = pll_rate / mclk_rate; 1123 if (mclkdiv <= 8) { 1124 mclk_prediv = 2; 1125 mclk_postdiv = 4; 1126 best_mclk_rate = pll_rate / (2 * 4); 1127 goto out; 1128 } 1129 1130 /* First check the prediv */ 1131 for (i = 0; i < ARRAY_SIZE(prediv); i++) { 1132 postdiv = mclkdiv / prediv[i]; 1133 1134 if (postdiv % 2) 1135 continue; 1136 1137 if (postdiv >= 4 && postdiv <= 512) { 1138 mclk_prediv = prediv[i]; 1139 mclk_postdiv = postdiv; 1140 best_mclk_rate = pll_rate / (prediv[i] * postdiv); 1141 goto out; 1142 } 1143 } 1144 1145 /* No suitable prediv found, so try to adjust the postdiv */ 1146 for (postdiv = 4; postdiv <= 512; postdiv += 2) { 1147 unsigned int pre; 1148 1149 pre = mclkdiv / postdiv; 1150 if (pre == 2 || pre == 4 || pre == 8) { 1151 mclk_prediv = pre; 1152 mclk_postdiv = postdiv; 1153 best_mclk_rate = pll_rate / (pre * postdiv); 1154 goto out; 1155 } 1156 } 1157 1158 /* The MCLK <-> PLL gap is to high -> use largest possible div */ 1159 mclk_prediv = 8; 1160 mclk_postdiv = 512; 1161 best_mclk_rate = pll_rate / (8 * 512); 1162 1163 out: 1164 tc358746->mclk_prediv = mclk_prediv; 1165 tc358746->mclk_postdiv = mclk_postdiv; 1166 tc358746->mclk_rate = best_mclk_rate; 1167 1168 if (best_mclk_rate != mclk_rate) 1169 dev_warn(dev, "Request MCLK freq:%lu, found MCLK freq:%lu\n", 1170 mclk_rate, best_mclk_rate); 1171 1172 dev_dbg(dev, "Found MCLK settings: freq:%lu prediv:%u postdiv:%u\n", 1173 best_mclk_rate, mclk_prediv, mclk_postdiv); 1174 1175 return best_mclk_rate; 1176 } 1177 > 1178 unsigned long tc358746_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 1179 { 1180 struct tc358746 *tc358746 = clk_hw_to_tc358746(hw); 1181 unsigned int prediv, postdiv; 1182 u32 val; 1183 int err; 1184 1185 err = tc358746_read(tc358746, MCLKCTL_REG, &val); 1186 if (err) 1187 return 0; 1188 1189 postdiv = FIELD_GET(MCLK_LOW_MASK, val) + 1; 1190 postdiv += FIELD_GET(MCLK_HIGH_MASK, val) + 1; 1191 1192 err = tc358746_read(tc358746, CLKCTL_REG, &val); 1193 if (err) 1194 return 0; 1195 1196 prediv = FIELD_GET(MCLKDIV_MASK, val); 1197 if (prediv == MCLKDIV_8) 1198 prediv = 8; 1199 else if (prediv == MCLKDIV_4) 1200 prediv = 4; 1201 else 1202 prediv = 2; 1203 1204 return tc358746->pll_rate / (prediv * postdiv); 1205 } 1206 -- 0-DAY CI Kernel Test Service https://01.org/lkp