Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1329831 > unrolled thread

[PATCH 00/14] clk_hw based clkdev/DT providers

Started byStephen Boyd <sboyd@codeaurora.org>
First post2016-02-09 02:50 +0100
Last post2016-02-15 23:20 +0100
Articles 20 on this page of 21 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 06/14] clk: divider: Add hw based registration APIs Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 05/14] clkdev: Add clk_hw based registration APIs Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 11/14] clk: composite: Add hw based registration APIs Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 13/14] clk: fixed-rate: Add hw based registration APIs Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 04/14] clk: Add clk_hw OF clk providers Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 07/14] clk: gate: Add hw based registration APIs Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 08/14] clk: mux: Add hw based registration APIs Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 09/14] clk: fixed-factor: Add hw based registration APIs Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 12/14] clk: gpio: Add hw based registration APIs Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
    [PATCH 02/14] clkdev: Remove clk_register_clkdevs() Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
      Re: [PATCH 02/14] clkdev: Remove clk_register_clkdevs() Andy Shevchenko <andriy.shevchenko@linux.intel.com> - 2016-02-15 16:20 +0100
      Re: [PATCH 02/14] clkdev: Remove clk_register_clkdevs() Michael Turquette <mturquette@baylibre.com> - 2016-02-15 23:20 +0100
    [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd <sboyd@codeaurora.org> - 2016-02-09 02:50 +0100
      Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Lee Jones <lee.jones@linaro.org> - 2016-02-10 17:30 +0100
        Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd <sboyd@codeaurora.org> - 2016-02-10 19:40 +0100
          Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Lee Jones <lee.jones@linaro.org> - 2016-02-11 10:20 +0100
      Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Lee Jones <lee.jones@linaro.org> - 2016-02-11 12:10 +0100
      Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Andy Shevchenko <andriy.shevchenko@linux.intel.com> - 2016-02-15 16:20 +0100
      Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Michael Turquette <mturquette@baylibre.com> - 2016-02-15 23:20 +0100

Page 1 of 2  [1] 2  Next page →


#1329831 — [PATCH 00/14] clk_hw based clkdev/DT providers

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 00/14] clk_hw based clkdev/DT providers
Message-ID<r05Bf-5h7-5@gated-at.bofh.it>
We've mostly split the clk API between consumers and providers
along struct clk and struct clk_hw, but the registration and
clkdev/DT code is still struct clk focused. This series
lays the foundation for changing that design by making
clk_register() return an int instead of a struct clk and
clkdev/DT lookups take a struct clk_hw instead of a struct clk.

After this series is applied, we can avoid using struct clk
in provider drivers entirely, unless we want to use the consumer
APIs. There are quite a few registration callers, so this change
will require converting all of them. I plan to do that gradually
over the coming weeks, but I've included a change to qcom
platforms because I could easily test it and show how things
will work.

The first two patches are cleanups to clkdev APIs that I found
while doing this work. I'd like to take those into clk-next
with the appropriate acks. They're mostly included because
they cause merge conflicts otherwise.

Cc: Lee Jones <lee.jones@linaro.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Russell King <linux@arm.linux.org.uk>

Stephen Boyd (14):
  mfd: intel_quark_i2c_gpio: Use clkdev_create()
  clkdev: Remove clk_register_clkdevs()
  clk: Add {devm_}clk_hw_{register,unregister}() APIs
  clk: Add clk_hw OF clk providers
  clkdev: Add clk_hw based registration APIs
  clk: divider: Add hw based registration APIs
  clk: gate: Add hw based registration APIs
  clk: mux: Add hw based registration APIs
  clk: fixed-factor: Add hw based registration APIs
  clk: fractional-divider: Add hw based registration APIs
  clk: composite: Add hw based registration APIs
  clk: gpio: Add hw based registration APIs
  clk: fixed-rate: Add hw based registration APIs
  clk: qcom: Migrate to clk_hw based registration and OF APIs

 Documentation/driver-model/devres.txt |   1 +
 drivers/clk/clk-composite.c           |  45 ++++++---
 drivers/clk/clk-divider.c             |  91 ++++++++++++++++--
 drivers/clk/clk-fixed-factor.c        |  41 ++++++--
 drivers/clk/clk-fixed-rate.c          |  44 +++++++--
 drivers/clk/clk-fractional-divider.c  |  40 +++++++-
 drivers/clk/clk-gate.c                |  43 +++++++--
 drivers/clk/clk-gpio.c                |  52 ++++++++---
 drivers/clk/clk-mux.c                 |  57 ++++++++++--
 drivers/clk/clk.c                     | 170 +++++++++++++++++++++++++++++++++-
 drivers/clk/clkdev.c                  |  71 ++++++++++----
 drivers/clk/qcom/clk-regmap.c         |   5 +-
 drivers/clk/qcom/clk-regmap.h         |   3 +-
 drivers/clk/qcom/common.c             |  41 ++++----
 drivers/clk/qcom/gcc-msm8996.c        |   9 +-
 drivers/clk/qcom/mmcc-msm8996.c       |   9 +-
 drivers/mfd/intel_quark_i2c_gpio.c    |  26 ++----
 include/linux/clk-provider.h          |  92 ++++++++++++++++++
 include/linux/clkdev.h                |   8 +-
 19 files changed, 706 insertions(+), 142 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [next] | [standalone]


#1329832 — [PATCH 06/14] clk: divider: Add hw based registration APIs

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 06/14] clk: divider: Add hw based registration APIs
Message-ID<r05Bg-5h7-9@gated-at.bofh.it>
In reply to#1329831
Add registration APIs in the clk divider code to return struct
clk_hw pointers instead of struct clk pointers. This way we hide
the struct clk pointer from providers unless they need to use
consumer facing APIs.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clk-divider.c    | 91 ++++++++++++++++++++++++++++++++++++++++----
 include/linux/clk-provider.h | 10 +++++
 2 files changed, 93 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index ded3ff4b91b9..65ea60c32856 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -423,15 +423,16 @@ const struct clk_ops clk_divider_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_divider_ops);
 
