Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-21 Thread Uwe Kleine-König
On Sat, Feb 20, 2021 at 10:18:27AM +0800, 班涛 wrote:
> Uwe Kleine-König  于2021年2月3日周三 下午11:12写道:
> 
> > Hello Ban,
> >
> > On Wed, Feb 03, 2021 at 08:53:17PM +0800, Ban Tao wrote:
> > > v1->v2:
> >
> > FTR: v1 wasn't sent to any list, so don't try to find it in some
> > archive.
> >
> 
> Sorry, I understand. So is the next patch v3? Or v2?

Using v3 is fine. Please don't send another series that is called v2.

Best regards
Uwe

-- 
Pengutronix e.K.   | Uwe Kleine-König|
Industrial Linux Solutions | https://www.pengutronix.de/ |


signature.asc
Description: PGP signature


Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-10 Thread Maxime Ripard
On Sat, Feb 06, 2021 at 09:27:30PM +0800, 班涛 wrote:
> Maxime Ripard  于2021年2月6日周六 上午12:12写道:
> 
> > Hi,
> >
> > On Thu, Feb 04, 2021 at 11:47:34AM +0800, 班涛 wrote:
> > > Maxime Ripard  于2021年2月3日周三 下午11:46写道:
> > >
> > > > Hi,
> > > >
> > > > On Wed, Feb 03, 2021 at 08:53:17PM +0800, Ban Tao wrote:
> > > > > From: Ban Tao 
> > > > >
> > > > > The Allwinner R818, A133, R329, V536 and V833 has a new PWM
> > controller
> > > > > IP compared to the older Allwinner SoCs.
> > > > >
> > > > > Signed-off-by: Ban Tao 
> > > >
> > > > Thanks for your patch. There's a bunch of warnings reported by
> > > > checkpatch --strict, they should be addressed.
> > > >
> > > > > ---
> > > > > v1->v2:
> > > > > 1.delete unnecessary code.
> > > > > 2.using a named define for some constants.
> > > > > 3.Add comment in sun50i_pwm_config function.
> > > > > 4.using dev_err_probe() for error handling.
> > > > > 5.disable the clock after pwmchip_remove().
> > > > > ---
> > > > >  MAINTAINERS  |   6 +
> > > > >  drivers/pwm/Kconfig  |  11 ++
> > > > >  drivers/pwm/Makefile |   1 +
> > > > >  drivers/pwm/pwm-sun50i.c | 348
> > +++
> > > > >  4 files changed, 366 insertions(+)
> > > > >  create mode 100644 drivers/pwm/pwm-sun50i.c
> > > > >
> > > > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > > > index e73636b75f29..d33cf1b69b43 100644
> > > > > --- a/MAINTAINERS
> > > > > +++ b/MAINTAINERS
> > > > > @@ -737,6 +737,12 @@ L:   linux-me...@vger.kernel.org
> > > > >  S:   Maintained
> > > > >  F:   drivers/staging/media/sunxi/cedrus/
> > > > >
> > > > > +ALLWINNER PWM DRIVER
> > > > > +M:   Ban Tao 
> > > > > +L:   linux-...@vger.kernel.org
> > > > > +S:   Maintained
> > > > > +F:   drivers/pwm/pwm-sun50i.c
> > > > > +
> > > > >  ALPHA PORT
> > > > >  M:   Richard Henderson 
> > > > >  M:   Ivan Kokshaysky 
> > > > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> > > > > index 9a4f66ae8070..17635a8f2ed3 100644
> > > > > --- a/drivers/pwm/Kconfig
> > > > > +++ b/drivers/pwm/Kconfig
> > > > > @@ -552,6 +552,17 @@ config PWM_SUN4I
> > > > > To compile this driver as a module, choose M here: the module
> > > > > will be called pwm-sun4i.
> > > > >
> > > > > +config PWM_SUN50I
> > > > > + tristate "Allwinner enhanced PWM support"
> > > > > + depends on ARCH_SUNXI || COMPILE_TEST
> > > > > + depends on HAS_IOMEM && COMMON_CLK
> > > > > + help
> > > > > +   Enhanced PWM framework driver for Allwinner R818, A133, R329,
> > > > > +   V536 and V833 SoCs.
> > > > > +
> > > > > +   To compile this driver as a module, choose M here: the module
> > > > > +   will be called pwm-sun50i.
> > > > > +
> > > >
> > > > Even though it's unfortunate, there's a bunch of other SoCs part of the
> > > > sun50i family that are supported by the sun4i driver.
> > > >
> > > > Which SoC introduced that new design? It's usually the name we pick up
> > > > then.
> > > >
> > >
> > > In fact, some SoCs has not been supported by the sun4i driver, such as
> > v833,
> > > v536, r818, a133 and r329.
> > > v833 and v536 are part of the sun8i family, but r818, a133 and r329 are
> > > part of the sun50i family.
> >
> > Indeed, I missed that sorry.
> >
> > > So,I'm confused, how do choose the name of this driver?
> >
> > Just go for the earliest SoC that introduced that design. What was the
> > first SoC to use it?
> >
>
> The V536 SOC first used this design, so, we should use the name
> "sun8i-pwm.c"?

sun8i-pwm would be too generic, but sun8i-v536-pwm would be great then

