Merge branch 'for-4.12-ti-clk-cleanups' of https://github.com/t-kristo/linux-pm into clk-next
* 'for-4.12-ti-clk-cleanups' of https://github.com/t-kristo/linux-pm:
clk: ti: convert to use proper register definition for all accesses
clk: ti: dpll44xx: fix clksel register initialization
clk: ti: gate: export gate_clk_ops locally
clk: ti: divider: add driver internal API for parsing divider data
clk: ti: divider: convert TI divider clock to use its own data representation
clk: ti: mux: convert TI mux clock to use its internal data representation
clk: ti: drop unnecessary MEMMAP_ADDRESSING flag
clk: ti: omap4: cleanup unnecessary clock aliases
clk: ti: enforce const types on string arrays
clk: ti: move omap2_init_clk_clkdm under TI clock driver
clk: ti: add clkdm_lookup to the exported functions
clk: ti: use automatic clock alias generation framework
clk: ti: add API for creating aliases automatically for simple clock types
clk: ti: add support for automatic clock alias generation
clk: ti: remove un-used definitions from public clk_hw_omap struct
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
index 59cf310..e8d4173 100644
--- a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -138,7 +138,8 @@
if (!dd)
return -EINVAL;
- tmpset.cm_clksel1_pll = readl_relaxed(dd->mult_div1_reg);
+ tmpset.cm_clksel1_pll =
+ omap_clk_ll_ops.clk_readl(&dd->mult_div1_reg);
tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
dd->div1_mask);
div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 1270afd..42881f2 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -54,9 +54,10 @@
#define OMAP3PLUS_DPLL_FINT_MIN 32000
#define OMAP3PLUS_DPLL_FINT_MAX 52000000
-static struct ti_clk_ll_ops omap_clk_ll_ops = {
+struct ti_clk_ll_ops omap_clk_ll_ops = {
.clkdm_clk_enable = clkdm_clk_enable,
.clkdm_clk_disable = clkdm_clk_disable,
+ .clkdm_lookup = clkdm_lookup,
.cm_wait_module_ready = omap_cm_wait_module_ready,
.cm_split_idlest_reg = cm_split_idlest_reg,
};
@@ -78,38 +79,6 @@
* OMAP2+ specific clock functions
*/
-/* Public functions */
-
-/**
- * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
- * @clk: OMAP clock struct ptr to use
- *
- * Convert a clockdomain name stored in a struct clk 'clk' into a
- * clockdomain pointer, and save it into the struct clk. Intended to be
- * called during clk_register(). No return value.
- */
-void omap2_init_clk_clkdm(struct clk_hw *hw)
-{
- struct clk_hw_omap *clk = to_clk_hw_omap(hw);
- struct clockdomain *clkdm;
- const char *clk_name;
-
- if (!clk->clkdm_name)
- return;
-
- clk_name = __clk_get_name(hw->clk);
-
- clkdm = clkdm_lookup(clk->clkdm_name);
- if (clkdm) {
- pr_debug("clock: associated clk %s to clkdm %s\n",
- clk_name, clk->clkdm_name);
- clk->clkdm = clkdm;
- } else {
- pr_debug("clock: could not associate clk %s to clkdm %s\n",
- clk_name, clk->clkdm_name);
- }
-}
-
/**
* ti_clk_init_features - init clock features struct for the SoC
*
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 4e66295..cf45550 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -64,6 +64,8 @@
#define OMAP4XXX_EN_DPLL_FRBYPASS 0x6
#define OMAP4XXX_EN_DPLL_LOCKED 0x7
+extern struct ti_clk_ll_ops omap_clk_ll_ops;
+
extern u16 cpu_mask;
extern const struct clkops clkops_omap2_dflt_wait;
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index 1fe3e6b..de75cbc 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -23,6 +23,7 @@
#define MAX_MODULE_READY_TIME 2000
# ifndef __ASSEMBLER__
+#include <linux/clk/ti.h>
extern void __iomem *cm_base;
extern void __iomem *cm2_base;
extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
@@ -50,7 +51,7 @@
* @module_disable: ptr to the SoC CM-specific module_disable impl
*/
struct cm_ll_data {
- int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
+ int (*split_idlest_reg)(struct clk_omap_reg *idlest_reg, s16 *prcm_inst,
u8 *idlest_reg_id);
int (*wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg,
u8 idlest_shift);
@@ -60,7 +61,7 @@
void (*module_disable)(u8 part, u16 inst, u16 clkctrl_offs);
};
-extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
+extern int cm_split_idlest_reg(struct clk_omap_reg *idlest_reg, s16 *prcm_inst,
u8 *idlest_reg_id);
int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg,
u8 idlest_shift);
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index 3e5fd35..cd90b4c 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -204,7 +204,7 @@
* XXX This function is only needed until absolute register addresses are
* removed from the OMAP struct clk records.
*/
-static int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
+static int omap2xxx_cm_split_idlest_reg(struct clk_omap_reg *idlest_reg,
s16 *prcm_inst,
u8 *idlest_reg_id)
{
@@ -212,10 +212,7 @@
u8 idlest_offs;
int i;
- if (idlest_reg < cm_base || idlest_reg > (cm_base + 0x0fff))
- return -EINVAL;
-
- idlest_offs = (unsigned long)idlest_reg & 0xff;
+ idlest_offs = idlest_reg->offset & 0xff;
for (i = 0; i < ARRAY_SIZE(omap2xxx_cm_idlest_offs); i++) {
if (idlest_offs == omap2xxx_cm_idlest_offs[i]) {
*idlest_reg_id = i + 1;
@@ -226,7 +223,7 @@
if (i == ARRAY_SIZE(omap2xxx_cm_idlest_offs))
return -EINVAL;
- offs = idlest_reg - cm_base;
+ offs = idlest_reg->offset;
offs &= 0xff00;
*prcm_inst = offs;
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
index d91ae82..55b046a 100644
--- a/arch/arm/mach-omap2/cm3xxx.c
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -118,7 +118,7 @@
* XXX This function is only needed until absolute register addresses are
* removed from the OMAP struct clk records.
*/
-static int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
+static int omap3xxx_cm_split_idlest_reg(struct clk_omap_reg *idlest_reg,
s16 *prcm_inst,
u8 *idlest_reg_id)
{
@@ -126,11 +126,7 @@
u8 idlest_offs;
int i;
- if (idlest_reg < (cm_base + OMAP3430_IVA2_MOD) ||
- idlest_reg > (cm_base + 0x1ffff))
- return -EINVAL;
-
- idlest_offs = (unsigned long)idlest_reg & 0xff;
+ idlest_offs = idlest_reg->offset & 0xff;
for (i = 0; i < ARRAY_SIZE(omap3xxx_cm_idlest_offs); i++) {
if (idlest_offs == omap3xxx_cm_idlest_offs[i]) {
*idlest_reg_id = i + 1;
@@ -141,7 +137,7 @@
if (i == ARRAY_SIZE(omap3xxx_cm_idlest_offs))
return -EINVAL;
- offs = idlest_reg - cm_base;
+ offs = idlest_reg->offset;
offs &= 0xff00;
*prcm_inst = offs;
diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c
index 23e8bce..bbe41f4 100644
--- a/arch/arm/mach-omap2/cm_common.c
+++ b/arch/arm/mach-omap2/cm_common.c
@@ -65,7 +65,7 @@
* or 0 upon success. XXX This function is only needed until absolute
* register addresses are removed from the OMAP struct clk records.
*/
-int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
+int cm_split_idlest_reg(struct clk_omap_reg *idlest_reg, s16 *prcm_inst,
u8 *idlest_reg_id)
{
if (!cm_ll_data->split_idlest_reg) {
diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 6411e13..06f486b 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -55,20 +55,20 @@
state <<= __ffs(ad->idlest_mask);
/* Check is already locked */
- v = ti_clk_ll_ops->clk_readl(ad->idlest_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->idlest_reg);
if ((v & ad->idlest_mask) == state)
return r;
- v = ti_clk_ll_ops->clk_readl(ad->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->control_reg);
v &= ~ad->enable_mask;
v |= APLL_FORCE_LOCK << __ffs(ad->enable_mask);
- ti_clk_ll_ops->clk_writel(v, ad->control_reg);
+ ti_clk_ll_ops->clk_writel(v, &ad->control_reg);
state <<= __ffs(ad->idlest_mask);
while (1) {
- v = ti_clk_ll_ops->clk_readl(ad->idlest_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->idlest_reg);
if ((v & ad->idlest_mask) == state)
break;
if (i > MAX_APLL_WAIT_TRIES)
@@ -99,10 +99,10 @@
state <<= __ffs(ad->idlest_mask);
- v = ti_clk_ll_ops->clk_readl(ad->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->control_reg);
v &= ~ad->enable_mask;
v |= APLL_AUTO_IDLE << __ffs(ad->enable_mask);
- ti_clk_ll_ops->clk_writel(v, ad->control_reg);
+ ti_clk_ll_ops->clk_writel(v, &ad->control_reg);
}
static int dra7_apll_is_enabled(struct clk_hw *hw)
@@ -113,7 +113,7 @@
ad = clk->dpll_data;
- v = ti_clk_ll_ops->clk_readl(ad->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->control_reg);
v &= ad->enable_mask;
v >>= __ffs(ad->enable_mask);
@@ -164,7 +164,7 @@
ad->clk_bypass = __clk_get_hw(clk);
- clk = clk_register(NULL, &clk_hw->hw);
+ clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
if (!IS_ERR(clk)) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
kfree(clk_hw->hw.init->parent_names);
@@ -185,6 +185,7 @@
struct clk_hw_omap *clk_hw = NULL;
struct clk_init_data *init = NULL;
const char **parent_names = NULL;
+ int ret;
ad = kzalloc(sizeof(*ad), GFP_KERNEL);
clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
@@ -194,7 +195,6 @@
clk_hw->dpll_data = ad;
clk_hw->hw.init = init;
- clk_hw->flags = MEMMAP_ADDRESSING;
init->name = node->name;
init->ops = &apll_ck_ops;
@@ -213,10 +213,10 @@
init->parent_names = parent_names;
- ad->control_reg = ti_clk_get_reg_addr(node, 0);
- ad->idlest_reg = ti_clk_get_reg_addr(node, 1);
+ ret = ti_clk_get_reg_addr(node, 0, &ad->control_reg);
+ ret |= ti_clk_get_reg_addr(node, 1, &ad->idlest_reg);
- if (IS_ERR(ad->control_reg) || IS_ERR(ad->idlest_reg))
+ if (ret)
goto cleanup;
ad->idlest_mask = 0x1;
@@ -242,7 +242,7 @@
struct dpll_data *ad = clk->dpll_data;
u32 v;
- v = ti_clk_ll_ops->clk_readl(ad->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->control_reg);
v &= ad->enable_mask;
v >>= __ffs(ad->enable_mask);
@@ -268,13 +268,13 @@
u32 v;
int i = 0;
- v = ti_clk_ll_ops->clk_readl(ad->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->control_reg);
v &= ~ad->enable_mask;
v |= OMAP2_EN_APLL_LOCKED << __ffs(ad->enable_mask);
- ti_clk_ll_ops->clk_writel(v, ad->control_reg);
+ ti_clk_ll_ops->clk_writel(v, &ad->control_reg);
while (1) {
- v = ti_clk_ll_ops->clk_readl(ad->idlest_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->idlest_reg);
if (v & ad->idlest_mask)
break;
if (i > MAX_APLL_WAIT_TRIES)
@@ -298,10 +298,10 @@
struct dpll_data *ad = clk->dpll_data;
u32 v;
- v = ti_clk_ll_ops->clk_readl(ad->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->control_reg);
v &= ~ad->enable_mask;
v |= OMAP2_EN_APLL_STOPPED << __ffs(ad->enable_mask);
- ti_clk_ll_ops->clk_writel(v, ad->control_reg);
+ ti_clk_ll_ops->clk_writel(v, &ad->control_reg);
}
static struct clk_ops omap2_apll_ops = {
@@ -316,10 +316,10 @@
struct dpll_data *ad = clk->dpll_data;
u32 v;
- v = ti_clk_ll_ops->clk_readl(ad->autoidle_reg);
+ v = ti_clk_ll_ops->clk_readl(&ad->autoidle_reg);
v &= ~ad->autoidle_mask;
v |= val << __ffs(ad->autoidle_mask);
- ti_clk_ll_ops->clk_writel(v, ad->control_reg);
+ ti_clk_ll_ops->clk_writel(v, &ad->control_reg);
}
#define OMAP2_APLL_AUTOIDLE_LOW_POWER_STOP 0x3
@@ -348,6 +348,7 @@
struct clk *clk;
const char *parent_name;
u32 val;
+ int ret;
ad = kzalloc(sizeof(*ad), GFP_KERNEL);
clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
@@ -393,12 +394,11 @@
ad->idlest_mask = 1 << val;
- ad->control_reg = ti_clk_get_reg_addr(node, 0);
- ad->autoidle_reg = ti_clk_get_reg_addr(node, 1);
- ad->idlest_reg = ti_clk_get_reg_addr(node, 2);
+ ret = ti_clk_get_reg_addr(node, 0, &ad->control_reg);
+ ret |= ti_clk_get_reg_addr(node, 1, &ad->autoidle_reg);
+ ret |= ti_clk_get_reg_addr(node, 2, &ad->idlest_reg);
- if (IS_ERR(ad->control_reg) || IS_ERR(ad->autoidle_reg) ||
- IS_ERR(ad->idlest_reg))
+ if (ret)
goto cleanup;
clk = clk_register(NULL, &clk_hw->hw);
diff --git a/drivers/clk/ti/autoidle.c b/drivers/clk/ti/autoidle.c
index 345af43..7bb9afb 100644
--- a/drivers/clk/ti/autoidle.c
+++ b/drivers/clk/ti/autoidle.c
@@ -25,7 +25,7 @@
#include "clock.h"
struct clk_ti_autoidle {
- void __iomem *reg;
+ struct clk_omap_reg reg;
u8 shift;
u8 flags;
const char *name;
@@ -73,28 +73,28 @@
{
u32 val;
- val = ti_clk_ll_ops->clk_readl(clk->reg);
+ val = ti_clk_ll_ops->clk_readl(&clk->reg);
if (clk->flags & AUTOIDLE_LOW)
val &= ~(1 << clk->shift);
else
val |= (1 << clk->shift);
- ti_clk_ll_ops->clk_writel(val, clk->reg);
+ ti_clk_ll_ops->clk_writel(val, &clk->reg);
}
static void _deny_autoidle(struct clk_ti_autoidle *clk)
{
u32 val;
- val = ti_clk_ll_ops->clk_readl(clk->reg);
+ val = ti_clk_ll_ops->clk_readl(&clk->reg);
if (clk->flags & AUTOIDLE_LOW)
val |= (1 << clk->shift);
else
val &= ~(1 << clk->shift);
- ti_clk_ll_ops->clk_writel(val, clk->reg);
+ ti_clk_ll_ops->clk_writel(val, &clk->reg);
}
/**
@@ -140,6 +140,7 @@
{
u32 shift;
struct clk_ti_autoidle *clk;
+ int ret;
/* Check if this clock has autoidle support or not */
if (of_property_read_u32(node, "ti,autoidle-shift", &shift))
@@ -152,11 +153,10 @@
clk->shift = shift;
clk->name = node->name;
- clk->reg = ti_clk_get_reg_addr(node, 0);
-
- if (IS_ERR(clk->reg)) {
+ ret = ti_clk_get_reg_addr(node, 0, &clk->reg);
+ if (ret) {
kfree(clk);
- return -EINVAL;
+ return ret;
}
if (of_property_read_bool(node, "ti,invert-autoidle-bit"))
diff --git a/drivers/clk/ti/clk-3xxx.c b/drivers/clk/ti/clk-3xxx.c
index 11d8aa3..b1251ca 100644
--- a/drivers/clk/ti/clk-3xxx.c
+++ b/drivers/clk/ti/clk-3xxx.c
@@ -52,14 +52,13 @@
* @idlest_reg and @idlest_bit. No return value.
*/
static void omap3430es2_clk_ssi_find_idlest(struct clk_hw_omap *clk,
- void __iomem **idlest_reg,
+ struct clk_omap_reg *idlest_reg,
u8 *idlest_bit,
u8 *idlest_val)
{
- u32 r;
-
- r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
- *idlest_reg = (__force void __iomem *)r;
+ memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
+ idlest_reg->offset &= ~0xf0;
+ idlest_reg->offset |= 0x20;
*idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
}
@@ -85,15 +84,15 @@
* default find_idlest code assumes that they are at the same
* position.) No return value.
*/
-static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk_hw_omap *clk,
- void __iomem **idlest_reg,
- u8 *idlest_bit,
- u8 *idlest_val)
+static void
+omap3430es2_clk_dss_usbhost_find_idlest(struct clk_hw_omap *clk,
+ struct clk_omap_reg *idlest_reg,
+ u8 *idlest_bit, u8 *idlest_val)
{
- u32 r;
+ memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
- r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
- *idlest_reg = (__force void __iomem *)r;
+ idlest_reg->offset &= ~0xf0;
+ idlest_reg->offset |= 0x20;
/* USBHOST_IDLE has same shift */
*idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT;
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
@@ -122,15 +121,15 @@
* shift from the CM_{I,F}CLKEN bit. Pass back the correct info via
* @idlest_reg and @idlest_bit. No return value.
*/
-static void omap3430es2_clk_hsotgusb_find_idlest(struct clk_hw_omap *clk,
- void __iomem **idlest_reg,
- u8 *idlest_bit,
- u8 *idlest_val)
+static void
+omap3430es2_clk_hsotgusb_find_idlest(struct clk_hw_omap *clk,
+ struct clk_omap_reg *idlest_reg,
+ u8 *idlest_bit,
+ u8 *idlest_val)
{
- u32 r;
-
- r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
- *idlest_reg = (__force void __iomem *)r;
+ memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
+ idlest_reg->offset &= ~0xf0;
+ idlest_reg->offset |= 0x20;
*idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT;
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
}
@@ -154,11 +153,11 @@
* bit. A value of 1 indicates that clock is enabled.
*/
static void am35xx_clk_find_idlest(struct clk_hw_omap *clk,
- void __iomem **idlest_reg,
+ struct clk_omap_reg *idlest_reg,
u8 *idlest_bit,
u8 *idlest_val)
{
- *idlest_reg = (__force void __iomem *)(clk->enable_reg);
+ memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
*idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET;
*idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL;
}
@@ -178,10 +177,10 @@
* avoid this issue, and remove the casts. No return value.
*/
static void am35xx_clk_find_companion(struct clk_hw_omap *clk,
- void __iomem **other_reg,
+ struct clk_omap_reg *other_reg,
u8 *other_bit)
{
- *other_reg = (__force void __iomem *)(clk->enable_reg);
+ memcpy(other_reg, &clk->enable_reg, sizeof(*other_reg));
if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
*other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET;
else
@@ -205,14 +204,14 @@
* and @idlest_bit. No return value.
*/
static void am35xx_clk_ipss_find_idlest(struct clk_hw_omap *clk,
- void __iomem **idlest_reg,
+ struct clk_omap_reg *idlest_reg,
u8 *idlest_bit,
u8 *idlest_val)
{
- u32 r;
+ memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
- r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
- *idlest_reg = (__force void __iomem *)r;
+ idlest_reg->offset &= ~0xf0;
+ idlest_reg->offset |= 0x20;
*idlest_bit = AM35XX_ST_IPSS_SHIFT;
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
}
diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index 7a8b51b..1c8bb83 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -34,196 +34,13 @@
#define OMAP4_DPLL_USB_DEFFREQ 960000000
static struct ti_dt_clk omap44xx_clks[] = {
- DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
- DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
- DT_CLK(NULL, "pad_clks_ck", "pad_clks_ck"),
- DT_CLK(NULL, "pad_slimbus_core_clks_ck", "pad_slimbus_core_clks_ck"),
- DT_CLK(NULL, "secure_32k_clk_src_ck", "secure_32k_clk_src_ck"),
- DT_CLK(NULL, "slimbus_src_clk", "slimbus_src_clk"),
- DT_CLK(NULL, "slimbus_clk", "slimbus_clk"),
- DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"),
- DT_CLK(NULL, "virt_12000000_ck", "virt_12000000_ck"),
- DT_CLK(NULL, "virt_13000000_ck", "virt_13000000_ck"),
- DT_CLK(NULL, "virt_16800000_ck", "virt_16800000_ck"),
- DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"),
- DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"),
- DT_CLK(NULL, "virt_27000000_ck", "virt_27000000_ck"),
- DT_CLK(NULL, "virt_38400000_ck", "virt_38400000_ck"),
- DT_CLK(NULL, "sys_clkin_ck", "sys_clkin_ck"),
- DT_CLK(NULL, "tie_low_clock_ck", "tie_low_clock_ck"),
- DT_CLK(NULL, "utmi_phy_clkout_ck", "utmi_phy_clkout_ck"),
- DT_CLK(NULL, "xclk60mhsp1_ck", "xclk60mhsp1_ck"),
- DT_CLK(NULL, "xclk60mhsp2_ck", "xclk60mhsp2_ck"),
- DT_CLK(NULL, "xclk60motg_ck", "xclk60motg_ck"),
- DT_CLK(NULL, "abe_dpll_bypass_clk_mux_ck", "abe_dpll_bypass_clk_mux_ck"),
- DT_CLK(NULL, "abe_dpll_refclk_mux_ck", "abe_dpll_refclk_mux_ck"),
- DT_CLK(NULL, "dpll_abe_ck", "dpll_abe_ck"),
- DT_CLK(NULL, "dpll_abe_x2_ck", "dpll_abe_x2_ck"),
- DT_CLK(NULL, "dpll_abe_m2x2_ck", "dpll_abe_m2x2_ck"),
- DT_CLK(NULL, "abe_24m_fclk", "abe_24m_fclk"),
- DT_CLK(NULL, "abe_clk", "abe_clk"),
- DT_CLK(NULL, "aess_fclk", "aess_fclk"),
- DT_CLK(NULL, "dpll_abe_m3x2_ck", "dpll_abe_m3x2_ck"),
- DT_CLK(NULL, "core_hsd_byp_clk_mux_ck", "core_hsd_byp_clk_mux_ck"),
- DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"),
- DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"),
- DT_CLK(NULL, "dpll_core_m6x2_ck", "dpll_core_m6x2_ck"),
- DT_CLK(NULL, "dbgclk_mux_ck", "dbgclk_mux_ck"),
- DT_CLK(NULL, "dpll_core_m2_ck", "dpll_core_m2_ck"),
- DT_CLK(NULL, "ddrphy_ck", "ddrphy_ck"),
- DT_CLK(NULL, "dpll_core_m5x2_ck", "dpll_core_m5x2_ck"),
- DT_CLK(NULL, "div_core_ck", "div_core_ck"),
- DT_CLK(NULL, "div_iva_hs_clk", "div_iva_hs_clk"),
- DT_CLK(NULL, "div_mpu_hs_clk", "div_mpu_hs_clk"),
- DT_CLK(NULL, "dpll_core_m4x2_ck", "dpll_core_m4x2_ck"),
- DT_CLK(NULL, "dll_clk_div_ck", "dll_clk_div_ck"),
- DT_CLK(NULL, "dpll_abe_m2_ck", "dpll_abe_m2_ck"),
- DT_CLK(NULL, "dpll_core_m3x2_ck", "dpll_core_m3x2_ck"),
- DT_CLK(NULL, "dpll_core_m7x2_ck", "dpll_core_m7x2_ck"),
- DT_CLK(NULL, "iva_hsd_byp_clk_mux_ck", "iva_hsd_byp_clk_mux_ck"),
- DT_CLK(NULL, "dpll_iva_ck", "dpll_iva_ck"),
- DT_CLK(NULL, "dpll_iva_x2_ck", "dpll_iva_x2_ck"),
- DT_CLK(NULL, "dpll_iva_m4x2_ck", "dpll_iva_m4x2_ck"),
- DT_CLK(NULL, "dpll_iva_m5x2_ck", "dpll_iva_m5x2_ck"),
- DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"),
- DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"),
- DT_CLK(NULL, "per_hs_clk_div_ck", "per_hs_clk_div_ck"),
- DT_CLK(NULL, "per_hsd_byp_clk_mux_ck", "per_hsd_byp_clk_mux_ck"),
- DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"),
- DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"),
- DT_CLK(NULL, "dpll_per_x2_ck", "dpll_per_x2_ck"),
- DT_CLK(NULL, "dpll_per_m2x2_ck", "dpll_per_m2x2_ck"),
- DT_CLK(NULL, "dpll_per_m3x2_ck", "dpll_per_m3x2_ck"),
- DT_CLK(NULL, "dpll_per_m4x2_ck", "dpll_per_m4x2_ck"),
- DT_CLK(NULL, "dpll_per_m5x2_ck", "dpll_per_m5x2_ck"),
- DT_CLK(NULL, "dpll_per_m6x2_ck", "dpll_per_m6x2_ck"),
- DT_CLK(NULL, "dpll_per_m7x2_ck", "dpll_per_m7x2_ck"),
- DT_CLK(NULL, "usb_hs_clk_div_ck", "usb_hs_clk_div_ck"),
- DT_CLK(NULL, "dpll_usb_ck", "dpll_usb_ck"),
- DT_CLK(NULL, "dpll_usb_clkdcoldo_ck", "dpll_usb_clkdcoldo_ck"),
- DT_CLK(NULL, "dpll_usb_m2_ck", "dpll_usb_m2_ck"),
- DT_CLK(NULL, "ducati_clk_mux_ck", "ducati_clk_mux_ck"),
- DT_CLK(NULL, "func_12m_fclk", "func_12m_fclk"),
- DT_CLK(NULL, "func_24m_clk", "func_24m_clk"),
- DT_CLK(NULL, "func_24mc_fclk", "func_24mc_fclk"),
- DT_CLK(NULL, "func_48m_fclk", "func_48m_fclk"),
- DT_CLK(NULL, "func_48mc_fclk", "func_48mc_fclk"),
- DT_CLK(NULL, "func_64m_fclk", "func_64m_fclk"),
- DT_CLK(NULL, "func_96m_fclk", "func_96m_fclk"),
- DT_CLK(NULL, "init_60m_fclk", "init_60m_fclk"),
- DT_CLK(NULL, "l3_div_ck", "l3_div_ck"),
- DT_CLK(NULL, "l4_div_ck", "l4_div_ck"),
- DT_CLK(NULL, "lp_clk_div_ck", "lp_clk_div_ck"),
- DT_CLK(NULL, "l4_wkup_clk_mux_ck", "l4_wkup_clk_mux_ck"),
DT_CLK("smp_twd", NULL, "mpu_periphclk"),
- DT_CLK(NULL, "ocp_abe_iclk", "ocp_abe_iclk"),
- DT_CLK(NULL, "per_abe_24m_fclk", "per_abe_24m_fclk"),
- DT_CLK(NULL, "per_abe_nc_fclk", "per_abe_nc_fclk"),
- DT_CLK(NULL, "syc_clk_div_ck", "syc_clk_div_ck"),
- DT_CLK(NULL, "aes1_fck", "aes1_fck"),
- DT_CLK(NULL, "aes2_fck", "aes2_fck"),
- DT_CLK(NULL, "dmic_sync_mux_ck", "dmic_sync_mux_ck"),
- DT_CLK(NULL, "func_dmic_abe_gfclk", "func_dmic_abe_gfclk"),
- DT_CLK(NULL, "dss_sys_clk", "dss_sys_clk"),
- DT_CLK(NULL, "dss_tv_clk", "dss_tv_clk"),
- DT_CLK(NULL, "dss_dss_clk", "dss_dss_clk"),
- DT_CLK(NULL, "dss_48mhz_clk", "dss_48mhz_clk"),
- DT_CLK(NULL, "dss_fck", "dss_fck"),
DT_CLK("omapdss_dss", "ick", "dss_fck"),
- DT_CLK(NULL, "fdif_fck", "fdif_fck"),
- DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"),
- DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"),
- DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"),
- DT_CLK(NULL, "gpio4_dbclk", "gpio4_dbclk"),
- DT_CLK(NULL, "gpio5_dbclk", "gpio5_dbclk"),
- DT_CLK(NULL, "gpio6_dbclk", "gpio6_dbclk"),
- DT_CLK(NULL, "sgx_clk_mux", "sgx_clk_mux"),
- DT_CLK(NULL, "hsi_fck", "hsi_fck"),
- DT_CLK(NULL, "iss_ctrlclk", "iss_ctrlclk"),
- DT_CLK(NULL, "mcasp_sync_mux_ck", "mcasp_sync_mux_ck"),
- DT_CLK(NULL, "func_mcasp_abe_gfclk", "func_mcasp_abe_gfclk"),
- DT_CLK(NULL, "mcbsp1_sync_mux_ck", "mcbsp1_sync_mux_ck"),
- DT_CLK(NULL, "func_mcbsp1_gfclk", "func_mcbsp1_gfclk"),
- DT_CLK(NULL, "mcbsp2_sync_mux_ck", "mcbsp2_sync_mux_ck"),
- DT_CLK(NULL, "func_mcbsp2_gfclk", "func_mcbsp2_gfclk"),
- DT_CLK(NULL, "mcbsp3_sync_mux_ck", "mcbsp3_sync_mux_ck"),
- DT_CLK(NULL, "func_mcbsp3_gfclk", "func_mcbsp3_gfclk"),
- DT_CLK(NULL, "mcbsp4_sync_mux_ck", "mcbsp4_sync_mux_ck"),
- DT_CLK(NULL, "per_mcbsp4_gfclk", "per_mcbsp4_gfclk"),
- DT_CLK(NULL, "hsmmc1_fclk", "hsmmc1_fclk"),
- DT_CLK(NULL, "hsmmc2_fclk", "hsmmc2_fclk"),
- DT_CLK(NULL, "ocp2scp_usb_phy_phy_48m", "ocp2scp_usb_phy_phy_48m"),
- DT_CLK(NULL, "sha2md5_fck", "sha2md5_fck"),
- DT_CLK(NULL, "slimbus1_fclk_1", "slimbus1_fclk_1"),
- DT_CLK(NULL, "slimbus1_fclk_0", "slimbus1_fclk_0"),
- DT_CLK(NULL, "slimbus1_fclk_2", "slimbus1_fclk_2"),
- DT_CLK(NULL, "slimbus1_slimbus_clk", "slimbus1_slimbus_clk"),
- DT_CLK(NULL, "slimbus2_fclk_1", "slimbus2_fclk_1"),
- DT_CLK(NULL, "slimbus2_fclk_0", "slimbus2_fclk_0"),
- DT_CLK(NULL, "slimbus2_slimbus_clk", "slimbus2_slimbus_clk"),
- DT_CLK(NULL, "smartreflex_core_fck", "smartreflex_core_fck"),
- DT_CLK(NULL, "smartreflex_iva_fck", "smartreflex_iva_fck"),
- DT_CLK(NULL, "smartreflex_mpu_fck", "smartreflex_mpu_fck"),
- DT_CLK(NULL, "dmt1_clk_mux", "dmt1_clk_mux"),
- DT_CLK(NULL, "cm2_dm10_mux", "cm2_dm10_mux"),
- DT_CLK(NULL, "cm2_dm11_mux", "cm2_dm11_mux"),
- DT_CLK(NULL, "cm2_dm2_mux", "cm2_dm2_mux"),
- DT_CLK(NULL, "cm2_dm3_mux", "cm2_dm3_mux"),
- DT_CLK(NULL, "cm2_dm4_mux", "cm2_dm4_mux"),
- DT_CLK(NULL, "timer5_sync_mux", "timer5_sync_mux"),
- DT_CLK(NULL, "timer6_sync_mux", "timer6_sync_mux"),
- DT_CLK(NULL, "timer7_sync_mux", "timer7_sync_mux"),
- DT_CLK(NULL, "timer8_sync_mux", "timer8_sync_mux"),
- DT_CLK(NULL, "cm2_dm9_mux", "cm2_dm9_mux"),
- DT_CLK(NULL, "usb_host_fs_fck", "usb_host_fs_fck"),
DT_CLK("usbhs_omap", "fs_fck", "usb_host_fs_fck"),
- DT_CLK(NULL, "utmi_p1_gfclk", "utmi_p1_gfclk"),
- DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "usb_host_hs_utmi_p1_clk"),
- DT_CLK(NULL, "utmi_p2_gfclk", "utmi_p2_gfclk"),
- DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "usb_host_hs_utmi_p2_clk"),
- DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "usb_host_hs_utmi_p3_clk"),
- DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "usb_host_hs_hsic480m_p1_clk"),
- DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "usb_host_hs_hsic60m_p1_clk"),
- DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "usb_host_hs_hsic60m_p2_clk"),
- DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "usb_host_hs_hsic480m_p2_clk"),
- DT_CLK(NULL, "usb_host_hs_func48mclk", "usb_host_hs_func48mclk"),
- DT_CLK(NULL, "usb_host_hs_fck", "usb_host_hs_fck"),
DT_CLK("usbhs_omap", "hs_fck", "usb_host_hs_fck"),
- DT_CLK(NULL, "otg_60m_gfclk", "otg_60m_gfclk"),
- DT_CLK(NULL, "usb_otg_hs_xclk", "usb_otg_hs_xclk"),
- DT_CLK(NULL, "usb_otg_hs_ick", "usb_otg_hs_ick"),
DT_CLK("musb-omap2430", "ick", "usb_otg_hs_ick"),
- DT_CLK(NULL, "usb_phy_cm_clk32k", "usb_phy_cm_clk32k"),
- DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "usb_tll_hs_usb_ch2_clk"),
- DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "usb_tll_hs_usb_ch0_clk"),
- DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "usb_tll_hs_usb_ch1_clk"),
- DT_CLK(NULL, "usb_tll_hs_ick", "usb_tll_hs_ick"),
DT_CLK("usbhs_omap", "usbtll_ick", "usb_tll_hs_ick"),
DT_CLK("usbhs_tll", "usbtll_ick", "usb_tll_hs_ick"),
- DT_CLK(NULL, "usim_ck", "usim_ck"),
- DT_CLK(NULL, "usim_fclk", "usim_fclk"),
- DT_CLK(NULL, "pmd_stm_clock_mux_ck", "pmd_stm_clock_mux_ck"),
- DT_CLK(NULL, "pmd_trace_clk_mux_ck", "pmd_trace_clk_mux_ck"),
- DT_CLK(NULL, "stm_clk_div_ck", "stm_clk_div_ck"),
- DT_CLK(NULL, "trace_clk_div_ck", "trace_clk_div_ck"),
- DT_CLK(NULL, "auxclk0_src_ck", "auxclk0_src_ck"),
- DT_CLK(NULL, "auxclk0_ck", "auxclk0_ck"),
- DT_CLK(NULL, "auxclkreq0_ck", "auxclkreq0_ck"),
- DT_CLK(NULL, "auxclk1_src_ck", "auxclk1_src_ck"),
- DT_CLK(NULL, "auxclk1_ck", "auxclk1_ck"),
- DT_CLK(NULL, "auxclkreq1_ck", "auxclkreq1_ck"),
- DT_CLK(NULL, "auxclk2_src_ck", "auxclk2_src_ck"),
- DT_CLK(NULL, "auxclk2_ck", "auxclk2_ck"),
- DT_CLK(NULL, "auxclkreq2_ck", "auxclkreq2_ck"),
- DT_CLK(NULL, "auxclk3_src_ck", "auxclk3_src_ck"),
- DT_CLK(NULL, "auxclk3_ck", "auxclk3_ck"),
- DT_CLK(NULL, "auxclkreq3_ck", "auxclkreq3_ck"),
- DT_CLK(NULL, "auxclk4_src_ck", "auxclk4_src_ck"),
- DT_CLK(NULL, "auxclk4_ck", "auxclk4_ck"),
- DT_CLK(NULL, "auxclkreq4_ck", "auxclkreq4_ck"),
- DT_CLK(NULL, "auxclk5_src_ck", "auxclk5_src_ck"),
- DT_CLK(NULL, "auxclk5_ck", "auxclk5_ck"),
- DT_CLK(NULL, "auxclkreq5_ck", "auxclkreq5_ck"),
DT_CLK("omap_i2c.1", "ick", "dummy_ck"),
DT_CLK("omap_i2c.2", "ick", "dummy_ck"),
DT_CLK("omap_i2c.3", "ick", "dummy_ck"),
@@ -263,9 +80,6 @@
DT_CLK("4013c000.timer", "timer_sys_ck", "syc_clk_div_ck"),
DT_CLK("4013e000.timer", "timer_sys_ck", "syc_clk_div_ck"),
DT_CLK(NULL, "cpufreq_ck", "dpll_mpu_ck"),
- DT_CLK(NULL, "bandgap_fclk", "bandgap_fclk"),
- DT_CLK(NULL, "div_ts_ck", "div_ts_ck"),
- DT_CLK(NULL, "bandgap_ts_fclk", "bandgap_ts_fclk"),
{ .node_name = NULL },
};
@@ -278,6 +92,8 @@
omap2_clk_disable_autoidle_all();
+ ti_clk_add_aliases();
+
/*
* Lock USB DPLL on OMAP4 devices so that the L3INIT power
* domain can transition to retention state when not in use.
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
index 45d0533..13eb04f7 100644
--- a/drivers/clk/ti/clk-dra7-atl.c
+++ b/drivers/clk/ti/clk-dra7-atl.c
@@ -24,6 +24,9 @@
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/clk/ti.h>
+
+#include "clock.h"
#define DRA7_ATL_INSTANCES 4
@@ -171,6 +174,7 @@
struct clk_init_data init = { NULL };
const char **parent_names = NULL;
struct clk *clk;
+ int ret;
clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
if (!clk_hw) {
@@ -200,9 +204,14 @@
init.parent_names = parent_names;
- clk = clk_register(NULL, &clk_hw->hw);
+ clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
if (!IS_ERR(clk)) {
+ ret = ti_clk_add_alias(NULL, clk, node->name);
+ if (ret) {
+ clk_unregister(clk);
+ goto cleanup;
+ }
of_clk_add_provider(node, of_clk_src_simple_get, clk);
kfree(parent_names);
return;
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 5fcf247..ddbad7e 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -24,6 +24,7 @@
#include <linux/list.h>
#include <linux/regmap.h>
#include <linux/bootmem.h>
+#include <linux/device.h>
#include "clock.h"
@@ -42,27 +43,29 @@
static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
-static void clk_memmap_writel(u32 val, void __iomem *reg)
+static void clk_memmap_writel(u32 val, const struct clk_omap_reg *reg)
{
- struct clk_omap_reg *r = (struct clk_omap_reg *)®
- struct clk_iomap *io = clk_memmaps[r->index];
+ struct clk_iomap *io = clk_memmaps[reg->index];
- if (io->regmap)
- regmap_write(io->regmap, r->offset, val);
+ if (reg->ptr)
+ writel_relaxed(val, reg->ptr);
+ else if (io->regmap)
+ regmap_write(io->regmap, reg->offset, val);
else
- writel_relaxed(val, io->mem + r->offset);
+ writel_relaxed(val, io->mem + reg->offset);
}
-static u32 clk_memmap_readl(void __iomem *reg)
+static u32 clk_memmap_readl(const struct clk_omap_reg *reg)
{
u32 val;
- struct clk_omap_reg *r = (struct clk_omap_reg *)®
- struct clk_iomap *io = clk_memmaps[r->index];
+ struct clk_iomap *io = clk_memmaps[reg->index];
- if (io->regmap)
- regmap_read(io->regmap, r->offset, &val);
+ if (reg->ptr)
+ val = readl_relaxed(reg->ptr);
+ else if (io->regmap)
+ regmap_read(io->regmap, reg->offset, &val);
else
- val = readl_relaxed(io->mem + r->offset);
+ val = readl_relaxed(io->mem + reg->offset);
return val;
}
@@ -161,20 +164,18 @@
* ti_clk_get_reg_addr - get register address for a clock register
* @node: device node for the clock
* @index: register index from the clock node
+ * @reg: pointer to target register struct
*
- * Builds clock register address from device tree information. This
- * is a struct of type clk_omap_reg. Returns a pointer to the register
- * address, or a pointer error value in failure.
+ * Builds clock register address from device tree information, and returns
+ * the data via the provided output pointer @reg. Returns 0 on success,
+ * negative error value on failure.
*/
-void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
+int ti_clk_get_reg_addr(struct device_node *node, int index,
+ struct clk_omap_reg *reg)
{
- struct clk_omap_reg *reg;
u32 val;
- u32 tmp;
int i;
- reg = (struct clk_omap_reg *)&tmp;
-
for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
if (clocks_node_ptr[i] == node->parent)
break;
@@ -182,19 +183,20 @@
if (i == CLK_MAX_MEMMAPS) {
pr_err("clk-provider not found for %s!\n", node->name);
- return IOMEM_ERR_PTR(-ENOENT);
+ return -ENOENT;
}
reg->index = i;
if (of_property_read_u32_index(node, "reg", index, &val)) {
pr_err("%s must have reg[%d]!\n", node->name, index);
- return IOMEM_ERR_PTR(-EINVAL);
+ return -EINVAL;
}
reg->offset = val;
+ reg->ptr = NULL;
- return (__force void __iomem *)tmp;
+ return 0;
}
/**
@@ -297,6 +299,7 @@
struct ti_clk_fixed *fixed;
struct ti_clk_fixed_factor *fixed_factor;
struct clk_hw *clk_hw;
+ int ret;
if (setup->clk)
return setup->clk;
@@ -307,6 +310,13 @@
clk = clk_register_fixed_rate(NULL, setup->name, NULL, 0,
fixed->frequency);
+ if (!IS_ERR(clk)) {
+ ret = ti_clk_add_alias(NULL, clk, setup->name);
+ if (ret) {
+ clk_unregister(clk);
+ clk = ERR_PTR(ret);
+ }
+ }
break;
case TI_CLK_MUX:
clk = ti_clk_register_mux(setup);
@@ -324,6 +334,13 @@
fixed_factor->parent,
0, fixed_factor->mult,
fixed_factor->div);
+ if (!IS_ERR(clk)) {
+ ret = ti_clk_add_alias(NULL, clk, setup->name);
+ if (ret) {
+ clk_unregister(clk);
+ clk = ERR_PTR(ret);
+ }
+ }
break;
case TI_CLK_GATE:
clk = ti_clk_register_gate(setup);
@@ -354,6 +371,12 @@
return clk;
}
+static const struct of_device_id simple_clk_match_table[] __initconst = {
+ { .compatible = "fixed-clock" },
+ { .compatible = "fixed-factor-clock" },
+ { }
+};
+
int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
{
struct clk *clk;
@@ -371,9 +394,6 @@
clks->clk->name, PTR_ERR(clk));
return PTR_ERR(clk);
}
- } else {
- clks->lk.clk = clk;
- clkdev_add(&clks->lk);
}
clks++;
}
@@ -396,8 +416,6 @@
}
} else {
retry = true;
- retry_clk->lk.clk = clk;
- clkdev_add(&retry_clk->lk);
list_del(&retry_clk->link);
}
}
@@ -408,6 +426,26 @@
#endif
/**
+ * ti_clk_add_aliases - setup clock aliases
+ *
+ * Sets up any missing clock aliases. No return value.
+ */
+void __init ti_clk_add_aliases(void)
+{
+ struct device_node *np;
+ struct clk *clk;
+
+ for_each_matching_node(np, simple_clk_match_table) {
+ struct of_phandle_args clkspec;
+
+ clkspec.np = np;
+ clk = of_clk_get_from_provider(&clkspec);
+
+ ti_clk_add_alias(NULL, clk, np->name);
+ }
+}
+
+/**
* ti_clk_setup_features - setup clock features flags
* @features: features definition to use
*
@@ -453,3 +491,66 @@
clk_prepare_enable(init_clk);
}
}
+
+/**
+ * ti_clk_add_alias - add a clock alias for a TI clock
+ * @dev: device alias for this clock
+ * @clk: clock handle to create alias for
+ * @con: connection ID for this clock
+ *
+ * Creates a clock alias for a TI clock. Allocates the clock lookup entry
+ * and assigns the data to it. Returns 0 if successful, negative error
+ * value otherwise.
+ */
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
+{
+ struct clk_lookup *cl;
+
+ if (!clk)
+ return 0;
+
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+ if (!cl)
+ return -ENOMEM;
+
+ if (dev)
+ cl->dev_id = dev_name(dev);
+ cl->con_id = con;
+ cl->clk = clk;
+
+ clkdev_add(cl);
+
+ return 0;
+}
+
+/**
+ * ti_clk_register - register a TI clock to the common clock framework
+ * @dev: device for this clock
+ * @hw: hardware clock handle
+ * @con: connection ID for this clock
+ *
+ * Registers a TI clock to the common clock framework, and adds a clock
+ * alias for it. Returns a handle to the registered clock if successful,
+ * ERR_PTR value in failure.
+ */
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+ const char *con)
+{
+ struct clk *clk;
+ int ret;
+
+ clk = clk_register(dev, hw);
+ if (IS_ERR(clk))
+ return clk;
+
+ ret = ti_clk_add_alias(dev, clk, con);
+ if (ret) {
+ clk_unregister(clk);
+ return ERR_PTR(ret);
+ }
+
+ return clk;
+}
diff --git a/drivers/clk/ti/clkt_dflt.c b/drivers/clk/ti/clkt_dflt.c
index c6ae563..91751dd 100644
--- a/drivers/clk/ti/clkt_dflt.c
+++ b/drivers/clk/ti/clkt_dflt.c
@@ -55,7 +55,8 @@
* elapsed. XXX Deprecated - should be moved into drivers for the
* individual IP block that the IDLEST register exists in.
*/
-static int _wait_idlest_generic(struct clk_hw_omap *clk, void __iomem *reg,
+static int _wait_idlest_generic(struct clk_hw_omap *clk,
+ struct clk_omap_reg *reg,
u32 mask, u8 idlest, const char *name)
{
int i = 0, ena = 0;
@@ -91,7 +92,7 @@
*/
static void _omap2_module_wait_ready(struct clk_hw_omap *clk)
{
- void __iomem *companion_reg, *idlest_reg;
+ struct clk_omap_reg companion_reg, idlest_reg;
u8 other_bit, idlest_bit, idlest_val, idlest_reg_id;
s16 prcm_mod;
int r;
@@ -99,17 +100,17 @@
/* Not all modules have multiple clocks that their IDLEST depends on */
if (clk->ops->find_companion) {
clk->ops->find_companion(clk, &companion_reg, &other_bit);
- if (!(ti_clk_ll_ops->clk_readl(companion_reg) &
+ if (!(ti_clk_ll_ops->clk_readl(&companion_reg) &
(1 << other_bit)))
return;
}
clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
- r = ti_clk_ll_ops->cm_split_idlest_reg(idlest_reg, &prcm_mod,
+ r = ti_clk_ll_ops->cm_split_idlest_reg(&idlest_reg, &prcm_mod,
&idlest_reg_id);
if (r) {
/* IDLEST register not in the CM module */
- _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit),
+ _wait_idlest_generic(clk, &idlest_reg, (1 << idlest_bit),
idlest_val, clk_hw_get_name(&clk->hw));
} else {
ti_clk_ll_ops->cm_wait_module_ready(0, prcm_mod, idlest_reg_id,
@@ -139,17 +140,17 @@
* avoid this issue, and remove the casts. No return value.
*/
void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
- void __iomem **other_reg, u8 *other_bit)
+ struct clk_omap_reg *other_reg,
+ u8 *other_bit)
{
- u32 r;
+ memcpy(other_reg, &clk->enable_reg, sizeof(*other_reg));
/*
* Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes
* it's just a matter of XORing the bits.
*/
- r = ((__force u32)clk->enable_reg ^ (CM_FCLKEN ^ CM_ICLKEN));
+ other_reg->offset ^= (CM_FCLKEN ^ CM_ICLKEN);
- *other_reg = (__force void __iomem *)r;
*other_bit = clk->enable_bit;
}
@@ -168,13 +169,14 @@
* CM_IDLEST2). This is not true for all modules. No return value.
*/
void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
- void __iomem **idlest_reg, u8 *idlest_bit,
+ struct clk_omap_reg *idlest_reg, u8 *idlest_bit,
u8 *idlest_val)
{
- u32 r;
+ memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
- r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
- *idlest_reg = (__force void __iomem *)r;
+ idlest_reg->offset &= ~0xf0;
+ idlest_reg->offset |= 0x20;
+
*idlest_bit = clk->enable_bit;
/*
@@ -222,31 +224,19 @@
}
}
- if (IS_ERR(clk->enable_reg)) {
- pr_err("%s: %s missing enable_reg\n", __func__,
- clk_hw_get_name(hw));
- ret = -EINVAL;
- goto err;
- }
-
/* FIXME should not have INVERT_ENABLE bit here */
- v = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+ v = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
if (clk->flags & INVERT_ENABLE)
v &= ~(1 << clk->enable_bit);
else
v |= (1 << clk->enable_bit);
- ti_clk_ll_ops->clk_writel(v, clk->enable_reg);
- v = ti_clk_ll_ops->clk_readl(clk->enable_reg); /* OCP barrier */
+ ti_clk_ll_ops->clk_writel(v, &clk->enable_reg);
+ v = ti_clk_ll_ops->clk_readl(&clk->enable_reg); /* OCP barrier */
if (clk->ops && clk->ops->find_idlest)
_omap2_module_wait_ready(clk);
return 0;
-
-err:
- if (clkdm_control && clk->clkdm)
- ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
- return ret;
}
/**
@@ -264,22 +254,13 @@
u32 v;
clk = to_clk_hw_omap(hw);
- if (IS_ERR(clk->enable_reg)) {
- /*
- * 'independent' here refers to a clock which is not
- * controlled by its parent.
- */
- pr_err("%s: independent clock %s has no enable_reg\n",
- __func__, clk_hw_get_name(hw));
- return;
- }
- v = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+ v = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
if (clk->flags & INVERT_ENABLE)
v |= (1 << clk->enable_bit);
else
v &= ~(1 << clk->enable_bit);
- ti_clk_ll_ops->clk_writel(v, clk->enable_reg);
+ ti_clk_ll_ops->clk_writel(v, &clk->enable_reg);
/* No OCP barrier needed here since it is a disable operation */
if (!(ti_clk_get_features()->flags & TI_CLK_DISABLE_CLKDM_CONTROL) &&
@@ -300,7 +281,7 @@
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
u32 v;
- v = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+ v = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
if (clk->flags & INVERT_ENABLE)
v ^= BIT(clk->enable_bit);
diff --git a/drivers/clk/ti/clkt_dpll.c b/drivers/clk/ti/clkt_dpll.c
index b919fdf..ce98da2 100644
--- a/drivers/clk/ti/clkt_dpll.c
+++ b/drivers/clk/ti/clkt_dpll.c
@@ -213,7 +213,7 @@
if (!dd)
return -EINVAL;
- v = ti_clk_ll_ops->clk_readl(dd->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
v &= dd->enable_mask;
v >>= __ffs(dd->enable_mask);
@@ -249,14 +249,14 @@
return 0;
/* Return bypass rate if DPLL is bypassed */
- v = ti_clk_ll_ops->clk_readl(dd->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
v &= dd->enable_mask;
v >>= __ffs(dd->enable_mask);
if (_omap2_dpll_is_in_bypass(v))
return clk_hw_get_rate(dd->clk_bypass);
- v = ti_clk_ll_ops->clk_readl(dd->mult_div1_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg);
dpll_mult = v & dd->mult_mask;
dpll_mult >>= __ffs(dd->mult_mask);
dpll_div = v & dd->div1_mask;
diff --git a/drivers/clk/ti/clkt_iclk.c b/drivers/clk/ti/clkt_iclk.c
index 38c3690..60b583d 100644
--- a/drivers/clk/ti/clkt_iclk.c
+++ b/drivers/clk/ti/clkt_iclk.c
@@ -31,28 +31,29 @@
void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk)
{
u32 v;
- void __iomem *r;
+ struct clk_omap_reg r;
- r = (__force void __iomem *)
- ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+ memcpy(&r, &clk->enable_reg, sizeof(r));
+ r.offset ^= (CM_AUTOIDLE ^ CM_ICLKEN);
- v = ti_clk_ll_ops->clk_readl(r);
+ v = ti_clk_ll_ops->clk_readl(&r);
v |= (1 << clk->enable_bit);
- ti_clk_ll_ops->clk_writel(v, r);
+ ti_clk_ll_ops->clk_writel(v, &r);
}
/* XXX */
void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk)
{
u32 v;
- void __iomem *r;
+ struct clk_omap_reg r;
- r = (__force void __iomem *)
- ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+ memcpy(&r, &clk->enable_reg, sizeof(r));
- v = ti_clk_ll_ops->clk_readl(r);
+ r.offset ^= (CM_AUTOIDLE ^ CM_ICLKEN);
+
+ v = ti_clk_ll_ops->clk_readl(&r);
v &= ~(1 << clk->enable_bit);
- ti_clk_ll_ops->clk_writel(v, r);
+ ti_clk_ll_ops->clk_writel(v, &r);
}
/**
@@ -68,14 +69,12 @@
* modules. No return value.
*/
static void omap2430_clk_i2chs_find_idlest(struct clk_hw_omap *clk,
- void __iomem **idlest_reg,
+ struct clk_omap_reg *idlest_reg,
u8 *idlest_bit,
u8 *idlest_val)
{
- u32 r;
-
- r = ((__force u32)clk->enable_reg ^ (OMAP24XX_CM_FCLKEN2 ^ CM_IDLEST));
- *idlest_reg = (__force void __iomem *)r;
+ memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
+ idlest_reg->offset ^= (OMAP24XX_CM_FCLKEN2 ^ CM_IDLEST);
*idlest_bit = clk->enable_bit;
*idlest_val = OMAP24XX_CM_IDLEST_VAL;
}
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 13c37f4..3f7b265 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -16,6 +16,28 @@
#ifndef __DRIVERS_CLK_TI_CLOCK__
#define __DRIVERS_CLK_TI_CLOCK__
+struct clk_omap_divider {
+ struct clk_hw hw;
+ struct clk_omap_reg reg;
+ u8 shift;
+ u8 width;
+ u8 flags;
+ const struct clk_div_table *table;
+};
+
+#define to_clk_omap_divider(_hw) container_of(_hw, struct clk_omap_divider, hw)
+
+struct clk_omap_mux {
+ struct clk_hw hw;
+ struct clk_omap_reg reg;
+ u32 *table;
+ u32 mask;
+ u8 shift;
+ u8 flags;
+};
+
+#define to_clk_omap_mux(_hw) container_of(_hw, struct clk_omap_mux, hw)
+
enum {
TI_CLK_FIXED,
TI_CLK_MUX,
@@ -86,7 +108,7 @@
int num_parents;
u16 reg;
u8 module;
- const char **parents;
+ const char * const *parents;
u16 flags;
};
@@ -189,16 +211,25 @@
struct clk *ti_clk_register_divider(struct ti_clk *setup);
struct clk *ti_clk_register_composite(struct ti_clk *setup);
struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+ const char *con);
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
+void ti_clk_add_aliases(void);
struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup);
struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup);
struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup);
+int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
+ u8 flags, u8 *width,
+ const struct clk_div_table **table);
+
void ti_clk_patch_legacy_clks(struct ti_clk **patch);
struct clk *ti_clk_register_clk(struct ti_clk *setup);
int ti_clk_register_legacy_clks(struct ti_clk_alias *clks);
-void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
+int ti_clk_get_reg_addr(struct device_node *node, int index,
+ struct clk_omap_reg *reg);
void ti_dt_clocks_register(struct ti_dt_clk *oclks);
int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
ti_of_clk_init_cb_t func);
@@ -223,7 +254,9 @@
extern const struct clk_ops ti_clk_divider_ops;
extern const struct clk_ops ti_clk_mux_ops;
+extern const struct clk_ops omap_gate_clk_ops;
+void omap2_init_clk_clkdm(struct clk_hw *hw);
int omap2_clkops_enable_clkdm(struct clk_hw *hw);
void omap2_clkops_disable_clkdm(struct clk_hw *hw);
@@ -231,10 +264,10 @@
void omap2_dflt_clk_disable(struct clk_hw *hw);
int omap2_dflt_clk_is_enabled(struct clk_hw *hw);
void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
- void __iomem **other_reg,
+ struct clk_omap_reg *other_reg,
u8 *other_bit);
void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
- void __iomem **idlest_reg,
+ struct clk_omap_reg *idlest_reg,
u8 *idlest_bit, u8 *idlest_val);
void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk);
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 6cf9dd1..fbedc6a 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -52,10 +52,6 @@
return -EINVAL;
}
- if (unlikely(clk->enable_reg))
- pr_err("%s: %s: should use dflt_clk_enable ?!\n", __func__,
- clk_hw_get_name(hw));
-
if (ti_clk_get_features()->flags & TI_CLK_DISABLE_CLKDM_CONTROL) {
pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n",
__func__, clk_hw_get_name(hw));
@@ -90,10 +86,6 @@
return;
}
- if (unlikely(clk->enable_reg))
- pr_err("%s: %s: should use dflt_clk_disable ?!\n", __func__,
- clk_hw_get_name(hw));
-
if (ti_clk_get_features()->flags & TI_CLK_DISABLE_CLKDM_CONTROL) {
pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n",
__func__, clk_hw_get_name(hw));
@@ -103,6 +95,36 @@
ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
}
+/**
+ * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Convert a clockdomain name stored in a struct clk 'clk' into a
+ * clockdomain pointer, and save it into the struct clk. Intended to be
+ * called during clk_register(). No return value.
+ */
+void omap2_init_clk_clkdm(struct clk_hw *hw)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ struct clockdomain *clkdm;
+ const char *clk_name;
+
+ if (!clk->clkdm_name)
+ return;
+
+ clk_name = __clk_get_name(hw->clk);
+
+ clkdm = ti_clk_ll_ops->clkdm_lookup(clk->clkdm_name);
+ if (clkdm) {
+ pr_debug("clock: associated clk %s to clkdm %s\n",
+ clk_name, clk->clkdm_name);
+ clk->clkdm = clkdm;
+ } else {
+ pr_debug("clock: could not associate clk %s to clkdm %s\n",
+ clk_name, clk->clkdm_name);
+ }
+}
+
static void __init of_ti_clockdomain_setup(struct device_node *node)
{
struct clk *clk;
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 1cf70f4..beea894 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -124,8 +124,9 @@
struct clk_hw *mux;
struct clk_hw *div;
int num_parents = 1;
- const char **parent_names = NULL;
+ const char * const *parent_names = NULL;
struct clk *clk;
+ int ret;
comp = setup->data;
@@ -150,6 +151,12 @@
&ti_composite_divider_ops, gate,
&ti_composite_gate_ops, 0);
+ ret = ti_clk_add_alias(NULL, clk, setup->name);
+ if (ret) {
+ clk_unregister(clk);
+ return ERR_PTR(ret);
+ }
+
return clk;
}
#endif
@@ -163,6 +170,7 @@
int num_parents = 0;
const char **parent_names = NULL;
int i;
+ int ret;
/* Check for presence of each component clock */
for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) {
@@ -217,8 +225,14 @@
_get_hw(cclk, CLK_COMPONENT_TYPE_GATE),
&ti_composite_gate_ops, 0);
- if (!IS_ERR(clk))
+ if (!IS_ERR(clk)) {
+ ret = ti_clk_add_alias(NULL, clk, node->name);
+ if (ret) {
+ clk_unregister(clk);
+ goto cleanup;
+ }
of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ }
cleanup:
/* Free component clock list entries */
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index 6bb8778..d6dcb28 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -39,7 +39,7 @@
return maxdiv;
}
-static unsigned int _get_maxdiv(struct clk_divider *divider)
+static unsigned int _get_maxdiv(struct clk_omap_divider *divider)
{
if (divider->flags & CLK_DIVIDER_ONE_BASED)
return div_mask(divider);
@@ -61,7 +61,7 @@
return 0;
}
-static unsigned int _get_div(struct clk_divider *divider, unsigned int val)
+static unsigned int _get_div(struct clk_omap_divider *divider, unsigned int val)
{
if (divider->flags & CLK_DIVIDER_ONE_BASED)
return val;
@@ -83,7 +83,7 @@
return 0;
}
-static unsigned int _get_val(struct clk_divider *divider, u8 div)
+static unsigned int _get_val(struct clk_omap_divider *divider, u8 div)
{
if (divider->flags & CLK_DIVIDER_ONE_BASED)
return div;
@@ -97,10 +97,10 @@
static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
- struct clk_divider *divider = to_clk_divider(hw);
+ struct clk_omap_divider *divider = to_clk_omap_divider(hw);
unsigned int div, val;
- val = ti_clk_ll_ops->clk_readl(divider->reg) >> divider->shift;
+ val = ti_clk_ll_ops->clk_readl(÷r->reg) >> divider->shift;
val &= div_mask(divider);
div = _get_div(divider, val);
@@ -131,7 +131,7 @@
return false;
}
-static bool _is_valid_div(struct clk_divider *divider, unsigned int div)
+static bool _is_valid_div(struct clk_omap_divider *divider, unsigned int div)
{
if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
return is_power_of_2(div);
@@ -172,7 +172,7 @@
static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
unsigned long *best_parent_rate)
{
- struct clk_divider *divider = to_clk_divider(hw);
+ struct clk_omap_divider *divider = to_clk_omap_divider(hw);
int i, bestdiv = 0;
unsigned long parent_rate, best = 0, now, maxdiv;
unsigned long parent_rate_saved = *best_parent_rate;
@@ -239,14 +239,14 @@
static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
- struct clk_divider *divider;
+ struct clk_omap_divider *divider;
unsigned int div, value;
u32 val;
if (!hw || !rate)
return -EINVAL;
- divider = to_clk_divider(hw);
+ divider = to_clk_omap_divider(hw);
div = DIV_ROUND_UP(parent_rate, rate);
value = _get_val(divider, div);
@@ -257,11 +257,11 @@
if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
val = div_mask(divider) << (divider->shift + 16);
} else {
- val = ti_clk_ll_ops->clk_readl(divider->reg);
+ val = ti_clk_ll_ops->clk_readl(÷r->reg);
val &= ~(div_mask(divider) << divider->shift);
}
val |= value << divider->shift;
- ti_clk_ll_ops->clk_writel(val, divider->reg);
+ ti_clk_ll_ops->clk_writel(val, ÷r->reg);
return 0;
}
@@ -274,11 +274,12 @@
static struct clk *_register_divider(struct device *dev, const char *name,
const char *parent_name,
- unsigned long flags, void __iomem *reg,
+ unsigned long flags,
+ struct clk_omap_reg *reg,
u8 shift, u8 width, u8 clk_divider_flags,
const struct clk_div_table *table)
{
- struct clk_divider *div;
+ struct clk_omap_divider *div;
struct clk *clk;
struct clk_init_data init;
@@ -303,7 +304,7 @@
init.num_parents = (parent_name ? 1 : 0);
/* struct clk_divider assignments */
- div->reg = reg;
+ memcpy(&div->reg, reg, sizeof(*reg));
div->shift = shift;
div->width = width;
div->flags = clk_divider_flags;
@@ -311,7 +312,7 @@
div->table = table;
/* register the clock */
- clk = clk_register(dev, &div->hw);
+ clk = ti_clk_register(dev, &div->hw, name);
if (IS_ERR(clk))
kfree(div);
@@ -319,20 +320,17 @@
return clk;
}
-static struct clk_div_table *
-_get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width)
+int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
+ u8 flags, u8 *width,
+ const struct clk_div_table **table)
{
int valid_div = 0;
- struct clk_div_table *table;
- int i;
- int div;
u32 val;
- u8 flags;
+ int div;
+ int i;
+ struct clk_div_table *tmp;
- if (!setup->num_dividers) {
- /* Clk divider table not provided, determine min/max divs */
- flags = setup->flags;
-
+ if (!div_table) {
if (flags & CLKF_INDEX_STARTS_AT_ONE)
val = 1;
else
@@ -340,7 +338,7 @@
div = 1;
- while (div < setup->max_div) {
+ while (div < max_div) {
if (flags & CLKF_INDEX_POWER_OF_TWO)
div <<= 1;
else
@@ -349,37 +347,59 @@
}
*width = fls(val);
+ *table = NULL;
- return NULL;
+ return 0;
}
- for (i = 0; i < setup->num_dividers; i++)
- if (setup->dividers[i])
- valid_div++;
+ i = 0;
- table = kzalloc(sizeof(*table) * (valid_div + 1), GFP_KERNEL);
- if (!table)
- return ERR_PTR(-ENOMEM);
+ while (!num_dividers || i < num_dividers) {
+ if (div_table[i] == -1)
+ break;
+ if (div_table[i])
+ valid_div++;
+ i++;
+ }
+
+ num_dividers = i;
+
+ tmp = kzalloc(sizeof(*tmp) * (valid_div + 1), GFP_KERNEL);
+ if (!tmp)
+ return -ENOMEM;
valid_div = 0;
*width = 0;
- for (i = 0; i < setup->num_dividers; i++)
- if (setup->dividers[i]) {
- table[valid_div].div = setup->dividers[i];
- table[valid_div].val = i;
+ for (i = 0; i < num_dividers; i++)
+ if (div_table[i] > 0) {
+ tmp[valid_div].div = div_table[i];
+ tmp[valid_div].val = i;
valid_div++;
*width = i;
}
*width = fls(*width);
+ *table = tmp;
+
+ return 0;
+}
+
+static const struct clk_div_table *
+_get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width)
+{
+ const struct clk_div_table *table = NULL;
+
+ ti_clk_parse_divider_data(setup->dividers, setup->num_dividers,
+ setup->max_div, setup->flags, width,
+ &table);
return table;
}
struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup)
{
- struct clk_divider *div;
+ struct clk_omap_divider *div;
struct clk_omap_reg *reg;
if (!setup)
@@ -414,7 +434,7 @@
u8 width;
u32 flags = 0;
u8 div_flags = 0;
- struct clk_div_table *table;
+ const struct clk_div_table *table;
struct clk *clk;
div = setup->data;
@@ -542,14 +562,15 @@
}
static int __init ti_clk_divider_populate(struct device_node *node,
- void __iomem **reg, const struct clk_div_table **table,
+ struct clk_omap_reg *reg, const struct clk_div_table **table,
u32 *flags, u8 *div_flags, u8 *width, u8 *shift)
{
u32 val;
+ int ret;
- *reg = ti_clk_get_reg_addr(node, 0);
- if (IS_ERR(*reg))
- return PTR_ERR(*reg);
+ ret = ti_clk_get_reg_addr(node, 0, reg);
+ if (ret)
+ return ret;
if (!of_property_read_u32(node, "ti,bit-shift", &val))
*shift = val;
@@ -588,7 +609,7 @@
{
struct clk *clk;
const char *parent_name;
- void __iomem *reg;
+ struct clk_omap_reg reg;
u8 clk_divider_flags = 0;
u8 width = 0;
u8 shift = 0;
@@ -601,7 +622,7 @@
&clk_divider_flags, &width, &shift))
goto cleanup;
- clk = _register_divider(NULL, node->name, parent_name, flags, reg,
+ clk = _register_divider(NULL, node->name, parent_name, flags, ®,
shift, width, clk_divider_flags, table);
if (!IS_ERR(clk)) {
@@ -617,7 +638,7 @@
static void __init of_ti_composite_divider_clk_setup(struct device_node *node)
{
- struct clk_divider *div;
+ struct clk_omap_divider *div;
u32 val;
div = kzalloc(sizeof(*div), GFP_KERNEL);
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 4b9a419..96d8488 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -185,7 +185,7 @@
dd->clk_bypass = __clk_get_hw(clk);
/* register the clock */
- clk = clk_register(NULL, &clk_hw->hw);
+ clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
if (!IS_ERR(clk)) {
omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
@@ -203,17 +203,10 @@
}
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS)
-static void __iomem *_get_reg(u8 module, u16 offset)
+void _get_reg(u8 module, u16 offset, struct clk_omap_reg *reg)
{
- u32 reg;
- struct clk_omap_reg *reg_setup;
-
- reg_setup = (struct clk_omap_reg *)®
-
- reg_setup->index = module;
- reg_setup->offset = offset;
-
- return (void __iomem *)reg;
+ reg->index = module;
+ reg->offset = offset;
}
struct clk *ti_clk_register_dpll(struct ti_clk *setup)
@@ -248,7 +241,6 @@
clk_hw->dpll_data = dd;
clk_hw->ops = &clkhwops_omap3_dpll;
clk_hw->hw.init = &init;
- clk_hw->flags = MEMMAP_ADDRESSING;
init.name = setup->name;
init.ops = ops;
@@ -256,10 +248,10 @@
init.num_parents = dpll->num_parents;
init.parent_names = dpll->parents;
- dd->control_reg = _get_reg(dpll->module, dpll->control_reg);
- dd->idlest_reg = _get_reg(dpll->module, dpll->idlest_reg);
- dd->mult_div1_reg = _get_reg(dpll->module, dpll->mult_div1_reg);
- dd->autoidle_reg = _get_reg(dpll->module, dpll->autoidle_reg);
+ _get_reg(dpll->module, dpll->control_reg, &dd->control_reg);
+ _get_reg(dpll->module, dpll->idlest_reg, &dd->idlest_reg);
+ _get_reg(dpll->module, dpll->mult_div1_reg, &dd->mult_div1_reg);
+ _get_reg(dpll->module, dpll->autoidle_reg, &dd->autoidle_reg);
dd->modes = dpll->modes;
dd->div1_mask = dpll->div1_mask;
@@ -288,7 +280,7 @@
if (dpll->flags & CLKF_J_TYPE)
dd->flags |= DPLL_J_TYPE;
- clk = clk_register(NULL, &clk_hw->hw);
+ clk = ti_clk_register(NULL, &clk_hw->hw, setup->name);
if (!IS_ERR(clk))
return clk;
@@ -320,6 +312,7 @@
struct clk_hw_omap *clk_hw;
const char *name = node->name;
const char *parent_name;
+ int ret;
parent_name = of_clk_get_parent_name(node, 0);
if (!parent_name) {
@@ -339,8 +332,19 @@
init.parent_names = &parent_name;
init.num_parents = 1;
+ if (hw_ops == &clkhwops_omap4_dpllmx) {
+ /* Check if register defined, if not, drop hw-ops */
+ ret = of_property_count_elems_of_size(node, "reg", 1);
+ if (ret <= 0) {
+ hw_ops = NULL;
+ } else if (ti_clk_get_reg_addr(node, 0, &clk_hw->clksel_reg)) {
+ kfree(clk_hw);
+ return;
+ }
+ }
+
/* register the clock */
- clk = clk_register(NULL, &clk_hw->hw);
+ clk = ti_clk_register(NULL, &clk_hw->hw, name);
if (IS_ERR(clk)) {
kfree(clk_hw);
@@ -380,7 +384,6 @@
clk_hw->dpll_data = dd;
clk_hw->ops = &clkhwops_omap3_dpll;
clk_hw->hw.init = init;
- clk_hw->flags = MEMMAP_ADDRESSING;
init->name = node->name;
init->ops = ops;
@@ -399,7 +402,8 @@
init->parent_names = parent_names;
- dd->control_reg = ti_clk_get_reg_addr(node, 0);
+ if (ti_clk_get_reg_addr(node, 0, &dd->control_reg))
+ goto cleanup;
/*
* Special case for OMAP2 DPLL, register order is different due to
@@ -407,25 +411,22 @@
* missing idlest_mask.
*/
if (!dd->idlest_mask) {
- dd->mult_div1_reg = ti_clk_get_reg_addr(node, 1);
+ if (ti_clk_get_reg_addr(node, 1, &dd->mult_div1_reg))
+ goto cleanup;
#ifdef CONFIG_ARCH_OMAP2
clk_hw->ops = &clkhwops_omap2xxx_dpll;
omap2xxx_clkt_dpllcore_init(&clk_hw->hw);
#endif
} else {
- dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
- if (IS_ERR(dd->idlest_reg))
+ if (ti_clk_get_reg_addr(node, 1, &dd->idlest_reg))
goto cleanup;
- dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
+ if (ti_clk_get_reg_addr(node, 2, &dd->mult_div1_reg))
+ goto cleanup;
}
- if (IS_ERR(dd->control_reg) || IS_ERR(dd->mult_div1_reg))
- goto cleanup;
-
if (dd->autoidle_mask) {
- dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);
- if (IS_ERR(dd->autoidle_reg))
+ if (ti_clk_get_reg_addr(node, 3, &dd->autoidle_reg))
goto cleanup;
}
diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c
index 4cdd28a..4534de2 100644
--- a/drivers/clk/ti/dpll3xxx.c
+++ b/drivers/clk/ti/dpll3xxx.c
@@ -54,10 +54,10 @@
dd = clk->dpll_data;
- v = ti_clk_ll_ops->clk_readl(dd->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
v &= ~dd->enable_mask;
v |= clken_bits << __ffs(dd->enable_mask);
- ti_clk_ll_ops->clk_writel(v, dd->control_reg);
+ ti_clk_ll_ops->clk_writel(v, &dd->control_reg);
}
/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
@@ -73,7 +73,7 @@
state <<= __ffs(dd->idlest_mask);
- while (((ti_clk_ll_ops->clk_readl(dd->idlest_reg) & dd->idlest_mask)
+ while (((ti_clk_ll_ops->clk_readl(&dd->idlest_reg) & dd->idlest_mask)
!= state) && i < MAX_DPLL_WAIT_TRIES) {
i++;
udelay(1);
@@ -151,7 +151,7 @@
state <<= __ffs(dd->idlest_mask);
/* Check if already locked */
- if ((ti_clk_ll_ops->clk_readl(dd->idlest_reg) & dd->idlest_mask) ==
+ if ((ti_clk_ll_ops->clk_readl(&dd->idlest_reg) & dd->idlest_mask) ==
state)
goto done;
@@ -317,14 +317,14 @@
* only since freqsel field is no longer present on other devices.
*/
if (ti_clk_get_features()->flags & TI_CLK_DPLL_HAS_FREQSEL) {
- v = ti_clk_ll_ops->clk_readl(dd->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
v &= ~dd->freqsel_mask;
v |= freqsel << __ffs(dd->freqsel_mask);
- ti_clk_ll_ops->clk_writel(v, dd->control_reg);
+ ti_clk_ll_ops->clk_writel(v, &dd->control_reg);
}
/* Set DPLL multiplier, divider */
- v = ti_clk_ll_ops->clk_readl(dd->mult_div1_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg);
/* Handle Duty Cycle Correction */
if (dd->dcc_mask) {
@@ -370,11 +370,11 @@
}
}
- ti_clk_ll_ops->clk_writel(v, dd->mult_div1_reg);
+ ti_clk_ll_ops->clk_writel(v, &dd->mult_div1_reg);
/* Set 4X multiplier and low-power mode */
if (dd->m4xen_mask || dd->lpmode_mask) {
- v = ti_clk_ll_ops->clk_readl(dd->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
if (dd->m4xen_mask) {
if (dd->last_rounded_m4xen)
@@ -390,7 +390,7 @@
v &= ~dd->lpmode_mask;
}
- ti_clk_ll_ops->clk_writel(v, dd->control_reg);
+ ti_clk_ll_ops->clk_writel(v, &dd->control_reg);
}
/* We let the clock framework set the other output dividers later */
@@ -652,10 +652,10 @@
dd = clk->dpll_data;
- if (!dd->autoidle_reg)
+ if (!dd->autoidle_mask)
return -EINVAL;
- v = ti_clk_ll_ops->clk_readl(dd->autoidle_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->autoidle_reg);
v &= dd->autoidle_mask;
v >>= __ffs(dd->autoidle_mask);
@@ -681,7 +681,7 @@
dd = clk->dpll_data;
- if (!dd->autoidle_reg)
+ if (!dd->autoidle_mask)
return;
/*
@@ -689,10 +689,10 @@
* by writing 0x5 instead of 0x1. Add some mechanism to
* optionally enter this mode.
*/
- v = ti_clk_ll_ops->clk_readl(dd->autoidle_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->autoidle_reg);
v &= ~dd->autoidle_mask;
v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
- ti_clk_ll_ops->clk_writel(v, dd->autoidle_reg);
+ ti_clk_ll_ops->clk_writel(v, &dd->autoidle_reg);
}
/**
@@ -711,13 +711,13 @@
dd = clk->dpll_data;
- if (!dd->autoidle_reg)
+ if (!dd->autoidle_mask)
return;
- v = ti_clk_ll_ops->clk_readl(dd->autoidle_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->autoidle_reg);
v &= ~dd->autoidle_mask;
v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
- ti_clk_ll_ops->clk_writel(v, dd->autoidle_reg);
+ ti_clk_ll_ops->clk_writel(v, &dd->autoidle_reg);
}
/* Clock control for DPLL outputs */
@@ -773,7 +773,7 @@
WARN_ON(!dd->enable_mask);
- v = ti_clk_ll_ops->clk_readl(dd->control_reg) & dd->enable_mask;
+ v = ti_clk_ll_ops->clk_readl(&dd->control_reg) & dd->enable_mask;
v >>= __ffs(dd->enable_mask);
if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
rate = parent_rate;
diff --git a/drivers/clk/ti/dpll44xx.c b/drivers/clk/ti/dpll44xx.c
index 82c05b5..d7a3f7e 100644
--- a/drivers/clk/ti/dpll44xx.c
+++ b/drivers/clk/ti/dpll44xx.c
@@ -42,17 +42,17 @@
u32 v;
u32 mask;
- if (!clk || !clk->clksel_reg)
+ if (!clk)
return;
mask = clk->flags & CLOCK_CLKOUTX2 ?
OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
- v = ti_clk_ll_ops->clk_readl(clk->clksel_reg);
+ v = ti_clk_ll_ops->clk_readl(&clk->clksel_reg);
/* Clear the bit to allow gatectrl */
v &= ~mask;
- ti_clk_ll_ops->clk_writel(v, clk->clksel_reg);
+ ti_clk_ll_ops->clk_writel(v, &clk->clksel_reg);
}
static void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk)
@@ -60,17 +60,17 @@
u32 v;
u32 mask;
- if (!clk || !clk->clksel_reg)
+ if (!clk)
return;
mask = clk->flags & CLOCK_CLKOUTX2 ?
OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
- v = ti_clk_ll_ops->clk_readl(clk->clksel_reg);
+ v = ti_clk_ll_ops->clk_readl(&clk->clksel_reg);
/* Set the bit to deny gatectrl */
v |= mask;
- ti_clk_ll_ops->clk_writel(v, clk->clksel_reg);
+ ti_clk_ll_ops->clk_writel(v, &clk->clksel_reg);
}
const struct clk_hw_omap_ops clkhwops_omap4_dpllmx = {
@@ -128,7 +128,7 @@
rate = omap2_get_dpll_rate(clk);
/* regm4xen adds a multiplier of 4 to DPLL calculations */
- v = ti_clk_ll_ops->clk_readl(dd->control_reg);
+ v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
if (v & OMAP4430_DPLL_REGM4XEN_MASK)
rate *= OMAP4430_REGM4XEN_MULT;
diff --git a/drivers/clk/ti/fixed-factor.c b/drivers/clk/ti/fixed-factor.c
index 3cd4067..0174a51 100644
--- a/drivers/clk/ti/fixed-factor.c
+++ b/drivers/clk/ti/fixed-factor.c
@@ -62,6 +62,7 @@
if (!IS_ERR(clk)) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
of_ti_clk_autoidle_setup(node);
+ ti_clk_add_alias(NULL, clk, clk_name);
}
}
CLK_OF_DECLARE(ti_fixed_factor_clk, "ti,fixed-factor-clock",
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
index bc05f27..7151ec3 100644
--- a/drivers/clk/ti/gate.c
+++ b/drivers/clk/ti/gate.c
@@ -35,7 +35,7 @@
.disable = &omap2_clkops_disable_clkdm,
};
-static const struct clk_ops omap_gate_clk_ops = {
+const struct clk_ops omap_gate_clk_ops = {
.init = &omap2_init_clk_clkdm,
.enable = &omap2_dflt_clk_enable,
.disable = &omap2_dflt_clk_disable,
@@ -62,7 +62,7 @@
*/
static int omap36xx_gate_clk_enable_with_hsdiv_restore(struct clk_hw *hw)
{
- struct clk_divider *parent;
+ struct clk_omap_divider *parent;
struct clk_hw *parent_hw;
u32 dummy_v, orig_v;
int ret;
@@ -72,19 +72,19 @@
/* Parent is the x2 node, get parent of parent for the m2 div */
parent_hw = clk_hw_get_parent(clk_hw_get_parent(hw));
- parent = to_clk_divider(parent_hw);
+ parent = to_clk_omap_divider(parent_hw);
/* Restore the dividers */
if (!ret) {
- orig_v = ti_clk_ll_ops->clk_readl(parent->reg);
+ orig_v = ti_clk_ll_ops->clk_readl(&parent->reg);
dummy_v = orig_v;
/* Write any other value different from the Read value */
dummy_v ^= (1 << parent->shift);
- ti_clk_ll_ops->clk_writel(dummy_v, parent->reg);
+ ti_clk_ll_ops->clk_writel(dummy_v, &parent->reg);
/* Write the original divider */
- ti_clk_ll_ops->clk_writel(orig_v, parent->reg);
+ ti_clk_ll_ops->clk_writel(orig_v, &parent->reg);
}
return ret;
@@ -92,7 +92,7 @@
static struct clk *_register_gate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
- void __iomem *reg, u8 bit_idx,
+ struct clk_omap_reg *reg, u8 bit_idx,
u8 clk_gate_flags, const struct clk_ops *ops,
const struct clk_hw_omap_ops *hw_ops)
{
@@ -109,18 +109,18 @@
init.name = name;
init.ops = ops;
- clk_hw->enable_reg = reg;
+ memcpy(&clk_hw->enable_reg, reg, sizeof(*reg));
clk_hw->enable_bit = bit_idx;
clk_hw->ops = hw_ops;
- clk_hw->flags = MEMMAP_ADDRESSING | clk_gate_flags;
+ clk_hw->flags = clk_gate_flags;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = flags;
- clk = clk_register(NULL, &clk_hw->hw);
+ clk = ti_clk_register(NULL, &clk_hw->hw, name);
if (IS_ERR(clk))
kfree(clk_hw);
@@ -133,8 +133,7 @@
{
const struct clk_ops *ops = &omap_gate_clk_ops;
const struct clk_hw_omap_ops *hw_ops = NULL;
- u32 reg;
- struct clk_omap_reg *reg_setup;
+ struct clk_omap_reg reg;
u32 flags = 0;
u8 clk_gate_flags = 0;
struct ti_clk_gate *gate;
@@ -144,8 +143,6 @@
if (gate->flags & CLKF_INTERFACE)
return ti_clk_register_interface(setup);
- reg_setup = (struct clk_omap_reg *)®
-
if (gate->flags & CLKF_SET_RATE_PARENT)
flags |= CLK_SET_RATE_PARENT;
@@ -169,11 +166,12 @@
if (gate->flags & CLKF_AM35XX)
hw_ops = &clkhwops_am35xx_ipss_module_wait;
- reg_setup->index = gate->module;
- reg_setup->offset = gate->reg;
+ reg.index = gate->module;
+ reg.offset = gate->reg;
+ reg.ptr = NULL;
return _register_gate(NULL, setup->name, gate->parent, flags,
- (void __iomem *)reg, gate->bit_shift,
+ ®, gate->bit_shift,
clk_gate_flags, ops, hw_ops);
}
@@ -203,7 +201,6 @@
ops = &clkhwops_iclk_wait;
gate->ops = ops;
- gate->flags = MEMMAP_ADDRESSING;
return &gate->hw;
}
@@ -215,15 +212,14 @@
{
struct clk *clk;
const char *parent_name;
- void __iomem *reg = NULL;
+ struct clk_omap_reg reg;
u8 enable_bit = 0;
u32 val;
u32 flags = 0;
u8 clk_gate_flags = 0;
if (ops != &omap_gate_clkdm_clk_ops) {
- reg = ti_clk_get_reg_addr(node, 0);
- if (IS_ERR(reg))
+ if (ti_clk_get_reg_addr(node, 0, ®))
return;
if (!of_property_read_u32(node, "ti,bit-shift", &val))
@@ -243,7 +239,7 @@
if (of_property_read_bool(node, "ti,set-bit-to-disable"))
clk_gate_flags |= INVERT_ENABLE;
- clk = _register_gate(NULL, node->name, parent_name, flags, reg,
+ clk = _register_gate(NULL, node->name, parent_name, flags, ®,
enable_bit, clk_gate_flags, ops, hw_ops);
if (!IS_ERR(clk))
@@ -261,15 +257,13 @@
if (!gate)
return;
- gate->enable_reg = ti_clk_get_reg_addr(node, 0);
- if (IS_ERR(gate->enable_reg))
+ if (ti_clk_get_reg_addr(node, 0, &gate->enable_reg))
goto cleanup;
of_property_read_u32(node, "ti,bit-shift", &val);
gate->enable_bit = val;
gate->ops = hw_ops;
- gate->flags = MEMMAP_ADDRESSING;
if (!ti_clk_add_component(node, &gate->hw, CLK_COMPONENT_TYPE_GATE))
return;
diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
index e505e6f..62cf50c 100644
--- a/drivers/clk/ti/interface.c
+++ b/drivers/clk/ti/interface.c
@@ -34,7 +34,7 @@
static struct clk *_register_interface(struct device *dev, const char *name,
const char *parent_name,
- void __iomem *reg, u8 bit_idx,
+ struct clk_omap_reg *reg, u8 bit_idx,
const struct clk_hw_omap_ops *ops)
{
struct clk_init_data init = { NULL };
@@ -47,8 +47,7 @@
clk_hw->hw.init = &init;
clk_hw->ops = ops;
- clk_hw->flags = MEMMAP_ADDRESSING;
- clk_hw->enable_reg = reg;
+ memcpy(&clk_hw->enable_reg, reg, sizeof(*reg));
clk_hw->enable_bit = bit_idx;
init.name = name;
@@ -58,7 +57,7 @@
init.num_parents = 1;
init.parent_names = &parent_name;
- clk = clk_register(NULL, &clk_hw->hw);
+ clk = ti_clk_register(NULL, &clk_hw->hw, name);
if (IS_ERR(clk))
kfree(clk_hw);
@@ -72,14 +71,13 @@
struct clk *ti_clk_register_interface(struct ti_clk *setup)
{
const struct clk_hw_omap_ops *ops = &clkhwops_iclk_wait;
- u32 reg;
- struct clk_omap_reg *reg_setup;
+ struct clk_omap_reg reg;
struct ti_clk_gate *gate;
gate = setup->data;
- reg_setup = (struct clk_omap_reg *)®
- reg_setup->index = gate->module;
- reg_setup->offset = gate->reg;
+ reg.index = gate->module;
+ reg.offset = gate->reg;
+ reg.ptr = NULL;
if (gate->flags & CLKF_NO_WAIT)
ops = &clkhwops_iclk;
@@ -97,7 +95,7 @@
ops = &clkhwops_am35xx_ipss_wait;
return _register_interface(NULL, setup->name, gate->parent,
- (void __iomem *)reg, gate->bit_shift, ops);
+ ®, gate->bit_shift, ops);
}
#endif
@@ -106,12 +104,11 @@
{
struct clk *clk;
const char *parent_name;
- void __iomem *reg;
+ struct clk_omap_reg reg;
u8 enable_bit = 0;
u32 val;
- reg = ti_clk_get_reg_addr(node, 0);
- if (IS_ERR(reg))
+ if (ti_clk_get_reg_addr(node, 0, ®))
return;
if (!of_property_read_u32(node, "ti,bit-shift", &val))
@@ -123,7 +120,7 @@
return;
}
- clk = _register_interface(NULL, node->name, parent_name, reg,
+ clk = _register_interface(NULL, node->name, parent_name, ®,
enable_bit, ops);
if (!IS_ERR(clk))
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 44777ab..18c267b 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -28,7 +28,7 @@
static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
{
- struct clk_mux *mux = to_clk_mux(hw);
+ struct clk_omap_mux *mux = to_clk_omap_mux(hw);
int num_parents = clk_hw_get_num_parents(hw);
u32 val;
@@ -39,7 +39,7 @@
* OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
* val = 0x4 really means "bit 2, index starts at bit 0"
*/
- val = ti_clk_ll_ops->clk_readl(mux->reg) >> mux->shift;
+ val = ti_clk_ll_ops->clk_readl(&mux->reg) >> mux->shift;
val &= mux->mask;
if (mux->table) {
@@ -65,7 +65,7 @@
static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
{
- struct clk_mux *mux = to_clk_mux(hw);
+ struct clk_omap_mux *mux = to_clk_omap_mux(hw);
u32 val;
if (mux->table) {
@@ -81,11 +81,11 @@
if (mux->flags & CLK_MUX_HIWORD_MASK) {
val = mux->mask << (mux->shift + 16);
} else {
- val = ti_clk_ll_ops->clk_readl(mux->reg);
+ val = ti_clk_ll_ops->clk_readl(&mux->reg);
val &= ~(mux->mask << mux->shift);
}
val |= index << mux->shift;
- ti_clk_ll_ops->clk_writel(val, mux->reg);
+ ti_clk_ll_ops->clk_writel(val, &mux->reg);
return 0;
}
@@ -97,12 +97,12 @@
};
static struct clk *_register_mux(struct device *dev, const char *name,
- const char **parent_names, u8 num_parents,
- unsigned long flags, void __iomem *reg,
- u8 shift, u32 mask, u8 clk_mux_flags,
- u32 *table)
+ const char * const *parent_names,
+ u8 num_parents, unsigned long flags,
+ struct clk_omap_reg *reg, u8 shift, u32 mask,
+ u8 clk_mux_flags, u32 *table)
{
- struct clk_mux *mux;
+ struct clk_omap_mux *mux;
struct clk *clk;
struct clk_init_data init;
@@ -120,14 +120,14 @@
init.num_parents = num_parents;
/* struct clk_mux assignments */
- mux->reg = reg;
+ memcpy(&mux->reg, reg, sizeof(*reg));
mux->shift = shift;
mux->mask = mask;
mux->flags = clk_mux_flags;
mux->table = table;
mux->hw.init = &init;
- clk = clk_register(dev, &mux->hw);
+ clk = ti_clk_register(dev, &mux->hw, name);
if (IS_ERR(clk))
kfree(mux);
@@ -140,12 +140,9 @@
struct ti_clk_mux *mux;
u32 flags;
u8 mux_flags = 0;
- struct clk_omap_reg *reg_setup;
- u32 reg;
+ struct clk_omap_reg reg;
u32 mask;
- reg_setup = (struct clk_omap_reg *)®
-
mux = setup->data;
flags = CLK_SET_RATE_NO_REPARENT;
@@ -154,8 +151,9 @@
mask--;
mask = (1 << fls(mask)) - 1;
- reg_setup->index = mux->module;
- reg_setup->offset = mux->reg;
+ reg.index = mux->module;
+ reg.offset = mux->reg;
+ reg.ptr = NULL;
if (mux->flags & CLKF_INDEX_STARTS_AT_ONE)
mux_flags |= CLK_MUX_INDEX_ONE;
@@ -164,7 +162,7 @@
flags |= CLK_SET_RATE_PARENT;
return _register_mux(NULL, setup->name, mux->parents, mux->num_parents,
- flags, (void __iomem *)reg, mux->bit_shift, mask,
+ flags, ®, mux->bit_shift, mask,
mux_flags, NULL);
}
@@ -177,7 +175,7 @@
static void of_mux_clk_setup(struct device_node *node)
{
struct clk *clk;
- void __iomem *reg;
+ struct clk_omap_reg reg;
unsigned int num_parents;
const char **parent_names;
u8 clk_mux_flags = 0;
@@ -196,9 +194,7 @@
of_clk_parent_fill(node, parent_names, num_parents);
- reg = ti_clk_get_reg_addr(node, 0);
-
- if (IS_ERR(reg))
+ if (ti_clk_get_reg_addr(node, 0, ®))
goto cleanup;
of_property_read_u32(node, "ti,bit-shift", &shift);
@@ -217,7 +213,7 @@
mask = (1 << fls(mask)) - 1;
clk = _register_mux(NULL, node->name, parent_names, num_parents,
- flags, reg, shift, mask, clk_mux_flags, NULL);
+ flags, ®, shift, mask, clk_mux_flags, NULL);
if (!IS_ERR(clk))
of_clk_add_provider(node, of_clk_src_simple_get, clk);
@@ -229,8 +225,7 @@
struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup)
{
- struct clk_mux *mux;
- struct clk_omap_reg *reg;
+ struct clk_omap_mux *mux;
int num_parents;
if (!setup)
@@ -240,12 +235,10 @@
if (!mux)
return ERR_PTR(-ENOMEM);
- reg = (struct clk_omap_reg *)&mux->reg;
-
mux->shift = setup->bit_shift;
- reg->index = setup->module;
- reg->offset = setup->reg;
+ mux->reg.index = setup->module;
+ mux->reg.offset = setup->reg;
if (setup->flags & CLKF_INDEX_STARTS_AT_ONE)
mux->flags |= CLK_MUX_INDEX_ONE;
@@ -260,7 +253,7 @@
static void __init of_ti_composite_mux_clk_setup(struct device_node *node)
{
- struct clk_mux *mux;
+ struct clk_omap_mux *mux;
unsigned int num_parents;
u32 val;
@@ -268,9 +261,7 @@
if (!mux)
return;
- mux->reg = ti_clk_get_reg_addr(node, 0);
-
- if (IS_ERR(mux->reg))
+ if (ti_clk_get_reg_addr(node, 0, &mux->reg))
goto cleanup;
if (!of_property_read_u32(node, "ti,bit-shift", &val))
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 6110fe0..d18da83 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -19,6 +19,18 @@
#include <linux/clkdev.h>
/**
+ * struct clk_omap_reg - OMAP register declaration
+ * @offset: offset from the master IP module base address
+ * @index: index of the master IP module
+ */
+struct clk_omap_reg {
+ void __iomem *ptr;
+ u16 offset;
+ u8 index;
+ u8 flags;
+};
+
+/**
* struct dpll_data - DPLL registers and integration data
* @mult_div1_reg: register containing the DPLL M and N bitfields
* @mult_mask: mask of the DPLL M bitfield in @mult_div1_reg
@@ -67,12 +79,12 @@
* can be placed into read-only space.
*/
struct dpll_data {
- void __iomem *mult_div1_reg;
+ struct clk_omap_reg mult_div1_reg;
u32 mult_mask;
u32 div1_mask;
struct clk_hw *clk_bypass;
struct clk_hw *clk_ref;
- void __iomem *control_reg;
+ struct clk_omap_reg control_reg;
u32 enable_mask;
unsigned long last_rounded_rate;
u16 last_rounded_m;
@@ -84,8 +96,8 @@
u16 max_divider;
unsigned long max_rate;
u8 modes;
- void __iomem *autoidle_reg;
- void __iomem *idlest_reg;
+ struct clk_omap_reg autoidle_reg;
+ struct clk_omap_reg idlest_reg;
u32 autoidle_mask;
u32 freqsel_mask;
u32 idlest_mask;
@@ -113,10 +125,10 @@
*/
struct clk_hw_omap_ops {
void (*find_idlest)(struct clk_hw_omap *oclk,
- void __iomem **idlest_reg,
+ struct clk_omap_reg *idlest_reg,
u8 *idlest_bit, u8 *idlest_val);
void (*find_companion)(struct clk_hw_omap *oclk,
- void __iomem **other_reg,
+ struct clk_omap_reg *other_reg,
u8 *other_bit);
void (*allow_idle)(struct clk_hw_omap *oclk);
void (*deny_idle)(struct clk_hw_omap *oclk);
@@ -129,8 +141,6 @@
* @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
* @flags: see "struct clk.flags possibilities" above
* @clksel_reg: for clksel clks, register va containing src/divisor select
- * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
- * @clksel: for clksel clks, pointer to struct clksel for this clock
* @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
* @clkdm_name: clockdomain name that this clock is contained in
* @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
@@ -141,12 +151,10 @@
struct list_head node;
unsigned long fixed_rate;
u8 fixed_div;
- void __iomem *enable_reg;
+ struct clk_omap_reg enable_reg;
u8 enable_bit;
u8 flags;
- void __iomem *clksel_reg;
- u32 clksel_mask;
- const struct clksel *clksel;
+ struct clk_omap_reg clksel_reg;
struct dpll_data *dpll_data;
const char *clkdm_name;
struct clockdomain *clkdm;
@@ -172,7 +180,6 @@
* should be used. This is a temporary solution - a better approach
* would be to associate clock type-specific data with the clock,
* similar to the struct dpll_data approach.
- * MEMMAP_ADDRESSING: Use memmap addressing to access clock registers.
*/
#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */
#define CLOCK_IDLE_CONTROL (1 << 1)
@@ -180,7 +187,6 @@
#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */
#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */
#define CLOCK_CLKOUTX2 (1 << 5)
-#define MEMMAP_ADDRESSING (1 << 6)
/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */
#define DPLL_LOW_POWER_STOP 0x1
@@ -202,21 +208,12 @@
};
/**
- * struct clk_omap_reg - OMAP register declaration
- * @offset: offset from the master IP module base address
- * @index: index of the master IP module
- */
-struct clk_omap_reg {
- u16 offset;
- u16 index;
-};
-
-/**
* struct ti_clk_ll_ops - low-level ops for clocks
* @clk_readl: pointer to register read function
* @clk_writel: pointer to register write function
* @clkdm_clk_enable: pointer to clockdomain enable function
* @clkdm_clk_disable: pointer to clockdomain disable function
+ * @clkdm_lookup: pointer to clockdomain lookup function
* @cm_wait_module_ready: pointer to CM module wait ready function
* @cm_split_idlest_reg: pointer to CM module function to split idlest reg
*
@@ -227,20 +224,20 @@
* operations not provided directly by clock drivers.
*/
struct ti_clk_ll_ops {
- u32 (*clk_readl)(void __iomem *reg);
- void (*clk_writel)(u32 val, void __iomem *reg);
+ u32 (*clk_readl)(const struct clk_omap_reg *reg);
+ void (*clk_writel)(u32 val, const struct clk_omap_reg *reg);
int (*clkdm_clk_enable)(struct clockdomain *clkdm, struct clk *clk);
int (*clkdm_clk_disable)(struct clockdomain *clkdm,
struct clk *clk);
+ struct clockdomain * (*clkdm_lookup)(const char *name);
int (*cm_wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg,
u8 idlest_shift);
- int (*cm_split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
- u8 *idlest_reg_id);
+ int (*cm_split_idlest_reg)(struct clk_omap_reg *idlest_reg,
+ s16 *prcm_inst, u8 *idlest_reg_id);
};
#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
-void omap2_init_clk_clkdm(struct clk_hw *clk);
int omap2_clk_disable_autoidle_all(void);
int omap2_clk_enable_autoidle_all(void);
int omap2_clk_allow_idle(struct clk *clk);