Message ID | d197ab836d84b89b94ff1927872126767d921e94.1582533919.git-series.maxime@cerno.tech (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/vc4: Support BCM2711 Display Pipeline | expand |
Hi Maxime,
I love your patch! Perhaps something to improve:
[auto build test WARNING on clk/clk-next]
[also build test WARNING on robh/for-next anholt/for-next v5.6-rc3 next-20200224]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Maxime-Ripard/drm-vc4-Support-BCM2711-Display-Pipeline/20200224-172730
base: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
coccinelle warnings: (new ones prefixed by >>)
>> drivers/clk/bcm/clk-raspberrypi.c:327:31-37: ERROR: application of sizeof to pointer
Please review and possibly fold the followup patch.
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On 2/24/20 1:06 AM, Maxime Ripard wrote: > The firmware has an interface to discover the clocks it exposes. > > Let's use it to discover, register the clocks in the clocks framework and > then expose them through the device tree for consumers to use them. > > Cc: Michael Turquette <mturquette@baylibre.com> > Cc: Stephen Boyd <sboyd@kernel.org> > Cc: linux-clk@vger.kernel.org > Signed-off-by: Maxime Ripard <maxime@cerno.tech> That seems like a re-implementaiton of SCMI without all of its protocols, without being able to use the existing drivers, maybe a firmware update should be considered so standard drivers can be leveraged?
Hi Maxime, I love your patch! Perhaps something to improve: [auto build test WARNING on clk/clk-next] [also build test WARNING on robh/for-next anholt/for-next v5.6-rc3 next-20200224] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/Maxime-Ripard/drm-vc4-Support-BCM2711-Display-Pipeline/20200224-172730 base: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next reproduce: # apt-get install sparse # sparse version: v0.6.1-173-ge0787745-dirty make ARCH=x86_64 allmodconfig make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' If you fix the issue, kindly add following tag Reported-by: kbuild test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) >> drivers/clk/bcm/clk-raspberrypi.c:365:56: sparse: sparse: incorrect type in argument 2 (different base types) >> drivers/clk/bcm/clk-raspberrypi.c:365:56: sparse: expected unsigned int parent >> drivers/clk/bcm/clk-raspberrypi.c:365:56: sparse: got restricted __le32 [usertype] parent drivers/clk/bcm/clk-raspberrypi.c:365:70: sparse: sparse: incorrect type in argument 3 (different base types) >> drivers/clk/bcm/clk-raspberrypi.c:365:70: sparse: expected unsigned int id >> drivers/clk/bcm/clk-raspberrypi.c:365:70: sparse: got restricted __le32 [usertype] id >> drivers/clk/bcm/clk-raspberrypi.c:369:31: sparse: sparse: restricted __le32 degrades to integer drivers/clk/bcm/clk-raspberrypi.c:370:33: sparse: sparse: restricted __le32 degrades to integer vim +365 drivers/clk/bcm/clk-raspberrypi.c 345 346 static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi, 347 struct clk_hw_onecell_data *data) 348 { 349 struct rpi_firmware_get_clocks_response *clks; 350 size_t clks_size = NUM_FW_CLKS * sizeof(*clks); 351 int ret; 352 353 clks = devm_kzalloc(rpi->dev, clks_size, GFP_KERNEL); 354 if (!clks) 355 return -ENOMEM; 356 357 ret = rpi_firmware_property(rpi->firmware, RPI_FIRMWARE_GET_CLOCKS, 358 clks, clks_size); 359 if (ret) 360 return ret; 361 362 while (clks->id) { 363 struct clk_hw *hw; 364 > 365 hw = raspberrypi_clk_register(rpi, clks->parent, clks->id); 366 if (IS_ERR(hw)) 367 return PTR_ERR(hw); 368 > 369 data->hws[clks->id] = hw; 370 data->num = clks->id + 1; 371 clks++; 372 } 373 374 return 0; 375 } 376 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Florian, On Mon, Feb 24, 2020 at 10:15:32AM -0800, Florian Fainelli wrote: > On 2/24/20 1:06 AM, Maxime Ripard wrote: > > The firmware has an interface to discover the clocks it exposes. > > > > Let's use it to discover, register the clocks in the clocks framework and > > then expose them through the device tree for consumers to use them. > > > > Cc: Michael Turquette <mturquette@baylibre.com> > > Cc: Stephen Boyd <sboyd@kernel.org> > > Cc: linux-clk@vger.kernel.org > > Signed-off-by: Maxime Ripard <maxime@cerno.tech> > > That seems like a re-implementaiton of SCMI without all of its > protocols, without being able to use the existing drivers, maybe a > firmware update should be considered so standard drivers can be leveraged? I'm not really qualified to talk about how the firmware will evolve in the future, but you're right that it looks a lot like what SCMI can do. Even if a firmware update was to support SCMI at some point, since the firmware is flashed in an EEPROM, we'd still have to support that interface. Maxime
Quoting Maxime Ripard (2020-02-24 01:06:24) > The firmware has an interface to discover the clocks it exposes. > > Let's use it to discover, register the clocks in the clocks framework and > then expose them through the device tree for consumers to use them. Everyone's doing it! :) > diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c > index 3f21888a3e3e..bf6a1e2dc099 100644 > --- a/drivers/clk/bcm/clk-raspberrypi.c > +++ b/drivers/clk/bcm/clk-raspberrypi.c > @@ -285,6 +285,95 @@ static struct clk_hw *raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi) > return &raspberrypi_clk_pllb_arm.hw; > } > > +static long raspberrypi_fw_dumb_round_rate(struct clk_hw *hw, > + unsigned long rate, > + unsigned long *parent_rate) > +{ > + return rate; Can we get a comment here like "The firmware does the rounding but doesn't tell us so we have to assume anything goes!" > +} > + > +static const struct clk_ops raspberrypi_firmware_clk_ops = { > + .is_prepared = raspberrypi_fw_is_prepared, > + .recalc_rate = raspberrypi_fw_get_rate, > + .round_rate = raspberrypi_fw_dumb_round_rate, > + .set_rate = raspberrypi_fw_set_rate, > +}; > + > +static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, > + unsigned int parent, > + unsigned int id) > +{ > + struct raspberrypi_clk_data *data; > + struct clk_init_data init = {}; > + int ret; > + > + if (id == RPI_FIRMWARE_ARM_CLK_ID) { > + struct clk_hw *hw; > + > + hw = raspberrypi_register_pllb(rpi); > + if (IS_ERR(hw)) { > + dev_err(rpi->dev, "Failed to initialize pllb, %ld\n", > + PTR_ERR(hw)); > + return hw; > + } > + > + hw = raspberrypi_register_pllb_arm(rpi); > + if (IS_ERR(hw)) > + return hw; > + > + return hw; Why the double return? Not just return raspberrypi_register_pllb_arm(rpi); > + } > + > + data = devm_kzalloc(rpi->dev, sizeof(data), GFP_KERNEL); > + if (!data) > + return ERR_PTR(-ENOMEM); > + data->rpi = rpi; > + data->id = id; > + > + init.name = devm_kasprintf(rpi->dev, GFP_KERNEL, "fw-clk-%u", id); > + init.ops = &raspberrypi_firmware_clk_ops; > + init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED; Why ignore unused? Doesn't seem to support enable/disable anyway so not sure this flag adds any value. > + > + data->hw.init = &init; > + > + ret = devm_clk_hw_register(rpi->dev, &data->hw); > + if (ret) > + return ERR_PTR(ret); > + > + return &data->hw; > +} > + > +static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi, > + struct clk_hw_onecell_data *data) > +{ > + struct rpi_firmware_get_clocks_response *clks; > + size_t clks_size = NUM_FW_CLKS * sizeof(*clks); > + int ret; > + > + clks = devm_kzalloc(rpi->dev, clks_size, GFP_KERNEL); Use devm_kcalloc to avoid overflow and indicate it's an array. > + if (!clks) > + return -ENOMEM; > + > + ret = rpi_firmware_property(rpi->firmware, RPI_FIRMWARE_GET_CLOCKS, > + clks, clks_size); > + if (ret) > + return ret; > + > + while (clks->id) { > + struct clk_hw *hw; > + > + hw = raspberrypi_clk_register(rpi, clks->parent, clks->id); > + if (IS_ERR(hw)) > + return PTR_ERR(hw); > + > + data->hws[clks->id] = hw; > + data->num = clks->id + 1; > + clks++; > + } > + > + return 0; > +} > + > static int raspberrypi_clk_probe(struct platform_device *pdev) > { > struct clk_hw_onecell_data *clk_data; > diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h > index 7800e12ee042..e5b7a41bba6b 100644 > --- a/include/soc/bcm2835/raspberrypi-firmware.h > +++ b/include/soc/bcm2835/raspberrypi-firmware.h > @@ -135,6 +135,11 @@ enum rpi_firmware_property_tag { > RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, > }; > > +struct rpi_firmware_get_clocks_response { > + __le32 parent; > + __le32 id; Why double spaced or tabbed out? > +}; > + > #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) > int rpi_firmware_property(struct rpi_firmware *fw,
diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index 3f21888a3e3e..bf6a1e2dc099 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -285,6 +285,95 @@ static struct clk_hw *raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi) return &raspberrypi_clk_pllb_arm.hw; } +static long raspberrypi_fw_dumb_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *parent_rate) +{ + return rate; +} + +static const struct clk_ops raspberrypi_firmware_clk_ops = { + .is_prepared = raspberrypi_fw_is_prepared, + .recalc_rate = raspberrypi_fw_get_rate, + .round_rate = raspberrypi_fw_dumb_round_rate, + .set_rate = raspberrypi_fw_set_rate, +}; + +static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, + unsigned int parent, + unsigned int id) +{ + struct raspberrypi_clk_data *data; + struct clk_init_data init = {}; + int ret; + + if (id == RPI_FIRMWARE_ARM_CLK_ID) { + struct clk_hw *hw; + + hw = raspberrypi_register_pllb(rpi); + if (IS_ERR(hw)) { + dev_err(rpi->dev, "Failed to initialize pllb, %ld\n", + PTR_ERR(hw)); + return hw; + } + + hw = raspberrypi_register_pllb_arm(rpi); + if (IS_ERR(hw)) + return hw; + + return hw; + } + + data = devm_kzalloc(rpi->dev, sizeof(data), GFP_KERNEL); + if (!data) + return ERR_PTR(-ENOMEM); + data->rpi = rpi; + data->id = id; + + init.name = devm_kasprintf(rpi->dev, GFP_KERNEL, "fw-clk-%u", id); + init.ops = &raspberrypi_firmware_clk_ops; + init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED; + + data->hw.init = &init; + + ret = devm_clk_hw_register(rpi->dev, &data->hw); + if (ret) + return ERR_PTR(ret); + + return &data->hw; +} + +static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi, + struct clk_hw_onecell_data *data) +{ + struct rpi_firmware_get_clocks_response *clks; + size_t clks_size = NUM_FW_CLKS * sizeof(*clks); + int ret; + + clks = devm_kzalloc(rpi->dev, clks_size, GFP_KERNEL); + if (!clks) + return -ENOMEM; + + ret = rpi_firmware_property(rpi->firmware, RPI_FIRMWARE_GET_CLOCKS, + clks, clks_size); + if (ret) + return ret; + + while (clks->id) { + struct clk_hw *hw; + + hw = raspberrypi_clk_register(rpi, clks->parent, clks->id); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + data->hws[clks->id] = hw; + data->num = clks->id + 1; + clks++; + } + + return 0; +} + static int raspberrypi_clk_probe(struct platform_device *pdev) { struct clk_hw_onecell_data *clk_data; @@ -292,7 +381,7 @@ static int raspberrypi_clk_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rpi_firmware *firmware; struct raspberrypi_clk *rpi; - struct clk_hw *hw; + int ret; firmware_node = of_parse_phandle(dev->of_node, "raspberrypi,firmware", 0); if (!firmware_node) { @@ -317,17 +406,9 @@ static int raspberrypi_clk_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - hw = raspberrypi_register_pllb(rpi); - if (IS_ERR(hw)) { - dev_err(dev, "Failed to initialize pllb, %ld\n", PTR_ERR(hw)); - return PTR_ERR(hw); - } - - hw = raspberrypi_register_pllb_arm(rpi); - if (IS_ERR(hw)) - return PTR_ERR(hw); - clk_data->hws[RPI_FIRMWARE_ARM_CLK_ID] = hw; - clk_data->num = RPI_FIRMWARE_ARM_CLK_ID + 1; + ret = raspberrypi_discover_clocks(rpi, clk_data); + if (ret) + return ret; ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h index 7800e12ee042..e5b7a41bba6b 100644 --- a/include/soc/bcm2835/raspberrypi-firmware.h +++ b/include/soc/bcm2835/raspberrypi-firmware.h @@ -135,6 +135,11 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, }; +struct rpi_firmware_get_clocks_response { + __le32 parent; + __le32 id; +}; + #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) int rpi_firmware_property(struct rpi_firmware *fw, u32 tag, void *data, size_t len);
The firmware has an interface to discover the clocks it exposes. Let's use it to discover, register the clocks in the clocks framework and then expose them through the device tree for consumers to use them. Cc: Michael Turquette <mturquette@baylibre.com> Cc: Stephen Boyd <sboyd@kernel.org> Cc: linux-clk@vger.kernel.org Signed-off-by: Maxime Ripard <maxime@cerno.tech> --- drivers/clk/bcm/clk-raspberrypi.c | 105 +++++++++++++++++++--- include/soc/bcm2835/raspberrypi-firmware.h | 5 +- 2 files changed, 98 insertions(+), 12 deletions(-)