> 
> > > > > +static const struct sun50i_pwm_data sun8i_pwm_data_c9 = {
> > > > > + .npwm = 9,
> > > > > +};
> > > > > +
> > > > > +static const struct sun50i_pwm_data sun50i_pwm_data_c16 = {
> > > > > + .npwm = 16,
> > > > > +};
> > > > > +
> > > > > +static const struct of_device_id sun50i_pwm_dt_ids[] = {
> > > > > + {
> > > > > + .compatible = "allwinner,sun8i-v833-pwm",
> > > > > + .data = _pwm_data_c9,
> > > > > + }, {
> > > > > + .compatible = "allwinner,sun8i-v536-pwm",
> > > > > + .data = _pwm_data_c9,
> > > > > + }, {
> > > > > + .compatible = "allwinner,sun50i-r818-pwm",
> > > > > + .data = _pwm_data_c16,
> > > > > + }, {
> > > > > + .compatible = "allwinner,sun50i-a133-pwm",
> > > > > + .data = _pwm_data_c16,
> > > > > + }, {
> > > > > + .compatible = "allwinner,sun50i-r329-pwm",
> > > > > + .data = _pwm_data_c9,
> > > > > + }, {
> > > > > + /* sentinel */
> > > > > + },
> > > > > +};
> > > > > +MODULE_DEVICE_TABLE(of, sun50i_pwm_dt_ids);
> > > >
> > > > What are the differences between all these SoCs? If there's none
> > between
> > > > the v833, v536 and R329, and between the r818 and the A133, you should
> > > > use the same compatible.
> > >
> > > Compared with the sun4i driver, this patch is a completely 

Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-05 Thread Maxime Ripard
Hi,

On Thu, Feb 04, 2021 at 11:47:34AM +0800, 班涛 wrote:
> Maxime Ripard  于2021年2月3日周三 下午11:46写道:
> 
> > Hi,
> >
> > On Wed, Feb 03, 2021 at 08:53:17PM +0800, Ban Tao wrote:
> > > From: Ban Tao 
> > >
> > > The Allwinner R818, A133, R329, V536 and V833 has a new PWM controller
> > > IP compared to the older Allwinner SoCs.
> > >
> > > Signed-off-by: Ban Tao 
> >
> > Thanks for your patch. There's a bunch of warnings reported by
> > checkpatch --strict, they should be addressed.
> >
> > > ---
> > > v1->v2:
> > > 1.delete unnecessary code.
> > > 2.using a named define for some constants.
> > > 3.Add comment in sun50i_pwm_config function.
> > > 4.using dev_err_probe() for error handling.
> > > 5.disable the clock after pwmchip_remove().
> > > ---
> > >  MAINTAINERS  |   6 +
> > >  drivers/pwm/Kconfig  |  11 ++
> > >  drivers/pwm/Makefile |   1 +
> > >  drivers/pwm/pwm-sun50i.c | 348 +++
> > >  4 files changed, 366 insertions(+)
> > >  create mode 100644 drivers/pwm/pwm-sun50i.c
> > >
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index e73636b75f29..d33cf1b69b43 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -737,6 +737,12 @@ L:   linux-me...@vger.kernel.org
> > >  S:   Maintained
> > >  F:   drivers/staging/media/sunxi/cedrus/
> > >
> > > +ALLWINNER PWM DRIVER
> > > +M:   Ban Tao 
> > > +L:   linux-...@vger.kernel.org
> > > +S:   Maintained
> > > +F:   drivers/pwm/pwm-sun50i.c
> > > +
> > >  ALPHA PORT
> > >  M:   Richard Henderson 
> > >  M:   Ivan Kokshaysky 
> > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> > > index 9a4f66ae8070..17635a8f2ed3 100644
> > > --- a/drivers/pwm/Kconfig
> > > +++ b/drivers/pwm/Kconfig
> > > @@ -552,6 +552,17 @@ config PWM_SUN4I
> > > To compile this driver as a module, choose M here: the module
> > > will be called pwm-sun4i.
> > >
> > > +config PWM_SUN50I
> > > + tristate "Allwinner enhanced PWM support"
> > > + depends on ARCH_SUNXI || COMPILE_TEST
> > > + depends on HAS_IOMEM && COMMON_CLK
> > > + help
> > > +   Enhanced PWM framework driver for Allwinner R818, A133, R329,
> > > +   V536 and V833 SoCs.
> > > +
> > > +   To compile this driver as a module, choose M here: the module
> > > +   will be called pwm-sun50i.
> > > +
> >
> > Even though it's unfortunate, there's a bunch of other SoCs part of the
> > sun50i family that are supported by the sun4i driver.
> >
> > Which SoC introduced that new design? It's usually the name we pick up
> > then.
> >
> 
> In fact, some SoCs has not been supported by the sun4i driver, such as v833,
> v536, r818, a133 and r329.
> v833 and v536 are part of the sun8i family, but r818, a133 and r329 are
> part of the sun50i family.

Indeed, I missed that sorry. 

> So,I'm confused, how do choose the name of this driver?

Just go for the earliest SoC that introduced that design. What was the
first SoC to use it?

> > > +static const struct sun50i_pwm_data sun8i_pwm_data_c9 = {
> > > + .npwm = 9,
> > > +};
> > > +
> > > +static const struct sun50i_pwm_data sun50i_pwm_data_c16 = {
> > > + .npwm = 16,
> > > +};
> > > +
> > > +static const struct of_device_id sun50i_pwm_dt_ids[] = {
> > > + {
> > > + .compatible = "allwinner,sun8i-v833-pwm",
> > > + .data = _pwm_data_c9,
> > > + }, {
> > > + .compatible = "allwinner,sun8i-v536-pwm",
> > > + .data = _pwm_data_c9,
> > > + }, {
> > > + .compatible = "allwinner,sun50i-r818-pwm",
> > > + .data = _pwm_data_c16,
> > > + }, {
> > > + .compatible = "allwinner,sun50i-a133-pwm",
> > > + .data = _pwm_data_c16,
> > > + }, {
> > > + .compatible = "allwinner,sun50i-r329-pwm",
> > > + .data = _pwm_data_c9,
> > > + }, {
> > > + /* sentinel */
> > > + },
> > > +};
> > > +MODULE_DEVICE_TABLE(of, sun50i_pwm_dt_ids);
> >
> > What are the differences between all these SoCs? If there's none between
> > the v833, v536 and R329, and between the r818 and the A133, you should
> > use the same compatible.
> 
> Compared with the sun4i driver, this patch is a completely different PWM IP
> controller.

