2022-03-31 12:26:05

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <[email protected]> wrote:

> +static int sp_pll_enable(struct clk_hw *hw)
> +{
> + struct sp_pll *clk = to_sp_pll(hw);
> + unsigned long flags;
> +
> + spin_lock_irqsave(clk->lock, flags);
> + writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> + spin_unlock_irqrestore(clk->lock, flags);
> +
> + return 0;
> +}
> +
> +static void sp_pll_disable(struct clk_hw *hw)
> +{
> + struct sp_pll *clk = to_sp_pll(hw);
> + unsigned long flags;
> +
> + spin_lock_irqsave(clk->lock, flags);
> + writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> + spin_unlock_irqrestore(clk->lock, flags);
> +}

What does the spinlock actually protect here? As writel() is posted, it
can already leak of of the lock, and the inputs would appear to be
constant.

> + /* This memory region include multi HW regs in discontinuous order.
> + * clk driver used some discontinuous areas in the memory region.
> + * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> + */
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> + if (!sp_clk_base)
> + return -ENXIO;

Can you explain this comment in more detail? Generally, the 'reg' properties
of drivers should not overlap, so it is supposed to be safe to call
devm_platform_ioremap_resource() here.

We discussed this in the context of the iop driver that did have overlapping
registers with this driver, and that was incorrect. Are there any other drivers
that conflict with the clk driver?

Arnd


2022-04-01 15:14:00

by Qin Jian

[permalink] [raw]
Subject: RE: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver

>
> > +static int sp_pll_enable(struct clk_hw *hw)
> > +{
> > + struct sp_pll *clk = to_sp_pll(hw);
> > + unsigned long flags;
> > +
> > + spin_lock_irqsave(clk->lock, flags);
> > + writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> > + spin_unlock_irqrestore(clk->lock, flags);
> > +
> > + return 0;
> > +}
> > +
> > +static void sp_pll_disable(struct clk_hw *hw)
> > +{
> > + struct sp_pll *clk = to_sp_pll(hw);
> > + unsigned long flags;
> > +
> > + spin_lock_irqsave(clk->lock, flags);
> > + writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> > + spin_unlock_irqrestore(clk->lock, flags);
> > +}
>
> What does the spinlock actually protect here? As writel() is posted, it
> can already leak of of the lock, and the inputs would appear to be
> constant.
>

These code is refered from other clk driver.
But, other driver need read then write, so need lock protected.
Our HW is HIWORD_MASKED_REG, means modify bits no need to read, just 1 write only.
So, the lock is useless.
Did I right?

> > + /* This memory region include multi HW regs in discontinuous order.
> > + * clk driver used some discontinuous areas in the memory region.
> > + * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> > + */
> > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> > + if (!sp_clk_base)
> > + return -ENXIO;
>
> Can you explain this comment in more detail? Generally, the 'reg' properties
> of drivers should not overlap, so it is supposed to be safe to call
> devm_platform_ioremap_resource() here.
>
> We discussed this in the context of the iop driver that did have overlapping
> registers with this driver, and that was incorrect. Are there any other drivers
> that conflict with the clk driver?
>
> Arnd

I means, I must split up the origin reg region into 4 small pieces,
and call devm_platform_ioremap_resource() 4 times.
Did I should follow this way?

2022-04-01 18:56:30

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver

On Fri, Apr 1, 2022 at 11:47 AM qinjian[覃健] <[email protected]> wrote:
> > > +static int sp_pll_enable(struct clk_hw *hw)
> > > +{
> > > + struct sp_pll *clk = to_sp_pll(hw);
> > > + unsigned long flags;
> > > +
> > > + spin_lock_irqsave(clk->lock, flags);
> > > + writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> > > + spin_unlock_irqrestore(clk->lock, flags);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static void sp_pll_disable(struct clk_hw *hw)
> > > +{
> > > + struct sp_pll *clk = to_sp_pll(hw);
> > > + unsigned long flags;
> > > +
> > > + spin_lock_irqsave(clk->lock, flags);
> > > + writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> > > + spin_unlock_irqrestore(clk->lock, flags);
> > > +}
> >
> > What does the spinlock actually protect here? As writel() is posted, it
> > can already leak of of the lock, and the inputs would appear to be
> > constant.
> >
>
> These code is refered from other clk driver.
> But, other driver need read then write, so need lock protected.
> Our HW is HIWORD_MASKED_REG, means modify bits no need to read, just 1 write only.
> So, the lock is useless.
> Did I right?

If the read-modify-write is done on a different register, then it is
fine to remove
the lock. You can also consider having shadow registers to avoid expensive
r-m-w cycles and just always write the register directly.

> > > + /* This memory region include multi HW regs in discontinuous order.
> > > + * clk driver used some discontinuous areas in the memory region.
> > > + * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> > > + */
> > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > + sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> > > + if (!sp_clk_base)
> > > + return -ENXIO;
> >
> > Can you explain this comment in more detail? Generally, the 'reg' properties
> > of drivers should not overlap, so it is supposed to be safe to call
> > devm_platform_ioremap_resource() here.
> >
> > We discussed this in the context of the iop driver that did have overlapping
> > registers with this driver, and that was incorrect. Are there any other drivers
> > that conflict with the clk driver?
>
> I means, I must split up the origin reg region into 4 small pieces,
> and call devm_platform_ioremap_resource() 4 times.
> Did I should follow this way?

It depends. What are those other registers, and what drivers use them?

Arnd

2022-04-05 01:59:06

by Qin Jian

[permalink] [raw]
Subject: RE: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver

>
> > > > + /* This memory region include multi HW regs in discontinuous order.
> > > > + * clk driver used some discontinuous areas in the memory region.
> > > > + * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> > > > + */
> > > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > > + sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> > > > + if (!sp_clk_base)
> > > > + return -ENXIO;
> > >
> > > Can you explain this comment in more detail? Generally, the 'reg' properties
> > > of drivers should not overlap, so it is supposed to be safe to call
> > > devm_platform_ioremap_resource() here.
> > >
> > > We discussed this in the context of the iop driver that did have overlapping
> > > registers with this driver, and that was incorrect. Are there any other drivers
> > > that conflict with the clk driver?
> >
> > I means, I must split up the origin reg region into 4 small pieces,
> > and call devm_platform_ioremap_resource() 4 times.
> > Did I should follow this way?
>
> It depends. What are those other registers, and what drivers use them?
>
> Arnd

Include Reset / PinMux / USBC / UPHY regs, which used by related drivers.