-static struct clk *_register_divider(struct device *dev, const char *name,
+static struct clk_hw *_register_divider(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
 		u8 clk_divider_flags, const struct clk_div_table *table,
 		spinlock_t *lock)
 {
 	struct clk_divider *div;
-	struct clk *clk;
+	struct clk_hw *hw;
 	struct clk_init_data init;
+	int ret;
 
 	if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
 		if (width + shift > 16) {
@@ -461,12 +462,14 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 	div->table = table;
 
 	/* register the clock */
-	clk = clk_register(dev, &div->hw);
-
-	if (IS_ERR(clk))
+	hw = &div->hw;
+	ret = clk_hw_register(dev, hw);
+	if (ret) {
 		kfree(div);
+		hw = ERR_PTR(ret);
+	}
 
-	return clk;
+	return hw;
 }
 
 /**
@@ -486,12 +489,39 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
 		void __iomem *reg, u8 shift, u8 width,
 		u8 clk_divider_flags, spinlock_t *lock)
 {
-	return _register_divider(dev, name, parent_name, flags, reg, shift,
+	struct clk_hw *hw;
+
+	hw =  _register_divider(dev, name, parent_name, flags, reg, shift,
 			width, clk_divider_flags, NULL, lock);
+	if (IS_ERR(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_divider);
 
 /**
+ * clk_hw_register_divider - register a divider clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags, spinlock_t *lock)
+{
+	return _register_divider(dev, name, parent_name, flags, reg, shift,
+			width, clk_divider_flags, NULL, lock);
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_divider);
+
+/**
  * clk_register_divider_table - register a table based divider clock with
  * the clock framework
  * @dev: device registering this clock
@@ -511,11 +541,41 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
 		u8 clk_divider_flags, const struct clk_div_table *table,
 		spinlock_t *lock)
 {
-	return _register_divider(dev, name, parent_name, flags, reg, shift,
+	struct clk_hw *hw;
+
+	hw =  _register_divider(dev, name, parent_name, flags, reg, shift,
 			width, clk_divider_flags, table, lock);
+	if (IS_ERR(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_divider_table);
 
+/**
+ * clk_hw_register_divider_table - register a table based divider clock with
+ * the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @table: array of divider/value pairs ending with a div set to 0
+ * @lock: shared register lock for this clock
+ */
+struct clk_hw *clk_hw_register_divider_table(struct device *dev,
+		const char *name, const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags, const struct clk_div_table *table,
+		spinlock_t *lock)
+{
+	return _register_divider(dev, name, parent_name, flags, reg, shift,
+			width, clk_divider_flags, table, lock);
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
+
 void clk_unregister_divider(struct clk *clk)
 {
 	struct clk_divider *div;
@@ -531,3 +591,18 @@ void clk_unregister_divider(struct clk *clk)
 	kfree(div);
 }
 EXPORT_SYMBOL_GPL(clk_unregister_divider);
+
+/**
+ * clk_hw_unregister_divider - unregister a clk divider
+ * @hw: hardware-specific clock data to unregister
+ */
+void clk_hw_unregister_divider(struct clk_hw *hw)
+{
+	struct clk_divider *div;
+
+	div = to_clk_divider(hw);
+
+	clk_hw_unregister(hw);
+	kfree(div);
+}
+EXPORT_SYMBOL_GPL(clk_hw_unregister_divider);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 1af1afae05f8..666462958ef2 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -400,12 +400,22 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
 		u8 clk_divider_flags, spinlock_t *lock);
+struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags, spinlock_t *lock);
 struct clk *clk_register_divider_table(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
 		u8 clk_divider_flags, const struct clk_div_table *table,
 		spinlock_t *lock);
+struct clk_hw *clk_hw_register_divider_table(struct device *dev,
+		const char *name, const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags, const struct clk_div_table *table,
+		spinlock_t *lock);
 void clk_unregister_divider(struct clk *clk);
+void clk_hw_unregister_divider(struct clk_hw *hw);
 
 /**
  * struct clk_mux - multiplexer clock
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329833 — [PATCH 05/14] clkdev: Add clk_hw based registration APIs

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 05/14] clkdev: Add clk_hw based registration APIs
Message-ID<r05Bh-5h7-11@gated-at.bofh.it>
In reply to#1329831
Now that we have a clk registration API that doesn't return
struct clks, we need to have some way to hand out struct clks via
the clk_get() APIs that doesn't involve associating struct clk
pointers with a struct clk_lookup. Luckily, clkdev already
operates on struct clk_hw pointers, except for the registration
facing APIs where it converts struct clk pointers into struct
clk_hw pointers almost immediately.

Let's add clk_hw based registration APIs so that we can skip the
conversion step and provide a way for clk provider drivers to
operate exclusively on clk_hw structs. This way we clearly
split the API between consumers and providers.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clkdev.c   | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/clkdev.h |  7 ++++++
 2 files changed, 67 insertions(+)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index ae61f2e57048..485d3b141843 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -301,6 +301,20 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
 }
 EXPORT_SYMBOL(clkdev_alloc);
 
+struct clk_lookup *
+clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	va_start(ap, dev_fmt);
+	cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
+	va_end(ap);
+
+	return cl;
+}
+EXPORT_SYMBOL(clkdev_hw_alloc);
+
 /**
  * clkdev_create - allocate and add a clkdev lookup structure
  * @clk: struct clk to associate with all clk_lookups
@@ -324,6 +338,29 @@ struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
 }
 EXPORT_SYMBOL_GPL(clkdev_create);
 
+/**
+ * clkdev_hw_create - allocate and add a clkdev lookup structure
+ * @hw: struct clk_hw to associate with all clk_lookups
+ * @con_id: connection ID string on device
+ * @dev_fmt: format string describing device name
+ *
+ * Returns a clk_lookup structure, which can be later unregistered and
+ * freed.
+ */
+struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
+	const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	va_start(ap, dev_fmt);
+	cl = vclkdev_create(hw, con_id, dev_fmt, ap);
+	va_end(ap);
+
+	return cl;
+}
+EXPORT_SYMBOL_GPL(clkdev_hw_create);
+
 int clk_add_alias(const char *alias, const char *alias_dev_name,
 	const char *con_id, struct device *dev)
 {
@@ -383,3 +420,26 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
 	return cl ? 0 : -ENOMEM;
 }
 EXPORT_SYMBOL(clk_register_clkdev);
+
+/**
+ * clk_hw_register_clkdev - register one clock lookup for a struct clk_hw
+ * @hw: struct clk_hw to associate with all clk_lookups
+ * @con_id: connection ID string on device
+ * @dev_id: format string describing device name
+ *
+ * con_id or dev_id may be NULL as a wildcard, just as in the rest of
+ * clkdev.
+ */
+int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
+	const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	va_start(ap, dev_fmt);
+	cl = vclkdev_create(hw, con_id, dev_fmt, ap);
+	va_end(ap);
+
+	return cl ? 0 : -ENOMEM;
+}
+EXPORT_SYMBOL(clk_hw_register_clkdev);
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index 43a8c2e8ac29..5084295617dc 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -15,6 +15,7 @@
 #include <asm/clkdev.h>
 
 struct clk;
+struct clk_hw;
 struct device;
 
 struct clk_lookup {
@@ -34,18 +35,24 @@ struct clk_lookup {
 
 struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
 	const char *dev_fmt, ...) __printf(3, 4);
+struct clk_lookup *clkdev_hw_alloc(struct clk_hw *hw, const char *con_id,
+	const char *dev_fmt, ...) __printf(3, 4);
 
 void clkdev_add(struct clk_lookup *cl);
 void clkdev_drop(struct clk_lookup *cl);
 
 struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
 	const char *dev_fmt, ...) __printf(3, 4);
+struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
+	const char *dev_fmt, ...) __printf(3, 4);
 
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, const char *, struct device *);
 
 int clk_register_clkdev(struct clk *, const char *, const char *, ...)
 	__printf(3, 4);
+int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *, ...)
+	__printf(3, 4);
 
 #ifdef CONFIG_COMMON_CLK
 int __clk_get(struct clk *clk);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329834 — [PATCH 11/14] clk: composite: Add hw based registration APIs

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 11/14] clk: composite: Add hw based registration APIs
Message-ID<r05Bh-5h7-13@gated-at.bofh.it>
In reply to#1329831
Add registration APIs in the clk composite code to return struct
clk_hw pointers instead of struct clk pointers. This way we hide
the struct clk pointer from providers unless they need to use
consumer facing APIs.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clk-composite.c  | 45 ++++++++++++++++++++++++++++++++------------
 include/linux/clk-provider.h |  7 +++++++
 2 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 4735de0660cc..9c38a3563e8c 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -186,17 +186,18 @@ static void clk_composite_disable(struct clk_hw *hw)
 	gate_ops->disable(gate_hw);
 }
 