Sure, I didn't mean to compare it to sun4i. What I meant was that as far
as these struct goes, the A133 and the R818 look to have the same PWM
controller. Just like the v833, v536 and R329.

If the PWM controllers are indeed identical across those SoCs, you can
just use two compatibles, one for the PWM with 9 channels (again, the
earliest SoC among the V833, v536 and r329), and one for the PWM with 16
channels.

None of those SoCs are supported at the moment in Linux though, so it
would make more sense to support them first before adding a new driver
for those SoCs, it's gonna be dead code otherwise.

Maxime


Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-04 Thread Thierry Reding
On Thu, Feb 04, 2021 at 02:54:36PM +0100, Uwe Kleine-König wrote:
> Hello Thierry,
> 
> On Thu, Feb 04, 2021 at 02:38:40PM +0100, Thierry Reding wrote:
> > All I'm saying is that I don't think we need to require everyone to
> > adopt a prefix, especially if this hasn't been followed consistently,
> > because then we don't actually gain anything.
> 
> Is "we didn't do this consistently in the past" a reason to never
> improve here? I hope it's not ...

You're implying that consistently using a prefix is an improvement. I
don't agree, so I don't see a need to introduce any new rules for this.

Thierry


signature.asc
Description: PGP signature


Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-04 Thread Uwe Kleine-König
Hello Thierry,

On Thu, Feb 04, 2021 at 02:38:40PM +0100, Thierry Reding wrote:
> All I'm saying is that I don't think we need to require everyone to
> adopt a prefix, especially if this hasn't been followed consistently,
> because then we don't actually gain anything.

Is "we didn't do this consistently in the past" a reason to never
improve here? I hope it's not ...

Best regards
Uwe

-- 
Pengutronix e.K.   | Uwe Kleine-König|
Industrial Linux Solutions | https://www.pengutronix.de/ |


signature.asc
Description: PGP signature


Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-04 Thread Thierry Reding
On Wed, Feb 03, 2021 at 09:59:13PM +0100, Uwe Kleine-König wrote:
> Hello Thierry, hello Ban,
> 
> On Wed, Feb 03, 2021 at 05:33:16PM +0100, Thierry Reding wrote:
> > On Wed, Feb 03, 2021 at 04:12:00PM +0100, Uwe Kleine-König wrote:
> > > On Wed, Feb 03, 2021 at 08:53:17PM +0800, Ban Tao wrote:
> > [...]
> > > > +#define PWM_GET_CLK_OFFSET(chan)   (0x20 + ((chan >> 1) * 0x4))
> > > > +#define PWM_CLK_APB_SCRBIT(7)
> > > > +#define PWM_DIV_M  0
> > > > +#define PWM_DIV_M_WIDTH0x4
> > > > +
> > > > +#define PWM_CLK_REG0x40
> > > > +#define PWM_CLK_GATING BIT(0)
> > > > +
> > > > +#define PWM_ENABLE_REG 0x80
> > > > +#define PWM_EN BIT(0)
> > > > +
> > > > +#define PWM_CTL_REG(chan)  (0x100 + 0x20 * chan)
> > > > +#define PWM_ACT_STABIT(8)
> > > > +#define PWM_PRESCAL_K  0
> > > > +#define PWM_PRESCAL_K_WIDTH0x8
> > > > +
> > > > +#define PWM_PERIOD_REG(chan)   (0x104 + 0x20 * chan)
> > > > +#define PWM_ENTIRE_CYCLE   16
> > > > +#define PWM_ENTIRE_CYCLE_WIDTH 0x10
> > > > +#define PWM_ACT_CYCLE  0
> > > > +#define PWM_ACT_CYCLE_WIDTH0x10
> > > 
> > > Please use a driver specific prefix for these defines.
> > 
> > These are nice and to the point, so I think it'd be fine to leave these
> > as-is. Unless of course if they conflict with something from the PWM
> > core, which I don't think any of these do.
> 
> In my eyes PWM_CLK_REG, PWM_CLK_GATING, PWM_ENABLE_REG and PWM_EN are
> not so nice. pwm-sun4i.c has already PWM_EN, pwm-mtk-disp.c has
> DISP_PWM_EN, pwm-zx.c has ZX_PWM_EN, pwm-berlin.c has BERLIN_PWM_EN.
> Luckily most of them already use a prefix. So it doesn't conflict with
> the core, but might with other drivers.

"Conflicts with another driver" is not something that makes sense. By
definition drivers should be specific to a given device, so you better
make sure there's no namespace sharing between them.

I'm fine if somebody wants to use a prefix, but I'm also fine if they
don't use a prefix, provided that there are no conflicts, which should
be immediately obvious because it typically causes build errors.

All I'm saying is that I don't think we need to require everyone to
adopt a prefix, especially if this hasn't been followed consistently,
because then we don't actually gain anything.

> And also if you only care about
> conflicts with the core, using a prefix is the future-proof strategy.

It's not like these symbol names are carved in stone. If we ever
introduce a symbol in the PWM core that happens to conflicts with one or
more drivers, we can always fix the drivers at that point.

> For tools like ctags and cscope a unique name is great, too.
> 
> Also comparing
> 
>   tmp |= BIT_CH(PWM_EN, pwm->hwpwm);
> 
> with (say)
> 
>   tmp |= BIT_CH(SUN5I_PWM_PWM_EN, pwm->hwpwm);
> 
> I prefer the latter as it is obvious that this is a driver specific
> constant.

