summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mxs
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mxs')
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c34
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c57
-rw-r--r--arch/arm/mach-mxs/devices.c8
-rw-r--r--arch/arm/mach-mxs/devices/amba-duart.c2
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxs-mmc.c2
-rw-r--r--arch/arm/mach-mxs/include/mach/common.h2
-rw-r--r--arch/arm/mach-mxs/include/mach/system.h25
-rw-r--r--arch/arm/mach-mxs/pm.c3
-rw-r--r--arch/arm/mach-mxs/system.c16
9 files changed, 46 insertions, 103 deletions
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index e12e11231dc7..293958beb505 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -223,7 +223,6 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
{
u32 reg, bm_busy, div_max, d, f, div, frac;
unsigned long diff, parent_rate, calc_rate;
- int i;
parent_rate = clk_get_rate(clk->parent);
@@ -275,14 +274,7 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
- for (i = 10000; i; i--)
- if (!(__raw_readl(CLKCTRL_BASE_ADDR +
- HW_CLKCTRL_CPU) & bm_busy))
- break;
- if (!i) {
- pr_err("%s: divider writing timeout\n", __func__);
- return -ETIMEDOUT;
- }
+ mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy);
return 0;
}
@@ -292,7 +284,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
{ \
u32 reg, div_max, div; \
unsigned long parent_rate; \
- int i; \
\
parent_rate = clk_get_rate(clk->parent); \
div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
@@ -310,15 +301,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
} \
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
\
- for (i = 10000; i; i--) \
- if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
- HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
- break; \
- if (!i) { \
- pr_err("%s: divider writing timeout\n", __func__); \
- return -ETIMEDOUT; \
- } \
- \
+ mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY); \
return 0; \
}
@@ -461,7 +444,7 @@ static struct clk_lookup lookups[] = {
static int clk_misc_init(void)
{
u32 reg;
- int i;
+ int ret;
/* Fix up parent per register setting */
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
@@ -510,14 +493,7 @@ static int clk_misc_init(void)
reg |= 3 << BP_CLKCTRL_HBUS_DIV;
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
- for (i = 10000; i; i--)
- if (!(__raw_readl(CLKCTRL_BASE_ADDR +
- HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
- break;
- if (!i) {
- pr_err("%s: divider writing timeout\n", __func__);
- return -ETIMEDOUT;
- }
+ ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY);
/* Gate off cpu clock in WFI for power saving */
__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
@@ -532,7 +508,7 @@ static int clk_misc_init(void)
reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
- return 0;
+ return ret;
}
int __init mx23_clocks_init(void)
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 5d68e4152220..22ad12f6e4de 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -322,7 +322,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
{ \
u32 reg, bm_busy, div_max, d, f, div, frac; \
unsigned long diff, parent_rate, calc_rate; \
- int i; \
\
div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
bm_busy = BM_CLKCTRL_##dr##_BUSY; \
@@ -396,16 +395,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
} \
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
\
- for (i = 10000; i; i--) \
- if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
- HW_CLKCTRL_##dr) & bm_busy)) \
- break; \
- if (!i) { \
- pr_err("%s: divider writing timeout\n", __func__); \
- return -ETIMEDOUT; \
- } \
- \
- return 0; \
+ return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy); \
}
_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
@@ -421,7 +411,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
{ \
u32 reg, div_max, div; \
unsigned long parent_rate; \
- int i; \
\
parent_rate = clk_get_rate(clk->parent); \
div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
@@ -439,16 +428,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
} \
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
\
- for (i = 10000; i; i--) \
- if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
- HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
- break; \
- if (!i) { \
- pr_err("%s: divider writing timeout\n", __func__); \
- return -ETIMEDOUT; \
- } \
- \
- return 0; \
+ return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\
}
_CLK_SET_RATE1(xbus_clk, XBUS)
@@ -461,7 +441,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
u32 reg; \
u64 lrate; \
unsigned long parent_rate; \
- int i; \
\
parent_rate = clk_get_rate(clk->parent); \
if (rate > parent_rate) \
@@ -477,18 +456,13 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
reg &= ~BM_CLKCTRL_##rs##_DIV; \
reg |= div << BP_CLKCTRL_##rs##_DIV; \
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
- \
- for (i = 10000; i; i--) \
- if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
- HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY)) \
- break; \
- if (!i) { \
- pr_err("%s: divider writing timeout\n", __func__); \
- return -ETIMEDOUT; \
+ if (reg & (1 << clk->enable_shift)) { \
+ pr_err("%s: clock is gated\n", __func__); \
+ return -EINVAL; \
} \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
\
- return 0; \
+ return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\
}
_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
@@ -654,6 +628,8 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
+ _REGISTER_CLOCK("mxs-mmc.2", NULL, ssp2_clk)
+ _REGISTER_CLOCK("mxs-mmc.3", NULL, ssp3_clk)
_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -676,7 +652,7 @@ static struct clk_lookup lookups[] = {
static int clk_misc_init(void)
{
u32 reg;
- int i;
+ int ret;
/* Fix up parent per register setting */
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
@@ -756,14 +732,7 @@ static int clk_misc_init(void)
reg |= 3 << BP_CLKCTRL_HBUS_DIV;
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
- for (i = 10000; i; i--)
- if (!(__raw_readl(CLKCTRL_BASE_ADDR +
- HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
- break;
- if (!i) {
- pr_err("%s: divider writing timeout\n", __func__);
- return -ETIMEDOUT;
- }
+ ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY);
/* Gate off cpu clock in WFI for power saving */
__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
@@ -790,7 +759,7 @@ static int clk_misc_init(void)
reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
- return 0;
+ return ret;
}
int __init mx28_clocks_init(void)
@@ -803,6 +772,8 @@ int __init mx28_clocks_init(void)
*/
clk_set_parent(&ssp0_clk, &ref_io0_clk);
clk_set_parent(&ssp1_clk, &ref_io0_clk);
+ clk_set_parent(&ssp2_clk, &ref_io1_clk);
+ clk_set_parent(&ssp3_clk, &ref_io1_clk);
clk_prepare_enable(&cpu_clk);
clk_prepare_enable(&hbus_clk);
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
index fe3e847930c9..01faffec3064 100644
--- a/arch/arm/mach-mxs/devices.c
+++ b/arch/arm/mach-mxs/devices.c
@@ -77,16 +77,18 @@ err:
int __init mxs_add_amba_device(const struct amba_device *dev)
{
- struct amba_device *adev = kmalloc(sizeof(*adev), GFP_KERNEL);
+ struct amba_device *adev = amba_device_alloc(dev->dev.init_name,
+ dev->res.start, resource_size(&dev->res));
if (!adev) {
pr_err("%s: failed to allocate memory", __func__);
return -ENOMEM;
}
- *adev = *dev;
+ adev->irq[0] = dev->irq[0];
+ adev->irq[1] = dev->irq[1];
- return amba_device_register(adev, &iomem_resource);
+ return amba_device_add(adev, &iomem_resource);
}
struct device mxs_apbh_bus = {
diff --git a/arch/arm/mach-mxs/devices/amba-duart.c b/arch/arm/mach-mxs/devices/amba-duart.c
index a559db09b49c..a5479f766046 100644
--- a/arch/arm/mach-mxs/devices/amba-duart.c
+++ b/arch/arm/mach-mxs/devices/amba-duart.c
@@ -23,7 +23,7 @@ const struct amba_device name##_device __initconst = { \
.end = (soc ## _DUART_BASE_ADDR) + SZ_8K - 1, \
.flags = IORESOURCE_MEM, \
}, \
- .irq = {soc ## _INT_DUART, NO_IRQ}, \
+ .irq = {soc ## _INT_DUART}, \
}
#ifdef CONFIG_SOC_IMX23
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
index 382dacbeca21..bef9d923f54e 100644
--- a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
+++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
@@ -41,6 +41,8 @@ const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
mxs_mxs_mmc_data_entry(MX28, 0, 0),
mxs_mxs_mmc_data_entry(MX28, 1, 1),
+ mxs_mxs_mmc_data_entry(MX28, 2, 2),
+ mxs_mxs_mmc_data_entry(MX28, 3, 3),
};
#endif
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index e1237ab25862..c50c3ea28a9d 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -31,4 +31,6 @@ extern void mx28_init_irq(void);
extern void icoll_init_irq(void);
+extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask);
+
#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
deleted file mode 100644
index e7ad1bb29423..000000000000
--- a/arch/arm/mach-mxs/include/mach/system.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __MACH_MXS_SYSTEM_H__
-#define __MACH_MXS_SYSTEM_H__
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
index fb042da29bda..a9b4bbcdafb4 100644
--- a/arch/arm/mach-mxs/pm.c
+++ b/arch/arm/mach-mxs/pm.c
@@ -15,13 +15,12 @@
#include <linux/kernel.h>
#include <linux/suspend.h>
#include <linux/io.h>
-#include <mach/system.h>
static int mxs_suspend_enter(suspend_state_t state)
{
switch (state) {
case PM_SUSPEND_MEM:
- arch_idle();
+ cpu_do_idle();
break;
default:
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
index 54f91ad1c965..7aa5ac5d78bf 100644
--- a/arch/arm/mach-mxs/system.c
+++ b/arch/arm/mach-mxs/system.c
@@ -37,6 +37,8 @@
#define MXS_MODULE_CLKGATE (1 << 30)
#define MXS_MODULE_SFTRST (1 << 31)
+#define CLKCTRL_TIMEOUT 10 /* 10 ms */
+
static void __iomem *mxs_clkctrl_reset_addr;
/*
@@ -137,3 +139,17 @@ error:
return -ETIMEDOUT;
}
EXPORT_SYMBOL(mxs_reset_block);
+
+int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT);
+ while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR)
+ + reg_offset) & mask) {
+ if (time_after(jiffies, timeout)) {
+ pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset);
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
OpenPOWER on IntegriCloud