lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <6b3e8322-40fa-0d79-3212-fae76d04de64@linux.intel.com>
Date:   Thu, 13 Feb 2020 16:04:46 +0800
From:   "Tanwar, Rahul" <rahul.tanwar@...ux.intel.com>
To:     Stephen Boyd <sboyd@...nel.org>, linux-clk@...r.kernel.org,
        mark.rutland@....com, mturquette@...libre.com, robh+dt@...nel.org,
        robh@...nel.org
Cc:     linux-kernel@...r.kernel.org, devicetree@...r.kernel.org,
        andriy.shevchenko@...el.com, qi-ming.wu@...el.com,
        yixin.zhu@...ux.intel.com, cheol.yong.kim@...el.com,
        rtanwar <rahul.tanwar@...el.com>
Subject: Re: [PATCH v4 1/2] clk: intel: Add CGU clock driver for a new SoC


Hi Stephen,

Thanks a lot for taking time out to review and providing feedback. I have
tried to address all your review concerns except few below mentioned points
where i need more clarification.

On 31/1/2020 10:24 AM, Stephen Boyd wrote:
> Quoting Rahul Tanwar (2020-01-30 01:04:02)
>> From: rtanwar <rahul.tanwar@...el.com>
>>
>> Clock Generation Unit(CGU) is a new clock controller IP of a forthcoming

(...)

>> +               raw_spin_unlock_irqrestore(&ctx->lock, flags);
>> +       }
>> +
>> +       return clk_hw_register_fixed_rate(NULL, list->name,
>> +                                         list->parent_names[0],
>> +                                         list->flags, list->mux_flags);
> Can fixed rate clks come from DT? Or does this value change sometimes?

Fixed rate clks may need enable/disable clk ops. That's the only reason
for making it visible to clock driver.

>> +lgm_clk_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
>> +                     unsigned long prate)
>> +{
>> +       struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
>> +       u32 div, ddiv1, ddiv2;
>> +       unsigned long flags;
>> +
>> +       div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
>> +
>> +       raw_spin_lock_irqsave(&ddiv->lock, flags);
>> +       if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
>> +               div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
>> +               div = div * 2;
>> +       }
>> +       raw_spin_unlock_irqrestore(&ddiv->lock, flags);
> Does the math need to be inside the spinlock? Should probably not have
> any spinlock at all and just read it with lgm_get_clk_val() and trust
> that the hardware will return us something sane?
>
>> +
>> +       if (div <= 0)
>> +               return -EINVAL;
>> +
>> +       if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2))
>> +               return -EINVAL;
>> +
>> +       raw_spin_lock_irqsave(&ddiv->lock, flags);
>> +       lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift0, ddiv->width0,
>> +                       ddiv1 - 1);
>> +
>> +       lgm_set_clk_val(ddiv->membase, ddiv->reg,  ddiv->shift1, ddiv->width1,
>> +                       ddiv2 - 1);
> Can this not be combined? lgm_set_clk_val is sort of obfuscating the
> code. Please consider inlining it and then holding the spinlock across
> this entire function while doing the read/modify/write.

These two set_clk_val's can not be combined because they have different
non-contiguous bitmaps (shifts) and lgm_set_clk_val() is defined to handle
only one shift. However, i have addressed your other comment i.e. inline it
and hold spinlock across the function during read/modify/write.