I think the context makes it plenty clear that this is driver specific,
so the prefix is a bit redundant.

> Having said that, I'm also a fan of having the register name in the bit
> field define to simplify spotting errors like 4b75f8000361 ("serial:
> imx: Fix DCD reading").
> 
> So looking at:
> 
> +   /* disable pwm controller */
> +   tmp = sun50i_pwm_readl(sun50i_pwm, PWM_ENABLE_REG);
> +   tmp &= ~BIT_CH(PWM_EN, pwm->hwpwm);
> +   sun50i_pwm_writel(sun50i_pwm, tmp, PWM_ENABLE_REG);
> 
> my preferred version would be instead:
> 
> +   /* disable pwm controller */
> +   enable = sun50i_pwm_readl(sun50i_pwm, SUN50I_REG_PWM_ENABLE);
> +   enable &= ~SUN50I_REG_PWM_ENABLE_EN(pwm->hwpwm);
> +   sun50i_pwm_writel(sun50i_pwm, enable, SUN50I_REG_PWM_ENABLE);
> 
> where variable name, register name and bitfield name are obviously
> matching.

I don't have any particular objection to the above, but I've also seen
this kind of naming result in ridiculously long (as in almost impossible
to read) lines, so I think we need to strike the right balance. Given
that there aren't any rigorous rules for this, I don't think it's worth
requiring everyone to adopt some style that's not consistently followed
anyway.

> > > > +struct sun50i_pwm_data {
> > > > +   unsigned int npwm;
> > > > +};
> > > > +
> > > > +struct sun50i_pwm_chip {
> > > > +   struct pwm_chip chip;
> > > > +   struct clk *clk;
> > > > +   struct reset_control *rst_clk;
> > > > +   void __iomem *base;
> > > > +   const struct sun50i_pwm_data *data;
> > > > +};
> > > > +
> > > > +static inline struct sun50i_pwm_chip *sun50i_pwm_from_chip(struct 
> > > > pwm_chip *chip)
> > > > +{
> > > > +   return container_of(chip, struct sun50i_pwm_chip, chip);
> > > > +}
> > 
> > I wanted to reply to Uwe's comment on v1 but you sent this 

Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-03 Thread Uwe Kleine-König
Hello Thierry, hello Ban,

On Wed, Feb 03, 2021 at 05:33:16PM +0100, Thierry Reding wrote:
> On Wed, Feb 03, 2021 at 04:12:00PM +0100, Uwe Kleine-König wrote:
> > On Wed, Feb 03, 2021 at 08:53:17PM +0800, Ban Tao wrote:
> [...]
> > > +#define PWM_GET_CLK_OFFSET(chan) (0x20 + ((chan >> 1) * 0x4))
> > > +#define PWM_CLK_APB_SCR  BIT(7)
> > > +#define PWM_DIV_M0
> > > +#define PWM_DIV_M_WIDTH  0x4
> > > +
> > > +#define PWM_CLK_REG  0x40
> > > +#define PWM_CLK_GATING   BIT(0)
> > > +
> > > +#define PWM_ENABLE_REG   0x80
> > > +#define PWM_EN   BIT(0)
> > > +
> > > +#define PWM_CTL_REG(chan)(0x100 + 0x20 * chan)
> > > +#define PWM_ACT_STA  BIT(8)
> > > +#define PWM_PRESCAL_K0
> > > +#define PWM_PRESCAL_K_WIDTH  0x8
> > > +
> > > +#define PWM_PERIOD_REG(chan) (0x104 + 0x20 * chan)
> > > +#define PWM_ENTIRE_CYCLE 16
> > > +#define PWM_ENTIRE_CYCLE_WIDTH   0x10
> > > +#define PWM_ACT_CYCLE0
> > > +#define PWM_ACT_CYCLE_WIDTH  0x10
> > 
> > Please use a driver specific prefix for these defines.
> 
> These are nice and to the point, so I think it'd be fine to leave these
> as-is. Unless of course if they conflict with something from the PWM
> core, which I don't think any of these do.

In my eyes PWM_CLK_REG, PWM_CLK_GATING, PWM_ENABLE_REG and PWM_EN are
not so nice. pwm-sun4i.c has already PWM_EN, pwm-mtk-disp.c has
DISP_PWM_EN, pwm-zx.c has ZX_PWM_EN, pwm-berlin.c has BERLIN_PWM_EN.
Luckily most of them already use a prefix. So it doesn't conflict with
the core, but might with other drivers. And also if you only care about
conflicts with the core, using a prefix is the future-proof strategy.
For tools like ctags and cscope a unique name is great, too.

Also comparing

tmp |= BIT_CH(PWM_EN, pwm->hwpwm);

with (say)

tmp |= BIT_CH(SUN5I_PWM_PWM_EN, pwm->hwpwm);

I prefer the latter as it is obvious that this is a driver specific
constant.

Having said that, I'm also a fan of having the register name in the bit
field define to simplify spotting errors like 4b75f8000361 ("serial:
imx: Fix DCD reading").

So looking at:

+   /* disable pwm controller */
+   tmp = sun50i_pwm_readl(sun50i_pwm, PWM_ENABLE_REG);
+   tmp &= ~BIT_CH(PWM_EN, pwm->hwpwm);
+   sun50i_pwm_writel(sun50i_pwm, tmp, PWM_ENABLE_REG);

my preferred version would be instead:

+   /* disable pwm controller */
+   enable = sun50i_pwm_readl(sun50i_pwm, SUN50I_REG_PWM_ENABLE);
+   enable &= ~SUN50I_REG_PWM_ENABLE_EN(pwm->hwpwm);
+   sun50i_pwm_writel(sun50i_pwm, enable, SUN50I_REG_PWM_ENABLE);

where variable name, register name and bitfield name are obviously
matching.

> > > +struct sun50i_pwm_data {
> > > + unsigned int npwm;
> > > +};
> > > +
> > > +struct sun50i_pwm_chip {
> > > + struct pwm_chip chip;
> > > + struct clk *clk;
> > > + struct reset_control *rst_clk;
> > > + void __iomem *base;
> > > + const struct sun50i_pwm_data *data;
> > > +};
> > > +
> > > +static inline struct sun50i_pwm_chip *sun50i_pwm_from_chip(struct 
> > > pwm_chip *chip)
> > > +{
> > > + return container_of(chip, struct sun50i_pwm_chip, chip);
> > > +}
> 
> I wanted to reply to Uwe's comment on v1 but you sent this before I got
> around to it, so I'll mention it here. I recognize the usefulness of
> having a common prefix for function names, though admittedly it's not
> totally necessary in these drivers because these are all local symbols.
> But it does makes things a bit consistent and helps when looking at
> backtraces and such, so that's all good.
> 
> That said, I consider these casting helpers a bit of a special case
> because they usually won't show up in backtraces, or anywhere else for
> that matter. Traditionally these have been named to_*(), so it'd be
> entirely consistent to keep doing that.
> 
> But I don't have any strong objections to this variant either, so pick
> whichever you want. Although, please, nobody take that as a hint that
> any existing helpers should be converted.

@Thierry: I don't understand your motivation to write this. For me
consistence is a quite important aspect. Obviously for you it's less so
and the code presented here over-fulfils your standards. So everything
is fine as is, isn't it?

I think using a rule like "A common prefix for driver specific functions"
consistently is easier than allowing some exceptions. There is no gain
in not using the prefix, so IMHO keep the rules simple without
exceptions.

> [...]
> > > +static int sun50i_pwm_probe(struct platform_device *pdev)
> > > +{
> > > + struct sun50i_pwm_chip *pwm;
> > 
> > "pwm" isn't a good name, in PWM code this name is usually used for
> > struct pwm_device pointers (and sometimes the global pwm id). I usually
> > use "ddata" for driver data (and would have called 

Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-03 Thread Thierry Reding
On Wed, Feb 03, 2021 at 04:12:00PM +0100, Uwe Kleine-König wrote:
> On Wed, Feb 03, 2021 at 08:53:17PM +0800, Ban Tao wrote:
[...]
> > +#define PWM_GET_CLK_OFFSET(chan)   (0x20 + ((chan >> 1) * 0x4))
> > +#define PWM_CLK_APB_SCRBIT(7)
> > +#define PWM_DIV_M  0
> > +#define PWM_DIV_M_WIDTH0x4
> > +
> > +#define PWM_CLK_REG0x40
> > +#define PWM_CLK_GATING BIT(0)
> > +
> > +#define PWM_ENABLE_REG 0x80
> > +#define PWM_EN BIT(0)
> > +
> > +#define PWM_CTL_REG(chan)  (0x100 + 0x20 * chan)
> > +#define PWM_ACT_STABIT(8)
> > +#define PWM_PRESCAL_K  0
> > +#define PWM_PRESCAL_K_WIDTH0x8
> > +
> > +#define PWM_PERIOD_REG(chan)   (0x104 + 0x20 * chan)
> > +#define PWM_ENTIRE_CYCLE   16
> > +#define PWM_ENTIRE_CYCLE_WIDTH 0x10
> > +#define PWM_ACT_CYCLE  0
> > +#define PWM_ACT_CYCLE_WIDTH0x10
> 
> Please use a driver specific prefix for these defines.

These are nice and to the point, so I think it'd be fine to leave these
as-is. Unless of course if they conflict with something from the PWM
core, which I don't think any of these do.

> > +struct sun50i_pwm_data {
> > +   unsigned int npwm;
> > +};
> > +
> > +struct sun50i_pwm_chip {
> > +   struct pwm_chip chip;
> > +   struct clk *clk;
> > +   struct reset_control *rst_clk;
> > +   void __iomem *base;
> > +   const struct sun50i_pwm_data *data;
> > +};
> > +
> > +static inline struct sun50i_pwm_chip *sun50i_pwm_from_chip(struct pwm_chip 
> > *chip)
> > +{
> > +   return container_of(chip, struct sun50i_pwm_chip, chip);
> > +}

I wanted to reply to Uwe's comment on v1 but you sent this before I got
around to it, so I'll mention it here. I recognize the usefulness of
having a common prefix for function names, though admittedly it's not
totally necessary in these drivers because these are all local symbols.
But it does makes things a bit consistent and helps when looking at
backtraces and such, so that's all good.

That said, I consider these casting helpers a bit of a special case
because they usually won't show up in backtraces, or anywhere else for
that matter. Traditionally these have been named to_*(), so it'd be
entirely consistent to keep doing that.

But I don't have any strong objections to this variant either, so pick
whichever you want. Although, please, nobody take that as a hint that
any existing helpers should be converted.

[...]
> > +static int sun50i_pwm_probe(struct platform_device *pdev)
> > +{
> > +   struct sun50i_pwm_chip *pwm;
> 
> "pwm" isn't a good name, in PWM code this name is usually used for
> struct pwm_device pointers (and sometimes the global pwm id). I usually
> use "ddata" for driver data (and would have called "sun50i_pwm_chip"
> "sun50i_pwm_ddata" instead). Another common name is "priv".

This driver already declares sun50i_pwm_data for per-SoC data, so having
a struct sun50i_pwm_ddata would just be confusing. sun50i_pwm_chip is
consistent with what other drivers name this, so I think that's fine.

Agreed on "pwm" being a bad choice here, though.

Thierry


signature.asc
Description: PGP signature


Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-03 Thread Maxime Ripard
Hi,

On Wed, Feb 03, 2021 at 08:53:17PM +0800, Ban Tao wrote:
> From: Ban Tao 
> 
> The Allwinner R818, A133, R329, V536 and V833 has a new PWM controller
> IP compared to the older Allwinner SoCs.
> 
> Signed-off-by: Ban Tao 

Thanks for your patch. There's a bunch of warnings reported by
checkpatch --strict, they should be addressed.

> ---
> v1->v2:
> 1.delete unnecessary code.
> 2.using a named define for some constants.
> 3.Add comment in sun50i_pwm_config function.
> 4.using dev_err_probe() for error handling.
> 5.disable the clock after pwmchip_remove().
> ---
>  MAINTAINERS  |   6 +
>  drivers/pwm/Kconfig  |  11 ++
>  drivers/pwm/Makefile |   1 +
>  drivers/pwm/pwm-sun50i.c | 348 +++
>  4 files changed, 366 insertions(+)
>  create mode 100644 drivers/pwm/pwm-sun50i.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e73636b75f29..d33cf1b69b43 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -737,6 +737,12 @@ L:   linux-me...@vger.kernel.org
>  S:   Maintained
>  F:   drivers/staging/media/sunxi/cedrus/
>  
> +ALLWINNER PWM DRIVER
> +M:   Ban Tao 
> +L:   linux-...@vger.kernel.org
> +S:   Maintained
> +F:   drivers/pwm/pwm-sun50i.c
> +
>  ALPHA PORT
>  M:   Richard Henderson 
>  M:   Ivan Kokshaysky 
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index 9a4f66ae8070..17635a8f2ed3 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -552,6 +552,17 @@ config PWM_SUN4I
> To compile this driver as a module, choose M here: the module
> will be called pwm-sun4i.
>  
> +config PWM_SUN50I
> + tristate "Allwinner enhanced PWM support"
> + depends on ARCH_SUNXI || COMPILE_TEST
> + depends on HAS_IOMEM && COMMON_CLK
> + help
> +   Enhanced PWM framework driver for Allwinner R818, A133, R329,
> +   V536 and V833 SoCs.
> +
> +   To compile this driver as a module, choose M here: the module
> +   will be called pwm-sun50i.
> +

Even though it's unfortunate, there's a bunch of other SoCs part of the
sun50i family that are supported by the sun4i driver.

Which SoC introduced that new design? It's usually the name we pick up
then.

>  config PWM_TEGRA
>   tristate "NVIDIA Tegra PWM support"
>   depends on ARCH_TEGRA || COMPILE_TEST
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 6374d3b1d6f3..b4754927fd8f 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -51,6 +51,7 @@ obj-$(CONFIG_PWM_STM32) += pwm-stm32.o
>  obj-$(CONFIG_PWM_STM32_LP)   += pwm-stm32-lp.o
>  obj-$(CONFIG_PWM_STMPE)  += pwm-stmpe.o
>  obj-$(CONFIG_PWM_SUN4I)  += pwm-sun4i.o
> +obj-$(CONFIG_PWM_SUN50I) += pwm-sun50i.o
>  obj-$(CONFIG_PWM_TEGRA)  += pwm-tegra.o
>  obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
>  obj-$(CONFIG_PWM_TIEHRPWM)   += pwm-tiehrpwm.o
> diff --git a/drivers/pwm/pwm-sun50i.c b/drivers/pwm/pwm-sun50i.c
> new file mode 100644
> index ..37285d771924
> --- /dev/null
> +++ b/drivers/pwm/pwm-sun50i.c
> @@ -0,0 +1,348 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Driver for Allwinner sun50i Pulse Width Modulation Controller
> + *
> + * Copyright (C) 2020 Ban Tao 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define PWM_GET_CLK_OFFSET(chan) (0x20 + ((chan >> 1) * 0x4))
> +#define PWM_CLK_APB_SCR  BIT(7)
> +#define PWM_DIV_M0
> +#define PWM_DIV_M_WIDTH  0x4
> +
> +#define PWM_CLK_REG  0x40
> +#define PWM_CLK_GATING   BIT(0)
> +
> +#define PWM_ENABLE_REG   0x80
> +#define PWM_EN   BIT(0)
> +
> +#define PWM_CTL_REG(chan)(0x100 + 0x20 * chan)
> +#define PWM_ACT_STA  BIT(8)
> +#define PWM_PRESCAL_K0
> +#define PWM_PRESCAL_K_WIDTH  0x8
> +
> +#define PWM_PERIOD_REG(chan) (0x104 + 0x20 * chan)
> +#define PWM_ENTIRE_CYCLE 16
> +#define PWM_ENTIRE_CYCLE_WIDTH   0x10
> +#define PWM_ACT_CYCLE0
> +#define PWM_ACT_CYCLE_WIDTH  0x10
> +
> +#define BIT_CH(bit, chan)((bit) << (chan))
> +
> +#define SETMASK(width, shift)((width?((-1U) >> 
> (32-width)):0)  << (shift))
> +#define CLRMASK(width, shift)(~(SETMASK(width, shift)))
> +#define GET_BITS(shift, width, reg) \
> + (((reg) & SETMASK(width, shift)) >> (shift))
> +#define SET_BITS(shift, width, reg, val) \
> + (((reg) & CLRMASK(width, shift)) | (val << (shift)))
> +
> +#define PWM_OSC_CLK  2400
> +#define PWM_PRESCALER_MAX256
> +#define PWM_CLK_DIV_M__MAX   9
> +#define PWM_ENTIRE_CYCLE_MAX 65536
> +
> +struct sun50i_pwm_data {
> + unsigned int npwm;
> +};
> +
> +struct sun50i_pwm_chip {
> + 

Re: [PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-03 Thread Uwe Kleine-König
Hello Ban,

On Wed, Feb 03, 2021 at 08:53:17PM +0800, Ban Tao wrote:
> v1->v2:

FTR: v1 wasn't sent to any list, so don't try to find it in some
archive.

> diff --git a/drivers/pwm/pwm-sun50i.c b/drivers/pwm/pwm-sun50i.c
> new file mode 100644
> index ..37285d771924
> --- /dev/null
> +++ b/drivers/pwm/pwm-sun50i.c
> @@ -0,0 +1,348 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Driver for Allwinner sun50i Pulse Width Modulation Controller
> + *
> + * Copyright (C) 2020 Ban Tao 
> + */

Please add a section here about how this PWM behaves. Things to cover:

 - Mention if the hardware cannot do 0% or 100%
 - Describe if changing the settings is racy, e.g. if it can happen when
   switching from duty_cycle=100 + period=1000 to duty_cycle=200 +
   period=2000 that we see a period with duty_cycle=100 and period=2000
   or similar
 - Tell if on a reconfiguration the currently running period is
   completed.

Please stick to the format used in other drivers to simplify grepping,
see the Limitations section in drivers/pwm/pwm-sl28cpld.c for an
example.

> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define PWM_GET_CLK_OFFSET(chan) (0x20 + ((chan >> 1) * 0x4))
> +#define PWM_CLK_APB_SCR  BIT(7)
> +#define PWM_DIV_M0
> +#define PWM_DIV_M_WIDTH  0x4
> +
> +#define PWM_CLK_REG  0x40
> +#define PWM_CLK_GATING   BIT(0)
> +
> +#define PWM_ENABLE_REG   0x80
> +#define PWM_EN   BIT(0)
> +
> +#define PWM_CTL_REG(chan)(0x100 + 0x20 * chan)
> +#define PWM_ACT_STA  BIT(8)
> +#define PWM_PRESCAL_K0
> +#define PWM_PRESCAL_K_WIDTH  0x8
> +
> +#define PWM_PERIOD_REG(chan) (0x104 + 0x20 * chan)
> +#define PWM_ENTIRE_CYCLE 16
> +#define PWM_ENTIRE_CYCLE_WIDTH   0x10
> +#define PWM_ACT_CYCLE0
> +#define PWM_ACT_CYCLE_WIDTH  0x10

Please use a driver specific prefix for these defines.

> +
> +#define BIT_CH(bit, chan)((bit) << (chan))
> +
> +#define SETMASK(width, shift)((width?((-1U) >> 
> (32-width)):0)  << (shift))
> +#define CLRMASK(width, shift)(~(SETMASK(width, shift)))
> +#define GET_BITS(shift, width, reg) \
> + (((reg) & SETMASK(width, shift)) >> (shift))
> +#define SET_BITS(shift, width, reg, val) \
> + (((reg) & CLRMASK(width, shift)) | (val << (shift)))

You're reinventing the stuff from  here. Please don't.

> +
> +#define PWM_OSC_CLK  2400
> +#define PWM_PRESCALER_MAX256
> +#define PWM_CLK_DIV_M__MAX   9
> +#define PWM_ENTIRE_CYCLE_MAX 65536
> +
> +struct sun50i_pwm_data {
> + unsigned int npwm;
> +};
> +
> +struct sun50i_pwm_chip {
> + struct pwm_chip chip;
> + struct clk *clk;
> + struct reset_control *rst_clk;
> + void __iomem *base;
> + const struct sun50i_pwm_data *data;
> +};
> +
> +static inline struct sun50i_pwm_chip *sun50i_pwm_from_chip(struct pwm_chip 
> *chip)
> +{
> + return container_of(chip, struct sun50i_pwm_chip, chip);
> +}
> +
> +static inline u32 sun50i_pwm_readl(struct sun50i_pwm_chip *chip,
> +   unsigned long offset)
> +{
> + return readl(chip->base + offset);
> +}
> +
> +static inline void sun50i_pwm_writel(struct sun50i_pwm_chip *chip,
> + u32 val, unsigned long offset)
> +{
> + writel(val, chip->base + offset);
> +}
> +
> +static int sun50i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device 
> *pwm,
> + enum pwm_polarity polarity)
> +{
> + struct sun50i_pwm_chip *sun50i_pwm = sun50i_pwm_from_chip(chip);
> + u32 temp;
> +
> + temp = sun50i_pwm_readl(sun50i_pwm, PWM_CTL_REG(pwm->hwpwm));
> +
> + if (polarity == PWM_POLARITY_NORMAL)
> + temp |= PWM_ACT_STA;
> + else
> + temp &= ~PWM_ACT_STA;
> +
> + sun50i_pwm_writel(sun50i_pwm, temp, PWM_CTL_REG(pwm->hwpwm));
> +
> + return 0;
> +}

