Message ID | 20210504105940.100004-2-greentime.hu@sifive.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add SiFive FU740 PCIe host controller driver support | expand |
On Tue, May 04, 2021 at 06:59:35PM +0800, Greentime Hu wrote: > We add pcie_aux clock in this patch so that pcie driver can use > clk_prepare_enable() and clk_disable_unprepare() to enable and disable > pcie_aux clock. > > Signed-off-by: Greentime Hu <greentime.hu@sifive.com> > Acked-by: Stephen Boyd <sboyd@kernel.org> > --- > drivers/clk/sifive/fu740-prci.c | 11 +++++ > drivers/clk/sifive/fu740-prci.h | 2 +- > drivers/clk/sifive/sifive-prci.c | 41 +++++++++++++++++++ > drivers/clk/sifive/sifive-prci.h | 9 ++++ > include/dt-bindings/clock/sifive-fu740-prci.h | 1 + > 5 files changed, 63 insertions(+), 1 deletion(-) > > diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c > index 764d1097aa51..53f6e00a03b9 100644 > --- a/drivers/clk/sifive/fu740-prci.c > +++ b/drivers/clk/sifive/fu740-prci.c > @@ -72,6 +72,12 @@ static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = { > .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate, <...> > +/* PCIE AUX clock APIs for enable, disable. */ > +int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw) It should be bool > +{ > + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); > + struct __prci_data *pd = pc->pd; > + u32 r; > + > + r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); > + > + if (r & PRCI_PCIE_AUX_EN_MASK) > + return 1; > + else > + return 0; > +} and here simple "return r & PRCI_PCIE_AUX_EN_MASK;" > + > +int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw) > +{ > + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); > + struct __prci_data *pd = pc->pd; > + u32 r __maybe_unused; > + > + if (sifive_prci_pcie_aux_clock_is_enabled(hw)) > + return 0; You actually call to this new function only once, put your __prci_readl() here. Thanks
On Tue, May 04, 2021 at 03:24:19PM +0300, Leon Romanovsky wrote: > On Tue, May 04, 2021 at 06:59:35PM +0800, Greentime Hu wrote: > > We add pcie_aux clock in this patch so that pcie driver can use > > clk_prepare_enable() and clk_disable_unprepare() to enable and disable > > pcie_aux clock. > > > > Signed-off-by: Greentime Hu <greentime.hu@sifive.com> > > Acked-by: Stephen Boyd <sboyd@kernel.org> > > --- > > drivers/clk/sifive/fu740-prci.c | 11 +++++ > > drivers/clk/sifive/fu740-prci.h | 2 +- > > drivers/clk/sifive/sifive-prci.c | 41 +++++++++++++++++++ > > drivers/clk/sifive/sifive-prci.h | 9 ++++ > > include/dt-bindings/clock/sifive-fu740-prci.h | 1 + > > 5 files changed, 63 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c > > index 764d1097aa51..53f6e00a03b9 100644 > > --- a/drivers/clk/sifive/fu740-prci.c > > +++ b/drivers/clk/sifive/fu740-prci.c > > @@ -72,6 +72,12 @@ static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = { > > .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate, > > <...> > > > +/* PCIE AUX clock APIs for enable, disable. */ > > +int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw) > > It should be bool It's used via this function pointer: struct clk_ops { int (*is_enabled)(struct clk_hw *hw); so I think "int" is actually appropriate here. There are some weird/interesting bool vs int usages nearby, though: "bool __is_clk_gate_enabled()" goes to some trouble to convert int to bool ("return (reg_val & bit_mask) != 0;"), and then kona_peri_clk_is_enabled() converts the bool back to int ("return is_clk_gate_enabled(bcm_clk->ccu, gate) ? 1 : 0;"). "int lpc32xx_clk_gate_is_enabled()" actually returns a bool that is implicitly converted to int. Many *_is_enabled() functions return !!(...) where !! is an int-to-bool conversion that is arguably unnecessary and again results in an implicit conversion to int. I don't see any *problems* with any of these; it just seems like a little more mental effort to think about all the explicit and implicit conversions going on. > > +int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw) > > +{ > > + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); > > + struct __prci_data *pd = pc->pd; > > + u32 r __maybe_unused; > > + > > + if (sifive_prci_pcie_aux_clock_is_enabled(hw)) > > + return 0; > > You actually call to this new function only once, put your > __prci_readl() here. Both sifive_prci_pcie_aux_clock_enable() and sifive_prci_pcie_aux_clock_is_enabled() are used via the clk_ops function pointers. Maybe sifive_prci_pcie_aux_clock_is_enabled() could be replaced by the __prci_readl() here, but I don't know enough about clk_ops internals to know. Bjorn
On Tue, May 04, 2021 at 11:23:31AM -0500, Bjorn Helgaas wrote: > On Tue, May 04, 2021 at 03:24:19PM +0300, Leon Romanovsky wrote: > > On Tue, May 04, 2021 at 06:59:35PM +0800, Greentime Hu wrote: > > > We add pcie_aux clock in this patch so that pcie driver can use > > > clk_prepare_enable() and clk_disable_unprepare() to enable and disable > > > pcie_aux clock. > > > > > > Signed-off-by: Greentime Hu <greentime.hu@sifive.com> > > > Acked-by: Stephen Boyd <sboyd@kernel.org> > > > --- > > > drivers/clk/sifive/fu740-prci.c | 11 +++++ > > > drivers/clk/sifive/fu740-prci.h | 2 +- > > > drivers/clk/sifive/sifive-prci.c | 41 +++++++++++++++++++ > > > drivers/clk/sifive/sifive-prci.h | 9 ++++ > > > include/dt-bindings/clock/sifive-fu740-prci.h | 1 + > > > 5 files changed, 63 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c > > > index 764d1097aa51..53f6e00a03b9 100644 > > > --- a/drivers/clk/sifive/fu740-prci.c > > > +++ b/drivers/clk/sifive/fu740-prci.c > > > @@ -72,6 +72,12 @@ static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = { > > > .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate, > > > > <...> > > > > > +/* PCIE AUX clock APIs for enable, disable. */ > > > +int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw) > > > > It should be bool > > It's used via this function pointer: > > struct clk_ops { > int (*is_enabled)(struct clk_hw *hw); > > so I think "int" is actually appropriate here. Ahh, sorry, I missed that assignment. > > There are some weird/interesting bool vs int usages nearby, though: > > "bool __is_clk_gate_enabled()" goes to some trouble to convert > int to bool ("return (reg_val & bit_mask) != 0;"), and then > kona_peri_clk_is_enabled() converts the bool back to int ("return > is_clk_gate_enabled(bcm_clk->ccu, gate) ? 1 : 0;"). > > "int lpc32xx_clk_gate_is_enabled()" actually returns a bool that is > implicitly converted to int. > > Many *_is_enabled() functions return !!(...) where !! is an > int-to-bool conversion that is arguably unnecessary and again > results in an implicit conversion to int. > > I don't see any *problems* with any of these; it just seems like a > little more mental effort to think about all the explicit and implicit > conversions going on. The code is written once but read many times and I can't agree with your that examples given by you are not the *problems*. They clearly says "the API is not great and easily can be improved". Driver authors struggled to write bool-to-int conversion, it is very optimistic view that they won't struggle to read code too. Thanks
On Tue, May 04, 2021 at 09:12:57PM +0300, Leon Romanovsky wrote: > On Tue, May 04, 2021 at 11:23:31AM -0500, Bjorn Helgaas wrote: > > There are some weird/interesting bool vs int usages nearby, though: > > > > "bool __is_clk_gate_enabled()" goes to some trouble to convert > > int to bool ("return (reg_val & bit_mask) != 0;"), and then > > kona_peri_clk_is_enabled() converts the bool back to int ("return > > is_clk_gate_enabled(bcm_clk->ccu, gate) ? 1 : 0;"). > > > > "int lpc32xx_clk_gate_is_enabled()" actually returns a bool that is > > implicitly converted to int. > > > > Many *_is_enabled() functions return !!(...) where !! is an > > int-to-bool conversion that is arguably unnecessary and again > > results in an implicit conversion to int. > > > > I don't see any *problems* with any of these; it just seems like a > > little more mental effort to think about all the explicit and implicit > > conversions going on. > > The code is written once but read many times and I can't agree with > your that examples given by you are not the *problems*. They clearly > says "the API is not great and easily can be improved". I certainly agree that it's easier for readers if the style is consistent. I just meant I didn't see anything that's an actual bug. Bjorn
On Tue, May 04, 2021 at 01:45:55PM -0500, Bjorn Helgaas wrote: > On Tue, May 04, 2021 at 09:12:57PM +0300, Leon Romanovsky wrote: > > On Tue, May 04, 2021 at 11:23:31AM -0500, Bjorn Helgaas wrote: > > > > There are some weird/interesting bool vs int usages nearby, though: > > > > > > "bool __is_clk_gate_enabled()" goes to some trouble to convert > > > int to bool ("return (reg_val & bit_mask) != 0;"), and then > > > kona_peri_clk_is_enabled() converts the bool back to int ("return > > > is_clk_gate_enabled(bcm_clk->ccu, gate) ? 1 : 0;"). > > > > > > "int lpc32xx_clk_gate_is_enabled()" actually returns a bool that is > > > implicitly converted to int. > > > > > > Many *_is_enabled() functions return !!(...) where !! is an > > > int-to-bool conversion that is arguably unnecessary and again > > > results in an implicit conversion to int. > > > > > > I don't see any *problems* with any of these; it just seems like a > > > little more mental effort to think about all the explicit and implicit > > > conversions going on. > > > > The code is written once but read many times and I can't agree with > > your that examples given by you are not the *problems*. They clearly > > says "the API is not great and easily can be improved". > > I certainly agree that it's easier for readers if the style is > consistent. I just meant I didn't see anything that's an actual bug. No one said that it is a bug. My comment is better seen as s suggestion to the maintainers on how other subsystems keep their code base clean and up-to date. Once "the problem" is spotted, the submitter is asked to fix it globally including fixing other drivers if needed, before "new feature" can be merged. Of course, there are exceptions from this rule, but they are rare and usually given to the people who has proven record. Thanks > > Bjorn
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c index 764d1097aa51..53f6e00a03b9 100644 --- a/drivers/clk/sifive/fu740-prci.c +++ b/drivers/clk/sifive/fu740-prci.c @@ -72,6 +72,12 @@ static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = { .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate, }; +static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = { + .enable = sifive_prci_pcie_aux_clock_enable, + .disable = sifive_prci_pcie_aux_clock_disable, + .is_enabled = sifive_prci_pcie_aux_clock_is_enabled, +}; + /* List of clock controls provided by the PRCI */ struct __prci_clock __prci_init_clocks_fu740[] = { [PRCI_CLK_COREPLL] = { @@ -120,4 +126,9 @@ struct __prci_clock __prci_init_clocks_fu740[] = { .parent_name = "hfpclkpll", .ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops, }, + [PRCI_CLK_PCIE_AUX] = { + .name = "pcie_aux", + .parent_name = "hfclk", + .ops = &sifive_fu740_prci_pcie_aux_clk_ops, + }, }; diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h index 13ef971f7764..511a0bf7ba2b 100644 --- a/drivers/clk/sifive/fu740-prci.h +++ b/drivers/clk/sifive/fu740-prci.h @@ -9,7 +9,7 @@ #include "sifive-prci.h" -#define NUM_CLOCK_FU740 8 +#define NUM_CLOCK_FU740 9 extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740]; diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c index 1490b01ce629..9997a3fa4a38 100644 --- a/drivers/clk/sifive/sifive-prci.c +++ b/drivers/clk/sifive/sifive-prci.c @@ -453,6 +453,47 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd) r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */ } +/* PCIE AUX clock APIs for enable, disable. */ +int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw) +{ + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); + struct __prci_data *pd = pc->pd; + u32 r; + + r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); + + if (r & PRCI_PCIE_AUX_EN_MASK) + return 1; + else + return 0; +} + +int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw) +{ + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); + struct __prci_data *pd = pc->pd; + u32 r __maybe_unused; + + if (sifive_prci_pcie_aux_clock_is_enabled(hw)) + return 0; + + __prci_writel(1, PRCI_PCIE_AUX_OFFSET, pd); + r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */ + + return 0; +} + +void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw) +{ + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); + struct __prci_data *pd = pc->pd; + u32 r __maybe_unused; + + __prci_writel(0, PRCI_PCIE_AUX_OFFSET, pd); + r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */ + +} + /** * __prci_register_clocks() - register clock controls in the PRCI * @dev: Linux struct device diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h index dbdbd1722688..022c67cf053c 100644 --- a/drivers/clk/sifive/sifive-prci.h +++ b/drivers/clk/sifive/sifive-prci.h @@ -67,6 +67,11 @@ #define PRCI_DDRPLLCFG1_CKE_SHIFT 31 #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT) +/* PCIEAUX */ +#define PRCI_PCIE_AUX_OFFSET 0x14 +#define PRCI_PCIE_AUX_EN_SHIFT 0 +#define PRCI_PCIE_AUX_EN_MASK (0x1 << PRCI_PCIE_AUX_EN_SHIFT) + /* GEMGXLPLLCFG0 */ #define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0 @@ -296,4 +301,8 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw, unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate); +int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw); +int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw); +void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw); + #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */ diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h b/include/dt-bindings/clock/sifive-fu740-prci.h index cd7706ea5677..7899b7fee7db 100644 --- a/include/dt-bindings/clock/sifive-fu740-prci.h +++ b/include/dt-bindings/clock/sifive-fu740-prci.h @@ -19,5 +19,6 @@ #define PRCI_CLK_CLTXPLL 5 #define PRCI_CLK_TLCLK 6 #define PRCI_CLK_PCLK 7 +#define PRCI_CLK_PCIE_AUX 8 #endif /* __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H */