-struct clk *clk_register_composite(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
 			const char * const *parent_names, int num_parents,
 			struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
 			struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
 			struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
 			unsigned long flags)
 {
-	struct clk *clk;
+	struct clk_hw *hw;
 	struct clk_init_data init;
 	struct clk_composite *composite;
 	struct clk_ops *clk_composite_ops;
+	int ret;
 
 	composite = kzalloc(sizeof(*composite), GFP_KERNEL);
 	if (!composite)
@@ -206,12 +207,13 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 	init.flags = flags | CLK_IS_BASIC;
 	init.parent_names = parent_names;
 	init.num_parents = num_parents;
+	hw = &composite->hw;
 
 	clk_composite_ops = &composite->ops;
 
 	if (mux_hw && mux_ops) {
 		if (!mux_ops->get_parent) {
-			clk = ERR_PTR(-EINVAL);
+			hw = ERR_PTR(-EINVAL);
 			goto err;
 		}
 
@@ -226,7 +228,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 
 	if (rate_hw && rate_ops) {
 		if (!rate_ops->recalc_rate) {
-			clk = ERR_PTR(-EINVAL);
+			hw = ERR_PTR(-EINVAL);
 			goto err;
 		}
 		clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
@@ -255,7 +257,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 	if (gate_hw && gate_ops) {
 		if (!gate_ops->is_enabled || !gate_ops->enable ||
 		    !gate_ops->disable) {
-			clk = ERR_PTR(-EINVAL);
+			hw = ERR_PTR(-EINVAL);
 			goto err;
 		}
 
@@ -269,22 +271,41 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 	init.ops = clk_composite_ops;
 	composite->hw.init = &init;
 
-	clk = clk_register(dev, &composite->hw);
-	if (IS_ERR(clk))
+	ret = clk_hw_register(dev, hw);
+	if (ret) {
+		hw = ERR_PTR(ret);
 		goto err;
+	}
 
 	if (composite->mux_hw)
-		composite->mux_hw->clk = clk;
+		composite->mux_hw->clk = hw->clk;
 
 	if (composite->rate_hw)
-		composite->rate_hw->clk = clk;
+		composite->rate_hw->clk = hw->clk;
 
 	if (composite->gate_hw)
-		composite->gate_hw->clk = clk;
+		composite->gate_hw->clk = hw->clk;
 
-	return clk;
+	return hw;
 
 err:
 	kfree(composite);
-	return clk;
+	return hw;
+}
+
+struct clk *clk_register_composite(struct device *dev, const char *name,
+			const char * const *parent_names, int num_parents,
+			struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+			struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
+			struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+			unsigned long flags)
+{
+	struct clk_hw *hw;
+
+	hw = clk_hw_register_composite(dev, name, parent_names, num_parents,
+			mux_hw, mux_ops, rate_hw, rate_ops, gate_hw, gate_ops,
+			flags);
+	if (IS_ERR(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
 }
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 549ed3844876..64037ab95a31 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -620,6 +620,13 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 		struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
 		struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
 		unsigned long flags);
+struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
+		const char * const *parent_names, int num_parents,
+		struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+		struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
+		struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+		unsigned long flags);
+void clk_hw_unregister_composite(struct clk_hw *hw);
 
 /***
  * struct clk_gpio_gate - gpio gated clock
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329835 — [PATCH 13/14] clk: fixed-rate: Add hw based registration APIs

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 13/14] clk: fixed-rate: Add hw based registration APIs
Message-ID<r05Bh-5h7-17@gated-at.bofh.it>
In reply to#1329831
Add registration APIs in the clk fixed-rate code to return struct
clk_hw pointers instead of struct clk pointers. This way we hide
the struct clk pointer from providers unless they need to use
consumer facing APIs.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clk-fixed-rate.c | 44 ++++++++++++++++++++++++++++++++++++--------
 include/linux/clk-provider.h |  6 ++++++
 2 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index f85ec8d1711f..fe9f83fc04ac 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -47,8 +47,8 @@ const struct clk_ops clk_fixed_rate_ops = {
 EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
 
 /**
- * clk_register_fixed_rate_with_accuracy - register fixed-rate clock with the
- *					   clock framework
+ * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
+ * the clock framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_name: name of clock's parent
@@ -56,13 +56,14 @@ EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
  * @fixed_rate: non-adjustable clock rate
  * @fixed_accuracy: non-adjustable clock rate
  */
-struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
+struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
 		const char *name, const char *parent_name, unsigned long flags,
 		unsigned long fixed_rate, unsigned long fixed_accuracy)
 {
 	struct clk_fixed_rate *fixed;
-	struct clk *clk;
+	struct clk_hw *hw;
 	struct clk_init_data init;
+	int ret;
 
 	/* allocate fixed-rate clock */
 	fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
@@ -81,22 +82,49 @@ struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
 	fixed->hw.init = &init;
 
 	/* register the clock */
-	clk = clk_register(dev, &fixed->hw);
-	if (IS_ERR(clk))
+	hw = &fixed->hw;
+	ret = clk_hw_register(dev, hw);
+	if (ret) {
 		kfree(fixed);
+		hw = ERR_PTR(ret);
+	}
 
-	return clk;
+	return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate_with_accuracy);
+
+struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
+		const char *name, const char *parent_name, unsigned long flags,
+		unsigned long fixed_rate, unsigned long fixed_accuracy)
+{
+	struct clk_hw *hw;
+
+	hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
+			flags, fixed_rate, fixed_accuracy);
+	if (IS_ERR(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy);
 
 /**
- * clk_register_fixed_rate - register fixed-rate clock with the clock framework
+ * clk_hw_register_fixed_rate - register fixed-rate clock with the clock
+ * framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_name: name of clock's parent
  * @flags: framework-specific flags
  * @fixed_rate: non-adjustable clock rate
  */
+struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		unsigned long fixed_rate)
+{
+	return clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
+						     flags, fixed_rate, 0);
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate);
+
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		unsigned long fixed_rate)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 148ad0dc2906..98fad9fb8a7d 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -280,9 +280,15 @@ extern const struct clk_ops clk_fixed_rate_ops;
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		unsigned long fixed_rate);
+struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		unsigned long fixed_rate);
 struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
 		const char *name, const char *parent_name, unsigned long flags,
 		unsigned long fixed_rate, unsigned long fixed_accuracy);
+struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
+		const char *name, const char *parent_name, unsigned long flags,
+		unsigned long fixed_rate, unsigned long fixed_accuracy);
 
 void of_fixed_clk_setup(struct device_node *np);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329836 — [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs
Message-ID<r05Bh-5h7-19@gated-at.bofh.it>
In reply to#1329831
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/qcom/clk-regmap.c   |  5 ++---
 drivers/clk/qcom/clk-regmap.h   |  3 +--
 drivers/clk/qcom/common.c       | 41 +++++++++++++++++++----------------------
 drivers/clk/qcom/gcc-msm8996.c  |  9 ++++-----
 drivers/clk/qcom/mmcc-msm8996.c |  9 ++++-----
 5 files changed, 30 insertions(+), 37 deletions(-)

diff --git a/drivers/clk/qcom/clk-regmap.c b/drivers/clk/qcom/clk-regmap.c
index a58ba39a900c..1c856d330733 100644
--- a/drivers/clk/qcom/clk-regmap.c
+++ b/drivers/clk/qcom/clk-regmap.c
@@ -101,14 +101,13 @@ EXPORT_SYMBOL_GPL(clk_disable_regmap);
  * clk_regmap struct via this function so that the regmap is initialized
  * and so that the clock is registered with the common clock framework.
  */
-struct clk *devm_clk_register_regmap(struct device *dev,
-				     struct clk_regmap *rclk)
+int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk)
 {
 	if (dev && dev_get_regmap(dev, NULL))
 		rclk->regmap = dev_get_regmap(dev, NULL);
 	else if (dev && dev->parent)
 		rclk->regmap = dev_get_regmap(dev->parent, NULL);
 
-	return devm_clk_register(dev, &rclk->hw);
+	return devm_clk_hw_register(dev, &rclk->hw);
 }
 EXPORT_SYMBOL_GPL(devm_clk_register_regmap);
diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h
index 491a63d537df..90d95cd11ec6 100644
--- a/drivers/clk/qcom/clk-regmap.h
+++ b/drivers/clk/qcom/clk-regmap.h
@@ -39,7 +39,6 @@ struct clk_regmap {
 int clk_is_enabled_regmap(struct clk_hw *hw);
 int clk_enable_regmap(struct clk_hw *hw);
 void clk_disable_regmap(struct clk_hw *hw);
-struct clk *
-devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk);
+int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk);
 
 #endif
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index c112ebaba70d..16068af45f5d 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -27,8 +27,7 @@
 
 struct qcom_cc {
 	struct qcom_reset_controller reset;
-	struct clk_onecell_data data;
-	struct clk *clks[];
+	struct clk_hw_onecell_data data;
 };
 
 const
@@ -102,8 +101,8 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
 	struct device_node *clocks_node;
 	struct clk_fixed_factor *factor;
 	struct clk_fixed_rate *fixed;
-	struct clk *clk;
 	struct clk_init_data init_data = { };
+	int ret;
 
 	clocks_node = of_find_node_by_path("/clocks");
 	if (clocks_node)
@@ -122,9 +121,9 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
 		init_data.flags = CLK_IS_ROOT;
 		init_data.ops = &clk_fixed_rate_ops;
 
-		clk = devm_clk_register(dev, &fixed->hw);
-		if (IS_ERR(clk))
-			return PTR_ERR(clk);
+		ret = devm_clk_hw_register(dev, &fixed->hw);
+		if (ret)
+			return ret;
 	}
 	of_node_put(node);
 
@@ -142,9 +141,9 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
 		init_data.flags = 0;
 		init_data.ops = &clk_fixed_factor_ops;
 
-		clk = devm_clk_register(dev, &factor->hw);
-		if (IS_ERR(clk))
-			return PTR_ERR(clk);
+		ret = devm_clk_hw_register(dev, &factor->hw);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -180,36 +179,34 @@ int qcom_cc_really_probe(struct platform_device *pdev,
 {
 	int i, ret;
 	struct device *dev = &pdev->dev;
-	struct clk *clk;
-	struct clk_onecell_data *data;
-	struct clk **clks;
+	struct clk_hw_onecell_data *data;
+	struct clk_hw **hws;
 	struct qcom_reset_controller *reset;
 	struct qcom_cc *cc;
 	size_t num_clks = desc->num_clks;
 	struct clk_regmap **rclks = desc->clks;
 
-	cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
+	cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*hws) * num_clks,
 			  GFP_KERNEL);
 	if (!cc)
 		return -ENOMEM;
 
-	clks = cc->clks;
 	data = &cc->data;
-	data->clks = clks;
-	data->clk_num = num_clks;
+	data->num = num_clks;
+	hws = data->hws;
 
 	for (i = 0; i < num_clks; i++) {
 		if (!rclks[i]) {
-			clks[i] = ERR_PTR(-ENOENT);
+			hws[i] = ERR_PTR(-ENOENT);
 			continue;
 		}
-		clk = devm_clk_register_regmap(dev, rclks[i]);
-		if (IS_ERR(clk))
-			return PTR_ERR(clk);
-		clks[i] = clk;
+		ret = devm_clk_register_regmap(dev, rclks[i]);
+		if (ret)
+			return ret;
+		hws[i] = &rclks[i]->hw;
 	}
 