For v1 I asked to test this driver with PWM_DEBUG enabled and to fix all
emitted warnings. This didn't happen :-\

> +static int sun50i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> + int duty_ns, int period_ns)

Please align to the opening brace in the line above.

> +{
> + struct sun50i_pwm_chip *sun50i_pwm = sun50i_pwm_from_chip(chip);
> + unsigned long long c;
> + unsigned long entire_cycles, active_cycles;
> + unsigned int div_m, prescaler;
> + u32 tmp;
> +
> + if (period_ns > 334) {
> + /* if freq < 3M, then select 24M clock */
> + c = PWM_OSC_CLK;
> + tmp = sun50i_pwm_readl(sun50i_pwm, 
> PWM_GET_CLK_OFFSET(pwm->hwpwm));
> + tmp &= ~PWM_CLK_APB_SCR;
> + 

[PATCH v2] pwm: sunxi: Add Allwinner SoC PWM controller driver

2021-02-03 Thread Ban Tao
From: Ban Tao 

The Allwinner R818, A133, R329, V536 and V833 has a new PWM controller
IP compared to the older Allwinner SoCs.

Signed-off-by: Ban Tao 

---
v1->v2:
1.delete unnecessary code.
2.using a named define for some constants.
3.Add comment in sun50i_pwm_config function.
4.using dev_err_probe() for error handling.
5.disable the clock after pwmchip_remove().
---
 MAINTAINERS  |   6 +
 drivers/pwm/Kconfig  |  11 ++
 drivers/pwm/Makefile |   1 +
 drivers/pwm/pwm-sun50i.c | 348 +++
 4 files changed, 366 insertions(+)
 create mode 100644 drivers/pwm/pwm-sun50i.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e73636b75f29..d33cf1b69b43 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -737,6 +737,12 @@ L: linux-me...@vger.kernel.org
 S: Maintained
 F: drivers/staging/media/sunxi/cedrus/
 
+ALLWINNER PWM DRIVER
+M: Ban Tao 
+L: linux-...@vger.kernel.org
+S: Maintained
+F: drivers/pwm/pwm-sun50i.c
+
 ALPHA PORT
 M: Richard Henderson 
 M: Ivan Kokshaysky 
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 9a4f66ae8070..17635a8f2ed3 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -552,6 +552,17 @@ config PWM_SUN4I
  To compile this driver as a module, choose M here: the module
  will be called pwm-sun4i.
 
+config PWM_SUN50I
+   tristate "Allwinner enhanced PWM support"
+   depends on ARCH_SUNXI || COMPILE_TEST
+   depends on HAS_IOMEM && COMMON_CLK
+   help
+ Enhanced PWM framework driver for Allwinner R818, A133, R329,
+ V536 and V833 SoCs.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-sun50i.
+
 config PWM_TEGRA
tristate "NVIDIA Tegra PWM support"
depends on ARCH_TEGRA || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 6374d3b1d6f3..b4754927fd8f 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_PWM_STM32)   += pwm-stm32.o
 obj-$(CONFIG_PWM_STM32_LP) += pwm-stm32-lp.o
 obj-$(CONFIG_PWM_STMPE)+= pwm-stmpe.o
 obj-$(CONFIG_PWM_SUN4I)+= pwm-sun4i.o
+obj-$(CONFIG_PWM_SUN50I)   += pwm-sun50i.o
 obj-$(CONFIG_PWM_TEGRA)+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)   += pwm-tiecap.o
 obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o
