All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Boyd <sboyd@kernel.org>
To: Andrea della Porta <andrea.porta@suse.com>,
	Andrew Lunn <andrew@lunn.ch>, Arnd Bergmann <arnd@arndb.de>,
	Bartosz Golaszewski <brgl@bgdev.pl>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Broadcom internal kernel review list
	<bcm-kernel-feedback-list@broadcom.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Conor Dooley <conor+dt@kernel.org>,
	Derek Kiernan <derek.kiernan@amd.com>,
	Dragan Cvetic <dragan.cvetic@amd.com>,
	Florian Fainelli <florian.fainelli@broadcom.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Herve Codina <herve.codina@bootlin.com>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Krzysztof Wilczynski <kw@linux.com>,
	Linus Walleij <linus.walleij@linaro.org>,
	Lorenzo Pieralisi <lpieralisi@kernel.org>,
	Luca Ceresoli <luca.ceresoli@bootlin.com>,
	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>,
	Masahiro Yamada <masahiroy@kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Rob Herring <robh@kernel.org>,
	Saravana Kannan <saravanak@google.com>,
	Stefan Wahren <wahrenst@gmx.net>,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	Will Deacon <will@kernel.org>,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
	linux-rpi-kernel@lists.infradead.org
Subject: Re: [PATCH v3 07/12] clk: rp1: Add support for clocks provided by RP1
Date: Mon, 28 Oct 2024 15:20:55 -0700	[thread overview]
Message-ID: <01c2bb3609dcb32191a78293c1666b0a.sboyd@kernel.org> (raw)
In-Reply-To: <c20e3d6d87c71691b149cdeeafc94009953346b2.1730123575.git.andrea.porta@suse.com>

