Hi Baruch,
I love your patch! Yet something to improve:
[auto build test ERROR on pwm/for-next]
[also build test ERROR on robh/for-next v5.14-rc1 next-20210713]
[cannot apply to agross-msm/qcom/for-next]
[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]
url:
https://github.com/0day-ci/linux/commits/Baruch-Siach/arm64-dts-ipq6018-c...
base:
https://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git
for-next
config: riscv-randconfig-r032-20210713 (attached as .config)
compiler: clang version 13.0.0 (
https://github.com/llvm/llvm-project
8d69635ed9ecf36fd0ca85906bfde17949671cbe)
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
# install riscv cross compiling tool for clang build
# apt-get install binutils-riscv64-linux-gnu
#
https://github.com/0day-ci/linux/commit/3215e41e0c2fbd26202f21458ea6f1993...
git remote add linux-review
https://github.com/0day-ci/linux
git fetch --no-tags linux-review
Baruch-Siach/arm64-dts-ipq6018-correct-TCSR-block-area/20210713-193616
git checkout 3215e41e0c2fbd26202f21458ea6f1993f90e126
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All errors (new ones prefixed by >>):
> drivers/pwm/pwm-ipq.c:96:8: error: implicit declaration of
function 'FIELD_PREP' [-Werror,-Wimplicit-function-declaration]
val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) |
^
> drivers/pwm/pwm-ipq.c:182:12: error: implicit declaration of
function 'FIELD_GET' [-Werror,-Wimplicit-function-declaration]
pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0);
^
2 errors generated.
vim +/FIELD_PREP +96 drivers/pwm/pwm-ipq.c
80
81 static void config_div_and_duty(struct pwm_device *pwm, unsigned int pre_div,
82 unsigned int pwm_div, u64 period_ns, u64 duty_ns,
83 bool enable)
84 {
85 unsigned long hi_dur;
86 unsigned long long quotient;
87 unsigned long val = 0;
88
89 /*
90 * high duration = pwm duty * (pwm div + 1)
91 * pwm duty = duty_ns / period_ns
92 */
93 quotient = (pwm_div + 1) * duty_ns;
94 hi_dur = div64_u64(quotient, period_ns);
95
96 val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) |
97 FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div);
98 ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG0, val);
99
100 val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div);
101 ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG1, val);
102
103 /* Enable needs a separate write to REG1 */
104 val |= IPQ_PWM_REG1_UPDATE;
105 if (enable)
106 val |= IPQ_PWM_REG1_ENABLE;
107 else
108 val &= ~IPQ_PWM_REG1_ENABLE;
109 ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG1, val);
110 }
111
112 static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
113 const struct pwm_state *state)
114 {
115 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(chip);
116 unsigned long freq;
117 unsigned int pre_div, pwm_div, close_pre_div, close_pwm_div;
118 long long diff;
119 unsigned long rate = clk_get_rate(ipq_chip->clk);
120 unsigned long min_diff = rate;
121 uint64_t fin_ps;
122 u64 period_ns, duty_ns;
123
124 if (state->period < IPQ_PWM_MIN_PERIOD_NS)
125 return -ERANGE;
126
127 period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS);
128 duty_ns = min(state->duty_cycle, period_ns);
129
130 /* freq in Hz for period in nano second */
131 freq = div64_u64(NSEC_PER_SEC, period_ns);
132 fin_ps = div64_u64(NSEC_PER_SEC * 1000ULL, rate);
133 close_pre_div = IPQ_PWM_MAX_DIV;
134 close_pwm_div = IPQ_PWM_MAX_DIV;
135
136 for (pre_div = 0; pre_div <= IPQ_PWM_MAX_DIV; pre_div++) {
137 pwm_div = DIV64_U64_ROUND_CLOSEST(period_ns * 1000,
138 fin_ps * (pre_div + 1));
139 pwm_div--;
140 if (pwm_div > IPQ_PWM_MAX_DIV)
141 continue;
142
143 diff = ((uint64_t)freq * (pre_div + 1) * (pwm_div + 1))
144 - (uint64_t)rate;
145
146 if (diff < 0) /* period larger than requested */
147 continue;
148 if (diff == 0) { /* bingo */
149 close_pre_div = pre_div;
150 close_pwm_div = pwm_div;
151 break;
152 }
153 if (diff < min_diff) {
154 min_diff = diff;
155 close_pre_div = pre_div;
156 close_pwm_div = pwm_div;
157 }
158 }
159
160 /* config divider values for the closest possible frequency */
161 config_div_and_duty(pwm, close_pre_div, close_pwm_div,
162 period_ns, duty_ns, state->enabled);
163
164 return 0;
165 }
166
167 static void ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
168 struct pwm_state *state)
169 {
170 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(chip);
171 unsigned long rate = clk_get_rate(ipq_chip->clk);
172 unsigned int pre_div, pwm_div, hi_dur;
173 u64 effective_div, hi_div;
174 u32 reg0, reg1;
175
176 reg0 = ipq_pwm_reg_read(pwm, IPQ_PWM_CFG_REG0);
177 reg1 = ipq_pwm_reg_read(pwm, IPQ_PWM_CFG_REG1);
178
179 state->polarity = PWM_POLARITY_NORMAL;
180 state->enabled = reg1 & IPQ_PWM_REG1_ENABLE;
181
182 pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0);
183 hi_dur = FIELD_GET(IPQ_PWM_REG0_HI_DURATION, reg0);
184 pre_div = FIELD_GET(IPQ_PWM_REG1_PRE_DIV, reg1);
185
186 effective_div = (pre_div + 1) * (pwm_div + 1);
187 state->period = div64_u64(effective_div * NSEC_PER_SEC, rate);
188
189 hi_div = hi_dur * (pre_div + 1);
190 state->duty_cycle = div64_u64(hi_div * NSEC_PER_SEC, rate);
191 }
192
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org