diff --git a/drivers/pwm/pwm-sun50i.c b/drivers/pwm/pwm-sun50i.c
new file mode 100644
index ..37285d771924
--- /dev/null
+++ b/drivers/pwm/pwm-sun50i.c
@@ -0,0 +1,348 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for Allwinner sun50i Pulse Width Modulation Controller
+ *
+ * Copyright (C) 2020 Ban Tao 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PWM_GET_CLK_OFFSET(chan)   (0x20 + ((chan >> 1) * 0x4))
+#define PWM_CLK_APB_SCRBIT(7)
+#define PWM_DIV_M  0
+#define PWM_DIV_M_WIDTH0x4
+
+#define PWM_CLK_REG0x40
+#define PWM_CLK_GATING BIT(0)
+
+#define PWM_ENABLE_REG 0x80
+#define PWM_EN BIT(0)
+
+#define PWM_CTL_REG(chan)  (0x100 + 0x20 * chan)
+#define PWM_ACT_STABIT(8)
+#define PWM_PRESCAL_K  0
+#define PWM_PRESCAL_K_WIDTH0x8
+
+#define PWM_PERIOD_REG(chan)   (0x104 + 0x20 * chan)
+#define PWM_ENTIRE_CYCLE   16
+#define PWM_ENTIRE_CYCLE_WIDTH 0x10
+#define PWM_ACT_CYCLE  0
+#define PWM_ACT_CYCLE_WIDTH0x10
+
+#define BIT_CH(bit, chan)  ((bit) << (chan))
+
+#define SETMASK(width, shift)  ((width?((-1U) >> (32-width)):0)  << 
(shift))
+#define CLRMASK(width, shift)  (~(SETMASK(width, shift)))
+#define GET_BITS(shift, width, reg) \
+   (((reg) & SETMASK(width, shift)) >> (shift))
+#define SET_BITS(shift, width, reg, val) \
+   (((reg) & CLRMASK(width, shift)) | (val << (shift)))
+
+#define PWM_OSC_CLK2400
+#define PWM_PRESCALER_MAX  256
+#define PWM_CLK_DIV_M__MAX 9
+#define PWM_ENTIRE_CYCLE_MAX   65536
+
+struct sun50i_pwm_data {
+   unsigned int npwm;
+};
+
+struct sun50i_pwm_chip {
+   struct pwm_chip chip;
+   struct clk *clk;
+   struct reset_control *rst_clk;
+   void __iomem *base;
+   const struct sun50i_pwm_data *data;
+};
+
+static inline struct sun50i_pwm_chip *sun50i_pwm_from_chip(struct pwm_chip 
*chip)
+{
+   return container_of(chip, struct sun50i_pwm_chip, chip);
+}
+
+static inline u32 sun50i_pwm_readl(struct sun50i_pwm_chip *chip,
+ unsigned long offset)
+{
+   return readl(chip->base + offset);
+}
+
+static inline void sun50i_pwm_writel(struct sun50i_pwm_chip *chip,
+   u32 val,