summaryrefslogtreecommitdiff
path: root/drivers/clk/davinci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-09 12:06:24 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-09 12:06:24 -0700
commit6419945e3313fd894af79caefca6823d4511133f (patch)
treef6bc2ac4f5820f4bfada3a9e9abc7e52a8ea69cb /drivers/clk/davinci
parentd60dafdca4b463405e5586df923f05b10e9ac2f9 (diff)
parent55913c2d33307ac11797531ebbe7c122a73cc0fd (diff)
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd: "This time we have a good set of changes to the core framework that do some general cleanups, but nothing too major. The majority of the diff goes to two SoCs, Actions Semi and Qualcomm. A brand new driver is introduced for Actions Semi so it takes up some lines to add all the different types, and the Qualcomm diff is there because we add support for two SoCs and it's quite a bit of data. Otherwise the big driver updates are on TI Davinci and Amlogic platforms. And then the long tail of driver updates for various fixes and stuff follows after that. Core: - debugfs cleanups removing error checking and an unused provider API - Removal of a clk init typedef that isn't used - Usage of match_string() to simplify parent string name matching - OF clk helpers moved to their own file (linux/of_clk.h) - Make clk warnings more readable across kernel versions New Drivers: - Qualcomm SDM845 GCC and Video clk controllers - Qualcomm MSM8998 GCC - Actions Semi S900 SoC support - Nuvoton npcm750 microcontroller clks - Amlogic axg AO clock controller Removed Drivers: - Deprecated Rockchip clk-gate driver Updates: - debugfs functions stopped checking return values - Support for the MSIOF module clocks on Rensas R-Car M3-N - Support for the new Rensas RZ/G1C and R-Car E3 SoCs - Qualcomm GDSC, RCG, and PLL updates for clk changes in new SoCs - Berlin and Amlogic SPDX tagging - Usage of of_clk_get_parent_count() in more places - Proper implementation of the CDEV1/2 clocks on Tegra20 - Allwinner H6 PRCM clock support and R40 EMAC support - Add critical flag to meson8b's fdiv2 as temporary fixup for ethernet - Round closest support for meson's mpll driver - Support for meson8b nand clocks and gxbb video decoder clocks - Mediatek mali clks - STM32MP1 fixes - Uniphier LD11/LD20 stream demux system clock" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (134 commits) clk: qcom: Export clk_fabia_pll_configure() clk: bcm: Update and add Stingray clock entries dt-bindings: clk: Update Stingray binding doc clk-si544: Properly round requested frequency to nearest match clk: ingenic: jz4770: Add 150us delay after enabling VPU clock clk: ingenic: jz4770: Enable power of AHB1 bus after ungating VPU clock clk: ingenic: jz4770: Modify C1CLK clock to disable CPU clock stop on idle clk: ingenic: jz4770: Change OTG from custom to standard gated clock clk: ingenic: Support specifying "wait for clock stable" delay clk: ingenic: Add support for clocks whose gate bit is inverted clk: use match_string() helper clk: bcm2835: use match_string() helper clk: Return void from debug_init op clk: remove clk_debugfs_add_file() clk: tegra: no need to check return value of debugfs_create functions clk: davinci: no need to check return value of debugfs_create functions clk: bcm2835: no need to check return value of debugfs_create functions clk: no need to check return value of debugfs_create functions clk: imx6: add EPIT clock support clk: mvebu: use correct bit for 98DX3236 NAND ...
Diffstat (limited to 'drivers/clk/davinci')
-rw-r--r--drivers/clk/davinci/pll-da830.c5
-rw-r--r--drivers/clk/davinci/pll-da850.c37
-rw-r--r--drivers/clk/davinci/pll-dm355.c22
-rw-r--r--drivers/clk/davinci/pll-dm365.c9
-rw-r--r--drivers/clk/davinci/pll-dm644x.c9
-rw-r--r--drivers/clk/davinci/pll-dm646x.c11
-rw-r--r--drivers/clk/davinci/pll.c314
-rw-r--r--drivers/clk/davinci/pll.h41
-rw-r--r--drivers/clk/davinci/psc-da830.c3
-rw-r--r--drivers/clk/davinci/psc-dm355.c7
-rw-r--r--drivers/clk/davinci/psc-dm365.c22
-rw-r--r--drivers/clk/davinci/psc-dm644x.c3
-rw-r--r--drivers/clk/davinci/psc-dm646x.c3
-rw-r--r--drivers/clk/davinci/psc.c72
-rw-r--r--drivers/clk/davinci/psc.h12
15 files changed, 384 insertions, 186 deletions
diff --git a/drivers/clk/davinci/pll-da830.c b/drivers/clk/davinci/pll-da830.c
index 929a3d3a9adb..0a0d06fb25fd 100644
--- a/drivers/clk/davinci/pll-da830.c
+++ b/drivers/clk/davinci/pll-da830.c
@@ -6,6 +6,7 @@
*/
#include <linux/clkdev.h>
+#include <linux/clk/davinci.h>
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -36,11 +37,11 @@ SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0);
SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_FIXED_DIV);
SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0);
-int da830_pll_init(struct device *dev, void __iomem *base)
+int da830_pll_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
struct clk *clk;
- davinci_pll_clk_register(dev, &da830_pll_info, "ref_clk", base);
+ davinci_pll_clk_register(dev, &da830_pll_info, "ref_clk", base, cfgchip);
clk = davinci_pll_sysclk_register(dev, &pll0_sysclk2, base);
clk_register_clkdev(clk, "pll0_sysclk2", "da830-psc0");
diff --git a/drivers/clk/davinci/pll-da850.c b/drivers/clk/davinci/pll-da850.c
index 2a038b7908cc..0f7198191ea2 100644
--- a/drivers/clk/davinci/pll-da850.c
+++ b/drivers/clk/davinci/pll-da850.c
@@ -7,10 +7,14 @@
#include <linux/bitops.h>
#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
+#include <linux/device.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/types.h>
@@ -81,11 +85,11 @@ static const struct davinci_pll_obsclk_info da850_pll0_obsclk_info = {
.ocsrc_mask = GENMASK(4, 0),
};
-int da850_pll0_init(struct device *dev, void __iomem *base)
+int da850_pll0_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
struct clk *clk;
- davinci_pll_clk_register(dev, &da850_pll0_info, "ref_clk", base);
+ davinci_pll_clk_register(dev, &da850_pll0_info, "ref_clk", base, cfgchip);
clk = davinci_pll_sysclk_register(dev, &pll0_sysclk1, base);
clk_register_clkdev(clk, "pll0_sysclk1", "da850-psc0");
@@ -134,11 +138,22 @@ static const struct davinci_pll_sysclk_info *da850_pll0_sysclk_info[] = {
NULL
};
-int of_da850_pll0_init(struct device *dev, void __iomem *base)
+void of_da850_pll0_init(struct device_node *node)
{
- return of_davinci_pll_init(dev, &da850_pll0_info,
- &da850_pll0_obsclk_info,
- da850_pll0_sysclk_info, 7, base);
+ void __iomem *base;
+ struct regmap *cfgchip;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s: ioremap failed\n", __func__);
+ return;
+ }
+
+ cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
+
+ of_davinci_pll_init(NULL, node, &da850_pll0_info,
+ &da850_pll0_obsclk_info,
+ da850_pll0_sysclk_info, 7, base, cfgchip);
}
static const struct davinci_pll_clk_info da850_pll1_info = {
@@ -179,11 +194,11 @@ static const struct davinci_pll_obsclk_info da850_pll1_obsclk_info = {
.ocsrc_mask = GENMASK(4, 0),
};
-int da850_pll1_init(struct device *dev, void __iomem *base)
+int da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
struct clk *clk;
- davinci_pll_clk_register(dev, &da850_pll1_info, "oscin", base);
+ davinci_pll_clk_register(dev, &da850_pll1_info, "oscin", base, cfgchip);
davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
@@ -204,9 +219,9 @@ static const struct davinci_pll_sysclk_info *da850_pll1_sysclk_info[] = {
NULL
};
-int of_da850_pll1_init(struct device *dev, void __iomem *base)
+int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
- return of_davinci_pll_init(dev, &da850_pll1_info,
+ return of_davinci_pll_init(dev, dev->of_node, &da850_pll1_info,
&da850_pll1_obsclk_info,
- da850_pll1_sysclk_info, 3, base);
+ da850_pll1_sysclk_info, 3, base, cfgchip);
}
diff --git a/drivers/clk/davinci/pll-dm355.c b/drivers/clk/davinci/pll-dm355.c
index 5345f8286c50..505aed80be9a 100644
--- a/drivers/clk/davinci/pll-dm355.c
+++ b/drivers/clk/davinci/pll-dm355.c
@@ -6,6 +6,7 @@
*/
#include <linux/bitops.h>
+#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -22,16 +23,16 @@ static const struct davinci_pll_clk_info dm355_pll1_info = {
PLL_POSTDIV_ALWAYS_ENABLED | PLL_POSTDIV_FIXED_DIV,
};
-SYSCLK(1, pll1_sysclk1, pll1, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED);
-SYSCLK(2, pll1_sysclk2, pll1, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED);
-SYSCLK(3, pll1_sysclk3, pll1, 5, SYSCLK_ALWAYS_ENABLED);
-SYSCLK(4, pll1_sysclk4, pll1, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED);
+SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED);
+SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(4, pll1_sysclk4, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
-int dm355_pll1_init(struct device *dev, void __iomem *base)
+int dm355_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
struct clk *clk;
- davinci_pll_clk_register(dev, &dm355_pll1_info, "ref_clk", base);
+ davinci_pll_clk_register(dev, &dm355_pll1_info, "ref_clk", base, cfgchip);
clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
clk_register_clkdev(clk, "pll1_sysclk1", "dm355-psc");
@@ -62,17 +63,14 @@ static const struct davinci_pll_clk_info dm355_pll2_info = {
PLL_POSTDIV_ALWAYS_ENABLED | PLL_POSTDIV_FIXED_DIV,
};
-SYSCLK(1, pll2_sysclk1, pll2, 5, SYSCLK_FIXED_DIV);
-SYSCLK(2, pll2_sysclk2, pll2, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED);
+SYSCLK(1, pll2_sysclk1, pll2_pllen, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED);
-int dm355_pll2_init(struct device *dev, void __iomem *base)
+int dm355_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
- davinci_pll_clk_register(dev, &dm355_pll2_info, "oscin", base);
+ davinci_pll_clk_register(dev, &dm355_pll2_info, "oscin", base, cfgchip);
davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
- davinci_pll_sysclk_register(dev, &pll2_sysclk2, base);
-
davinci_pll_sysclkbp_clk_register(dev, "pll2_sysclkbp", base);
return 0;
diff --git a/drivers/clk/davinci/pll-dm365.c b/drivers/clk/davinci/pll-dm365.c
index 5f8d9f42d0f3..2d29712753a3 100644
--- a/drivers/clk/davinci/pll-dm365.c
+++ b/drivers/clk/davinci/pll-dm365.c
@@ -7,6 +7,7 @@
#include <linux/bitops.h>
#include <linux/clkdev.h>
+#include <linux/clk/davinci.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -56,11 +57,11 @@ static const struct davinci_pll_obsclk_info dm365_pll1_obsclk_info = {
.ocsrc_mask = BIT(4),
};
-int dm365_pll1_init(struct device *dev, void __iomem *base)
+int dm365_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
struct clk *clk;
- davinci_pll_clk_register(dev, &dm365_pll1_info, "ref_clk", base);
+ davinci_pll_clk_register(dev, &dm365_pll1_info, "ref_clk", base, cfgchip);
clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
clk_register_clkdev(clk, "pll1_sysclk1", "dm365-psc");
@@ -119,11 +120,11 @@ static const struct davinci_pll_obsclk_info dm365_pll2_obsclk_info = {
.ocsrc_mask = BIT(4),
};
-int dm365_pll2_init(struct device *dev, void __iomem *base)
+int dm365_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
struct clk *clk;
- davinci_pll_clk_register(dev, &dm365_pll2_info, "oscin", base);
+ davinci_pll_clk_register(dev, &dm365_pll2_info, "oscin", base, cfgchip);
davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
diff --git a/drivers/clk/davinci/pll-dm644x.c b/drivers/clk/davinci/pll-dm644x.c
index 69bf785377cf..7650fadfaac8 100644
--- a/drivers/clk/davinci/pll-dm644x.c
+++ b/drivers/clk/davinci/pll-dm644x.c
@@ -6,6 +6,7 @@
*/
#include <linux/bitops.h>
+#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -27,11 +28,11 @@ SYSCLK(2, pll1_sysclk2, pll1_pllen, 4, SYSCLK_FIXED_DIV);
SYSCLK(3, pll1_sysclk3, pll1_pllen, 4, SYSCLK_FIXED_DIV);
SYSCLK(5, pll1_sysclk5, pll1_pllen, 4, SYSCLK_FIXED_DIV);
-int dm644x_pll1_init(struct device *dev, void __iomem *base)
+int dm644x_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
struct clk *clk;
- davinci_pll_clk_register(dev, &dm644x_pll1_info, "ref_clk", base);
+ davinci_pll_clk_register(dev, &dm644x_pll1_info, "ref_clk", base, cfgchip);
clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
clk_register_clkdev(clk, "pll1_sysclk1", "dm644x-psc");
@@ -66,9 +67,9 @@ static const struct davinci_pll_clk_info dm644x_pll2_info = {
SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0);
SYSCLK(2, pll2_sysclk2, pll2_pllen, 4, 0);
-int dm644x_pll2_init(struct device *dev, void __iomem *base)
+int dm644x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
- davinci_pll_clk_register(dev, &dm644x_pll2_info, "oscin", base);
+ davinci_pll_clk_register(dev, &dm644x_pll2_info, "oscin", base, cfgchip);
davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
diff --git a/drivers/clk/davinci/pll-dm646x.c b/drivers/clk/davinci/pll-dm646x.c
index a61cc3256418..26982970df0e 100644
--- a/drivers/clk/davinci/pll-dm646x.c
+++ b/drivers/clk/davinci/pll-dm646x.c
@@ -6,6 +6,7 @@
*/
#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -29,11 +30,11 @@ SYSCLK(6, pll1_sysclk6, pll1_pllen, 4, 0);
SYSCLK(8, pll1_sysclk8, pll1_pllen, 4, 0);
SYSCLK(9, pll1_sysclk9, pll1_pllen, 4, 0);
-int dm646x_pll1_init(struct device *dev, void __iomem *base)
+int dm646x_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
struct clk *clk;
- davinci_pll_clk_register(dev, &dm646x_pll1_info, "ref_clk", base);
+ davinci_pll_clk_register(dev, &dm646x_pll1_info, "ref_clk", base, cfgchip);
clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
clk_register_clkdev(clk, "pll1_sysclk1", "dm646x-psc");
@@ -72,11 +73,11 @@ static const struct davinci_pll_clk_info dm646x_pll2_info = {
.flags = 0,
};
-SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0);
+SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, SYSCLK_ALWAYS_ENABLED);
-int dm646x_pll2_init(struct device *dev, void __iomem *base)
+int dm646x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
{
- davinci_pll_clk_register(dev, &dm646x_pll2_info, "oscin", base);
+ davinci_pll_clk_register(dev, &dm646x_pll2_info, "oscin", base, cfgchip);
davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
index 23a24c944f1d..1c99e992d638 100644
--- a/drivers/clk/davinci/pll.c
+++ b/drivers/clk/davinci/pll.c
@@ -11,6 +11,7 @@
#include <linux/clk-provider.h>
#include <linux/clk.h>
+#include <linux/clk/davinci.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -190,7 +191,7 @@ static int davinci_pll_set_rate(struct clk_hw *hw, unsigned long rate,
}
#ifdef CONFIG_DEBUG_FS
-static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry);
+static void davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry);
#else
#define davinci_pll_debug_init NULL
#endif
@@ -223,6 +224,7 @@ static const struct clk_ops dm365_pll_ops = {
/**
* davinci_pll_div_register - common *DIV clock implementation
+ * @dev: The PLL platform device or NULL
* @name: the clock name
* @parent_name: the parent clock name
* @reg: the *DIV register
@@ -240,17 +242,21 @@ static struct clk *davinci_pll_div_register(struct device *dev,
const struct clk_ops *divider_ops = &clk_divider_ops;
struct clk_gate *gate;
struct clk_divider *divider;
+ struct clk *clk;
+ int ret;
- gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
if (!gate)
return ERR_PTR(-ENOMEM);
gate->reg = reg;
gate->bit_idx = DIV_ENABLE_SHIFT;
- divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL);
- if (!divider)
- return ERR_PTR(-ENOMEM);
+ divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+ if (!divider) {
+ ret = -ENOMEM;
+ goto err_free_gate;
+ }
divider->reg = reg;
divider->shift = DIV_RATIO_SHIFT;
@@ -261,9 +267,22 @@ static struct clk *davinci_pll_div_register(struct device *dev,
divider_ops = &clk_divider_ro_ops;
}
- return clk_register_composite(dev, name, parent_names, num_parents,
- NULL, NULL, &divider->hw, divider_ops,
- &gate->hw, &clk_gate_ops, flags);
+ clk = clk_register_composite(dev, name, parent_names, num_parents,
+ NULL, NULL, &divider->hw, divider_ops,
+ &gate->hw, &clk_gate_ops, flags);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ goto err_free_divider;
+ }
+
+ return clk;
+
+err_free_divider:
+ kfree(divider);
+err_free_gate:
+ kfree(gate);
+
+ return ERR_PTR(ret);
}
struct davinci_pllen_clk {
@@ -321,36 +340,17 @@ static int davinci_pllen_rate_change(struct notifier_block *nb,
return NOTIFY_OK;
}
-static struct davinci_pll_platform_data *davinci_pll_get_pdata(struct device *dev)
-{
- struct davinci_pll_platform_data *pdata = dev_get_platdata(dev);
-
- /*
- * Platform data is optional, so allocate a new struct if one was not
- * provided. For device tree, this will always be the case.
- */
- if (!pdata)
- pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return NULL;
-
- /* for device tree, we need to fill in the struct */
- if (dev->of_node)
- pdata->cfgchip =
- syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
-
- return pdata;
-}
-
static struct notifier_block davinci_pllen_notifier = {
.notifier_call = davinci_pllen_rate_change,
};
/**
* davinci_pll_clk_register - Register a PLL clock
+ * @dev: The PLL platform device or NULL
* @info: The device-specific clock info
* @parent_name: The parent clock name
* @base: The PLL's memory region
+ * @cfgchip: CFGCHIP syscon regmap for info->unlock_reg or NULL
*
* This creates a series of clocks that represent the PLL.
*
@@ -366,9 +366,9 @@ static struct notifier_block davinci_pllen_notifier = {
struct clk *davinci_pll_clk_register(struct device *dev,
const struct davinci_pll_clk_info *info,
const char *parent_name,
- void __iomem *base)
+ void __iomem *base,
+ struct regmap *cfgchip)
{
- struct davinci_pll_platform_data *pdata;
char prediv_name[MAX_NAME_SIZE];
char pllout_name[MAX_NAME_SIZE];
char postdiv_name[MAX_NAME_SIZE];
@@ -376,11 +376,12 @@ struct clk *davinci_pll_clk_register(struct device *dev,
struct clk_init_data init;
struct davinci_pll_clk *pllout;
struct davinci_pllen_clk *pllen;
- struct clk *pllout_clk, *clk;
-
- pdata = davinci_pll_get_pdata(dev);
- if (!pdata)
- return ERR_PTR(-ENOMEM);
+ struct clk *oscin_clk = NULL;
+ struct clk *prediv_clk = NULL;
+ struct clk *pllout_clk;
+ struct clk *postdiv_clk = NULL;
+ struct clk *pllen_clk;
+ int ret;
if (info->flags & PLL_HAS_CLKMODE) {
/*
@@ -392,10 +393,10 @@ struct clk *davinci_pll_clk_register(struct device *dev,
* a number of different things. In this driver we use it to
* mean the signal after the PLLCTL[CLKMODE] switch.
*/
- clk = clk_register_fixed_factor(dev, OSCIN_CLK_NAME,
- parent_name, 0, 1, 1);
- if (IS_ERR(clk))
- return clk;
+ oscin_clk = clk_register_fixed_factor(dev, OSCIN_CLK_NAME,
+ parent_name, 0, 1, 1);
+ if (IS_ERR(oscin_clk))
+ return oscin_clk;
parent_name = OSCIN_CLK_NAME;
}
@@ -411,30 +412,34 @@ struct clk *davinci_pll_clk_register(struct device *dev,
/* Some? DM355 chips don't correctly report the PREDIV value */
if (info->flags & PLL_PREDIV_FIXED8)
- clk = clk_register_fixed_factor(dev, prediv_name,
- parent_name, flags, 1, 8);
+ prediv_clk = clk_register_fixed_factor(dev, prediv_name,
+ parent_name, flags, 1, 8);
else
- clk = davinci_pll_div_register(dev, prediv_name,
+ prediv_clk = davinci_pll_div_register(dev, prediv_name,
parent_name, base + PREDIV, fixed, flags);
- if (IS_ERR(clk))
- return clk;
+ if (IS_ERR(prediv_clk)) {
+ ret = PTR_ERR(prediv_clk);
+ goto err_unregister_oscin;
+ }
parent_name = prediv_name;
}
/* Unlock writing to PLL registers */
if (info->unlock_reg) {
- if (IS_ERR_OR_NULL(pdata->cfgchip))
+ if (IS_ERR_OR_NULL(cfgchip))
dev_warn(dev, "Failed to get CFGCHIP (%ld)\n",
- PTR_ERR(pdata->cfgchip));
+ PTR_ERR(cfgchip));
else
- regmap_write_bits(pdata->cfgchip, info->unlock_reg,
+ regmap_write_bits(cfgchip, info->unlock_reg,
info->unlock_mask, 0);
}
- pllout = devm_kzalloc(dev, sizeof(*pllout), GFP_KERNEL);
- if (!pllout)
- return ERR_PTR(-ENOMEM);
+ pllout = kzalloc(sizeof(*pllout), GFP_KERNEL);
+ if (!pllout) {
+ ret = -ENOMEM;
+ goto err_unregister_prediv;
+ }
snprintf(pllout_name, MAX_NAME_SIZE, "%s_pllout", info->name);
@@ -456,9 +461,11 @@ struct clk *davinci_pll_clk_register(struct device *dev,
pllout->pllm_min = info->pllm_min;
pllout->pllm_max = info->pllm_max;
- pllout_clk = devm_clk_register(dev, &pllout->hw);
- if (IS_ERR(pllout_clk))
- return pllout_clk;
+ pllout_clk = clk_register(dev, &pllout->hw);
+ if (IS_ERR(pllout_clk)) {
+ ret = PTR_ERR(pllout_clk);
+ goto err_free_pllout;
+ }
clk_hw_set_rate_range(&pllout->hw, info->pllout_min_rate,
info->pllout_max_rate);
@@ -474,17 +481,21 @@ struct clk *davinci_pll_clk_register(struct device *dev,
if (info->flags & PLL_POSTDIV_ALWAYS_ENABLED)
flags |= CLK_IS_CRITICAL;
- clk = davinci_pll_div_register(dev, postdiv_name, parent_name,
- base + POSTDIV, fixed, flags);
- if (IS_ERR(clk))
- return clk;
+ postdiv_clk = davinci_pll_div_register(dev, postdiv_name,
+ parent_name, base + POSTDIV, fixed, flags);
+ if (IS_ERR(postdiv_clk)) {
+ ret = PTR_ERR(postdiv_clk);
+ goto err_unregister_pllout;
+ }
parent_name = postdiv_name;
}
- pllen = devm_kzalloc(dev, sizeof(*pllout), GFP_KERNEL);
- if (!pllen)
- return ERR_PTR(-ENOMEM);
+ pllen = kzalloc(sizeof(*pllout), GFP_KERNEL);
+ if (!pllen) {
+ ret = -ENOMEM;
+ goto err_unregister_postdiv;
+ }
snprintf(pllen_name, MAX_NAME_SIZE, "%s_pllen", info->name);
@@ -497,17 +508,35 @@ struct clk *davinci_pll_clk_register(struct device *dev,
pllen->hw.init = &init;
pllen->base = base;
- clk = devm_clk_register(dev, &pllen->hw);
- if (IS_ERR(clk))
- return clk;
+ pllen_clk = clk_register(dev, &pllen->hw);
+ if (IS_ERR(pllen_clk)) {
+ ret = PTR_ERR(pllen_clk);
+ goto err_free_pllen;
+ }
- clk_notifier_register(clk, &davinci_pllen_notifier);
+ clk_notifier_register(pllen_clk, &davinci_pllen_notifier);
return pllout_clk;
+
+err_free_pllen:
+ kfree(pllen);
+err_unregister_postdiv:
+ clk_unregister(postdiv_clk);
+err_unregister_pllout:
+ clk_unregister(pllout_clk);
+err_free_pllout:
+ kfree(pllout);
+err_unregister_prediv:
+ clk_unregister(prediv_clk);
+err_unregister_oscin:
+ clk_unregister(oscin_clk);
+
+ return ERR_PTR(ret);
}
/**
* davinci_pll_auxclk_register - Register bypass clock (AUXCLK)
+ * @dev: The PLL platform device or NULL
* @name: The clock name
* @base: The PLL memory region
*/
@@ -521,6 +550,7 @@ struct clk *davinci_pll_auxclk_register(struct device *dev,
/**
* davinci_pll_sysclkbp_clk_register - Register bypass divider clock (SYSCLKBP)
+ * @dev: The PLL platform device or NULL
* @name: The clock name
* @base: The PLL memory region
*/
@@ -535,6 +565,7 @@ struct clk *davinci_pll_sysclkbp_clk_register(struct device *dev,
/**
* davinci_pll_obsclk_register - Register oscillator divider clock (OBSCLK)
+ * @dev: The PLL platform device or NULL
* @info: The clock info
* @base: The PLL memory region
*/
@@ -546,9 +577,11 @@ davinci_pll_obsclk_register(struct device *dev,
struct clk_mux *mux;
struct clk_gate *gate;
struct clk_divider *divider;
+ struct clk *clk;
u32 oscdiv;
+ int ret;
- mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux)
return ERR_PTR(-ENOMEM);
@@ -556,16 +589,20 @@ davinci_pll_obsclk_register(struct device *dev,
mux->table = info->table;
mux->mask = info->ocsrc_mask;
- gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
- if (!gate)
- return ERR_PTR(-ENOMEM);
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate) {
+ ret = -ENOMEM;
+ goto err_free_mux;
+ }
gate->reg = base + CKEN;
gate->bit_idx = CKEN_OBSCLK_SHIFT;
- divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL);
- if (!divider)
- return ERR_PTR(-ENOMEM);
+ divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+ if (!divider) {
+ ret = -ENOMEM;
+ goto err_free_gate;
+ }
divider->reg = base + OSCDIV;
divider->shift = DIV_RATIO_SHIFT;
@@ -576,11 +613,27 @@ davinci_pll_obsclk_register(struct device *dev,
oscdiv |= BIT(DIV_ENABLE_SHIFT);
writel(oscdiv, base + OSCDIV);
- return clk_register_composite(dev, info->name, info->parent_names,
- info->num_parents,
- &mux->hw, &clk_mux_ops,
- &divider->hw, &clk_divider_ops,
- &gate->hw, &clk_gate_ops, 0);
+ clk = clk_register_composite(dev, info->name, info->parent_names,
+ info->num_parents,
+ &mux->hw, &clk_mux_ops,
+ &divider->hw, &clk_divider_ops,
+ &gate->hw, &clk_gate_ops, 0);
+
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ goto err_free_divider;
+ }
+
+ return clk;
+
+err_free_divider:
+ kfree(divider);
+err_free_gate:
+ kfree(gate);
+err_free_mux:
+ kfree(mux);
+
+ return ERR_PTR(ret);
}
/* The PLL SYSCLKn clocks have a mechanism for synchronizing rate changes. */
@@ -616,6 +669,7 @@ static struct notifier_block davinci_pll_sysclk_notifier = {
/**
* davinci_pll_sysclk_register - Register divider clocks (SYSCLKn)
+ * @dev: The PLL platform device or NULL
* @info: The clock info
* @base: The PLL memory region
*/
@@ -630,6 +684,7 @@ davinci_pll_sysclk_register(struct device *dev,
struct clk *clk;
u32 reg;
u32 flags = 0;
+ int ret;
/* PLLDIVn registers are not entirely consecutive */
if (info->id < 4)
@@ -637,16 +692,18 @@ davinci_pll_sysclk_register(struct device *dev,
else
reg = PLLDIV4 + 4 * (info->id - 4);
- gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
if (!gate)
return ERR_PTR(-ENOMEM);
gate->reg = base + reg;
gate->bit_idx = DIV_ENABLE_SHIFT;
- divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL);
- if (!divider)
- return ERR_PTR(-ENOMEM);
+ divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+ if (!divider) {
+ ret = -ENOMEM;
+ goto err_free_gate;
+ }
divider->reg = base + reg;
divider->shift = DIV_RATIO_SHIFT;
@@ -668,22 +725,31 @@ davinci_pll_sysclk_register(struct device *dev,
clk = clk_register_composite(dev, info->name, &info->parent_name, 1,
NULL, NULL, &divider->hw, divider_ops,
&gate->hw, &clk_gate_ops, flags);
- if (IS_ERR(clk))
- return clk;
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ goto err_free_divider;
+ }
clk_notifier_register(clk, &davinci_pll_sysclk_notifier);
return clk;
+
+err_free_divider:
+ kfree(divider);
+err_free_gate:
+ kfree(gate);
+
+ return ERR_PTR(ret);
}
-int of_davinci_pll_init(struct device *dev,
+int of_davinci_pll_init(struct device *dev, struct device_node *node,
const struct davinci_pll_clk_info *info,
const struct davinci_pll_obsclk_info *obsclk_info,
const struct davinci_pll_sysclk_info **div_info,
u8 max_sysclk_id,
- void __iomem *base)
+ void __iomem *base,
+ struct regmap *cfgchip)
{
- struct device_node *node = dev->of_node;
struct device_node *child;
const char *parent_name;
struct clk *clk;
@@ -693,7 +759,7 @@ int of_davinci_pll_init(struct device *dev,
else
parent_name = OSCIN_CLK_NAME;
- clk = davinci_pll_clk_register(dev, info, parent_name, base);
+ clk = davinci_pll_clk_register(dev, info, parent_name, base, cfgchip);
if (IS_ERR(clk)) {
dev_err(dev, "failed to register %s\n", info->name);
return PTR_ERR(clk);
@@ -711,13 +777,15 @@ int of_davinci_pll_init(struct device *dev,
int n_clks = max_sysclk_id + 1;
int i;
- clk_data = devm_kzalloc(dev, sizeof(*clk_data), GFP_KERNEL);
+ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
- clks = devm_kmalloc_array(dev, n_clks, sizeof(*clks), GFP_KERNEL);
- if (!clks)
+ clks = kmalloc_array(n_clks, sizeof(*clks), GFP_KERNEL);
+ if (!clks) {
+ kfree(clk_data);
return -ENOMEM;
+ }
clk_data->clks = clks;
clk_data->clk_num = n_clks;
@@ -770,32 +838,73 @@ int of_davinci_pll_init(struct device *dev,
return 0;
}
+static struct davinci_pll_platform_data *davinci_pll_get_pdata(struct device *dev)
+{
+ struct davinci_pll_platform_data *pdata = dev_get_platdata(dev);
+
+ /*
+ * Platform data is optional, so allocate a new struct if one was not
+ * provided. For device tree, this will always be the case.
+ */
+ if (!pdata)
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ /* for device tree, we need to fill in the struct */
+ if (dev->of_node)
+ pdata->cfgchip =
+ syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
+
+ return pdata;
+}
+
+/* needed in early boot for clocksource/clockevent */
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+CLK_OF_DECLARE(da850_pll0, "ti,da850-pll0", of_da850_pll0_init);
+#endif
+
static const struct of_device_id davinci_pll_of_match[] = {
- { .compatible = "ti,da850-pll0", .data = of_da850_pll0_init },
+#ifdef CONFIG_ARCH_DAVINCI_DA850
{ .compatible = "ti,da850-pll1", .data = of_da850_pll1_init },
+#endif
{ }
};
static const struct platform_device_id davinci_pll_id_table[] = {
+#ifdef CONFIG_ARCH_DAVINCI_DA830
{ .name = "da830-pll", .driver_data = (kernel_ulong_t)da830_pll_init },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DA850
{ .name = "da850-pll0", .driver_data = (kernel_ulong_t)da850_pll0_init },
{ .name = "da850-pll1", .driver_data = (kernel_ulong_t)da850_pll1_init },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM355
{ .name = "dm355-pll1", .driver_data = (kernel_ulong_t)dm355_pll1_init },
{ .name = "dm355-pll2", .driver_data = (kernel_ulong_t)dm355_pll2_init },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM365
{ .name = "dm365-pll1", .driver_data = (kernel_ulong_t)dm365_pll1_init },
{ .name = "dm365-pll2", .driver_data = (kernel_ulong_t)dm365_pll2_init },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM644x
{ .name = "dm644x-pll1", .driver_data = (kernel_ulong_t)dm644x_pll1_init },
{ .name = "dm644x-pll2", .driver_data = (kernel_ulong_t)dm644x_pll2_init },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM646x
{ .name = "dm646x-pll1", .driver_data = (kernel_ulong_t)dm646x_pll1_init },
{ .name = "dm646x-pll2", .driver_data = (kernel_ulong_t)dm646x_pll2_init },
+#endif
{ }
};
-typedef int (*davinci_pll_init)(struct device *dev, void __iomem *base);
+typedef int (*davinci_pll_init)(struct device *dev, void __iomem *base,
+ struct regmap *cfgchip);
static int davinci_pll_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct davinci_pll_platform_data *pdata;
const struct of_device_id *of_id;
davinci_pll_init pll_init = NULL;
struct resource *res;
@@ -812,12 +921,18 @@ static int davinci_pll_probe(struct platform_device *pdev)
return -EINVAL;
}
+ pdata = davinci_pll_get_pdata(dev);
+ if (!pdata) {
+ dev_err(dev, "missing platform data\n");
+ return -EINVAL;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
- return pll_init(dev, base);
+ return pll_init(dev, base, pdata->cfgchip);
}
static struct platform_driver davinci_pll_driver = {
@@ -874,26 +989,19 @@ static const struct debugfs_reg32 davinci_pll_regs[] = {
DEBUG_REG(PLLDIV9),
};
-static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
+static void davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
{
struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
struct debugfs_regset32 *regset;
- struct dentry *d;
regset = kzalloc(sizeof(*regset), GFP_KERNEL);
if (!regset)
- return -ENOMEM;
+ return;
regset->regs = davinci_pll_regs;
regset->nregs = ARRAY_SIZE(davinci_pll_regs);
regset->base = pll->base;
- d = debugfs_create_regset32("registers", 0400, dentry, regset);
- if (IS_ERR(d)) {
- kfree(regset);
- return PTR_ERR(d);
- }
-
- return 0;
+ debugfs_create_regset32("registers", 0400, dentry, regset);
}
#endif
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
index b1b6fb23f972..7cc354dd29e2 100644
--- a/drivers/clk/davinci/pll.h
+++ b/drivers/clk/davinci/pll.h
@@ -11,6 +11,7 @@
#include <linux/bitops.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
+#include <linux/regmap.h>
#include <linux/types.h>
#define PLL_HAS_CLKMODE BIT(0) /* PLL has PLLCTL[CLKMODE] */
@@ -94,7 +95,8 @@ struct davinci_pll_obsclk_info {
struct clk *davinci_pll_clk_register(struct device *dev,
const struct davinci_pll_clk_info *info,
const char *parent_name,
- void __iomem *base);
+ void __iomem *base,
+ struct regmap *cfgchip);
struct clk *davinci_pll_auxclk_register(struct device *dev,
const char *name,
void __iomem *base);
@@ -110,32 +112,29 @@ davinci_pll_sysclk_register(struct device *dev,
const struct davinci_pll_sysclk_info *info,
void __iomem *base);
-int of_davinci_pll_init(struct device *dev,
+int of_davinci_pll_init(struct device *dev, struct device_node *node,
const struct davinci_pll_clk_info *info,
const struct davinci_pll_obsclk_info *obsclk_info,
const struct davinci_pll_sysclk_info **div_info,
u8 max_sysclk_id,
- void __iomem *base);
+ void __iomem *base,
+ struct regmap *cfgchip);
/* Platform-specific callbacks */
-int da830_pll_init(struct device *dev, void __iomem *base);
-
-int da850_pll0_init(struct device *dev, void __iomem *base);
-int da850_pll1_init(struct device *dev, void __iomem *base);
-int of_da850_pll0_init(struct device *dev, void __iomem *base);
-int of_da850_pll1_init(struct device *dev, void __iomem *base);
-
-int dm355_pll1_init(struct device *dev, void __iomem *base);
-int dm355_pll2_init(struct device *dev, void __iomem *base);
-
-int dm365_pll1_init(struct device *dev, void __iomem *base);
-int dm365_pll2_init(struct device *dev, void __iomem *base);
-
-int dm644x_pll1_init(struct device *dev, void __iomem *base);
-int dm644x_pll2_init(struct device *dev, void __iomem *base);
-
-int dm646x_pll1_init(struct device *dev, void __iomem *base);
-int dm646x_pll2_init(struct device *dev, void __iomem *base);
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+int da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
+void of_da850_pll0_init(struct device_node *node);
+int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM355
+int dm355_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM644x
+int dm644x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM646x
+int dm646x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
+#endif
#endif /* __CLK_DAVINCI_PLL_H___ */
diff --git a/drivers/clk/davinci/psc-da830.c b/drivers/clk/davinci/psc-da830.c
index f61abf5632ff..081b039fcb02 100644
--- a/drivers/clk/davinci/psc-da830.c
+++ b/drivers/clk/davinci/psc-da830.c
@@ -55,7 +55,8 @@ const struct davinci_psc_init_data da830_psc0_init_data = {
.psc_init = &da830_psc0_init,
};
-LPSC_CLKDEV2(usb0_clkdev, NULL, "musb-da8xx",
+LPSC_CLKDEV3(usb0_clkdev, "fck", "da830-usb-phy-clks",
+ NULL, "musb-da8xx",
NULL, "cppi41-dmaengine");
LPSC_CLKDEV1(usb1_clkdev, NULL, "ohci-da8xx");
/* REVISIT: gpio-davinci.c should be modified to drop con_id */
diff --git a/drivers/clk/davinci/psc-dm355.c b/drivers/clk/davinci/psc-dm355.c
index 6995ecea2677..ddd250107c4e 100644
--- a/drivers/clk/davinci/psc-dm355.c
+++ b/drivers/clk/davinci/psc-dm355.c
@@ -6,6 +6,7 @@
*/
#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/init.h>
@@ -41,14 +42,14 @@ static const struct davinci_lpsc_clk_info dm355_psc_info[] = {
LPSC(5, 0, timer3, pll1_auxclk, NULL, 0),
LPSC(6, 0, spi1, pll1_sysclk2, spi1_clkdev, 0),
LPSC(7, 0, mmcsd1, pll1_sysclk2, mmcsd1_clkdev, 0),
- LPSC(8, 0, asp1, pll1_sysclk2, NULL, 0),
+ LPSC(8, 0, asp1, pll1_sysclk2, mcbsp1_clkdev, 0),
LPSC(9, 0, usb, pll1_sysclk2, usb_clkdev, 0),
LPSC(10, 0, pwm3, pll1_auxclk, NULL, 0),
LPSC(11, 0, spi2, pll1_sysclk2, spi2_clkdev, 0),
LPSC(12, 0, rto, pll1_auxclk, NULL, 0),
LPSC(14, 0, aemif, pll1_sysclk2, aemif_clkdev, 0),
LPSC(15, 0, mmcsd0, pll1_sysclk2, mmcsd0_clkdev, 0),
- LPSC(17, 0, asp0, pll1_sysclk2, NULL, 0),
+ LPSC(17, 0, asp0, pll1_sysclk2, mcbsp0_clkdev, 0),
LPSC(18, 0, i2c, pll1_auxclk, i2c_clkdev, 0),
LPSC(19, 0, uart0, pll1_auxclk, uart0_clkdev, 0),
LPSC(20, 0, uart1, pll1_auxclk, uart1_clkdev, 0),
@@ -68,7 +69,7 @@ static const struct davinci_lpsc_clk_info dm355_psc_info[] = {
{ }
};
-static int dm355_psc_init(struct device *dev, void __iomem *base)
+int dm355_psc_init(struct device *dev, void __iomem *base)
{
return davinci_psc_register_clocks(dev, dm355_psc_info, 42, base);
}
diff --git a/drivers/clk/davinci/psc-dm365.c b/drivers/clk/davinci/psc-dm365.c
index 3ad915f37376..8c73086cc676 100644
--- a/drivers/clk/davinci/psc-dm365.c
+++ b/drivers/clk/davinci/psc-dm365.c
@@ -6,6 +6,7 @@
*/
#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/init.h>
@@ -65,15 +66,28 @@ static const struct davinci_lpsc_clk_info dm365_psc_info[] = {
LPSC(31, 0, arm, pll2_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
LPSC(38, 0, spi3, pll1_sysclk4, spi3_clkdev, 0),
LPSC(39, 0, spi4, pll1_auxclk, spi4_clkdev, 0),
- LPSC(40, 0, emac, pll2_sysclk4, emac_clkdev, 0),
- LPSC(44, 1, voice_codec, pll1_sysclk3, voice_codec_clkdev, 0),
- LPSC(46, 1, vpss_dac, pll1_sysclk3, vpss_dac_clkdev, 0),
+ LPSC(40, 0, emac, pll1_sysclk4, emac_clkdev, 0),
+ /*
+ * The TRM (ARM Subsystem User's Guide) shows two clocks input into
+ * voice codec module (PLL2 SYSCLK4 with a DIV2 and PLL1 SYSCLK4). Its
+ * not fully clear from documentation which clock should be considered
+ * as parent for PSC. The clock chosen here is to maintain
+ * compatibility with existing code in arch/arm/mach-davinci/dm365.c
+ */
+ LPSC(44, 0, voice_codec, pll2_sysclk4, voice_codec_clkdev, 0),
+ /*
+ * Its not fully clear from TRM (ARM Subsystem User's Guide) as to what
+ * the parent of VPSS DAC LPSC should actually be. PLL1 SYSCLK3 feeds
+ * into HDVICP and MJCP. The clock chosen here is to remain compatible
+ * with code existing in arch/arm/mach-davinci/dm365.c
+ */
+ LPSC(46, 0, vpss_dac, pll1_sysclk3, vpss_dac_clkdev, 0),
LPSC(47, 0, vpss_master, pll1_sysclk5, vpss_master_clkdev, 0),
LPSC(50, 0, mjcp, pll1_sysclk3, NULL, 0),
{ }
};
-static int dm365_psc_init(struct device *dev, void __iomem *base)
+int dm365_psc_init(struct device *dev, void __iomem *base)
{
return davinci_psc_register_clocks(dev, dm365_psc_info, 52, base);
}
diff --git a/drivers/clk/davinci/psc-dm644x.c b/drivers/clk/davinci/psc-dm644x.c
index c22367baa46f..fc0230e3a3d6 100644
--- a/drivers/clk/davinci/psc-dm644x.c
+++ b/drivers/clk/davinci/psc-dm644x.c
@@ -6,6 +6,7 @@
*/
#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/init.h>
@@ -63,7 +64,7 @@ static const struct davinci_lpsc_clk_info dm644x_psc_info[] = {
{ }
};
-static int dm644x_psc_init(struct device *dev, void __iomem *base)
+int dm644x_psc_init(struct device *dev, void __iomem *base)
{
return davinci_psc_register_clocks(dev, dm644x_psc_info, 41, base);
}
diff --git a/drivers/clk/davinci/psc-dm646x.c b/drivers/clk/davinci/psc-dm646x.c
index 468ef86ea40b..c3f82ed70a80 100644
--- a/drivers/clk/davinci/psc-dm646x.c
+++ b/drivers/clk/davinci/psc-dm646x.c
@@ -6,6 +6,7 @@
*/
#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/init.h>
@@ -58,7 +59,7 @@ static const struct davinci_lpsc_clk_info dm646x_psc_info[] = {
{ }
};
-static int dm646x_psc_init(struct device *dev, void __iomem *base)
+int dm646x_psc_init(struct device *dev, void __iomem *base)
{
return davinci_psc_register_clocks(dev, dm646x_psc_info, 46, base);
}
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
index ce170e600f09..fffbed5e263b 100644
--- a/drivers/clk/davinci/psc.c
+++ b/drivers/clk/davinci/psc.c
@@ -15,6 +15,7 @@
#include <linux/clk-provider.h>
#include <linux/clk.h>
+#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <linux/of_address.h>
@@ -63,7 +64,7 @@ struct davinci_psc_data {
/**
* struct davinci_lpsc_clk - LPSC clock structure
- * @dev: the device that provides this LPSC
+ * @dev: the device that provides this LPSC or NULL
* @hw: clk_hw for the LPSC
* @pm_domain: power domain for the LPSC
* @genpd_clk: clock reference owned by @pm_domain
@@ -221,6 +222,7 @@ static void davinci_psc_genpd_detach_dev(struct generic_pm_domain *pm_domain,
/**
* davinci_lpsc_clk_register - register LPSC clock
+ * @dev: the clocks's device or NULL
* @name: name of this clock
* @parent_name: name of clock's parent
* @regmap: PSC MMIO region
@@ -238,7 +240,7 @@ davinci_lpsc_clk_register(struct device *dev, const char *name,
int ret;
bool is_on;
- lpsc = devm_kzalloc(dev, sizeof(*lpsc), GFP_KERNEL);
+ lpsc = kzalloc(sizeof(*lpsc), GFP_KERNEL);
if (!lpsc)
return ERR_PTR(-ENOMEM);
@@ -261,9 +263,15 @@ davinci_lpsc_clk_register(struct device *dev, const char *name,
lpsc->pd = pd;
lpsc->flags = flags;
- ret = devm_clk_hw_register(dev, &lpsc->hw);
- if (ret < 0)
+ ret = clk_hw_register(dev, &lpsc->hw);
+ if (ret < 0) {
+ kfree(lpsc);
return ERR_PTR(ret);
+ }
+
+ /* for now, genpd is only registered when using device-tree */
+ if (!dev || !dev->of_node)
+ return lpsc;
/* genpd attach needs a way to look up this clock */
ret = clk_hw_register_clkdev(&lpsc->hw, name, best_dev_name(dev));
@@ -378,13 +386,15 @@ __davinci_psc_register_clocks(struct device *dev,
struct regmap *regmap;
int i, ret;
- psc = devm_kzalloc(dev, sizeof(*psc), GFP_KERNEL);
+ psc = kzalloc(sizeof(*psc), GFP_KERNEL);
if (!psc)
return ERR_PTR(-ENOMEM);
- clks = devm_kmalloc_array(dev, num_clks, sizeof(*clks), GFP_KERNEL);
- if (!clks)
- return ERR_PTR(-ENOMEM);
+ clks = kmalloc_array(num_clks, sizeof(*clks), GFP_KERNEL);
+ if (!clks) {
+ ret = -ENOMEM;
+ goto err_free_psc;
+ }
psc->clk_data.clks = clks;
psc->clk_data.clk_num = num_clks;
@@ -396,16 +406,20 @@ __davinci_psc_register_clocks(struct device *dev,
for (i = 0; i < num_clks; i++)
clks[i] = ERR_PTR(-ENOENT);
- pm_domains = devm_kcalloc(dev, num_clks, sizeof(*pm_domains), GFP_KERNEL);
- if (!pm_domains)
- return ERR_PTR(-ENOMEM);
+ pm_domains = kcalloc(num_clks, sizeof(*pm_domains), GFP_KERNEL);
+ if (!pm_domains) {
+ ret = -ENOMEM;
+ goto err_free_clks;
+ }
psc->pm_data.domains = pm_domains;
psc->pm_data.num_domains = num_clks;
- regmap = devm_regmap_init_mmio(dev, base, &davinci_psc_regmap_config);
- if (IS_ERR(regmap))
- return ERR_CAST(regmap);
+ regmap = regmap_init_mmio(dev, base, &davinci_psc_regmap_config);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ goto err_free_pm_domains;
+ }
for (; info->name; info++) {
struct davinci_lpsc_clk *lpsc;
@@ -423,6 +437,13 @@ __davinci_psc_register_clocks(struct device *dev,
pm_domains[info->md] = &lpsc->pm_domain;
}
+ /*
+ * for now, a reset controller is only registered when there is a device
+ * to associate it with.
+ */
+ if (!dev)
+ return psc;
+
psc->rcdev.ops = &davinci_psc_reset_ops;
psc->rcdev.owner = THIS_MODULE;
psc->rcdev.dev = dev;
@@ -436,6 +457,15 @@ __davinci_psc_register_clocks(struct device *dev,
dev_warn(dev, "Failed to register reset controller (%d)\n", ret);
return psc;
+
+err_free_pm_domains:
+ kfree(pm_domains);
+err_free_clks:
+ kfree(clks);
+err_free_psc:
+ kfree(psc);
+
+ return ERR_PTR(ret);
}
int davinci_psc_register_clocks(struct device *dev,
@@ -483,20 +513,34 @@ int of_davinci_psc_clk_init(struct device *dev,
}
static const struct of_device_id davinci_psc_of_match[] = {
+#ifdef CONFIG_ARCH_DAVINCI_DA850
{ .compatible = "ti,da850-psc0", .data = &of_da850_psc0_init_data },
{ .compatible = "ti,da850-psc1", .data = &of_da850_psc1_init_data },
+#endif
{ }
};
static const struct platform_device_id davinci_psc_id_table[] = {
+#ifdef CONFIG_ARCH_DAVINCI_DA830
{ .name = "da830-psc0", .driver_data = (kernel_ulong_t)&da830_psc0_init_data },
{ .name = "da830-psc1", .driver_data = (kernel_ulong_t)&da830_psc1_init_data },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DA850
{ .name = "da850-psc0", .driver_data = (kernel_ulong_t)&da850_psc0_init_data },
{ .name = "da850-psc1", .driver_data = (kernel_ulong_t)&da850_psc1_init_data },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM355
{ .name = "dm355-psc", .driver_data = (kernel_ulong_t)&dm355_psc_init_data },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM365
{ .name = "dm365-psc", .driver_data = (kernel_ulong_t)&dm365_psc_init_data },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM644x
{ .name = "dm644x-psc", .driver_data = (kernel_ulong_t)&dm644x_psc_init_data },
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM646x
{ .name = "dm646x-psc", .driver_data = (kernel_ulong_t)&dm646x_psc_init_data },
+#endif
{ }
};
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
index c2a7df6413fe..6a42529d31a9 100644
--- a/drivers/clk/davinci/psc.h
+++ b/drivers/clk/davinci/psc.h
@@ -94,15 +94,27 @@ struct davinci_psc_init_data {
int (*psc_init)(struct device *dev, void __iomem *base);
};
+#ifdef CONFIG_ARCH_DAVINCI_DA830
extern const struct davinci_psc_init_data da830_psc0_init_data;
extern const struct davinci_psc_init_data da830_psc1_init_data;
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DA850
extern const struct davinci_psc_init_data da850_psc0_init_data;
extern const struct davinci_psc_init_data da850_psc1_init_data;
extern const struct davinci_psc_init_data of_da850_psc0_init_data;
extern const struct davinci_psc_init_data of_da850_psc1_init_data;
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM355
extern const struct davinci_psc_init_data dm355_psc_init_data;
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM356
extern const struct davinci_psc_init_data dm365_psc_init_data;
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM644x
extern const struct davinci_psc_init_data dm644x_psc_init_data;
+#endif
+#ifdef CONFIG_ARCH_DAVINCI_DM646x
extern const struct davinci_psc_init_data dm646x_psc_init_data;
+#endif
#endif /* __CLK_DAVINCI_PSC_H__ */