-	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
+	ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, data);
 	if (ret)
 		return ret;
 
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 16d7c323db49..2cfd55141896 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -3373,9 +3373,8 @@ MODULE_DEVICE_TABLE(of, gcc_msm8996_match_table);
 
 static int gcc_msm8996_probe(struct platform_device *pdev)
 {
-	struct clk *clk;
 	struct device *dev = &pdev->dev;
-	int i;
+	int i, ret;
 	struct regmap *regmap;
 
 	regmap = qcom_cc_map(pdev, &gcc_msm8996_desc);
@@ -3389,9 +3388,9 @@ static int gcc_msm8996_probe(struct platform_device *pdev)
 	regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21));
 
 	for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) {
-		clk = devm_clk_register(dev, gcc_msm8996_hws[i]);
-		if (IS_ERR(clk))
-			return PTR_ERR(clk);
+		ret = devm_clk_hw_register(dev, gcc_msm8996_hws[i]);
+		if (ret)
+			return ret;
 	}
 
 	return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap);
diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c
index 064f3eaa39d0..8460daa6c567 100644
--- a/drivers/clk/qcom/mmcc-msm8996.c
+++ b/drivers/clk/qcom/mmcc-msm8996.c
@@ -3180,9 +3180,8 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8996_match_table);
 
 static int mmcc_msm8996_probe(struct platform_device *pdev)
 {
-	struct clk *clk;
 	struct device *dev = &pdev->dev;
-	int i;
+	int i, ret;
 	struct regmap *regmap;
 
 	regmap = qcom_cc_map(pdev, &mmcc_msm8996_desc);
@@ -3195,9 +3194,9 @@ static int mmcc_msm8996_probe(struct platform_device *pdev)
 	regmap_update_bits(regmap, 0x5054, BIT(15), 0);
 
 	for (i = 0; i < ARRAY_SIZE(mmcc_msm8996_hws); i++) {
-		clk = devm_clk_register(dev, mmcc_msm8996_hws[i]);
-		if (IS_ERR(clk))
-			return PTR_ERR(clk);
+		ret = devm_clk_hw_register(dev, mmcc_msm8996_hws[i]);
+		if (ret)
+			return ret;
 	}
 
 	return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329837 — [PATCH 04/14] clk: Add clk_hw OF clk providers

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 04/14] clk: Add clk_hw OF clk providers
Message-ID<r05Bh-5h7-23@gated-at.bofh.it>
In reply to#1329831
Now that we have a clk registration API that doesn't return
struct clks, we need to have some way to hand out struct clks via
the clk_get() APIs that doesn't involve associating struct clk
pointers with an OF node. Currently we ask the OF provider to
give us a struct clk pointer for some clkspec, turn that struct
clk into a struct clk_hw and then allocate a new struct clk to
return to the caller.

Let's add a clk_hw based OF provider hook that returns a struct
clk_hw directly, so that we skip the intermediate step of
converting from struct clk to struct clk_hw. Eventually when
we've converted all OF clk providers to struct clk_hw based APIs
we can remove the struct clk based ones.

It should also be noted that we change the onecell provider to
have a flex array instead of a pointer for the array of clk_hw
pointers. This allows providers to allocate one structure of the
correct length in one step instead of two.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clk.c            | 84 +++++++++++++++++++++++++++++++++++++++++---
 include/linux/clk-provider.h | 30 ++++++++++++++++
 2 files changed, 110 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index adaaead3639f..a40849d0c672 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3018,6 +3018,7 @@ struct of_clk_provider {
 
 	struct device_node *node;
 	struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
+	struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
 	void *data;
 };
 
@@ -3034,6 +3035,12 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
 }
 EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
 
+struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
+{
+	return data;
+}
+EXPORT_SYMBOL_GPL(of_clk_hw_simple_get);
+
 struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
 {
 	struct clk_onecell_data *clk_data = data;
@@ -3048,6 +3055,21 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
 }
 EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
 
+struct clk_hw *
+of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct clk_hw_onecell_data *hw_data = data;
+	unsigned int idx = clkspec->args[0];
+
+	if (idx >= hw_data->num) {
+		pr_err("%s: invalid index %u\n", __func__, idx);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return hw_data->hws[idx];
+}
+EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
+
 /**
  * of_clk_add_provider() - Register a clock provider for a node
  * @np: Device node pointer associated with clock provider
@@ -3084,6 +3106,40 @@ int of_clk_add_provider(struct device_node *np,
 EXPORT_SYMBOL_GPL(of_clk_add_provider);
 
 /**
+ * of_clk_add_hw_provider() - Register a clock provider for a node
+ * @np: Device node pointer associated with clock provider
+ * @get: callback for decoding clk_hw
+ * @data: context pointer for @get callback.
+ */
+int of_clk_add_hw_provider(struct device_node *np,
+			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+						 void *data),
+			   void *data)
+{
+	struct of_clk_provider *cp;
+	int ret;
+
+	cp = kzalloc(sizeof(*cp), GFP_KERNEL);
+	if (!cp)
+		return -ENOMEM;
+
+	cp->node = of_node_get(np);
+	cp->data = data;
+	cp->get_hw = get;
+
+	mutex_lock(&of_clk_mutex);
+	list_add(&cp->link, &of_clk_providers);
+	mutex_unlock(&of_clk_mutex);
+	pr_debug("Added clk_hw provider from %s\n", np->full_name);
+
+	ret = of_clk_set_defaults(np, true);
+	if (ret < 0)
+		of_clk_del_provider(np);
+
+	return ret;
+}
+
+/**
  * of_clk_del_provider() - Remove a previously registered clock provider
  * @np: Device node pointer associated with clock provider
  */
@@ -3104,11 +3160,32 @@ void of_clk_del_provider(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_clk_del_provider);
 
+static struct clk_hw *
+__of_clk_get_hw_from_provider(struct of_clk_provider *provider,
+			      struct of_phandle_args *clkspec)
+{
+	struct clk *clk;
+	struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
+
+	if (provider->get_hw) {
+		hw = provider->get_hw(clkspec, provider->data);
+	} else if (provider->get) {
+		clk = provider->get(clkspec, provider->data);
+		if (!IS_ERR(clk))
+			hw = __clk_get_hw(clk);
+		else
+			hw = ERR_CAST(clk);
+	}
+
+	return hw;
+}
+
 struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
 				       const char *dev_id, const char *con_id)
 {
 	struct of_clk_provider *provider;
 	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
+	struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
 
 	if (!clkspec)
 		return ERR_PTR(-EINVAL);
@@ -3117,10 +3194,9 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
 	mutex_lock(&of_clk_mutex);
 	list_for_each_entry(provider, &of_clk_providers, link) {
 		if (provider->node == clkspec->np)
-			clk = provider->get(clkspec, provider->data);
-		if (!IS_ERR(clk)) {
-			clk = __clk_create_clk(__clk_get_hw(clk), dev_id,
-					       con_id);
+			hw = __of_clk_get_hw_from_provider(provider, clkspec);
+		if (!IS_ERR(hw)) {
+			clk = __clk_create_clk(hw, dev_id, con_id);
 
 			if (!IS_ERR(clk) && !__clk_get(clk)) {
 				__clk_free_clk(clk);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index abc16d77fb62..1af1afae05f8 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -693,6 +693,11 @@ struct clk_onecell_data {
 	unsigned int clk_num;
 };
 
+struct clk_hw_onecell_data {
+	size_t num;
+	struct clk_hw *hws[];
+};
+
 extern struct of_device_id __clk_of_table;
 
 #define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
@@ -702,10 +707,18 @@ int of_clk_add_provider(struct device_node *np,
 			struct clk *(*clk_src_get)(struct of_phandle_args *args,
 						   void *data),
 			void *data);
+int of_clk_add_hw_provider(struct device_node *np,
+			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+						 void *data),
+			   void *data);
 void of_clk_del_provider(struct device_node *np);
 struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
 				  void *data);
+struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec,
+				    void *data);
 struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data);
+struct clk_hw *of_clk_hw_onecell_get(struct of_phandle_args *clkspec,
+				     void *data);
 int of_clk_get_parent_count(struct device_node *np);
 int of_clk_parent_fill(struct device_node *np, const char **parents,
 		       unsigned int size);
@@ -722,17 +735,34 @@ static inline int of_clk_add_provider(struct device_node *np,
 {
 	return 0;
 }
+int of_clk_add_hw_provider(struct device_node *np,
+			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+						 void *data),
+			   void *data)
+{
+	return 0;
+}
 static inline void of_clk_del_provider(struct device_node *np) {}
 static inline struct clk *of_clk_src_simple_get(
 	struct of_phandle_args *clkspec, void *data)
 {
 	return ERR_PTR(-ENOENT);
 }
+struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec,
+				    void *data)
+{
+	return ERR_PTR(-ENOENT);
+}
 static inline struct clk *of_clk_src_onecell_get(
 	struct of_phandle_args *clkspec, void *data)
 {
 	return ERR_PTR(-ENOENT);
 }