>> +struct lgm_clk_mux {
>> +       struct clk_hw hw;
>> +       struct device *dev;
>> +       void __iomem *membase;
>> +       unsigned int reg;
>> +       u8 shift;
>> +       u8 width;
>> +       unsigned long flags;
>> +       raw_spinlock_t lock;
>> +};
>> +
>> +struct lgm_clk_divider {
>> +       struct clk_hw hw;
>> +       struct device *dev;
>> +       void __iomem *membase;
>> +       unsigned int reg;
>> +       u8 shift;
>> +       u8 width;
>> +       u8 shift_gate;
>> +       u8 width_gate;
>> +       unsigned long flags;
>> +       const struct clk_div_table *table;
>> +       raw_spinlock_t lock;
>> +};
>> +
>> +struct lgm_clk_ddiv {
>> +       struct clk_hw hw;
>> +       struct device *dev;
>> +       void __iomem *membase;
>> +       unsigned int reg;
>> +       u8 shift0;
>> +       u8 width0;
>> +       u8 shift1;
>> +       u8 width1;
>> +       u8 shift2;
>> +       u8 width2;
>> +       u8 shift_gate;
>> +       u8 width_gate;
>> +       unsigned int mult;
>> +       unsigned int div;
>> +       unsigned long flags;
>> +       raw_spinlock_t lock;
>> +};
>> +
>> +struct lgm_clk_gate {
>> +       struct clk_hw hw;
>> +       struct device *dev;
> These all have dev pointers, is it necessary? In theory we can have a
> clk_hw API that gets the dev pointer out for you if you want it, now
> that we store the dev pointer when a clk registers

We needed dev pointers just for dev_err() in clk_ops when they are called
back from core. I have now removed dev_err() calls from the driver clk_ops
as i believe the error info was not that useful. And so i have removed dev
pointers from above structures.

However, i think it would be good to have a clk_hw API which returns dev
pointer for drivers. Presently, dev pointer is stored inside clk_hw->clk_core
and clk_core is private to core, inaccessible from clk drivers.

>> +enum pll_type {
>> +       TYPE_ROPLL,
>> +       TYPE_LJPLL,
>> +       TYPE_NONE,
> Is this used? Remove it if not.

It is actually used.

>> +struct lgm_pll_clk_data {
>> +       unsigned int id;
>> +       const char *name;
>> +       const char *const *parent_names;
> Can you use the new way of specifying clk parents instead of using plain
> strings? Reminder to self, write that document.

I have changed it to new way i.e. by using fw_name. Only exception is where we
use clk API's clk_hw_register_fixed_rate() & clk_hw_register_fixed_factor().
In these API's, i am, for now, passing parent_data[0].name as parent_name.

>> +/* clock flags definition */
>> +#define CLOCK_FLAG_VAL_INIT    BIT(16)
>> +#define GATE_CLK_HW            BIT(17)
>> +#define GATE_CLK_SW            BIT(18)
>> +#define MUX_CLK_SW             GATE_CLK_SW
> Why do these bits start at 16? 

To avoid the conflict with clk_flags used across common struct clk
defined in clk-provider.h. Bits 0~13 are already used there. So
we keep some gap and start with 16 :). We don't maintain a separate
pure driver only flags bitmask as that would make it confusing.

> What does _HW and _SW mean? Is there
> hardware control of clks?

GATE_CLK_HW & GATE_CLK_SW is no longer needed for this SoC. So i have
removed it. MUX_CLK_SW is still needed. It is more of a workaround for
one particular combophy module for which get_parent/set_parent does not
apply (no hardware translation to select/query input clk source).
However, other MUX clks in this clk group have valid hardware translation
for parent clock sources.

>> +static const struct clk_div_table dcl_div[] = {
>> +       { .val = 0, .div = 6  },
>> +       { .val = 1, .div = 12 },
>> +       { .val = 2, .div = 24 },
>> +       { .val = 3, .div = 32 },
>> +       { .val = 4, .div = 48 },
>> +       { .val = 5, .div = 96 },
>> +       {}
> I guess 'div' being equal to 0 is the terminator?

Yes, but i am missing your point. Can you please elaborate more ?

>> +       ctx->np = np;
>> +       ctx->dev = dev;
>> +       raw_spin_lock_init(&ctx->lock);
> Why is it a raw spinlock?

Agree. We use CONFIG_SMP with no PREEMPT_RT. So i think it is same.
Have switched to normal spinlocks.

Regards,
Rahul

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