Quoting Andrea della Porta (2024-10-28 07:07:24)
> diff --git a/drivers/clk/clk-rp1.c b/drivers/clk/clk-rp1.c
> new file mode 100644
> index 000000000000..69b9cf037cb2
> --- /dev/null
[...]
> +
> +struct rp1_clockman {
> +       struct device *dev;
> +       void __iomem *regs;

Do you still need this if there's a regmap?

> +       struct regmap *regmap;
> +       spinlock_t regs_lock; /* spinlock for all clocks */

Do you need this or is the spinlock in the regmap sufficient?

> +
> +       /* Must be last */
> +       struct clk_hw_onecell_data onecell;
> +};
> +
> +struct rp1_pll_core_data {
> +       const char *name;

These 'name' members can move to clk_init_data?

> +       u32 cs_reg;
> +       u32 pwr_reg;
> +       u32 fbdiv_int_reg;
> +       u32 fbdiv_frac_reg;
> +       unsigned long flags;

And probably flags as well? It seems like clk_init_data should be
declared at the same time as struct rp1_pll_core_data is.

> +       u32 fc0_src;
> +};
> +
> +struct rp1_pll_data {
> +       const char *name;
> +       u32 ctrl_reg;
> +       unsigned long flags;
> +       u32 fc0_src;
> +};
> +
> +struct rp1_pll_ph_data {
> +       const char *name;
> +       unsigned int phase;
> +       unsigned int fixed_divider;
> +       u32 ph_reg;
> +       unsigned long flags;
> +       u32 fc0_src;
> +};
> +
> +struct rp1_pll_divider_data {
> +       const char *name;
> +       u32 sec_reg;
> +       unsigned long flags;
> +       u32 fc0_src;
> +};
> +
> +struct rp1_clock_data {
> +       const char *name;
> +       int num_std_parents;
> +       int num_aux_parents;
> +       unsigned long flags;
> +       u32 oe_mask;
> +       u32 clk_src_mask;
> +       u32 ctrl_reg;
> +       u32 div_int_reg;
> +       u32 div_frac_reg;
> +       u32 sel_reg;
> +       u32 div_int_max;
> +       unsigned long max_freq;
> +       u32 fc0_src;
> +};
> +
> +struct rp1_clk_desc {
> +       struct clk_hw *(*clk_register)(struct rp1_clockman *clockman,
> +                                      struct rp1_clk_desc *desc);
> +       const void *data;
> +       struct clk_hw hw;
> +       struct rp1_clockman *clockman;
> +       unsigned long cached_rate;
> +       struct clk_divider div;
> +};
> +
> +#define FIELD_SET(_reg, _mask, _val)           \
> +do {                                           \
> +       u32 mask = (_mask);                     \
> +       (_reg) &= ~mask;                        \
> +       (_reg) |= FIELD_PREP(mask, (_val));     \

Please just write

	reg &= ~mask
	reg |= FIELD_PREP(mask, val);

instead of using this macro.

> +} while (0)
> +
> +
[...]
> +
> +static struct clk_hw *rp1_register_pll_core(struct rp1_clockman *clockman,
> +                                           struct rp1_clk_desc *desc)
> +{
> +       const struct rp1_pll_core_data *pll_core_data = desc->data;
> +       struct clk_init_data init = { };
> +       int ret;
> +
> +       /* All of the PLL cores derive from the external oscillator. */
> +       init.parent_data = desc->hw.init->parent_data;
> +       init.num_parents = desc->hw.init->num_parents;
> +       init.name = pll_core_data->name;
> +       init.ops = &rp1_pll_core_ops;
> +       init.flags = pll_core_data->flags | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL;
> +
> +       desc->clockman = clockman;
> +       desc->hw.init = &init;
> +
> +       ret = devm_clk_hw_register(clockman->dev, &desc->hw);
> +
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       return &desc->hw;
> +}
> +
> +static struct clk_hw *rp1_register_pll(struct rp1_clockman *clockman,
> +                                      struct rp1_clk_desc *desc)
> +{
> +       const struct rp1_pll_data *pll_data = desc->data;
> +       struct clk_init_data init = { };
> +       int ret;
> +
> +       init.parent_data = desc->hw.init->parent_data;
> +       init.num_parents = desc->hw.init->num_parents;
> +       init.name = pll_data->name;
> +       init.ops = &rp1_pll_ops;
> +       init.flags = pll_data->flags | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL;
> +
> +       desc->clockman = clockman;
> +       desc->hw.init = &init;
> +
> +       ret = devm_clk_hw_register(clockman->dev, &desc->hw);
> +
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       return &desc->hw;
> +}
> +
> +static struct clk_hw *rp1_register_pll_ph(struct rp1_clockman *clockman,
> +                                         struct rp1_clk_desc *desc)
> +{
> +       const struct rp1_pll_ph_data *ph_data = desc->data;
> +       struct clk_init_data init = { };
> +       int ret;
> +
> +       init.parent_data = desc->hw.init->parent_data;
> +       init.num_parents = desc->hw.init->num_parents;
> +       init.name = ph_data->name;
> +       init.ops = &rp1_pll_ph_ops;
> +       init.flags = ph_data->flags | CLK_IGNORE_UNUSED;
> +
> +       desc->clockman = clockman;
> +       desc->hw.init = &init;
> +
> +       ret = devm_clk_hw_register(clockman->dev, &desc->hw);
> +
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       return &desc->hw;
> +}
> +
> +static struct clk_hw *rp1_register_pll_divider(struct rp1_clockman *clockman,
> +                                              struct rp1_clk_desc *desc)
> +{
> +       const struct rp1_pll_data *divider_data = desc->data;
> +       struct clk_init_data init = { };
> +       int ret;
> +
> +       init.parent_data = desc->hw.init->parent_data;
> +       init.num_parents = desc->hw.init->num_parents;
> +       init.name = divider_data->name;
> +       init.ops = &rp1_pll_divider_ops;
> +       init.flags = divider_data->flags | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL;
> +
> +       desc->div.reg = clockman->regs + divider_data->ctrl_reg;

Why is 'regs' used here? Isn't everything using a regmap now so it's all
offsets?

> +       desc->div.shift = PLL_SEC_DIV_SHIFT;
> +       desc->div.width = PLL_SEC_DIV_WIDTH;
> +       desc->div.flags = CLK_DIVIDER_ROUND_CLOSEST;
> +       desc->div.flags |= CLK_IS_CRITICAL;
> +       desc->div.lock = &clockman->regs_lock;
> +       desc->div.hw.init = &init;
> +       desc->div.table = pll_sec_div_table;
> +
> +       desc->clockman = clockman;
> +
> +       ret = devm_clk_hw_register(clockman->dev, &desc->div.hw);
> +
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       return &desc->div.hw;
> +}
> +
> +static struct clk_hw *rp1_register_clock(struct rp1_clockman *clockman,
> +                                        struct rp1_clk_desc *desc)
> +{
> +       const struct rp1_clock_data *clock_data = desc->data;
> +       struct clk_init_data init = { };
> +       int ret;
> +
> +       if (WARN_ON_ONCE(MAX_CLK_PARENTS <
> +              clock_data->num_std_parents + clock_data->num_aux_parents))
> +               return NULL;
> +
> +       /* There must be a gap for the AUX selector */
> +       if (WARN_ON_ONCE(clock_data->num_std_parents > AUX_SEL &&
> +                        desc->hw.init->parent_data[AUX_SEL].index != -1))
> +               return NULL;
> +
> +       init.parent_data = desc->hw.init->parent_data;
> +       init.num_parents = desc->hw.init->num_parents;
> +       init.name = clock_data->name;
> +       init.flags = clock_data->flags | CLK_IGNORE_UNUSED;
> +       init.ops = &rp1_clk_ops;
> +
> +       desc->clockman = clockman;
> +       desc->hw.init = &init;
> +
> +       ret = devm_clk_hw_register(clockman->dev, &desc->hw);
> +
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       return &desc->hw;
> +}
> +
> +/* Assignment helper macros for different clock types. */
> +#define _REGISTER(f, ...)      { .clk_register = f, __VA_ARGS__ }
> +
> +#define PARENT_CLK(pnum, ...)  .hw.init = &(const struct clk_init_data) { \

