* [PATCH 00/14] clk_hw based clkdev/DT providers
@ 2016-02-09 1:45 Stephen Boyd
2016-02-09 1:45 ` [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd
` (13 more replies)
0 siblings, 14 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-10 16:23 ` Lee Jones
` (3 more replies)
2016-02-09 1:45 ` [PATCH 02/14] clkdev: Remove clk_register_clkdevs() Stephen Boyd
` (12 subsequent siblings)
13 siblings, 4 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 02/14] clkdev: Remove clk_register_clkdevs()
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
2016-02-09 1:45 ` [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-15 15:16 ` Andy Shevchenko
2016-02-15 22:12 ` Michael Turquette
2016-02-09 1:45 ` [PATCH 03/14] clk: Add {devm_}clk_hw_{register,unregister}() APIs Stephen Boyd
` (11 subsequent siblings)
13 siblings, 2 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 03/14] clk: Add {devm_}clk_hw_{register,unregister}() APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
2016-02-09 1:45 ` [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd
2016-02-09 1:45 ` [PATCH 02/14] clkdev: Remove clk_register_clkdevs() Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-15 22:13 ` [PATCH 03/14] clk: Add {devm_}clk_hw_{register, unregister}() APIs Michael Turquette
2016-02-09 1:45 ` [PATCH 04/14] clk: Add clk_hw OF clk providers Stephen Boyd
` (10 subsequent siblings)
13 siblings, 1 reply; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
We've largely split the clk consumer and provider APIs along
struct clk and struct clk_hw, but clk_register() still returns a
struct clk pointer for each struct clk_hw that's registered.
Eventually we'd like to only allocate struct clks when there's a
user, because struct clk is per-user now, so clk_register() needs
to change.
Let's add new APIs to register struct clk_hws, but this time
we'll hide the struct clk from the caller by returning an int
error code. Also add an unregistration API that takes the clk_hw
structure that was passed to the registration API. This way
provider drivers never have to deal with a struct clk pointer
unless they're using the clk consumer APIs.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
Documentation/driver-model/devres.txt | 1 +
drivers/clk/clk.c | 86 +++++++++++++++++++++++++++++++++++
include/linux/clk-provider.h | 6 +++
3 files changed, 93 insertions(+)
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 831a5363f6be..600e30bf52c5 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -236,6 +236,7 @@ certainly invest a bit more effort into libata core layer).
CLOCK
devm_clk_get()
devm_clk_put()
+ devm_clk_hw_register()
DMA
dmam_alloc_coherent()
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index b4db67a446c8..adaaead3639f 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2613,6 +2613,22 @@ fail_out:
}
EXPORT_SYMBOL_GPL(clk_register);
+/**
+ * clk_hw_register - register a clk_hw and return an error code
+ * @dev: device that is registering this clock
+ * @hw: link to hardware-specific clock data
+ *
+ * clk_hw_register is the primary interface for populating the clock tree with
+ * new clock nodes. It returns an integer equal to zero indicating success or
+ * less than zero indicating failure. Drivers must test for an error code after
+ * calling clk_hw_register().
+ */
+int clk_hw_register(struct device *dev, struct clk_hw *hw)
+{
+ return PTR_ERR_OR_ZERO(clk_register(dev, hw));
+}
+EXPORT_SYMBOL_GPL(clk_hw_register);
+
/* Free memory allocated for a clock. */
static void __clk_release(struct kref *ref)
{
@@ -2714,11 +2730,26 @@ void clk_unregister(struct clk *clk)
}
EXPORT_SYMBOL_GPL(clk_unregister);
+/**
+ * clk_hw_unregister - unregister a currently registered clk_hw
+ * @hw: hardware-specific clock data to unregister
+ */
+void clk_hw_unregister(struct clk_hw *hw)
+{
+ clk_unregister(hw->clk);
+}
+EXPORT_SYMBOL_GPL(clk_hw_unregister);
+
static void devm_clk_release(struct device *dev, void *res)
{
clk_unregister(*(struct clk **)res);
}
+static void devm_clk_hw_release(struct device *dev, void *res)
+{
+ clk_hw_unregister(*(struct clk_hw **)res);
+}
+
/**
* devm_clk_register - resource managed clk_register()
* @dev: device that is registering this clock
@@ -2749,6 +2780,36 @@ struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
}
EXPORT_SYMBOL_GPL(devm_clk_register);
+/**
+ * devm_clk_hw_register - resource managed clk_hw_register()
+ * @dev: device that is registering this clock
+ * @hw: link to hardware-specific clock data
+ *
+ * Managed clk_hw_register(). Clocks returned from this function are
+ * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register()
+ * for more information.
+ */
+int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
+{
+ struct clk_hw **hwp;
+ int ret;
+
+ hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL);
+ if (!hwp)
+ return -ENOMEM;
+
+ ret = clk_hw_register(dev, hw);
+ if (!ret) {
+ *hwp = hw;
+ devres_add(dev, hwp);
+ } else {
+ devres_free(hwp);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(devm_clk_hw_register);
+
static int devm_clk_match(struct device *dev, void *res, void *data)
{
struct clk *c = res;
@@ -2757,6 +2818,15 @@ static int devm_clk_match(struct device *dev, void *res, void *data)
return c == data;
}
+static int devm_clk_hw_match(struct device *dev, void *res, void *data)
+{
+ struct clk_hw *hw = res;
+
+ if (WARN_ON(!hw))
+ return 0;
+ return hw == data;
+}
+
/**
* devm_clk_unregister - resource managed clk_unregister()
* @clk: clock to unregister
@@ -2771,6 +2841,22 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
}
EXPORT_SYMBOL_GPL(devm_clk_unregister);
+/**
+ * devm_clk_hw_unregister - resource managed clk_hw_unregister()
+ * @dev: device that is unregistering the hardware-specific clock data
+ * @hw: link to hardware-specific clock data
+ *
+ * Unregister a clk_hw registered with devm_clk_hw_register(). Normally
+ * this function will not need to be called and the resource management
+ * code will ensure that the resource is freed.
+ */
+void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw)
+{
+ WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match,
+ hw));
+}
+EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
+
/*
* clkdev helpers
*/
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 1143e38555a4..abc16d77fb62 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -639,9 +639,15 @@ void of_gpio_mux_clk_setup(struct device_node *node);
struct clk *clk_register(struct device *dev, struct clk_hw *hw);
struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
+int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw);
+int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw);
+
void clk_unregister(struct clk *clk);
void devm_clk_unregister(struct device *dev, struct clk *clk);
+void clk_hw_unregister(struct clk_hw *hw);
+void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw);
+
/* helper functions */
const char *__clk_get_name(const struct clk *clk);
const char *clk_hw_get_name(const struct clk_hw *hw);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 04/14] clk: Add clk_hw OF clk providers
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (2 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 03/14] clk: Add {devm_}clk_hw_{register,unregister}() APIs Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 3:31 ` kbuild test robot
2016-02-09 1:45 ` [PATCH 05/14] clkdev: Add clk_hw based registration APIs Stephen Boyd
` (9 subsequent siblings)
13 siblings, 1 reply; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 05/14] clkdev: Add clk_hw based registration APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (3 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 04/14] clk: Add clk_hw OF clk providers Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 1:45 ` [PATCH 06/14] clk: divider: Add hw " Stephen Boyd
` (8 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 06/14] clk: divider: Add hw based registration APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (4 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 05/14] clkdev: Add clk_hw based registration APIs Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 1:45 ` [PATCH 07/14] clk: gate: " Stephen Boyd
` (7 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 07/14] clk: gate: Add hw based registration APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (5 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 06/14] clk: divider: Add hw " Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 1:45 ` [PATCH 08/14] clk: mux: " Stephen Boyd
` (6 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 08/14] clk: mux: Add hw based registration APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (6 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 07/14] clk: gate: " Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 1:45 ` [PATCH 09/14] clk: fixed-factor: " Stephen Boyd
` (5 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 09/14] clk: fixed-factor: Add hw based registration APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (7 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 08/14] clk: mux: " Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 1:45 ` [PATCH 10/14] clk: fractional-divider: " Stephen Boyd
` (4 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 10/14] clk: fractional-divider: Add hw based registration APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (8 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 09/14] clk: fixed-factor: " Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 1:45 ` [PATCH 11/14] clk: composite: " Stephen Boyd
` (3 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
Add registration APIs in the clk fractional 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-fractional-divider.c | 40 +++++++++++++++++++++++++++++++-----
include/linux/clk-provider.h | 5 +++++
2 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 5c4955e33f7a..e7a315e840e6 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -118,14 +118,15 @@ const struct clk_ops clk_fractional_divider_ops = {
};
EXPORT_SYMBOL_GPL(clk_fractional_divider_ops);
-struct clk *clk_register_fractional_divider(struct device *dev,
+struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
u8 clk_divider_flags, spinlock_t *lock)
{
struct clk_fractional_divider *fd;
struct clk_init_data init;
- struct clk *clk;
+ struct clk_hw *hw;
+ int ret;
fd = kzalloc(sizeof(*fd), GFP_KERNEL);
if (!fd)
@@ -148,10 +149,39 @@ struct clk *clk_register_fractional_divider(struct device *dev,
fd->lock = lock;
fd->hw.init = &init;
- clk = clk_register(dev, &fd->hw);
- if (IS_ERR(clk))
+ hw = &fd->hw;
+ ret = clk_hw_register(dev, hw);
+ if (ret) {
kfree(fd);
+ hw = ERR_PTR(ret);
+ }
+
+ return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_fractional_divider);
- return clk;
+struct clk *clk_register_fractional_divider(struct device *dev,
+ const char *name, const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
+ u8 clk_divider_flags, spinlock_t *lock)
+{
+ struct clk_hw *hw;
+
+ hw = clk_hw_register_fractional_divider(dev, name, parent_name, flags,
+ reg, mshift, mwidth, nshift, nwidth, clk_divider_flags,
+ lock);
+ if (IS_ERR(hw))
+ return ERR_CAST(hw);
+ return hw->clk;
}
EXPORT_SYMBOL_GPL(clk_register_fractional_divider);
+
+void clk_hw_unregister_fractional_divider(struct clk_hw *hw)
+{
+ struct clk_fractional_divider *fd;
+
+ fd = to_clk_fd(hw);
+
+ clk_hw_unregister(hw);
+ kfree(fd);
+}
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index d4d65f60b85e..549ed3844876 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -549,6 +549,11 @@ struct clk *clk_register_fractional_divider(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
u8 clk_divider_flags, spinlock_t *lock);
+struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
+ const char *name, const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
+ u8 clk_divider_flags, spinlock_t *lock);
+void clk_hw_unregister_fractional_divider(struct clk_hw *hw);
/**
* struct clk_multiplier - adjustable multiplier clock
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 11/14] clk: composite: Add hw based registration APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (9 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 10/14] clk: fractional-divider: " Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 1:45 ` [PATCH 12/14] clk: gpio: " Stephen Boyd
` (2 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 12/14] clk: gpio: Add hw based registration APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (10 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 11/14] clk: composite: " Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 1:45 ` [PATCH 13/14] clk: fixed-rate: " Stephen Boyd
2016-02-09 1:45 ` [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs Stephen Boyd
13 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 13/14] clk: fixed-rate: Add hw based registration APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (11 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 12/14] clk: gpio: " Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 1:45 ` [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs Stephen Boyd
13 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
` (12 preceding siblings ...)
2016-02-09 1:45 ` [PATCH 13/14] clk: fixed-rate: " Stephen Boyd
@ 2016-02-09 1:45 ` Stephen Boyd
2016-02-09 5:30 ` kbuild test robot
2016-02-09 8:01 ` kbuild test robot
13 siblings, 2 replies; 27+ messages in thread
From: Stephen Boyd @ 2016-02-09 1:45 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 04/14] clk: Add clk_hw OF clk providers
2016-02-09 1:45 ` [PATCH 04/14] clk: Add clk_hw OF clk providers Stephen Boyd
@ 2016-02-09 3:31 ` kbuild test robot
0 siblings, 0 replies; 27+ messages in thread
From: kbuild test robot @ 2016-02-09 3:31 UTC (permalink / raw
To: linux-arm-kernel
Hi Stephen,
[auto build test ERROR on ljones-mfd/for-mfd-next]
[also build test ERROR on v4.5-rc3 next-20160208]
[cannot apply to clk/clk-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Stephen-Boyd/clk_hw-based-clkdev-DT-providers/20160209-095211
base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: x86_64-rhel (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
drivers/clk/clk.o: In function `of_clk_hw_simple_get':
>> (.text+0x3ec0): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk.o: In function `of_clk_hw_onecell_get':
>> (.text+0x3ee0): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk.o: In function `of_clk_add_hw_provider':
>> (.text+0x3eb0): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/clk-divider.o: In function `of_clk_hw_simple_get':
(.text+0xb20): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk-divider.o: In function `of_clk_hw_onecell_get':
(.text+0xb40): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk-divider.o: In function `of_clk_add_hw_provider':
(.text+0xb10): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/clk-fixed-factor.o: In function `of_clk_hw_simple_get':
(.text+0x170): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk-fixed-factor.o: In function `of_clk_hw_onecell_get':
(.text+0x190): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk-fixed-factor.o: In function `of_clk_add_hw_provider':
(.text+0x160): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/clk-fixed-rate.o: In function `of_clk_hw_simple_get':
(.text+0x120): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk-fixed-rate.o: In function `of_clk_hw_onecell_get':
(.text+0x140): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk-fixed-rate.o: In function `of_clk_add_hw_provider':
(.text+0x110): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/clk-gate.o: In function `of_clk_hw_simple_get':
(.text+0x280): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk-gate.o: In function `of_clk_hw_onecell_get':
(.text+0x2a0): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk-gate.o: In function `of_clk_add_hw_provider':
(.text+0x270): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/clk-multiplier.o: In function `of_clk_hw_simple_get':
(.text+0x2b0): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk-multiplier.o: In function `of_clk_hw_onecell_get':
(.text+0x2d0): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk-multiplier.o: In function `of_clk_add_hw_provider':
(.text+0x2a0): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/clk-mux.o: In function `of_clk_hw_simple_get':
(.text+0x340): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk-mux.o: In function `of_clk_hw_onecell_get':
(.text+0x360): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk-mux.o: In function `of_clk_add_hw_provider':
(.text+0x330): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/clk-composite.o: In function `of_clk_add_hw_provider':
clk-composite.c:(.text+0x3a0): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/clk-composite.o: In function `of_clk_hw_simple_get':
clk-composite.c:(.text+0x3b0): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk-composite.o: In function `of_clk_hw_onecell_get':
clk-composite.c:(.text+0x3d0): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk-fractional-divider.o: In function `of_clk_hw_simple_get':
(.text+0x330): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk-fractional-divider.o: In function `of_clk_hw_onecell_get':
(.text+0x350): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk-fractional-divider.o: In function `of_clk_add_hw_provider':
(.text+0x320): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/clk-gpio.o: In function `of_clk_hw_simple_get':
(.text+0x340): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/clk-gpio.o: In function `of_clk_hw_onecell_get':
(.text+0x360): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/clk-gpio.o: In function `of_clk_add_hw_provider':
(.text+0x330): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
drivers/clk/x86/built-in.o: In function `of_clk_hw_simple_get':
(.text+0x90): multiple definition of `of_clk_hw_simple_get'
drivers/clk/clkdev.o:(.text+0x3e0): first defined here
drivers/clk/x86/built-in.o: In function `of_clk_hw_onecell_get':
(.text+0xb0): multiple definition of `of_clk_hw_onecell_get'
drivers/clk/clkdev.o:(.text+0x400): first defined here
drivers/clk/x86/built-in.o: In function `of_clk_add_hw_provider':
(.text+0x80): multiple definition of `of_clk_add_hw_provider'
drivers/clk/clkdev.o:(.text+0x3d0): first defined here
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 36062 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160209/4189771e/attachment-0001.obj>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs
2016-02-09 1:45 ` [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs Stephen Boyd
@ 2016-02-09 5:30 ` kbuild test robot
2016-02-09 8:01 ` kbuild test robot
1 sibling, 0 replies; 27+ messages in thread
From: kbuild test robot @ 2016-02-09 5:30 UTC (permalink / raw
To: linux-arm-kernel
Hi Stephen,
[auto build test ERROR on ljones-mfd/for-mfd-next]
[also build test ERROR on v4.5-rc3]
[cannot apply to clk/clk-next next-20160208]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Stephen-Boyd/clk_hw-based-clkdev-DT-providers/20160209-095211
base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: i386-allmodconfig (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
>> ERROR: "of_clk_add_hw_provider" undefined!
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 53452 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160209/22b3ed58/attachment-0001.obj>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs
2016-02-09 1:45 ` [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs Stephen Boyd
2016-02-09 5:30 ` kbuild test robot
@ 2016-02-09 8:01 ` kbuild test robot
1 sibling, 0 replies; 27+ messages in thread
From: kbuild test robot @ 2016-02-09 8:01 UTC (permalink / raw
To: linux-arm-kernel
Hi Stephen,
[auto build test ERROR on ljones-mfd/for-mfd-next]
[also build test ERROR on v4.5-rc3]
[cannot apply to clk/clk-next next-20160208]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Stephen-Boyd/clk_hw-based-clkdev-DT-providers/20160209-095211
base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: x86_64-allmodconfig (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
>> ERROR: "of_clk_add_hw_provider" [drivers/clk/qcom/clk-qcom.ko] undefined!
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 52114 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160209/66c7eadc/attachment-0001.obj>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
2016-02-09 1:45 ` [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd
@ 2016-02-10 16:23 ` Lee Jones
2016-02-10 18:35 ` Stephen Boyd
2016-02-11 11:08 ` Lee Jones
` (2 subsequent siblings)
3 siblings, 1 reply; 27+ messages in thread
From: Lee Jones @ 2016-02-10 16:23 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
2016-02-10 16:23 ` Lee Jones
@ 2016-02-10 18:35 ` Stephen Boyd
2016-02-11 9:09 ` Lee Jones
0 siblings, 1 reply; 27+ messages in thread
From: Stephen Boyd @ 2016-02-10 18:35 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
2016-02-10 18:35 ` Stephen Boyd
@ 2016-02-11 9:09 ` Lee Jones
0 siblings, 0 replies; 27+ messages in thread
From: Lee Jones @ 2016-02-11 9:09 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
2016-02-09 1:45 ` [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd
2016-02-10 16:23 ` Lee Jones
@ 2016-02-11 11:08 ` Lee Jones
2016-02-15 15:14 ` Andy Shevchenko
2016-02-15 22:13 ` Michael Turquette
3 siblings, 0 replies; 27+ messages in thread
From: Lee Jones @ 2016-02-11 11:08 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
2016-02-09 1:45 ` [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd
2016-02-10 16:23 ` Lee Jones
2016-02-11 11:08 ` Lee Jones
@ 2016-02-15 15:14 ` Andy Shevchenko
2016-02-15 22:13 ` Michael Turquette
3 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2016-02-15 15:14 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 02/14] clkdev: Remove clk_register_clkdevs()
2016-02-09 1:45 ` [PATCH 02/14] clkdev: Remove clk_register_clkdevs() Stephen Boyd
@ 2016-02-15 15:16 ` Andy Shevchenko
2016-02-15 22:12 ` Michael Turquette
1 sibling, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2016-02-15 15:16 UTC (permalink / raw
To: linux-arm-kernel
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
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 02/14] clkdev: Remove clk_register_clkdevs()
2016-02-09 1:45 ` [PATCH 02/14] clkdev: Remove clk_register_clkdevs() Stephen Boyd
2016-02-15 15:16 ` Andy Shevchenko
@ 2016-02-15 22:12 ` Michael Turquette
1 sibling, 0 replies; 27+ messages in thread
From: Michael Turquette @ 2016-02-15 22:12 UTC (permalink / raw
To: linux-arm-kernel
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
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create()
2016-02-09 1:45 ` [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd
` (2 preceding siblings ...)
2016-02-15 15:14 ` Andy Shevchenko
@ 2016-02-15 22:13 ` Michael Turquette
3 siblings, 0 replies; 27+ messages in thread
From: Michael Turquette @ 2016-02-15 22:13 UTC (permalink / raw
To: linux-arm-kernel
Quoting Stephen Boyd (2016-02-08 17:45:28)
> 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>
Looks good to me.
Regards,
Mike
> ---
> 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
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 03/14] clk: Add {devm_}clk_hw_{register, unregister}() APIs
2016-02-09 1:45 ` [PATCH 03/14] clk: Add {devm_}clk_hw_{register,unregister}() APIs Stephen Boyd
@ 2016-02-15 22:13 ` Michael Turquette
0 siblings, 0 replies; 27+ messages in thread
From: Michael Turquette @ 2016-02-15 22:13 UTC (permalink / raw
To: linux-arm-kernel
Quoting Stephen Boyd (2016-02-08 17:45:30)
> We've largely split the clk consumer and provider APIs along
> struct clk and struct clk_hw, but clk_register() still returns a
> struct clk pointer for each struct clk_hw that's registered.
> Eventually we'd like to only allocate struct clks when there's a
> user, because struct clk is per-user now, so clk_register() needs
> to change.
>
> Let's add new APIs to register struct clk_hws, but this time
> we'll hide the struct clk from the caller by returning an int
> error code. Also add an unregistration API that takes the clk_hw
> structure that was passed to the registration API. This way
> provider drivers never have to deal with a struct clk pointer
> unless they're using the clk consumer APIs.
>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Looks good to me.
Regards,
Mike
> ---
> Documentation/driver-model/devres.txt | 1 +
> drivers/clk/clk.c | 86 +++++++++++++++++++++++++++++++++++
> include/linux/clk-provider.h | 6 +++
> 3 files changed, 93 insertions(+)
>
> diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
> index 831a5363f6be..600e30bf52c5 100644
> --- a/Documentation/driver-model/devres.txt
> +++ b/Documentation/driver-model/devres.txt
> @@ -236,6 +236,7 @@ certainly invest a bit more effort into libata core layer).
> CLOCK
> devm_clk_get()
> devm_clk_put()
> + devm_clk_hw_register()
>
> DMA
> dmam_alloc_coherent()
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index b4db67a446c8..adaaead3639f 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2613,6 +2613,22 @@ fail_out:
> }
> EXPORT_SYMBOL_GPL(clk_register);
>
> +/**
> + * clk_hw_register - register a clk_hw and return an error code
> + * @dev: device that is registering this clock
> + * @hw: link to hardware-specific clock data
> + *
> + * clk_hw_register is the primary interface for populating the clock tree with
> + * new clock nodes. It returns an integer equal to zero indicating success or
> + * less than zero indicating failure. Drivers must test for an error code after
> + * calling clk_hw_register().
> + */
> +int clk_hw_register(struct device *dev, struct clk_hw *hw)
> +{
> + return PTR_ERR_OR_ZERO(clk_register(dev, hw));
> +}
> +EXPORT_SYMBOL_GPL(clk_hw_register);
> +
> /* Free memory allocated for a clock. */
> static void __clk_release(struct kref *ref)
> {
> @@ -2714,11 +2730,26 @@ void clk_unregister(struct clk *clk)
> }
> EXPORT_SYMBOL_GPL(clk_unregister);
>
> +/**
> + * clk_hw_unregister - unregister a currently registered clk_hw
> + * @hw: hardware-specific clock data to unregister
> + */
> +void clk_hw_unregister(struct clk_hw *hw)
> +{
> + clk_unregister(hw->clk);
> +}
> +EXPORT_SYMBOL_GPL(clk_hw_unregister);
> +
> static void devm_clk_release(struct device *dev, void *res)
> {
> clk_unregister(*(struct clk **)res);
> }
>
> +static void devm_clk_hw_release(struct device *dev, void *res)
> +{
> + clk_hw_unregister(*(struct clk_hw **)res);
> +}
> +
> /**
> * devm_clk_register - resource managed clk_register()
> * @dev: device that is registering this clock
> @@ -2749,6 +2780,36 @@ struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
> }
> EXPORT_SYMBOL_GPL(devm_clk_register);
>
> +/**
> + * devm_clk_hw_register - resource managed clk_hw_register()
> + * @dev: device that is registering this clock
> + * @hw: link to hardware-specific clock data
> + *
> + * Managed clk_hw_register(). Clocks returned from this function are
> + * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register()
> + * for more information.
> + */
> +int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
> +{
> + struct clk_hw **hwp;
> + int ret;
> +
> + hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL);
> + if (!hwp)
> + return -ENOMEM;
> +
> + ret = clk_hw_register(dev, hw);
> + if (!ret) {
> + *hwp = hw;
> + devres_add(dev, hwp);
> + } else {
> + devres_free(hwp);
> + }
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(devm_clk_hw_register);
> +
> static int devm_clk_match(struct device *dev, void *res, void *data)
> {
> struct clk *c = res;
> @@ -2757,6 +2818,15 @@ static int devm_clk_match(struct device *dev, void *res, void *data)
> return c == data;
> }
>
> +static int devm_clk_hw_match(struct device *dev, void *res, void *data)
> +{
> + struct clk_hw *hw = res;
> +
> + if (WARN_ON(!hw))
> + return 0;
> + return hw == data;
> +}
> +
> /**
> * devm_clk_unregister - resource managed clk_unregister()
> * @clk: clock to unregister
> @@ -2771,6 +2841,22 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
> }
> EXPORT_SYMBOL_GPL(devm_clk_unregister);
>
> +/**
> + * devm_clk_hw_unregister - resource managed clk_hw_unregister()
> + * @dev: device that is unregistering the hardware-specific clock data
> + * @hw: link to hardware-specific clock data
> + *
> + * Unregister a clk_hw registered with devm_clk_hw_register(). Normally
> + * this function will not need to be called and the resource management
> + * code will ensure that the resource is freed.
> + */
> +void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw)
> +{
> + WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match,
> + hw));
> +}
> +EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
> +
> /*
> * clkdev helpers
> */
> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
> index 1143e38555a4..abc16d77fb62 100644
> --- a/include/linux/clk-provider.h
> +++ b/include/linux/clk-provider.h
> @@ -639,9 +639,15 @@ void of_gpio_mux_clk_setup(struct device_node *node);
> struct clk *clk_register(struct device *dev, struct clk_hw *hw);
> struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
>
> +int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw);
> +int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw);
> +
> void clk_unregister(struct clk *clk);
> void devm_clk_unregister(struct device *dev, struct clk *clk);
>
> +void clk_hw_unregister(struct clk_hw *hw);
> +void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw);
> +
> /* helper functions */
> const char *__clk_get_name(const struct clk *clk);
> const char *clk_hw_get_name(const struct clk_hw *hw);
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2016-02-15 22:13 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-09 1:45 [PATCH 00/14] clk_hw based clkdev/DT providers Stephen Boyd
2016-02-09 1:45 ` [PATCH 01/14] mfd: intel_quark_i2c_gpio: Use clkdev_create() Stephen Boyd
2016-02-10 16:23 ` Lee Jones
2016-02-10 18:35 ` Stephen Boyd
2016-02-11 9:09 ` Lee Jones
2016-02-11 11:08 ` Lee Jones
2016-02-15 15:14 ` Andy Shevchenko
2016-02-15 22:13 ` Michael Turquette
2016-02-09 1:45 ` [PATCH 02/14] clkdev: Remove clk_register_clkdevs() Stephen Boyd
2016-02-15 15:16 ` Andy Shevchenko
2016-02-15 22:12 ` Michael Turquette
2016-02-09 1:45 ` [PATCH 03/14] clk: Add {devm_}clk_hw_{register,unregister}() APIs Stephen Boyd
2016-02-15 22:13 ` [PATCH 03/14] clk: Add {devm_}clk_hw_{register, unregister}() APIs Michael Turquette
2016-02-09 1:45 ` [PATCH 04/14] clk: Add clk_hw OF clk providers Stephen Boyd
2016-02-09 3:31 ` kbuild test robot
2016-02-09 1:45 ` [PATCH 05/14] clkdev: Add clk_hw based registration APIs Stephen Boyd
2016-02-09 1:45 ` [PATCH 06/14] clk: divider: Add hw " Stephen Boyd
2016-02-09 1:45 ` [PATCH 07/14] clk: gate: " Stephen Boyd
2016-02-09 1:45 ` [PATCH 08/14] clk: mux: " Stephen Boyd
2016-02-09 1:45 ` [PATCH 09/14] clk: fixed-factor: " Stephen Boyd
2016-02-09 1:45 ` [PATCH 10/14] clk: fractional-divider: " Stephen Boyd
2016-02-09 1:45 ` [PATCH 11/14] clk: composite: " Stephen Boyd
2016-02-09 1:45 ` [PATCH 12/14] clk: gpio: " Stephen Boyd
2016-02-09 1:45 ` [PATCH 13/14] clk: fixed-rate: " Stephen Boyd
2016-02-09 1:45 ` [PATCH 14/14] clk: qcom: Migrate to clk_hw based registration and OF APIs Stephen Boyd
2016-02-09 5:30 ` kbuild test robot
2016-02-09 8:01 ` kbuild test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).