summaryrefslogtreecommitdiffstats
path: root/drivers/clk/davinci
diff options
context:
space:
mode:
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__ */