Instead of this macro just use CLK_HW_INIT_HW() or
CLK_HW_INIT_PARENTS_DATA()?

> +                               .parent_data = (const struct               \
> +                                               clk_parent_data[]) {       \
> +                                                       __VA_ARGS__        \
> +                                               },                         \
> +                               .num_parents = pnum }
> +
> +#define CLK_DATA(type, ...)    .data = &(struct type) { __VA_ARGS__ }
> +
> +#define REGISTER_PLL_CORE(...) _REGISTER(&rp1_register_pll_core,       \
> +                                         __VA_ARGS__)
> +
> +#define REGISTER_PLL(...)      _REGISTER(&rp1_register_pll,            \
> +                                         __VA_ARGS__)
> +
> +#define REGISTER_PLL_PH(...)   _REGISTER(&rp1_register_pll_ph,         \
> +                                         __VA_ARGS__)
> +
> +#define REGISTER_PLL_DIV(...)  _REGISTER(&rp1_register_pll_divider,    \
> +                                         __VA_ARGS__)
> +
> +#define REGISTER_CLK(...)      _REGISTER(&rp1_register_clock,          \
> +                                         __VA_ARGS__)
> +
> +static struct rp1_clk_desc clk_desc_array[] = {
> +       [RP1_PLL_SYS_CORE] = REGISTER_PLL_CORE(PARENT_CLK(1, { .index = 0 }),
> +                               CLK_DATA(rp1_pll_core_data,
> +                                        .name = "pll_sys_core",
> +                                        .cs_reg = PLL_SYS_CS,
> +                                        .pwr_reg = PLL_SYS_PWR,
> +                                        .fbdiv_int_reg = PLL_SYS_FBDIV_INT,
> +                                        .fbdiv_frac_reg = PLL_SYS_FBDIV_FRAC,
> +                               )),
> +
> +       [RP1_PLL_AUDIO_CORE] = REGISTER_PLL_CORE(PARENT_CLK(1, { .index = 0 }),
> +                               CLK_DATA(rp1_pll_core_data,
> +                                        .name = "pll_audio_core",
> +                                        .cs_reg = PLL_AUDIO_CS,
> +                                        .pwr_reg = PLL_AUDIO_PWR,
> +                                        .fbdiv_int_reg = PLL_AUDIO_FBDIV_INT,
> +                                        .fbdiv_frac_reg = PLL_AUDIO_FBDIV_FRAC,
> +                               )),
> +
> +       [RP1_PLL_VIDEO_CORE] = REGISTER_PLL_CORE(PARENT_CLK(1, { .index = 0 }),
> +                               CLK_DATA(rp1_pll_core_data,
> +                                        .name = "pll_video_core",
> +                                        .cs_reg = PLL_VIDEO_CS,
> +                                        .pwr_reg = PLL_VIDEO_PWR,
> +                                        .fbdiv_int_reg = PLL_VIDEO_FBDIV_INT,
> +                                        .fbdiv_frac_reg = PLL_VIDEO_FBDIV_FRAC,
> +                               )),
> +
> +       [RP1_PLL_SYS] = REGISTER_PLL(PARENT_CLK(1,
> +                               { .hw = &clk_desc_array[RP1_PLL_SYS_CORE].hw }
> +                               ),
> +                               CLK_DATA(rp1_pll_data,
> +                                        .name = "pll_sys",
> +                                        .ctrl_reg = PLL_SYS_PRIM,
> +                                        .fc0_src = FC_NUM(0, 2),
> +                               )),
> +
> +       [RP1_CLK_ETH_TSU] = REGISTER_CLK(PARENT_CLK(1, { .index = 0 }),
> +                               CLK_DATA(rp1_clock_data,
> +                                        .name = "clk_eth_tsu",
> +                                        .num_std_parents = 0,
> +                                        .num_aux_parents = 1,
> +                                        .ctrl_reg = CLK_ETH_TSU_CTRL,
> +                                        .div_int_reg = CLK_ETH_TSU_DIV_INT,
> +                                        .sel_reg = CLK_ETH_TSU_SEL,
> +                                        .div_int_max = DIV_INT_8BIT_MAX,
> +                                        .max_freq = 50 * HZ_PER_MHZ,
> +                                        .fc0_src = FC_NUM(5, 7),
> +                               )),
> +
> +       [RP1_CLK_SYS] = REGISTER_CLK(PARENT_CLK(3,
> +                               { .index = 0 },
> +                               { .index = -1 },
> +                               { .hw = &clk_desc_array[RP1_PLL_SYS].hw }
> +                               ),
> +                               CLK_DATA(rp1_clock_data,
> +                                        .name = "clk_sys",
> +                                        .num_std_parents = 3,
> +                                        .num_aux_parents = 0,
> +                                        .ctrl_reg = CLK_SYS_CTRL,
> +                                        .div_int_reg = CLK_SYS_DIV_INT,
> +                                        .sel_reg = CLK_SYS_SEL,
> +                                        .div_int_max = DIV_INT_24BIT_MAX,
> +                                        .max_freq = 200 * HZ_PER_MHZ,
> +                                        .fc0_src = FC_NUM(0, 4),
> +                                        .clk_src_mask = 0x3,
> +                               )),
> +
> +       [RP1_PLL_SYS_PRI_PH] = REGISTER_PLL_PH(PARENT_CLK(1,
> +                               { .hw = &clk_desc_array[RP1_PLL_SYS].hw }
> +                               ),
> +                               CLK_DATA(rp1_pll_ph_data,
> +                                        .name = "pll_sys_pri_ph",
> +                                        .ph_reg = PLL_SYS_PRIM,
> +                                        .fixed_divider = 2,
> +                                        .phase = RP1_PLL_PHASE_0,
> +                                        .fc0_src = FC_NUM(1, 2),
> +                               )),
> +
> +       [RP1_PLL_SYS_SEC] = REGISTER_PLL_DIV(PARENT_CLK(1,
> +                               { .hw = &clk_desc_array[RP1_PLL_SYS_CORE].hw }
> +                               ),
> +                               CLK_DATA(rp1_pll_data,
> +                                        .name = "pll_sys_sec",
> +                                        .ctrl_reg = PLL_SYS_SEC,
> +                                        .fc0_src = FC_NUM(2, 2),
> +                               )),
> +};
> +
> +static const struct regmap_range rp1_reg_ranges[] = {
> +       regmap_reg_range(PLL_SYS_CS, PLL_SYS_SEC),
> +       regmap_reg_range(PLL_AUDIO_CS, PLL_AUDIO_TERN),
> +       regmap_reg_range(PLL_VIDEO_CS, PLL_VIDEO_SEC),
> +       regmap_reg_range(GPCLK_OE_CTRL, GPCLK_OE_CTRL),
> +       regmap_reg_range(CLK_SYS_CTRL, CLK_SYS_DIV_INT),
> +       regmap_reg_range(CLK_SYS_SEL, CLK_SYS_SEL),
> +       regmap_reg_range(CLK_SLOW_SYS_CTRL, CLK_SLOW_SYS_DIV_INT),
> +       regmap_reg_range(CLK_SLOW_SYS_SEL, CLK_SLOW_SYS_SEL),
> +       regmap_reg_range(CLK_DMA_CTRL, CLK_DMA_DIV_INT),
> +       regmap_reg_range(CLK_DMA_SEL, CLK_DMA_SEL),
> +       regmap_reg_range(CLK_UART_CTRL, CLK_UART_DIV_INT),
> +       regmap_reg_range(CLK_UART_SEL, CLK_UART_SEL),
> +       regmap_reg_range(CLK_ETH_CTRL, CLK_ETH_DIV_INT),
> +       regmap_reg_range(CLK_ETH_SEL, CLK_ETH_SEL),
> +       regmap_reg_range(CLK_PWM0_CTRL, CLK_PWM0_SEL),
> +       regmap_reg_range(CLK_PWM1_CTRL, CLK_PWM1_SEL),
> +       regmap_reg_range(CLK_AUDIO_IN_CTRL, CLK_AUDIO_IN_DIV_INT),
> +       regmap_reg_range(CLK_AUDIO_IN_SEL, CLK_AUDIO_IN_SEL),
> +       regmap_reg_range(CLK_AUDIO_OUT_CTRL, CLK_AUDIO_OUT_DIV_INT),
> +       regmap_reg_range(CLK_AUDIO_OUT_SEL, CLK_AUDIO_OUT_SEL),
> +       regmap_reg_range(CLK_I2S_CTRL, CLK_I2S_DIV_INT),
> +       regmap_reg_range(CLK_I2S_SEL, CLK_I2S_SEL),
> +       regmap_reg_range(CLK_MIPI0_CFG_CTRL, CLK_MIPI0_CFG_DIV_INT),
> +       regmap_reg_range(CLK_MIPI0_CFG_SEL, CLK_MIPI0_CFG_SEL),
> +       regmap_reg_range(CLK_MIPI1_CFG_CTRL, CLK_MIPI1_CFG_DIV_INT),
> +       regmap_reg_range(CLK_MIPI1_CFG_SEL, CLK_MIPI1_CFG_SEL),
> +       regmap_reg_range(CLK_PCIE_AUX_CTRL, CLK_PCIE_AUX_DIV_INT),
> +       regmap_reg_range(CLK_PCIE_AUX_SEL, CLK_PCIE_AUX_SEL),
> +       regmap_reg_range(CLK_USBH0_MICROFRAME_CTRL, CLK_USBH0_MICROFRAME_DIV_INT),
> +       regmap_reg_range(CLK_USBH0_MICROFRAME_SEL, CLK_USBH0_MICROFRAME_SEL),
> +       regmap_reg_range(CLK_USBH1_MICROFRAME_CTRL, CLK_USBH1_MICROFRAME_DIV_INT),
> +       regmap_reg_range(CLK_USBH1_MICROFRAME_SEL, CLK_USBH1_MICROFRAME_SEL),
> +       regmap_reg_range(CLK_USBH0_SUSPEND_CTRL, CLK_USBH0_SUSPEND_DIV_INT),
> +       regmap_reg_range(CLK_USBH0_SUSPEND_SEL, CLK_USBH0_SUSPEND_SEL),
> +       regmap_reg_range(CLK_USBH1_SUSPEND_CTRL, CLK_USBH1_SUSPEND_DIV_INT),
> +       regmap_reg_range(CLK_USBH1_SUSPEND_SEL, CLK_USBH1_SUSPEND_SEL),
> +       regmap_reg_range(CLK_ETH_TSU_CTRL, CLK_ETH_TSU_DIV_INT),
> +       regmap_reg_range(CLK_ETH_TSU_SEL, CLK_ETH_TSU_SEL),
> +       regmap_reg_range(CLK_ADC_CTRL, CLK_ADC_DIV_INT),
> +       regmap_reg_range(CLK_ADC_SEL, CLK_ADC_SEL),
> +       regmap_reg_range(CLK_SDIO_TIMER_CTRL, CLK_SDIO_TIMER_DIV_INT),
> +       regmap_reg_range(CLK_SDIO_TIMER_SEL, CLK_SDIO_TIMER_SEL),
> +       regmap_reg_range(CLK_SDIO_ALT_SRC_CTRL, CLK_SDIO_ALT_SRC_DIV_INT),
> +       regmap_reg_range(CLK_SDIO_ALT_SRC_SEL, CLK_SDIO_ALT_SRC_SEL),
> +       regmap_reg_range(CLK_GP0_CTRL, CLK_GP0_SEL),
> +       regmap_reg_range(CLK_GP1_CTRL, CLK_GP1_SEL),
> +       regmap_reg_range(CLK_GP2_CTRL, CLK_GP2_SEL),
> +       regmap_reg_range(CLK_GP3_CTRL, CLK_GP3_SEL),
> +       regmap_reg_range(CLK_GP4_CTRL, CLK_GP4_SEL),
> +       regmap_reg_range(CLK_GP5_CTRL, CLK_GP5_SEL),
> +       regmap_reg_range(CLK_SYS_RESUS_CTRL, CLK_SYS_RESUS_CTRL),
> +       regmap_reg_range(CLK_SLOW_SYS_RESUS_CTRL, CLK_SLOW_SYS_RESUS_CTRL),
> +       regmap_reg_range(FC0_REF_KHZ, FC0_RESULT),
> +       regmap_reg_range(VIDEO_CLK_VEC_CTRL, VIDEO_CLK_VEC_DIV_INT),
> +       regmap_reg_range(VIDEO_CLK_VEC_SEL, VIDEO_CLK_DPI_DIV_INT),
> +       regmap_reg_range(VIDEO_CLK_DPI_SEL, VIDEO_CLK_MIPI1_DPI_SEL),
> +};
> +
> +static const struct regmap_access_table rp1_reg_table = {
> +       .yes_ranges = rp1_reg_ranges,
> +       .n_yes_ranges = ARRAY_SIZE(rp1_reg_ranges),
> +};
> +
> +static const struct regmap_config rp1_clk_regmap_cfg = {
> +       .reg_bits = 32,
> +       .val_bits = 32,
> +       .reg_stride = 4,
> +       .max_register = PLL_VIDEO_SEC,
> +       .name = "rp1-clk",
> +       .rd_table = &rp1_reg_table,
> +};
> +
> +static int rp1_clk_probe(struct platform_device *pdev)
> +{
> +       const size_t asize = ARRAY_SIZE(clk_desc_array);
> +       struct rp1_clk_desc *desc;
> +       struct device *dev = &pdev->dev;
> +       struct rp1_clockman *clockman;
> +       struct clk_hw **hws;
> +       unsigned int i;
> +
> +       clockman = devm_kzalloc(dev, struct_size(clockman, onecell.hws, asize),
> +                               GFP_KERNEL);
> +       if (!clockman)
> +               return -ENOMEM;
> +
> +       spin_lock_init(&clockman->regs_lock);
> +       clockman->dev = dev;
> +
> +       clockman->regs = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(clockman->regs))
> +               return PTR_ERR(clockman->regs);
> +
> +       clockman->regmap = devm_regmap_init_mmio(dev, clockman->regs,
> +                                                &rp1_clk_regmap_cfg);
> +       if (IS_ERR(clockman->regmap)) {
> +               dev_err(dev, "could not init clock regmap\n");

return dev_err_probe()?

> +               return PTR_ERR(clockman->regmap);
> +       }
> +
> +       clockman->onecell.num = asize;
> +       hws = clockman->onecell.hws;
> +
> +       for (i = 0; i < asize; i++) {
> +               desc = &clk_desc_array[i];
> +               if (desc->clk_register && desc->data) {
> +                       hws[i] = desc->clk_register(clockman, desc);
> +                       if (IS_ERR_OR_NULL(hws[i]))
> +                               dev_err_probe(dev, PTR_ERR(hws[i]),
> +                                             "Unable to register clock: %s\n",
> +                                             clk_hw_get_name(hws[i]));
> +               }
> +       }
> +
> +       platform_set_drvdata(pdev, clockman);
> +
> +       return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
> +                                          &clockman->onecell);
> +}

  reply	other threads:[~2024-10-28 22:20 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-28 14:07 [PATCH v3 00/12] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
2024-10-28 14:07 ` [PATCH v3 01/12] dt-bindings: clock: Add RaspberryPi RP1 clock bindings Andrea della Porta
2024-10-28 14:21   ` Krzysztof Kozlowski
2024-10-29  7:23   ` Krzysztof Kozlowski
2024-10-31  9:16     ` Andrea della Porta
2024-11-15 11:31       ` Andrea della Porta
2024-11-15 23:00         ` Stephen Boyd
2024-10-28 14:07 ` [PATCH v3 02/12] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings Andrea della Porta
2024-10-29  7:26   ` Krzysztof Kozlowski
2024-10-31 14:07     ` Andrea della Porta
2024-10-31 18:10       ` Krzysztof Kozlowski
2024-11-04 11:11         ` Andrea della Porta
2024-11-07 11:57           ` Krzysztof Kozlowski
2024-10-28 14:07 ` [PATCH v3 03/12] dt-bindings: pci: Add common schema for devices accessible through PCI BARs Andrea della Porta
2024-10-29  7:28   ` Krzysztof Kozlowski
2024-10-31 14:20     ` Andrea della Porta
2024-10-31 18:06       ` Krzysztof Kozlowski
2024-11-04 11:18         ` Andrea della Porta
2024-10-28 14:07 ` [PATCH v3 04/12] dt-bindings: misc: Add device specific bindings for RaspberryPi RP1 Andrea della Porta
2024-11-06 14:50   ` Manivannan Sadhasivam
2024-11-07  7:17     ` Andrea della Porta
2024-10-28 14:07 ` [PATCH v3 05/12] PCI: of_property: Assign PCI instead of CPU bus address to dynamic bridge nodes Andrea della Porta
2024-10-28 16:57   ` Bjorn Helgaas
2024-11-02 17:09   ` Manivannan Sadhasivam
2024-11-04  8:54     ` Andrea della Porta
2024-11-04 15:05       ` Manivannan Sadhasivam
2024-11-04 23:49         ` Bjorn Helgaas
2024-11-06 14:35           ` Manivannan Sadhasivam
2024-11-07  9:06             ` Andrea della Porta
2024-11-07 10:48               ` Manivannan Sadhasivam
2024-11-07 11:51             ` Stanimir Varbanov
2024-11-04  8:06   ` Herve Codina
2024-11-04  8:38     ` Andrea della Porta
2024-10-28 14:07 ` [PATCH v3 06/12] of: address: Preserve the flags portion on 1:1 dma-ranges mapping Andrea della Porta
2024-11-04  8:08   ` Herve Codina
2024-10-28 14:07 ` [PATCH v3 07/12] clk: rp1: Add support for clocks provided by RP1 Andrea della Porta
2024-10-28 22:20   ` Stephen Boyd [this message]
2024-11-05  8:30     ` Andrea della Porta
2024-10-31 12:07   ` kernel test robot
2024-10-31 14:12   ` kernel test robot
2024-11-01  4:14   ` kernel test robot
2024-10-28 14:07 ` [PATCH v3 08/12] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
2024-10-28 22:16   ` Linus Walleij
2024-10-28 22:18   ` Linus Walleij
2024-10-31 14:44     ` Andrea della Porta
2024-10-28 14:07 ` [PATCH v3 09/12] arm64: dts: rp1: Add support for RaspberryPi's RP1 device Andrea della Porta
2024-11-04 13:29   ` Stanimir Varbanov
2024-11-05 14:31     ` Andrea della Porta
2024-11-06 12:28       ` Andrea della Porta
2024-10-28 14:07 ` [PATCH v3 10/12] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
2024-11-04 13:43   ` Stanimir Varbanov
2024-11-05 15:53     ` Andrea della Porta
2024-10-28 14:07 ` [PATCH v3 11/12] arm64: dts: bcm2712: Add external clock for RP1 chipset on Rpi5 Andrea della Porta
2024-10-28 20:49   ` Stephen Boyd
2024-10-31 14:46     ` Andrea della Porta
2024-10-28 14:07 ` [PATCH v3 12/12] arm64: defconfig: Enable RP1 misc/clock/gpio drivers Andrea della Porta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=01c2bb3609dcb32191a78293c1666b0a.sboyd@kernel.org \
    --to=sboyd@kernel.org \
    --cc=andrea.porta@suse.com \
    --cc=andrew@lunn.ch \
    --cc=arnd@arndb.de \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=bhelgaas@google.com \
    --cc=brgl@bgdev.pl \
    --cc=catalin.marinas@arm.com \
    --cc=conor+dt@kernel.org \
    --cc=derek.kiernan@amd.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dragan.cvetic@amd.com \
    --cc=florian.fainelli@broadcom.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=herve.codina@bootlin.com \
    --cc=krzk+dt@kernel.org \
    --cc=kw@linux.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=lpieralisi@kernel.org \
    --cc=luca.ceresoli@bootlin.com \
    --cc=manivannan.sadhasivam@linaro.org \
    --cc=masahiroy@kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=robh@kernel.org \
    --cc=saravanak@google.com \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=wahrenst@gmx.net \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.