summaryrefslogtreecommitdiff
path: root/arch/arm/plat-mxs
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-mxs')
-rw-r--r--arch/arm/plat-mxs/Kconfig1
-rw-r--r--arch/arm/plat-mxs/Makefile2
-rw-r--r--arch/arm/plat-mxs/clock.c48
-rw-r--r--arch/arm/plat-mxs/cpufreq.c62
-rw-r--r--arch/arm/plat-mxs/device.c84
-rw-r--r--arch/arm/plat-mxs/dma-apbx.c3
-rw-r--r--arch/arm/plat-mxs/dmaengine.c14
-rw-r--r--arch/arm/plat-mxs/gpio.c2
-rw-r--r--arch/arm/plat-mxs/icoll.c6
-rw-r--r--arch/arm/plat-mxs/include/mach/bus_freq.h11
-rw-r--r--arch/arm/plat-mxs/include/mach/clock.h21
-rw-r--r--arch/arm/plat-mxs/include/mach/device.h62
-rw-r--r--arch/arm/plat-mxs/include/mach/dmaengine.h1
-rw-r--r--arch/arm/plat-mxs/include/mach/system.h1
-rw-r--r--arch/arm/plat-mxs/include/mach/timex.h2
-rw-r--r--arch/arm/plat-mxs/iram.c5
-rw-r--r--arch/arm/plat-mxs/timer-nomatch.c9
-rw-r--r--arch/arm/plat-mxs/usb_common.c21
-rw-r--r--arch/arm/plat-mxs/utmixc.c4
19 files changed, 260 insertions, 99 deletions
diff --git a/arch/arm/plat-mxs/Kconfig b/arch/arm/plat-mxs/Kconfig
index dd6689ecf5d0..63768f85a327 100644
--- a/arch/arm/plat-mxs/Kconfig
+++ b/arch/arm/plat-mxs/Kconfig
@@ -19,6 +19,7 @@ config ARCH_MX28
config ARCH_MX23
bool "Freescale MX23"
select CPU_ARM926T
+ select FIQ
select ZONE_DMA
select MXS_ICOLL
select MXS_DMA_ENGINE
diff --git a/arch/arm/plat-mxs/Makefile b/arch/arm/plat-mxs/Makefile
index 2c271285bdfd..e252630479d9 100644
--- a/arch/arm/plat-mxs/Makefile
+++ b/arch/arm/plat-mxs/Makefile
@@ -8,6 +8,8 @@ obj-$(CONFIG_MXS_TIMER_WITH_MACH) += timer-match.o
obj-$(CONFIG_IRAM_ALLOC) += iram.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+obj-$(CONFIG_MXS_UNIQUE_ID) += unique-id.o
+
obj-$(CONFIG_MXS_ICOLL) += icoll.o
obj-$(CONFIG_MXS_DMA_ENGINE) += dmaengine.o dma-apbh.o dma-apbx.o
diff --git a/arch/arm/plat-mxs/clock.c b/arch/arm/plat-mxs/clock.c
index 9fecdbde49ad..1b98b1e51164 100644
--- a/arch/arm/plat-mxs/clock.c
+++ b/arch/arm/plat-mxs/clock.c
@@ -29,6 +29,9 @@
#include <mach/clock.h>
extern int cpufreq_trig_needed;
+static bool (*mxs_enable_h_autoslow)(bool enable);
+static void (*mxs_set_h_autoslow_flags)(u16 flags);
+
static DEFINE_SPINLOCK(clockfw_lock);
/*
@@ -109,7 +112,11 @@ int clk_enable(struct clk *clk)
return -EINVAL;
spin_lock_irqsave(&clockfw_lock, flags);
- pre_usage = clk->ref;
+ pre_usage = (clk->ref & CLK_EN_MASK);
+
+ if (clk->set_sys_dependent_parent)
+ clk->set_sys_dependent_parent(clk);
+
ret = __clk_enable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
@@ -133,7 +140,7 @@ void clk_disable(struct clk *clk)
__clk_disable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
- && (clk->ref == 0)) {
+ && ((clk->ref & CLK_EN_MASK) == 0)) {
cpufreq_trig_needed = 1;
cpufreq_update_policy(0);
}
@@ -279,3 +286,40 @@ void clk_unregister(struct clk_lookup *lookup)
lookup->clk->get_rate = NULL;
}
EXPORT_SYMBOL(clk_unregister);
+
+bool clk_enable_h_autoslow(bool enable)
+{
+ unsigned long flags;
+ bool ret = false;
+
+ if (mxs_enable_h_autoslow == NULL)
+ return ret;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = mxs_enable_h_autoslow(enable);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable_h_autoslow);
+
+void clk_set_h_autoslow_flags(u16 mask)
+{
+ unsigned long flags;
+
+ if (mxs_set_h_autoslow_flags == NULL)
+ return;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ mxs_set_h_autoslow_flags(mask);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+}
+EXPORT_SYMBOL(clk_set_h_autoslow_flags);
+
+void clk_en_public_h_asm_ctrl(bool (*enable_func)(bool),
+ void (*set_func)(u16))
+{
+ mxs_enable_h_autoslow = enable_func;
+ mxs_set_h_autoslow_flags = set_func;
+}
+EXPORT_SYMBOL(clk_en_public_h_asm_ctrl);
diff --git a/arch/arm/plat-mxs/cpufreq.c b/arch/arm/plat-mxs/cpufreq.c
index d36baa740dbc..a188b21d9bf4 100644
--- a/arch/arm/plat-mxs/cpufreq.c
+++ b/arch/arm/plat-mxs/cpufreq.c
@@ -40,6 +40,7 @@
static struct regulator *cpu_regulator;
static struct clk *cpu_clk;
static struct clk *ahb_clk;
+static struct clk *x_clk;
static struct clk *emi_clk;
static struct regulator *vddd;
static struct regulator *vdddbo;
@@ -62,11 +63,19 @@ static int set_freq_table(struct cpufreq_policy *policy, int end_index)
{
int ret = 0;
int i;
+ int zero_no = 0;
+
+ for (i = 0; i < end_index; i++) {
+ if (profiles[i].cpu == 0)
+ zero_no++;
+ }
+
+ end_index -= zero_no;
cpu_freq_khz_min = profiles[0].cpu;
cpu_freq_khz_max = profiles[0].cpu;
for (i = 0; i < end_index; i++) {
- imx_freq_table[end_index - 1 - i].index = end_index - i;
+ imx_freq_table[end_index - 1 - i].index = end_index - i;
imx_freq_table[end_index - 1 - i].frequency =
profiles[i].cpu;
@@ -135,8 +144,6 @@ static int set_op(struct cpufreq_policy *policy, unsigned int target_freq)
return 0;
}
- cpu_clk_set_pll_on(cpu_clk, freqs.new);
-
if (cpu_regulator && (freqs.old < freqs.new)) {
ret = regulator_set_current_limit(cpu_regulator,
profiles[i].cur, profiles[i].cur);
@@ -149,10 +156,16 @@ static int set_op(struct cpufreq_policy *policy, unsigned int target_freq)
if (freqs.old > freqs.new) {
int ss = profiles[i].ss;
+ /* change emi while cpu is fastest to minimize
+ * time spent changing emiclk
+ */
+ clk_set_rate(emi_clk, (profiles[i].emi) * 1000);
clk_set_rate(cpu_clk, (profiles[i].cpu) * 1000);
clk_set_rate(ahb_clk, (profiles[i].ahb) * 1000);
- clk_set_rate(emi_clk, (profiles[i].emi) * 1000);
+ /* x_clk order doesn't really matter */
+ clk_set_rate(x_clk, (profiles[i].xbus) * 1000);
timing_ctrl_rams(ss);
+
if (vddd && vdddbo && vddio && vdda) {
ret = regulator_set_voltage(vddd,
profiles[i].vddd,
@@ -208,17 +221,18 @@ static int set_op(struct cpufreq_policy *policy, unsigned int target_freq)
profiles[i].vdda,
profiles[i].vdda);
}
+ /* x_clk order doesn't really matter */
+ clk_set_rate(x_clk, (profiles[i].xbus) * 1000);
timing_ctrl_rams(ss);
- if (freqs.old == 64000)
- clk_set_rate(ahb_clk, (profiles[i].ahb) * 1000);
clk_set_rate(cpu_clk, (profiles[i].cpu) * 1000);
- if (freqs.old != 64000)
- clk_set_rate(ahb_clk, (profiles[i].ahb) * 1000);
+ clk_set_rate(ahb_clk, (profiles[i].ahb) * 1000);
clk_set_rate(emi_clk, (profiles[i].emi) * 1000);
}
- udelay(100);
- cpu_clk_set_pll_off(cpu_clk, freqs.new);
+ if (is_hclk_autoslow_ok())
+ clk_set_h_autoslow_flags(profiles[i].h_autoslow_flags);
+ else
+ clk_enable_h_autoslow(false);
if (high_freq_needed == 0)
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
@@ -231,7 +245,6 @@ static int set_op(struct cpufreq_policy *policy, unsigned int target_freq)
if (high_freq_needed == 1) {
high_freq_needed = 0;
cur_freq_table_size = lcd_on_freq_table_size;
- hbus_auto_slow_mode_disable();
set_freq_table(policy, cur_freq_table_size);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
@@ -293,11 +306,22 @@ static int mxs_target(struct cpufreq_policy *policy,
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
low_freq_bus_ready = low_freq_used();
if (low_freq_bus_ready) {
+ int i;
cur_freq_table_size = lcd_off_freq_table_size;
- hbus_auto_slow_mode_enable();
+ /* find current table index to get
+ * hbus autoslow flags and enable hbus autoslow.
+ */
+ for (i = cur_freq_table_size - 1; i > 0; i--) {
+ if (profiles[i].cpu <= target_freq &&
+ target_freq < profiles[i - 1].cpu) {
+ clk_set_h_autoslow_flags(
+ profiles[i].h_autoslow_flags);
+ break;
+ }
+ }
} else {
cur_freq_table_size = lcd_on_freq_table_size;
- hbus_auto_slow_mode_disable();
+ clk_enable_h_autoslow(false);
}
set_freq_table(policy, cur_freq_table_size);
@@ -354,6 +378,12 @@ static int __init mxs_cpu_init(struct cpufreq_policy *policy)
goto out_ahb;
}
+ x_clk = clk_get(NULL, "x");
+ if (IS_ERR(ahb_clk)) {
+ ret = PTR_ERR(x_clk);
+ goto out_x;
+ }
+
emi_clk = clk_get(NULL, "emi");
if (IS_ERR(emi_clk)) {
ret = PTR_ERR(emi_clk);
@@ -419,13 +449,13 @@ static int __init mxs_cpu_init(struct cpufreq_policy *policy)
for (i = 0; i < ARRAY_SIZE(profiles); i++) {
if ((profiles[i].cpu) == 0) {
- lcd_off_freq_table_size = i + 1;
+ lcd_off_freq_table_size = i;
break;
}
}
if (i == ARRAY_SIZE(profiles))
- lcd_off_freq_table_size = i + 1;
+ lcd_off_freq_table_size = i;
/* Set the current working point. */
set_freq_table(policy, lcd_on_freq_table_size);
@@ -447,6 +477,8 @@ out_cur:
clk_put(emi_clk);
out_emi:
+ clk_put(x_clk);
+out_x:
clk_put(ahb_clk);
out_ahb:
clk_put(cpu_clk);
diff --git a/arch/arm/plat-mxs/device.c b/arch/arm/plat-mxs/device.c
index 00180846885b..e3783d3fe87d 100644
--- a/arch/arm/plat-mxs/device.c
+++ b/arch/arm/plat-mxs/device.c
@@ -24,6 +24,7 @@
#include <linux/bitops.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/gpmi-nfc.h>
#include <mach/device.h>
@@ -138,10 +139,10 @@ static struct platform_device mxs_i2c[] = {
};
#endif
-#if defined(CONFIG_MTD_NAND_GPMI1) || \
- defined(CONFIG_MTD_NAND_GPMI1_MODULE)
-static struct platform_device mxs_gpmi = {
- .name = "gpmi",
+#if defined(CONFIG_MTD_NAND_GPMI_NFC) || \
+ defined(CONFIG_MTD_NAND_GPMI_NFC_MODULE)
+static struct platform_device gpmi_nfc = {
+ .name = GPMI_NFC_DRIVER_NAME,
.id = 0,
.dev = {
.dma_mask = &common_dmamask,
@@ -175,6 +176,20 @@ static struct platform_device mxs_mmc[] = {
};
#endif
+#if defined(CONFIG_SPI_MXS) || defined(CONFIG_SPI_MXS_MODULE)
+static struct platform_device mxs_spi[] = {
+ {
+ .name = "mxs-spi",
+ .id = 0,
+ .dev = {
+ .dma_mask = &common_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .release = mxs_nop_release,
+ },
+ },
+};
+#endif
+
#if defined(CONFIG_MXS_WATCHDOG) || defined(CONFIG_MXS_WATCHDOG_MODULE)
static struct platform_device mxs_wdt = {
.name = "mxs-wdt",
@@ -195,6 +210,25 @@ static struct platform_device mxs_fec[] = {
.release = mxs_nop_release,
},
},
+ {
+ .name = "fec",
+ .id = 1,
+ .dev = {
+ .release = mxs_nop_release,
+ },
+ },
+};
+#endif
+
+#if defined(CONFIG_FEC_L2SWITCH)
+static struct platform_device mxs_l2switch[] = {
+ {
+ .name = "mxs-l2switch",
+ .id = 0,
+ .dev = {
+ .release = mxs_nop_release,
+ },
+ },
};
#endif
@@ -451,6 +485,16 @@ static struct platform_device mxs_persistent = {
};
#endif
+#ifdef CONFIG_FSL_OTP
+static struct platform_device otp_device = {
+ .name = "ocotp",
+ .id = 0,
+ .dev = {
+ .release = mxs_nop_release,
+ },
+};
+#endif
+
static inline void mxs_init_busfreq(void)
{
(void)platform_device_register(&busfreq_device);
@@ -482,12 +526,12 @@ static struct mxs_dev_lookup dev_lookup[] = {
},
#endif
-#if defined(CONFIG_MTD_NAND_GPMI1) || \
- defined(CONFIG_MTD_NAND_GPMI1_MODULE)
+#if defined(CONFIG_MTD_NAND_GPMI_NFC) || \
+ defined(CONFIG_MTD_NAND_GPMI_NFC_MODULE)
{
- .name = "gpmi",
+ .name = GPMI_NFC_DRIVER_NAME,
.size = 1,
- .pdev = &mxs_gpmi,
+ .pdev = &gpmi_nfc,
},
#endif
@@ -500,6 +544,14 @@ static struct mxs_dev_lookup dev_lookup[] = {
},
#endif
+#if defined(CONFIG_SPI_MXS) || defined(CONFIG_SPI_MXS_MODULE)
+ {
+ .name = "mxs-spi",
+ .size = ARRAY_SIZE(mxs_spi),
+ .pdev = mxs_spi,
+ },
+#endif
+
#if defined(CONFIG_MXS_WATCHDOG) || defined(CONFIG_MXS_WATCHDOG_MODULE)
{
.name = "mxs-wdt",
@@ -524,6 +576,14 @@ static struct mxs_dev_lookup dev_lookup[] = {
},
#endif
+#if defined(CONFIG_FSL_OTP)
+ {
+ .name = "ocotp",
+ .size = 1,
+ .pdev = &otp_device,
+ },
+#endif
+
#if defined(CONFIG_FB_MXS) || defined(CONFIG_FB_MXS_MODULE)
{
.name = "mxs-fb",
@@ -565,6 +625,14 @@ static struct mxs_dev_lookup dev_lookup[] = {
},
#endif
+#if defined(CONFIG_FEC_L2SWITCH)
+ {
+ .name = "mxs-l2switch",
+ .size = ARRAY_SIZE(mxs_l2switch),
+ .pdev = mxs_l2switch,
+ },
+#endif
+
#ifdef CONFIG_MXS_LRADC
{
.name = "mxs-lradc",
diff --git a/arch/arm/plat-mxs/dma-apbx.c b/arch/arm/plat-mxs/dma-apbx.c
index c27414f8c18d..6d77a6933d98 100644
--- a/arch/arm/plat-mxs/dma-apbx.c
+++ b/arch/arm/plat-mxs/dma-apbx.c
@@ -99,6 +99,9 @@ static void mxs_dma_apbx_info(struct mxs_dma_device *pdev,
reg = __raw_readl(pdev->base + HW_APBX_CTRL2);
info->status = reg >> chan;
info->buf_addr = __raw_readl(pdev->base + HW_APBX_CHn_BAR(chan));
+ reg = __raw_readl(pdev->base + HW_APBX_CHn_CMD(chan));
+ info->xfer_count = (reg & BM_APBX_CHn_CMD_XFER_COUNT) >> \
+ BP_APBX_CHn_CMD_XFER_COUNT;
}
static int
diff --git a/arch/arm/plat-mxs/dmaengine.c b/arch/arm/plat-mxs/dmaengine.c
index 453346e4057f..0c2485b18506 100644
--- a/arch/arm/plat-mxs/dmaengine.c
+++ b/arch/arm/plat-mxs/dmaengine.c
@@ -127,14 +127,16 @@ int mxs_dma_enable(int channel)
if (!(pchan->flags & MXS_DMA_FLAGS_ALLOCATED))
return -EINVAL;
+ /*
+ * neednot mutex lock, this function will be called in irq context.
+ * The mutex may cause process schedule.
+ */
pdma = pchan->dma;
- mutex_lock(&mxs_dma_mutex);
spin_lock_irqsave(&pchan->lock, flags);
if (pchan->pending_num && pdma->enable)
ret = pdma->enable(pchan, channel - pdma->chan_base);
pchan->flags |= MXS_DMA_FLAGS_BUSY;
spin_unlock_irqrestore(&pchan->lock, flags);
- mutex_unlock(&mxs_dma_mutex);
return ret;
}
EXPORT_SYMBOL(mxs_dma_enable);
@@ -151,17 +153,19 @@ void mxs_dma_disable(int channel)
return;
if (!(pchan->flags & MXS_DMA_FLAGS_BUSY))
return;
+ /*
+ * neednot mutex lock, this function will be called in irq context.
+ * The mutex may cause process schedule.
+ */
pdma = pchan->dma;
- mutex_lock(&mxs_dma_mutex);
spin_lock_irqsave(&pchan->lock, flags);
if (pdma->disable)
pdma->disable(pchan, channel - pdma->chan_base);
pchan->flags &= ~MXS_DMA_FLAGS_BUSY;
pchan->active_num = 0;
pchan->pending_num = 0;
- list_splice(&pchan->active, &pchan->done);
+ list_splice_init(&pchan->active, &pchan->done);
spin_unlock_irqrestore(&pchan->lock, flags);
- mutex_unlock(&mxs_dma_mutex);
}
EXPORT_SYMBOL(mxs_dma_disable);
diff --git a/arch/arm/plat-mxs/gpio.c b/arch/arm/plat-mxs/gpio.c
index f12d417b03e9..6c67c2bcfc5b 100644
--- a/arch/arm/plat-mxs/gpio.c
+++ b/arch/arm/plat-mxs/gpio.c
@@ -175,6 +175,8 @@ static struct irq_chip gpio_irq_chip = {
.ack = mxs_gpio_ack_irq,
.mask = mxs_gpio_mask_irq,
.unmask = mxs_gpio_unmask_irq,
+ .enable = mxs_gpio_unmask_irq,
+ .disable = mxs_gpio_mask_irq,
.set_type = mxs_gpio_set_irq_type,
};
diff --git a/arch/arm/plat-mxs/icoll.c b/arch/arm/plat-mxs/icoll.c
index bb4e4c12cb23..1e0b55bd26a9 100644
--- a/arch/arm/plat-mxs/icoll.c
+++ b/arch/arm/plat-mxs/icoll.c
@@ -56,10 +56,16 @@ static void icoll_unmask_irq(unsigned int irq)
g_icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
}
+static int icoll_set_wake_irq(unsigned int irq, unsigned int enabled)
+{
+ return 0;
+}
+
static struct irq_chip icoll_chip = {
.ack = icoll_ack_irq,
.mask = icoll_mask_irq,
.unmask = icoll_unmask_irq,
+ .set_wake = icoll_set_wake_irq,
};
void __init avic_init_irq(void __iomem *base, int nr_irqs)
diff --git a/arch/arm/plat-mxs/include/mach/bus_freq.h b/arch/arm/plat-mxs/include/mach/bus_freq.h
index a0254e84ca5c..0c41cd2205ff 100644
--- a/arch/arm/plat-mxs/include/mach/bus_freq.h
+++ b/arch/arm/plat-mxs/include/mach/bus_freq.h
@@ -33,13 +33,14 @@ struct profile {
int cur;
int vddio;
int vdda;
- int pll_off;
+ u16 xbus;
+ /* map of the upper 16 bits of HW_CLKCTRL_HBUS register */
+ u16 h_autoslow_flags;
};
-void hbus_auto_slow_mode_enable(void);
-void hbus_auto_slow_mode_disable(void);
-extern int cpu_clk_set_pll_on(struct clk *clk, unsigned int freq);
-extern int cpu_clk_set_pll_off(struct clk *clk, unsigned int freq);
+/* map of the upper 16 bits of HW_CLKCTRL_HBUS register */
+int is_hclk_autoslow_ok(void);
+
extern int timing_ctrl_rams(int ss);
#endif
diff --git a/arch/arm/plat-mxs/include/mach/clock.h b/arch/arm/plat-mxs/include/mach/clock.h
index 744a031b42b6..b506468976b5 100644
--- a/arch/arm/plat-mxs/include/mach/clock.h
+++ b/arch/arm/plat-mxs/include/mach/clock.h
@@ -30,11 +30,12 @@ struct clk {
struct clk *secondary;
unsigned long flags;
- __s8 ref;
+ int ref;
unsigned int scale_bits;
unsigned int enable_bits;
unsigned int bypass_bits;
unsigned int busy_bits;
+ unsigned int xtal_busy_bits;
unsigned int wait:1;
unsigned int invert:1;
@@ -71,16 +72,24 @@ struct clk {
void (*disable) (struct clk *);
/* Function ptr to set the parent clock of the clock. */
int (*set_parent) (struct clk *, struct clk *);
+
+ /* Function ptr to change the parent clock depending
+ * the system configuration at that time. Will only
+ * change the parent clock if the ref count is 0 (the clock
+ * is not being used)
+ */
+ int (*set_sys_dependent_parent) (struct clk *);
+
};
int clk_get_usecount(struct clk *clk);
extern int clk_register(struct clk_lookup *lookup);
extern void clk_unregister(struct clk_lookup *lookup);
-static inline int clk_is_busy(struct clk *clk)
-{
- return __raw_readl(clk->busy_reg) & (1 << clk->busy_bits);
-}
+bool clk_enable_h_autoslow(bool enable);
+void clk_set_h_autoslow_flags(u16 mask);
+void clk_en_public_h_asm_ctrl(bool (*enable_func)(bool),
+ void (*set_func)(u16));
struct mxs_emi_scaling_data {
u32 emi_div;
@@ -89,6 +98,8 @@ struct mxs_emi_scaling_data {
u32 new_freq;
};
+
+
#ifdef CONFIG_MXS_RAM_FREQ_SCALING
extern int mxs_ram_freq_scale(struct mxs_emi_scaling_data *);
extern u32 mxs_ram_funcs_sz;
diff --git a/arch/arm/plat-mxs/include/mach/device.h b/arch/arm/plat-mxs/include/mach/device.h
index 7a99647ed0ff..199ec1e62963 100644
--- a/arch/arm/plat-mxs/include/mach/device.h
+++ b/arch/arm/plat-mxs/include/mach/device.h
@@ -54,6 +54,12 @@ struct mxs_dma_plat_data {
unsigned int chan_num;
};
+struct fsl_otp_data {
+ char **fuse_name;
+ char *regulator_name;
+ unsigned int fuse_num;
+};
+
struct mxs_i2c_plat_data {
unsigned int pioqueue_mode:1;
};
@@ -119,6 +125,11 @@ struct mxs_mma7450_platform_data {
int int2;
};
+struct mxs_spi_platform_data {
+ int (*hw_pin_init)(void);
+ int (*hw_pin_release)(void);
+};
+
struct flexcan_platform_data {
char *core_reg;
char *io_reg;
@@ -169,57 +180,6 @@ struct mxs_audio_platform_data {
void *priv; /* used by board specific functions */
};
-/**
- * struct gpmi_platform_data - GPMI driver platform data.
- *
- * This structure communicates platform-specific information to the GPMI driver
- * that can't be expressed as resources.
- *
- * @io_uA: The current limit, in uA.
- * @min_prop_delay_in_ns: Minimum propagation delay of GPMI signals to and
- * from the NAND Flash device, in nanoseconds.
- * @max_prop_delay_in_ns: Maximum propagation delay of GPMI signals to and
- * from the NAND Flash device, in nanoseconds.
- * @pinmux_handler: A pointer to a function the driver will call to
- * request the pins it needs.
- * @boot_area_size_in_bytes: The amount of space reserved for use by the boot
- * ROM on the first and second chips. If this value is
- * zero, it indicates we're not reserving any space
- * for the boot area.
- * @partition_source_types: An array of strings that name sources of
- * partitioning information (e.g., the boot loader,
- * the kernel command line, etc.). The function
- * parse_mtd_partitions() recognizes these names and
- * applies the appropriate "plugins" to discover
- * partitioning information. If any is found, it will
- * be applied to the "general use" MTD (it will NOT
- * override the boot area protection mechanism).
- * @partitions: An optional pointer to an array of partition
- * descriptions. If the driver finds no partitioning
- * information elsewhere, it will apply these to the
- * "general use" MTD (they do NOT override the boot
- * area protection mechanism).
- * @partition_count: The number of elements in the partitions array.
- */
-
-struct gpmi_platform_data {
-
- int io_uA;
-
- unsigned min_prop_delay_in_ns;
- unsigned max_prop_delay_in_ns;
-
- int (*pinmux_handler)(void);
-
- uint32_t boot_area_size_in_bytes;
-
- const char **partition_source_types;
-
- struct mtd_partition *partitions;
- unsigned partition_count;
-
-};
-
struct mxs_persistent_bit_config {
int reg;
int start;
diff --git a/arch/arm/plat-mxs/include/mach/dmaengine.h b/arch/arm/plat-mxs/include/mach/dmaengine.h
index eecd260ac5b4..cdf6b1e32a43 100644
--- a/arch/arm/plat-mxs/include/mach/dmaengine.h
+++ b/arch/arm/plat-mxs/include/mach/dmaengine.h
@@ -106,6 +106,7 @@ struct mxs_dma_info {
#define MXS_DMA_INFO_ERR 0x00000001
#define MXS_DMA_INFO_ERR_STAT 0x00010000
unsigned int buf_addr;
+ unsigned int xfer_count;
};
/**
diff --git a/arch/arm/plat-mxs/include/mach/system.h b/arch/arm/plat-mxs/include/mach/system.h
index 63604de8d74a..faaa2ff3cf13 100644
--- a/arch/arm/plat-mxs/include/mach/system.h
+++ b/arch/arm/plat-mxs/include/mach/system.h
@@ -25,5 +25,6 @@ extern void arch_idle(void);
void arch_reset(char mode, const char *cmd);
extern void (*machine_arch_reset)(char mode, const char *cmd);
int mxs_reset_block(void __iomem *hwreg, int just_enable);
+int get_evk_board_version(void);
#endif /* __ASM_ARCH_SYSTEM_H__ */
diff --git a/arch/arm/plat-mxs/include/mach/timex.h b/arch/arm/plat-mxs/include/mach/timex.h
index 9db3d688223a..d622dda141f2 100644
--- a/arch/arm/plat-mxs/include/mach/timex.h
+++ b/arch/arm/plat-mxs/include/mach/timex.h
@@ -20,4 +20,4 @@
/*
* System time clock is sourced from the 32k clock
*/
-#define CLOCK_TICK_RATE 32768
+#define CLOCK_TICK_RATE 32000
diff --git a/arch/arm/plat-mxs/iram.c b/arch/arm/plat-mxs/iram.c
index 3d2a391bd2d1..c63b0a2a9a10 100644
--- a/arch/arm/plat-mxs/iram.c
+++ b/arch/arm/plat-mxs/iram.c
@@ -36,6 +36,11 @@ void *iram_alloc(unsigned int size, unsigned long *dma_addr)
*dma_addr = gen_pool_alloc(iram_pool, size);
pr_debug("iram alloc - %dB@0x%p\n", size, (void *)*dma_addr);
+
+ WARN_ON(!*dma_addr);
+ if (!*dma_addr)
+ return NULL;
+
return iram_phys_to_virt(*dma_addr);
}
EXPORT_SYMBOL(iram_alloc);
diff --git a/arch/arm/plat-mxs/timer-nomatch.c b/arch/arm/plat-mxs/timer-nomatch.c
index 66c488c99b42..db8906192f16 100644
--- a/arch/arm/plat-mxs/timer-nomatch.c
+++ b/arch/arm/plat-mxs/timer-nomatch.c
@@ -21,6 +21,7 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/io.h>
+#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
@@ -119,9 +120,9 @@ void mxs_nomatch_timer_init(struct mxs_sys_timer *timer)
online_timer = timer;
- cksrc_mxs_nomatch.mult = clocksource_hz2mult(CLOCK_TICK_RATE,
+ cksrc_mxs_nomatch.mult = clocksource_hz2mult(clk_get_rate(timer->clk),
cksrc_mxs_nomatch.shift);
- ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
+ ckevt_timrot.mult = div_sc(clk_get_rate(timer->clk), NSEC_PER_SEC,
ckevt_timrot.shift);
ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot);
ckevt_timrot.max_delta_ns = clockevent_delta2ns(0xFFF, &ckevt_timrot);
@@ -145,7 +146,7 @@ void mxs_nomatch_timer_init(struct mxs_sys_timer *timer)
BM_TIMROT_TIMCTRLn_IRQ_EN,
online_timer->base + HW_TIMROT_TIMCTRLn(1));
- __raw_writel(CLOCK_TICK_RATE / HZ - 1,
+ __raw_writel(clk_get_rate(timer->clk) / HZ - 1,
online_timer->base + HW_TIMROT_TIMCOUNTn(0));
__raw_writel(0xFFFF, online_timer->base + HW_TIMROT_TIMCOUNTn(1));
@@ -181,7 +182,7 @@ void mxs_nomatch_resume_timer(void)
BM_TIMROT_TIMCTRLn_UPDATE |
BM_TIMROT_TIMCTRLn_IRQ_EN,
online_timer->base + HW_TIMROT_TIMCTRLn(1));
- __raw_writel(CLOCK_TICK_RATE / HZ - 1,
+ __raw_writel(clk_get_rate(online_timer->clk) / HZ - 1,
online_timer->base + HW_TIMROT_TIMCOUNTn(0));
__raw_writel(0xFFFF, online_timer->base + HW_TIMROT_TIMCOUNTn(1));
}
diff --git a/arch/arm/plat-mxs/usb_common.c b/arch/arm/plat-mxs/usb_common.c
index 5d8d0b6d9285..23134489472e 100644
--- a/arch/arm/plat-mxs/usb_common.c
+++ b/arch/arm/plat-mxs/usb_common.c
@@ -264,13 +264,16 @@ int usbotg_init(struct platform_device *pdev)
pdata->xcvr_type = xops->xcvr_type;
pdata->pdev = pdev;
- otg_used = 0;
if (!otg_used) {
pr_debug("%s: grab pins\n", __func__);
if (xops->init)
xops->init(xops);
usb_phy_enable(pdata);
}
+ /* Enable internal Phy clock */
+ tmp = __raw_readl(pdata->regs + UOG_PORTSC1);
+ tmp &= ~PORTSC_PHCD;
+ __raw_writel(tmp, pdata->regs + UOG_PORTSC1);
if (pdata->operating_mode == FSL_USB2_DR_HOST) {
/* enable FS/LS device */
@@ -288,11 +291,22 @@ EXPORT_SYMBOL(usbotg_init);
void usbotg_uninit(struct fsl_usb2_platform_data *pdata)
{
+ int tmp;
+ struct clk *usb_clk;
pr_debug("%s\n", __func__);
if (pdata->xcvr_ops && pdata->xcvr_ops->uninit)
pdata->xcvr_ops->uninit(pdata->xcvr_ops);
+ /* Disable internal Phy clock */
+ tmp = __raw_readl(pdata->regs + UOG_PORTSC1);
+ tmp |= PORTSC_PHCD;
+ __raw_writel(tmp, pdata->regs + UOG_PORTSC1);
+
+ usb_clk = clk_get(NULL, "usb_clk0");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
pdata->regs = NULL;
otg_used--;
}
@@ -331,11 +345,16 @@ EXPORT_SYMBOL(fsl_usb_host_init);
void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata)
{
+ struct clk *usb_clk;
pr_debug("%s\n", __func__);
if (pdata->xcvr_ops && pdata->xcvr_ops->uninit)
pdata->xcvr_ops->uninit(pdata->xcvr_ops);
+ usb_clk = clk_get(NULL, "usb_clk1");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
pdata->regs = NULL;
}
EXPORT_SYMBOL(fsl_usb_host_uninit);
diff --git a/arch/arm/plat-mxs/utmixc.c b/arch/arm/plat-mxs/utmixc.c
index 1e9015d6de3f..8e842840e87a 100644
--- a/arch/arm/plat-mxs/utmixc.c
+++ b/arch/arm/plat-mxs/utmixc.c
@@ -45,7 +45,7 @@ static void set_vbus_draw(struct fsl_xcvr_ops *this,
{
#ifdef CONFIG_MXS_VBUS_CURRENT_DRAW
if ((__raw_readl(REGS_POWER_BASE + HW_POWER_5VCTRL)
- & BM_POWER_5VCTRL_CHARGE_4P2_ILIMIT) == 0x8000) {
+ & BM_POWER_5VCTRL_CHARGE_4P2_ILIMIT) == 0x20000) {
printk(KERN_INFO "USB enumeration done,current limitation release\r\n");
__raw_writel(__raw_readl(REGS_POWER_BASE + HW_POWER_5VCTRL) |
BM_POWER_5VCTRL_CHARGE_4P2_ILIMIT, REGS_POWER_BASE +
@@ -80,7 +80,7 @@ static void __exit utmixc_exit(void)
#ifdef CONFIG_MXS_VBUS_CURRENT_DRAW
fs_initcall(utmixc_init);
#else
- module_init(utmixc_init);
+ subsys_initcall(utmixc_init);
#endif
module_exit(utmixc_exit);