+struct clk_hw *of_clk_hw_onecell_get(struct of_phandle_args *clkspec,
+				     void *data)
+{
+	return ERR_PTR(-ENOENT);
+}
 static inline int of_clk_get_parent_count(struct device_node *np)
 {
 	return 0;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329838 — [PATCH 07/14] clk: gate: Add hw based registration APIs

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 07/14] clk: gate: Add hw based registration APIs
Message-ID<r05Bh-5h7-15@gated-at.bofh.it>
In reply to#1329831
Add registration APIs in the clk gate code to return struct
clk_hw pointers instead of struct clk pointers. This way we hide
the struct clk pointer from providers unless they need to use
consumer facing APIs.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clk-gate.c       | 43 ++++++++++++++++++++++++++++++++++++-------
 include/linux/clk-provider.h |  5 +++++
 2 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index de0b322f5f58..3559a05dad15 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -112,7 +112,7 @@ const struct clk_ops clk_gate_ops = {
 EXPORT_SYMBOL_GPL(clk_gate_ops);
 
 /**
- * clk_register_gate - register a gate clock with the clock framework
+ * clk_hw_register_gate - register a gate clock with the clock framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_name: name of this clock's parent
@@ -122,14 +122,15 @@ EXPORT_SYMBOL_GPL(clk_gate_ops);
  * @clk_gate_flags: gate-specific flags for this clock
  * @lock: shared register lock for this clock
  */
-struct clk *clk_register_gate(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 bit_idx,
 		u8 clk_gate_flags, spinlock_t *lock)
 {
 	struct clk_gate *gate;
-	struct clk *clk;
+	struct clk_hw *hw;
 	struct clk_init_data init;
+	int ret;
 
 	if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
 		if (bit_idx > 15) {
@@ -156,12 +157,29 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
 	gate->lock = lock;
 	gate->hw.init = &init;
 
-	clk = clk_register(dev, &gate->hw);
-
-	if (IS_ERR(clk))
+	hw = &gate->hw;
+	ret = clk_hw_register(dev, hw);
+	if (ret) {
 		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
 
-	return clk;
+	return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_gate);
+
+struct clk *clk_register_gate(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 bit_idx,
+		u8 clk_gate_flags, spinlock_t *lock)
+{
+	struct clk_hw *hw;
+
+	hw = clk_hw_register_gate(dev, name, parent_name, flags, reg,
+				  bit_idx, clk_gate_flags, lock);
+	if (IS_ERR(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_gate);
 
@@ -180,3 +198,14 @@ void clk_unregister_gate(struct clk *clk)
 	kfree(gate);
 }
 EXPORT_SYMBOL_GPL(clk_unregister_gate);
+
+void clk_hw_unregister_gate(struct clk_hw *hw)
+{
+	struct clk_gate *gate;
+
+	gate = to_clk_gate(hw);
+
+	clk_hw_unregister(hw);
+	kfree(gate);
+}
+EXPORT_SYMBOL_GPL(clk_hw_unregister_gate);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 666462958ef2..b9a83216255b 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -322,7 +322,12 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 bit_idx,
 		u8 clk_gate_flags, spinlock_t *lock);
+struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 bit_idx,
+		u8 clk_gate_flags, spinlock_t *lock);
 void clk_unregister_gate(struct clk *clk);
+void clk_hw_unregister_gate(struct clk_hw *hw);
 
 struct clk_div_table {
 	unsigned int	val;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329839 — [PATCH 08/14] clk: mux: Add hw based registration APIs

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 08/14] clk: mux: Add hw based registration APIs
Message-ID<r05Bh-5h7-21@gated-at.bofh.it>
In reply to#1329831
Add registration APIs in the clk mux code to return struct clk_hw
pointers instead of struct clk pointers. This way we hide the
struct clk pointer from providers unless they need to use
consumer facing APIs.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clk-mux.c        | 57 +++++++++++++++++++++++++++++++++++++++-----
 include/linux/clk-provider.h | 11 +++++++++
 2 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 5ed03c8a8df9..6b0fcd3a4629 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -115,16 +115,17 @@ const struct clk_ops clk_mux_ro_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
 
-struct clk *clk_register_mux_table(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
 		const char * const *parent_names, u8 num_parents,
 		unsigned long flags,
 		void __iomem *reg, u8 shift, u32 mask,
 		u8 clk_mux_flags, u32 *table, spinlock_t *lock)
 {
 	struct clk_mux *mux;
-	struct clk *clk;
+	struct clk_hw *hw;
 	struct clk_init_data init;
 	u8 width = 0;
+	int ret;
 
 	if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
 		width = fls(mask) - ffs(mask) + 1;
@@ -159,12 +160,31 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
 	mux->table = table;
 	mux->hw.init = &init;
 
-	clk = clk_register(dev, &mux->hw);
-
-	if (IS_ERR(clk))
+	hw = &mux->hw;
+	ret = clk_hw_register(dev, hw);
+	if (ret) {
 		kfree(mux);
+		hw = ERR_PTR(ret);
+	}
 
-	return clk;
+	return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_mux_table);
+
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
+		const char * const *parent_names, u8 num_parents,
+		unsigned long flags,
+		void __iomem *reg, u8 shift, u32 mask,
+		u8 clk_mux_flags, u32 *table, spinlock_t *lock)
+{
+	struct clk_hw *hw;
+
+	hw = clk_hw_register_mux_table(dev, name, parent_names, num_parents,
+				       flags, reg, shift, mask, clk_mux_flags,
+				       table, lock);
+	if (IS_ERR(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_mux_table);
 
@@ -182,6 +202,20 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
 }
 EXPORT_SYMBOL_GPL(clk_register_mux);
 
+struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
+		const char * const *parent_names, u8 num_parents,
+		unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_mux_flags, spinlock_t *lock)
+{
+	u32 mask = BIT(width) - 1;
+
+	return clk_hw_register_mux_table(dev, name, parent_names, num_parents,
+				      flags, reg, shift, mask, clk_mux_flags,
+				      NULL, lock);
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_mux);
+
 void clk_unregister_mux(struct clk *clk)
 {
 	struct clk_mux *mux;
@@ -197,3 +231,14 @@ void clk_unregister_mux(struct clk *clk)
 	kfree(mux);
 }
 EXPORT_SYMBOL_GPL(clk_unregister_mux);
+
+void clk_hw_unregister_mux(struct clk_hw *hw)
+{
+	struct clk_mux *mux;
+
+	mux = to_clk_mux(hw);
+
+	clk_hw_unregister(hw);
+	kfree(mux);
+}
+EXPORT_SYMBOL_GPL(clk_hw_unregister_mux);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index b9a83216255b..df6353a086b9 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -469,14 +469,25 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
 		unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
 		u8 clk_mux_flags, spinlock_t *lock);
+struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
+		const char * const *parent_names, u8 num_parents,
+		unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_mux_flags, spinlock_t *lock);
 
 struct clk *clk_register_mux_table(struct device *dev, const char *name,
 		const char * const *parent_names, u8 num_parents,
 		unsigned long flags,
 		void __iomem *reg, u8 shift, u32 mask,
 		u8 clk_mux_flags, u32 *table, spinlock_t *lock);
+struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
+		const char * const *parent_names, u8 num_parents,
+		unsigned long flags,
+		void __iomem *reg, u8 shift, u32 mask,
+		u8 clk_mux_flags, u32 *table, spinlock_t *lock);
 
 void clk_unregister_mux(struct clk *clk);
+void clk_hw_unregister_mux(struct clk_hw *hw);
 
 void of_fixed_factor_clk_setup(struct device_node *node);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329841 — [PATCH 09/14] clk: fixed-factor: Add hw based registration APIs

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 09/14] clk: fixed-factor: Add hw based registration APIs
Message-ID<r05Bh-5h7-33@gated-at.bofh.it>
In reply to#1329831
Add registration APIs in the clk fixed-factor code to return
struct clk_hw pointers instead of struct clk pointers. This way
we hide the struct clk pointer from providers unless they need to
use consumer facing APIs.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clk-fixed-factor.c | 41 ++++++++++++++++++++++++++++++++++-------
 include/linux/clk-provider.h   |  4 ++++
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 83de57aeceea..c10b2eb2759f 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -70,13 +70,14 @@ const struct clk_ops clk_fixed_factor_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
 
-struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
-		const char *parent_name, unsigned long flags,
+struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
+		const char *name, const char *parent_name, unsigned long flags,
 		unsigned int mult, unsigned int div)
 {
 	struct clk_fixed_factor *fix;
 	struct clk_init_data init;
-	struct clk *clk;
+	struct clk_hw *hw;
+	int ret;
 
 	fix = kmalloc(sizeof(*fix), GFP_KERNEL);
 	if (!fix)
@@ -93,15 +94,41 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
 	init.parent_names = &parent_name;
 	init.num_parents = 1;
 
-	clk = clk_register(dev, &fix->hw);
-
-	if (IS_ERR(clk))
+	hw = &fix->hw;
+	ret = clk_hw_register(dev, hw);
+	if (ret) {
 		kfree(fix);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
+
+struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		unsigned int mult, unsigned int div)
+{
+	struct clk_hw *hw;
 
-	return clk;
+	hw = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
+					  div);
+	if (IS_ERR(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_fixed_factor);
 
+void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
+{
+	struct clk_fixed_factor *fix;
+
+	fix = to_clk_fixed_factor(hw);
+
+	clk_hw_unregister(hw);
+	kfree(fix);
+}
+
 #ifdef CONFIG_OF
 /**
  * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index df6353a086b9..d4d65f60b85e 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -513,6 +513,10 @@ extern const struct clk_ops clk_fixed_factor_ops;
 struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		unsigned int mult, unsigned int div);
+struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
+		const char *name, const char *parent_name, unsigned long flags,
+		unsigned int mult, unsigned int div);
+void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
 
 /**
  * struct clk_fractional_divider - adjustable fractional divider clock
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329842 — [PATCH 12/14] clk: gpio: Add hw based registration APIs

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 12/14] clk: gpio: Add hw based registration APIs
Message-ID<r05Bh-5h7-35@gated-at.bofh.it>
In reply to#1329831
Add registration APIs in the clk gpio code to return struct
clk_hw pointers instead of struct clk pointers. This way we hide
the struct clk pointer from providers unless they need to use
consumer facing APIs.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clk-gpio.c       | 52 ++++++++++++++++++++++++++++++++++----------
 include/linux/clk-provider.h |  8 +++++++
 2 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 19fed65587e8..807a94486324 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -94,13 +94,13 @@ const struct clk_ops clk_gpio_mux_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
 
-static struct clk *clk_register_gpio(struct device *dev, const char *name,
+static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
 		const char * const *parent_names, u8 num_parents, unsigned gpio,
 		bool active_low, unsigned long flags,
 		const struct clk_ops *clk_gpio_ops)
 {
 	struct clk_gpio *clk_gpio;
-	struct clk *clk;
+	struct clk_hw *hw;
 	struct clk_init_data init = {};
 	unsigned long gpio_flags;
 	int err;
@@ -141,24 +141,26 @@ static struct clk *clk_register_gpio(struct device *dev, const char *name,
 	clk_gpio->gpiod = gpio_to_desc(gpio);
 	clk_gpio->hw.init = &init;
 
+	hw = &clk_gpio->hw;
 	if (dev)
-		clk = devm_clk_register(dev, &clk_gpio->hw);
+		err = devm_clk_hw_register(dev, hw);
 	else
-		clk = clk_register(NULL, &clk_gpio->hw);
+		err = clk_hw_register(NULL, hw);
 
-	if (!IS_ERR(clk))
-		return clk;
+	if (!err)
+		return hw;
 
 	if (!dev) {
 		gpiod_put(clk_gpio->gpiod);
 		kfree(clk_gpio);
 	}
 
-	return clk;
+	return ERR_PTR(err);
 }
 
 /**
- * clk_register_gpio_gate - register a gpio clock gate with the clock framework
+ * clk_hw_register_gpio_gate - register a gpio clock gate with the clock
+ * framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_name: name of this clock's parent
@@ -166,7 +168,7 @@ static struct clk *clk_register_gpio(struct device *dev, const char *name,
  * @active_low: true if gpio should be set to 0 to enable clock
  * @flags: clock flags
  */
-struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned gpio, bool active_low,
 		unsigned long flags)
 {
@@ -175,10 +177,24 @@ struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
 			(parent_name ? 1 : 0), gpio, active_low, flags,
 			&clk_gpio_gate_ops);
 }
+EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
+
+struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
+		const char *parent_name, unsigned gpio, bool active_low,
+		unsigned long flags)
+{
+	struct clk_hw *hw;
+
+	hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpio, active_low,
+				       flags);
+	if (IS_ERR(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
+}
 EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
 
 /**
- * clk_register_gpio_mux - register a gpio clock mux with the clock framework
+ * clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_names: names of this clock's parents
@@ -187,7 +203,7 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
  * @active_low: true if gpio should be set to 0 to enable clock
  * @flags: clock flags
  */
-struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
 		const char * const *parent_names, u8 num_parents, unsigned gpio,
 		bool active_low, unsigned long flags)
 {
@@ -199,6 +215,20 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
 	return clk_register_gpio(dev, name, parent_names, num_parents,
 			gpio, active_low, flags, &clk_gpio_mux_ops);
 }
+EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
+
+struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
+		const char * const *parent_names, u8 num_parents, unsigned gpio,
+		bool active_low, unsigned long flags)
+{
+	struct clk_hw *hw;
+
+	hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
+			gpio, active_low, flags);
+	if (IS_ERR(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
+}
 EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
 
 #ifdef CONFIG_OF
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 64037ab95a31..148ad0dc2906 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -647,6 +647,10 @@ extern const struct clk_ops clk_gpio_gate_ops;
 struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned gpio, bool active_low,
 		unsigned long flags);
+struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
+		const char *parent_name, unsigned gpio, bool active_low,
+		unsigned long flags);
+void clk_hw_unregister_gpio_gate(struct clk_hw *hw);
 
 void of_gpio_clk_gate_setup(struct device_node *node);
 
@@ -664,6 +668,10 @@ extern const struct clk_ops clk_gpio_mux_ops;
 struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
 		const char * const *parent_names, u8 num_parents, unsigned gpio,
 		bool active_low, unsigned long flags);
+struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
+		const char * const *parent_names, u8 num_parents, unsigned gpio,
+		bool active_low, unsigned long flags);
+void clk_hw_unregister_gpio_mux(struct clk_hw *hw);
 
 void of_gpio_mux_clk_setup(struct device_node *node);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1329843 — [PATCH 02/14] clkdev: Remove clk_register_clkdevs()

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 02/14] clkdev: Remove clk_register_clkdevs()
Message-ID<r05Bh-5h7-37@gated-at.bofh.it>
In reply to#1329831
Now that we've converted the only caller over to another clkdev
API, remove this one.

Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/clkdev.c   | 27 ---------------------------
 include/linux/clkdev.h |  1 -
 2 files changed, 28 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 779b6ff0c7ad..ae61f2e57048 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -383,30 +383,3 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
 	return cl ? 0 : -ENOMEM;
 }
 EXPORT_SYMBOL(clk_register_clkdev);
