Hello Baolin, On Wed, Aug 14, 2019 at 06:01:50PM +0800, Baolin Wang wrote: > On Wed, 14 Aug 2019 at 17:23, Uwe Kleine-König > <u.kleine-koenig@xxxxxxxxxxxxxx> wrote: > > On Wed, Aug 14, 2019 at 04:42:28PM +0800, Baolin Wang wrote: > > > On Tue, 13 Aug 2019 at 23:16, Uwe Kleine-König > > > <u.kleine-koenig@xxxxxxxxxxxxxx> wrote: > > > > On Tue, Aug 13, 2019 at 09:46:41PM +0800, Baolin Wang wrote: > > > > [...] > > > Not really, our hardware's method is, when you changed a new > > > configuration (MOD or duty is changed) , the hardware will wait for a > > > while to complete current period, then change to the new period. > > > > Can you describe that in more detail? This doesn't explain why MOD must be > > configured before DUTY. Is there another reason for that? > > Sorry, I did not explain this explicitly. When we change a new PWM > configuration, the PWM controller will make sure the current period is > completed before changing to a new period. Once setting the MOD > register (since we always set MOD firstly), that will tell the > hardware that a new period need to change. So if the current period just ended after you reconfigured MOD but before you wrote to DUTY we'll see a bogus period, right? I assume the same holds true for writing the prescale value? > The reason MOD must be configured before DUTY is that, if we > configured DUTY firstly, the PWM can work abnormally if the current > DUTY is larger than previous MOD. That is also our hardware's > limitation. OK, so you must not get into a situation where DUTY > MOD, right? Now if the hardware was configured for period = 8s, duty = 4s and now you are supposed to change to period = 2s, duty = 1s you'd need to write DUTY first, don't you? > > > > > +static int sprd_pwm_remove(struct platform_device *pdev) > > > > > +{ > > > > > + struct sprd_pwm_chip *spc = platform_get_drvdata(pdev); > > > > > + int ret, i; > > > > > + > > > > > + ret = pwmchip_remove(&spc->chip); > > > > > + > > > > > + for (i = 0; i < spc->num_pwms; i++) { > > > > > + struct sprd_pwm_chn *chn = &spc->chn[i]; > > > > > + > > > > > + clk_bulk_disable_unprepare(SPRD_PWM_NUM_CLKS, chn->clks); > > > > > > > > If a PWM was still running you're effectively stopping it here, right? > > > > Are you sure you don't disable once more than you enabled? > > > > > > Yes, you are right. I should check current enable status of the PWM channel. > > > Thanks for your comments. > > > > I didn't recheck, but I think the right approach is to not fiddle with > > the clocks at all and rely on the PWM framework to not let someone call > > sprd_pwm_remove when a PWM is still in use. > > So you mean just return pwmchip_remove(&spc->chip); ? right. I just rechecked: If there is still a pwm in use, pwmchip_remove returns -EBUSY. So this should be safe. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ |