From: Mike Turquette <mturquette@linaro.org> To: Stephen Boyd <sboyd@codeaurora.org> Cc: linux-arm-msm@vger.kernel.org, Mark Brown <broonie@kernel.org>, Saravana Kannan <skannan@codeaurora.org>, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap Date: Thu, 09 Jan 2014 21:44:24 -0800 [thread overview] Message-ID: <20140110054424.7168.46289@quantum> (raw) In-Reply-To: <52CE055C.5030103@codeaurora.org> Quoting Stephen Boyd (2014-01-08 18:11:40) > On 01/08/14 17:51, Mike Turquette wrote: > > Quoting Stephen Boyd (2013-12-23 17:12:26) > >> Add support to the clock core so that drivers can pass in a > >> regmap. If no regmap is specified try to query the device that's > >> registering the clock for its regmap. This should allow drivers > >> to use the core regmap helpers. This is based on a similar design > >> in the regulator framework. > >> > >> Cc: Mark Brown <broonie@kernel.org> > >> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> > >> --- > >> drivers/clk/clk.c | 8 ++++++++ > >> include/linux/clk-provider.h | 7 +++++++ > >> 2 files changed, 15 insertions(+) > >> > >> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > >> index 9ad7b71..5e71f5c 100644 > >> --- a/drivers/clk/clk.c > >> +++ b/drivers/clk/clk.c > >> @@ -20,6 +20,7 @@ > >> #include <linux/device.h> > >> #include <linux/init.h> > >> #include <linux/sched.h> > >> +#include <linux/regmap.h> > >> > >> static DEFINE_SPINLOCK(enable_lock); > >> static DEFINE_MUTEX(prepare_lock); > >> @@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) > >> clk->num_parents = hw->init->num_parents; > >> hw->clk = clk; > >> > >> + if (hw->init->regmap) > >> + hw->regmap = hw->init->regmap; > > Hi Stephen, > > > > The whole series looks good to me except for the placement of the regmap > > details inside struct clk_hw. That structure exists only to hide struct > > clk from the hardware-specific clock structure and I'd not like to set > > the precedent of shoving per-clock data into it. > > > > As an alternative, how about finding a way to put these per-clock regmap > > details into the hardware-specific clock structure? I understand that > > you want to make these ops available to others, which is why they are in > > the public struct clk_hw. I'm just wondering if that is the right way to > > do it... > > The regulator framework has gone this way. It seemed like a similar > approach in the clock framework would be the right way to go too. > > > > > Patch #3 illustrates the sort of struct-member-creep that worries me. > > What is to stop someone from putting "unsigned int divider_reg" or > > "unsigned int mux_reg", and then the thing just keeps growing. > > > > I see two ways forward if you don't want these members in struct clk_hw. > > 1) Inheritance: struct clk_regmap wrapper struct and > clk_register_regmap() and devm_clk_register_regmap() and then another > wrapper struct around that. > > example: > > struct clk_regmap { > struct clk_hw hw; > struct regmap *regmap; > unsigned int enable_reg; > unsigned int enable_mask; > bool enable_is_inverted; > }; > > struct clk_branch { > u32 hwcg_reg; > u32 halt_reg; > u8 hwcg_bit; > u8 halt_bit; > u8 halt_check; > > struct clk_regmap clkr; > }; > > static struct clk_branch gsbi1_uart_clk = { > .halt_reg = 0x2fcc, > .halt_bit = 10, > .clkr = { > .enable_reg = 0x29d4, > .enable_mask = BIT(9), > .hw.init = &(struct clk_init_data){ > .name = "gsbi1_uart_clk", > .parent_names = (const char *[]){ > "gsbi1_uart_src", > }, > .num_parents = 1, > .ops = &clk_branch_ops, > .flags = CLK_SET_RATE_PARENT, > }, > }, > }; If we're going to use these wrappers, why make it regmap specific? The struct clk_desc patches[1][2] can achieve this, but in a more generic way. > > > 2) Interfaces: Add a void *data in struct clk_hw that can point to > whatever I want and still have the same clk_regmap_register() and > devm_clk_regmap_register() > > Example: > > struct clk_hw { > struct clk *clk; > const struct clk_init_data *init; > void *data; > }; > > struct clk_regmap { > struct regmap *regmap; > unsigned int enable_reg; > unsigned int enable_mask; > bool enable_is_inverted; > }; > > struct clk_branch { > u32 hwcg_reg; > u32 halt_reg; > u8 hwcg_bit; > u8 halt_bit; > u8 halt_check; > > struct clk_hw; > }; > > static struct clk_branch gsbi1_uart_clk = { > .halt_reg = 0x2fcc, > .halt_bit = 10, > .hw = { > .data = &(struct clk_regmap){ > .enable_reg = 0x29d4, > .enable_mask = BIT(9), > }; > .init = &(struct clk_init_data){ > .name = "gsbi1_uart_clk", > .parent_names = (const char *[]){ > "gsbi1_uart_src", > }, > .num_parents = 1, > .ops = &clk_branch_ops, > .flags = CLK_SET_RATE_PARENT, > }, > }, > }; > > I guess option 2 is less likely given your comment about clk_hw being > nothing more than a traversal mechanism. Instead of private data, how about a .register() callback function that can point to anything you like? The clk_desc patches implement this and it would suffice for registering regmap ops or anything else, without polluting struct clk_hw. [1] http://www.spinics.net/lists/linux-omap/msg101822.html [2] http://www.spinics.net/lists/linux-omap/msg101698.html So you could statically define gsbi1_uart_clk with: static struct clk_branch_desc gsbi1_uart_clk_desc = { .halt_reg = 0x2fcc, .halt_bit = 10, .enable_reg = 0x29d4, .enable_mask = BIT(9), .desc = { .name = "gsbi1_uart_clk", .parent_names = (const char *[]){ "gsbi1_uart_src", }, .num_parents = 1, .ops = &clk_branch_ops, .flags = CLK_SET_RATE_PARENT, }, }; And then register it with: clk_register_desc(NULL, &gsbi1_uart_clk_desc.desc); This is very analogous to the way that you use use &gsbi1_uart_clk.hw but it is more generic and also doesn't pollute clk_hw any further. I also think your static data is quite a bit prettier using this method. Thoughts? Regards, Mike > > -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, > hosted by The Linux Foundation >
WARNING: multiple messages have this Message-ID (diff)
From: mturquette@linaro.org (Mike Turquette) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap Date: Thu, 09 Jan 2014 21:44:24 -0800 [thread overview] Message-ID: <20140110054424.7168.46289@quantum> (raw) In-Reply-To: <52CE055C.5030103@codeaurora.org> Quoting Stephen Boyd (2014-01-08 18:11:40) > On 01/08/14 17:51, Mike Turquette wrote: > > Quoting Stephen Boyd (2013-12-23 17:12:26) > >> Add support to the clock core so that drivers can pass in a > >> regmap. If no regmap is specified try to query the device that's > >> registering the clock for its regmap. This should allow drivers > >> to use the core regmap helpers. This is based on a similar design > >> in the regulator framework. > >> > >> Cc: Mark Brown <broonie@kernel.org> > >> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> > >> --- > >> drivers/clk/clk.c | 8 ++++++++ > >> include/linux/clk-provider.h | 7 +++++++ > >> 2 files changed, 15 insertions(+) > >> > >> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > >> index 9ad7b71..5e71f5c 100644 > >> --- a/drivers/clk/clk.c > >> +++ b/drivers/clk/clk.c > >> @@ -20,6 +20,7 @@ > >> #include <linux/device.h> > >> #include <linux/init.h> > >> #include <linux/sched.h> > >> +#include <linux/regmap.h> > >> > >> static DEFINE_SPINLOCK(enable_lock); > >> static DEFINE_MUTEX(prepare_lock); > >> @@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) > >> clk->num_parents = hw->init->num_parents; > >> hw->clk = clk; > >> > >> + if (hw->init->regmap) > >> + hw->regmap = hw->init->regmap; > > Hi Stephen, > > > > The whole series looks good to me except for the placement of the regmap > > details inside struct clk_hw. That structure exists only to hide struct > > clk from the hardware-specific clock structure and I'd not like to set > > the precedent of shoving per-clock data into it. > > > > As an alternative, how about finding a way to put these per-clock regmap > > details into the hardware-specific clock structure? I understand that > > you want to make these ops available to others, which is why they are in > > the public struct clk_hw. I'm just wondering if that is the right way to > > do it... > > The regulator framework has gone this way. It seemed like a similar > approach in the clock framework would be the right way to go too. > > > > > Patch #3 illustrates the sort of struct-member-creep that worries me. > > What is to stop someone from putting "unsigned int divider_reg" or > > "unsigned int mux_reg", and then the thing just keeps growing. > > > > I see two ways forward if you don't want these members in struct clk_hw. > > 1) Inheritance: struct clk_regmap wrapper struct and > clk_register_regmap() and devm_clk_register_regmap() and then another > wrapper struct around that. > > example: > > struct clk_regmap { > struct clk_hw hw; > struct regmap *regmap; > unsigned int enable_reg; > unsigned int enable_mask; > bool enable_is_inverted; > }; > > struct clk_branch { > u32 hwcg_reg; > u32 halt_reg; > u8 hwcg_bit; > u8 halt_bit; > u8 halt_check; > > struct clk_regmap clkr; > }; > > static struct clk_branch gsbi1_uart_clk = { > .halt_reg = 0x2fcc, > .halt_bit = 10, > .clkr = { > .enable_reg = 0x29d4, > .enable_mask = BIT(9), > .hw.init = &(struct clk_init_data){ > .name = "gsbi1_uart_clk", > .parent_names = (const char *[]){ > "gsbi1_uart_src", > }, > .num_parents = 1, > .ops = &clk_branch_ops, > .flags = CLK_SET_RATE_PARENT, > }, > }, > }; If we're going to use these wrappers, why make it regmap specific? The struct clk_desc patches[1][2] can achieve this, but in a more generic way. > > > 2) Interfaces: Add a void *data in struct clk_hw that can point to > whatever I want and still have the same clk_regmap_register() and > devm_clk_regmap_register() > > Example: > > struct clk_hw { > struct clk *clk; > const struct clk_init_data *init; > void *data; > }; > > struct clk_regmap { > struct regmap *regmap; > unsigned int enable_reg; > unsigned int enable_mask; > bool enable_is_inverted; > }; > > struct clk_branch { > u32 hwcg_reg; > u32 halt_reg; > u8 hwcg_bit; > u8 halt_bit; > u8 halt_check; > > struct clk_hw; > }; > > static struct clk_branch gsbi1_uart_clk = { > .halt_reg = 0x2fcc, > .halt_bit = 10, > .hw = { > .data = &(struct clk_regmap){ > .enable_reg = 0x29d4, > .enable_mask = BIT(9), > }; > .init = &(struct clk_init_data){ > .name = "gsbi1_uart_clk", > .parent_names = (const char *[]){ > "gsbi1_uart_src", > }, > .num_parents = 1, > .ops = &clk_branch_ops, > .flags = CLK_SET_RATE_PARENT, > }, > }, > }; > > I guess option 2 is less likely given your comment about clk_hw being > nothing more than a traversal mechanism. Instead of private data, how about a .register() callback function that can point to anything you like? The clk_desc patches implement this and it would suffice for registering regmap ops or anything else, without polluting struct clk_hw. [1] http://www.spinics.net/lists/linux-omap/msg101822.html [2] http://www.spinics.net/lists/linux-omap/msg101698.html So you could statically define gsbi1_uart_clk with: static struct clk_branch_desc gsbi1_uart_clk_desc = { .halt_reg = 0x2fcc, .halt_bit = 10, .enable_reg = 0x29d4, .enable_mask = BIT(9), .desc = { .name = "gsbi1_uart_clk", .parent_names = (const char *[]){ "gsbi1_uart_src", }, .num_parents = 1, .ops = &clk_branch_ops, .flags = CLK_SET_RATE_PARENT, }, }; And then register it with: clk_register_desc(NULL, &gsbi1_uart_clk_desc.desc); This is very analogous to the way that you use use &gsbi1_uart_clk.hw but it is more generic and also doesn't pollute clk_hw any further. I also think your static data is quite a bit prettier using this method. Thoughts? Regards, Mike > > -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, > hosted by The Linux Foundation >
next prev parent reply other threads:[~2014-01-10 5:44 UTC|newest] Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top 2013-12-24 1:12 [PATCH v4 00/15] Add support for MSM's mmio clock/reset controller Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 01/15] reset: Silence warning in reset-controller.h Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2014-01-06 17:28 ` Philipp Zabel 2014-01-06 17:28 ` Philipp Zabel 2013-12-24 1:12 ` [PATCH v4 02/15] clk: Allow drivers to pass in a regmap Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 13:13 ` Mark Brown 2013-12-24 13:13 ` Mark Brown 2014-01-09 1:51 ` Mike Turquette 2014-01-09 1:51 ` Mike Turquette 2014-01-09 2:11 ` Stephen Boyd 2014-01-09 2:11 ` Stephen Boyd 2014-01-09 22:12 ` Stephen Boyd 2014-01-09 22:12 ` Stephen Boyd 2014-01-10 5:44 ` Mike Turquette [this message] 2014-01-10 5:44 ` Mike Turquette 2014-01-10 7:05 ` Stephen Boyd 2014-01-10 7:05 ` Stephen Boyd 2014-01-14 2:25 ` Stephen Boyd 2014-01-14 2:25 ` Stephen Boyd 2014-01-15 9:28 ` Mike Turquette 2014-01-15 9:28 ` Mike Turquette 2014-01-15 19:03 ` Stephen Boyd 2014-01-15 19:03 ` Stephen Boyd 2014-01-14 3:54 ` Saravana Kannan 2014-01-14 3:54 ` Saravana Kannan 2014-01-15 9:36 ` Mike Turquette 2014-01-15 9:36 ` Mike Turquette 2014-01-15 10:54 ` Mark Brown 2014-01-15 10:54 ` Mark Brown 2014-01-17 1:38 ` Saravana Kannan 2014-01-17 1:38 ` Saravana Kannan 2013-12-24 1:12 ` [PATCH v4 03/15] clk: Add regmap core helpers for enable/disable/is_enabled Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 13:14 ` Mark Brown 2013-12-24 13:14 ` Mark Brown 2013-12-24 15:07 ` Gerhard Sittig 2013-12-24 15:07 ` Gerhard Sittig 2013-12-26 19:31 ` Stephen Boyd 2013-12-26 19:31 ` Stephen Boyd 2013-12-31 13:02 ` Gerhard Sittig 2013-12-31 13:02 ` Gerhard Sittig 2013-12-24 1:12 ` [PATCH v4 04/15] clk: Add set_rate_and_parent() op Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 05/15] clk: qcom: Add support for phase locked loops (PLLs) Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 06/15] clk: qcom: Add support for root clock generators (RCGs) Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 07/15] clk: qcom: Add support for branches/gate clocks Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 08/15] clk: qcom: Add reset controller support Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 09/15] clk: qcom: Add support for MSM8960's global clock controller (GCC) Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 10/15] clk: qcom: Add support for MSM8960's multimedia clock controller (MMCC) Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 11/15] clk: qcom: Add support for MSM8974's global clock controller (GCC) Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 12/15] clk: qcom: Add support for MSM8974's multimedia clock controller (MMCC) Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 13/15] clk: qcom: Add support for MSM8660's global clock controller (GCC) Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 14/15] devicetree: bindings: Document qcom,gcc Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` [PATCH v4 15/15] devicetree: bindings: Document qcom,mmcc Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd 2013-12-24 1:12 ` Stephen Boyd
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=20140110054424.7168.46289@quantum \ --to=mturquette@linaro.org \ --cc=broonie@kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-arm-msm@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=sboyd@codeaurora.org \ --cc=skannan@codeaurora.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: linkBe 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.