-
-/**
- * clk_register_clkdevs - register a set of clk_lookup for a struct clk
- * @clk: struct clk to associate with all clk_lookups
- * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
- * @num: number of clk_lookup structures to register
- *
- * To make things easier for mass registration, we detect error clks
- * from a previous clk_register() call, and return the error code for
- * those.  This is to permit this function to be called immediately
- * after clk_register().
- */
-int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
-{
-	unsigned i;
-
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
-
-	for (i = 0; i < num; i++, cl++) {
-		cl->clk_hw = __clk_get_hw(clk);
-		__clkdev_add(cl);
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(clk_register_clkdevs);
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index 08bffcc466de..43a8c2e8ac29 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -46,7 +46,6 @@ int clk_add_alias(const char *, const char *, const char *, struct device *);
 
 int clk_register_clkdev(struct clk *, const char *, const char *, ...)
 	__printf(3, 4);
-int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
 
 #ifdef CONFIG_COMMON_CLK
 int __clk_get(struct clk *clk);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1334510 — Re: [PATCH 02/14] clkdev: Remove clk_register_clkdevs()

FromAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Date2016-02-15 16:20 +0100
SubjectRe: [PATCH 02/14] clkdev: Remove clk_register_clkdevs()
Message-ID<r2t6q-2Md-19@gated-at.bofh.it>
In reply to#1329843
On Mon, 2016-02-08 at 17:45 -0800, Stephen Boyd wrote:
> Now that we've converted the only caller over to another clkdev
> API, remove this one.
> 

This API didn't feel suitable, good we get rid of it eventually.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>> 

> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
>  drivers/clk/clkdev.c   | 27 ---------------------------
>  include/linux/clkdev.h |  1 -
>  2 files changed, 28 deletions(-)
> 
> diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
> index 779b6ff0c7ad..ae61f2e57048 100644
> --- a/drivers/clk/clkdev.c
> +++ b/drivers/clk/clkdev.c
> @@ -383,30 +383,3 @@ int clk_register_clkdev(struct clk *clk, const
> char *con_id,
>  	return cl ? 0 : -ENOMEM;
>  }
>  EXPORT_SYMBOL(clk_register_clkdev);
> -
> -/**
> - * clk_register_clkdevs - register a set of clk_lookup for a struct
> clk
> - * @clk: struct clk to associate with all clk_lookups
> - * @cl: array of clk_lookup structures with con_id and dev_id pre-
> initialized
> - * @num: number of clk_lookup structures to register
> - *
> - * To make things easier for mass registration, we detect error clks
> - * from a previous clk_register() call, and return the error code
> for
> - * those.  This is to permit this function to be called immediately
> - * after clk_register().
> - */
> -int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl,
> size_t num)
> -{
> -	unsigned i;
> -
> -	if (IS_ERR(clk))
> -		return PTR_ERR(clk);
> -
> -	for (i = 0; i < num; i++, cl++) {
> -		cl->clk_hw = __clk_get_hw(clk);
> -		__clkdev_add(cl);
> -	}
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL(clk_register_clkdevs);
> diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
> index 08bffcc466de..43a8c2e8ac29 100644
> --- a/include/linux/clkdev.h
> +++ b/include/linux/clkdev.h
> @@ -46,7 +46,6 @@ int clk_add_alias(const char *, const char *, const
> char *, struct device *);
>  
>  int clk_register_clkdev(struct clk *, const char *, const char *,
> ...)
>  	__printf(3, 4);
> -int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
>  
>  #ifdef CONFIG_COMMON_CLK
>  int __clk_get(struct clk *clk);

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

[toc] | [prev] | [next] | [standalone]


#1334852 — Re: [PATCH 02/14] clkdev: Remove clk_register_clkdevs()

FromMichael Turquette <mturquette@baylibre.com>
Date2016-02-15 23:20 +0100
SubjectRe: [PATCH 02/14] clkdev: Remove clk_register_clkdevs()
Message-ID<r2zES-7er-15@gated-at.bofh.it>
In reply to#1329843
Quoting Stephen Boyd (2016-02-08 17:45:29)
> Now that we've converted the only caller over to another clkdev
> API, remove this one.
> 
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>

Looks good to me.

Regards,
Mike

> ---
>  drivers/clk/clkdev.c   | 27 ---------------------------
>  include/linux/clkdev.h |  1 -
>  2 files changed, 28 deletions(-)
> 
> diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
> index 779b6ff0c7ad..ae61f2e57048 100644
> --- a/drivers/clk/clkdev.c
> +++ b/drivers/clk/clkdev.c
> @@ -383,30 +383,3 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
>         return cl ? 0 : -ENOMEM;
>  }
>  EXPORT_SYMBOL(clk_register_clkdev);
> -
> -/**
> - * clk_register_clkdevs - register a set of clk_lookup for a struct clk
> - * @clk: struct clk to associate with all clk_lookups
> - * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
> - * @num: number of clk_lookup structures to register
> - *
> - * To make things easier for mass registration, we detect error clks
> - * from a previous clk_register() call, and return the error code for
> - * those.  This is to permit this function to be called immediately
> - * after clk_register().
> - */
> -int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
> -{
> -       unsigned i;
> -
> -       if (IS_ERR(clk))
> -               return PTR_ERR(clk);
> -
> -       for (i = 0; i < num; i++, cl++) {
> -               cl->clk_hw = __clk_get_hw(clk);
> -               __clkdev_add(cl);
> -       }
> -
> -       return 0;
> -}
> -EXPORT_SYMBOL(clk_register_clkdevs);
> diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
> index 08bffcc466de..43a8c2e8ac29 100644
> --- a/include/linux/clkdev.h
> +++ b/include/linux/clkdev.h
> @@ -46,7 +46,6 @@ int clk_add_alias(const char *, const char *, const char *, struct device *);
>  
>  int clk_register_clkdev(struct clk *, const char *, const char *, ...)
>         __printf(3, 4);
> -int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
>  
>  #ifdef CONFIG_COMMON_CLK
>  int __clk_get(struct clk *clk);
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 

[toc] | [prev] | [next] | [standalone]


#1329844 — [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-09 02:50 +0100
Subject[PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
Message-ID<r05Bi-5h7-39@gated-at.bofh.it>
In reply to#1329831
Convert this driver to use clkdev_create() instead of
clk_register_clkdevs(). The latter API is only used by this driver,
although this driver only allocates one clk to add anyway.
Furthermore, this driver allocates the clk_lookup structure with
devm, but clkdev_drop() will free that structure when passed,
leading to a double free when this driver is removed. Clean it
all up and pave the way for the removal of clk_register_clkdevs().

Cc: Lee Jones <lee.jones@linaro.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/mfd/intel_quark_i2c_gpio.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
index 042137465300..bdc5e27222c0 100644
--- a/drivers/mfd/intel_quark_i2c_gpio.c
+++ b/drivers/mfd/intel_quark_i2c_gpio.c
@@ -52,8 +52,6 @@
 /* The Quark I2C controller source clock */
 #define INTEL_QUARK_I2C_CLK_HZ	33000000
 
-#define INTEL_QUARK_I2C_NCLK	1
-
 struct intel_quark_mfd {
 	struct pci_dev		*pdev;
 	struct clk		*i2c_clk;
@@ -128,30 +126,24 @@ MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
 static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
 {
 	struct pci_dev *pdev = quark_mfd->pdev;
-	struct clk_lookup *i2c_clk_lookup;
 	struct clk *i2c_clk;
-	int ret;
-
-	i2c_clk_lookup = devm_kcalloc(&pdev->dev, INTEL_QUARK_I2C_NCLK,
-				      sizeof(*i2c_clk_lookup), GFP_KERNEL);
-	if (!i2c_clk_lookup)
-		return -ENOMEM;
-
-	i2c_clk_lookup[0].dev_id = INTEL_QUARK_I2C_CONTROLLER_CLK;
 
 	i2c_clk = clk_register_fixed_rate(&pdev->dev,
 					  INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
 					  CLK_IS_ROOT, INTEL_QUARK_I2C_CLK_HZ);
+	if (IS_ERR(i2c_clk))
+		return PTR_ERR(i2c_clk);
 
-	quark_mfd->i2c_clk_lookup = i2c_clk_lookup;
 	quark_mfd->i2c_clk = i2c_clk;
+	quark_mfd->i2c_clk_lookup = clkdev_create(i2c_clk, NULL,
+						INTEL_QUARK_I2C_CONTROLLER_CLK);
 
-	ret = clk_register_clkdevs(i2c_clk, i2c_clk_lookup,
-				   INTEL_QUARK_I2C_NCLK);
-	if (ret)
-		dev_err(&pdev->dev, "Fixed clk register failed: %d\n", ret);
+	if (!quark_mfd->i2c_clk_lookup) {
+		dev_err(&pdev->dev, "Fixed clk register failed\n");
+		return -ENOMEM;
+	}
 
-	return ret;
+	return 0;
 }
 
 static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1331306 — Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()

FromLee Jones <lee.jones@linaro.org>
Date2016-02-10 17:30 +0100
SubjectRe: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
Message-ID<r0FOr-4zg-9@gated-at.bofh.it>
In reply to#1329844
On Mon, 08 Feb 2016, Stephen Boyd wrote:

> Convert this driver to use clkdev_create() instead of
> clk_register_clkdevs(). The latter API is only used by this driver,
> although this driver only allocates one clk to add anyway.
> Furthermore, this driver allocates the clk_lookup structure with
> devm, but clkdev_drop() will free that structure when passed,
> leading to a double free when this driver is removed. Clean it
> all up and pave the way for the removal of clk_register_clkdevs().
> 
> Cc: Lee Jones <lee.jones@linaro.org>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
>  drivers/mfd/intel_quark_i2c_gpio.c | 26 +++++++++-----------------
>  1 file changed, 9 insertions(+), 17 deletions(-)

I never much liked this code [0]

Glad for it to be simplified.

Applied, thanks.

[0] https://lkml.org/lkml/2014/11/25/845

> diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
> index 042137465300..bdc5e27222c0 100644
> --- a/drivers/mfd/intel_quark_i2c_gpio.c
> +++ b/drivers/mfd/intel_quark_i2c_gpio.c
> @@ -52,8 +52,6 @@
>  /* The Quark I2C controller source clock */
>  #define INTEL_QUARK_I2C_CLK_HZ	33000000
>  
> -#define INTEL_QUARK_I2C_NCLK	1
> -
>  struct intel_quark_mfd {
>  	struct pci_dev		*pdev;
>  	struct clk		*i2c_clk;
> @@ -128,30 +126,24 @@ MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
>  static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
>  {
>  	struct pci_dev *pdev = quark_mfd->pdev;
> -	struct clk_lookup *i2c_clk_lookup;
>  	struct clk *i2c_clk;
> -	int ret;
> -
> -	i2c_clk_lookup = devm_kcalloc(&pdev->dev, INTEL_QUARK_I2C_NCLK,
> -				      sizeof(*i2c_clk_lookup), GFP_KERNEL);
> -	if (!i2c_clk_lookup)
> -		return -ENOMEM;
> -
> -	i2c_clk_lookup[0].dev_id = INTEL_QUARK_I2C_CONTROLLER_CLK;
>  
>  	i2c_clk = clk_register_fixed_rate(&pdev->dev,
>  					  INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
>  					  CLK_IS_ROOT, INTEL_QUARK_I2C_CLK_HZ);
> +	if (IS_ERR(i2c_clk))
> +		return PTR_ERR(i2c_clk);
>  
> -	quark_mfd->i2c_clk_lookup = i2c_clk_lookup;
>  	quark_mfd->i2c_clk = i2c_clk;
> +	quark_mfd->i2c_clk_lookup = clkdev_create(i2c_clk, NULL,
> +						INTEL_QUARK_I2C_CONTROLLER_CLK);
>  
> -	ret = clk_register_clkdevs(i2c_clk, i2c_clk_lookup,
> -				   INTEL_QUARK_I2C_NCLK);
> -	if (ret)
> -		dev_err(&pdev->dev, "Fixed clk register failed: %d\n", ret);
> +	if (!quark_mfd->i2c_clk_lookup) {
> +		dev_err(&pdev->dev, "Fixed clk register failed\n");
> +		return -ENOMEM;
> +	}
>  
> -	return ret;
> +	return 0;
>  }
>  
>  static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

[toc] | [prev] | [next] | [standalone]


#1331428 — Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()

FromStephen Boyd <sboyd@codeaurora.org>
Date2016-02-10 19:40 +0100
SubjectRe: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
Message-ID<r0HQe-5YR-17@gated-at.bofh.it>
In reply to#1331306
On 02/10, Lee Jones wrote:
> On Mon, 08 Feb 2016, Stephen Boyd wrote:
> 
> > Convert this driver to use clkdev_create() instead of
> > clk_register_clkdevs(). The latter API is only used by this driver,
> > although this driver only allocates one clk to add anyway.
> > Furthermore, this driver allocates the clk_lookup structure with
> > devm, but clkdev_drop() will free that structure when passed,
> > leading to a double free when this driver is removed. Clean it
> > all up and pave the way for the removal of clk_register_clkdevs().
> > 
> > Cc: Lee Jones <lee.jones@linaro.org>
> > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > Cc: Russell King <linux@arm.linux.org.uk>
> > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > ---
> >  drivers/mfd/intel_quark_i2c_gpio.c | 26 +++++++++-----------------
> >  1 file changed, 9 insertions(+), 17 deletions(-)
> 
> I never much liked this code [0]
> 
> Glad for it to be simplified.
> 
> Applied, thanks.
> 

Can you please ack the patch instead? I'd like to take it through
the clk tree so that I can remove clk_register_clkdevs() as well.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1331774 — Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()

FromLee Jones <lee.jones@linaro.org>
Date2016-02-11 10:20 +0100
SubjectRe: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
Message-ID<r0VzR-6IR-43@gated-at.bofh.it>
In reply to#1331428
On Wed, 10 Feb 2016, Stephen Boyd wrote:

> On 02/10, Lee Jones wrote:
> > On Mon, 08 Feb 2016, Stephen Boyd wrote:
> > 
> > > Convert this driver to use clkdev_create() instead of
> > > clk_register_clkdevs(). The latter API is only used by this driver,
> > > although this driver only allocates one clk to add anyway.
> > > Furthermore, this driver allocates the clk_lookup structure with
> > > devm, but clkdev_drop() will free that structure when passed,
> > > leading to a double free when this driver is removed. Clean it
> > > all up and pave the way for the removal of clk_register_clkdevs().
> > > 
> > > Cc: Lee Jones <lee.jones@linaro.org>
> > > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > > Cc: Russell King <linux@arm.linux.org.uk>
> > > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > > ---
> > >  drivers/mfd/intel_quark_i2c_gpio.c | 26 +++++++++-----------------
> > >  1 file changed, 9 insertions(+), 17 deletions(-)
> > 
> > I never much liked this code [0]
> > 
> > Glad for it to be simplified.
> > 
> > Applied, thanks.
> > 
> 
> Can you please ack the patch instead? I'd like to take it through
> the clk tree so that I can remove clk_register_clkdevs() as well.

I'll make a branch you can pull from.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

[toc] | [prev] | [next] | [standalone]


#1331823 — Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()

FromLee Jones <lee.jones@linaro.org>
Date2016-02-11 12:10 +0100
SubjectRe: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
Message-ID<r0Xii-7Re-23@gated-at.bofh.it>
In reply to#1329844
Stephen,

The upstream patch.  Enjoy!

The following changes since commit 36f90b0a2ddd60823fe193a85e60ff1906c2a9b3:

  Linux 4.5-rc2 (2016-01-31 18:12:16 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git tags/ib-mfd-clk-v4.6

for you to fetch changes up to c4726abce63bf9b1887ce68fdf012a823bd94ec3:

  mfd: intel_quark_i2c_gpio: Use clkdev_create() (2016-02-11 11:03:07 +0000)

----------------------------------------------------------------
Immutable branch between MFD and Clk due for v4.6

----------------------------------------------------------------
Stephen Boyd (1):
      mfd: intel_quark_i2c_gpio: Use clkdev_create()

 drivers/mfd/intel_quark_i2c_gpio.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

[toc] | [prev] | [next] | [standalone]


#1334512 — Re: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()

FromAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Date2016-02-15 16:20 +0100
SubjectRe: [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
Message-ID<r2t6q-2Md-21@gated-at.bofh.it>
In reply to#1329844
On Mon, 2016-02-08 at 17:45 -0800, Stephen Boyd wrote:
> Convert this driver to use clkdev_create() instead of
> clk_register_clkdevs(). The latter API is only used by this driver,
> although this driver only allocates one clk to add anyway.
> Furthermore, this driver allocates the clk_lookup structure with
> devm, but clkdev_drop() will free that structure when passed,
> leading to a double free when this driver is removed. Clean it
> all up and pave the way for the removal of clk_register_clkdevs().

Good one.

I have still in my local tree the fix regarding to this code since I
found an error in the error path (we don't free clk resources). So, I
will re-base it, although it will require to go with two patches
instead of one if we go to stable.

For this one:
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Cc: Lee Jones <lee.jones@linaro.org>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
>  drivers/mfd/intel_quark_i2c_gpio.c | 26 +++++++++-----------------
>  1 file changed, 9 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/mfd/intel_quark_i2c_gpio.c
> b/drivers/mfd/intel_quark_i2c_gpio.c
> index 042137465300..bdc5e27222c0 100644
> --- a/drivers/mfd/intel_quark_i2c_gpio.c
> +++ b/drivers/mfd/intel_quark_i2c_gpio.c
> @@ -52,8 +52,6 @@
>  /* The Quark I2C controller source clock */
>  #define INTEL_QUARK_I2C_CLK_HZ	33000000
>  
> -#define INTEL_QUARK_I2C_NCLK	1
> -
>  struct intel_quark_mfd {
>  	struct pci_dev		*pdev;
>  	struct clk		*i2c_clk;
> @@ -128,30 +126,24 @@ MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
>  static int intel_quark_register_i2c_clk(struct intel_quark_mfd
> *quark_mfd)
>  {
>  	struct pci_dev *pdev = quark_mfd->pdev;
> -	struct clk_lookup *i2c_clk_lookup;
>  	struct clk *i2c_clk;
> -	int ret;
> -
> -	i2c_clk_lookup = devm_kcalloc(&pdev->dev,
> INTEL_QUARK_I2C_NCLK,
> -				      sizeof(*i2c_clk_lookup),
> GFP_KERNEL);
> -	if (!i2c_clk_lookup)
> -		return -ENOMEM;
> -
> -	i2c_clk_lookup[0].dev_id = INTEL_QUARK_I2C_CONTROLLER_CLK;
>  
>  	i2c_clk = clk_register_fixed_rate(&pdev->dev,
>  					  INTEL_QUARK_I2C_CONTROLLER
> _CLK, NULL,
>  					  CLK_IS_ROOT,
> INTEL_QUARK_I2C_CLK_HZ);
> +	if (IS_ERR(i2c_clk))
> +		return PTR_ERR(i2c_clk);
>  
> -	quark_mfd->i2c_clk_lookup = i2c_clk_lookup;
>  	quark_mfd->i2c_clk = i2c_clk;
> +	quark_mfd->i2c_clk_lookup = clkdev_create(i2c_clk, NULL,
> +						INTEL_QUARK_I2C_CONT
> ROLLER_CLK);
>  
> -	ret = clk_register_clkdevs(i2c_clk, i2c_clk_lookup,
> -				   INTEL_QUARK_I2C_NCLK);
> -	if (ret)
> -		dev_err(&pdev->dev, "Fixed clk register failed:
> %d\n", ret);
> +	if (!quark_mfd->i2c_clk_lookup) {
> +		dev_err(&pdev->dev, "Fixed clk register failed\n");
> +		return -ENOMEM;
> +	}
>  
> -	return ret;
> +	return 0;
>  }
>  
>  static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | linux.kernel


csiph-web