diff options
Diffstat (limited to 'arch/arm/plat-mxs')
-rw-r--r-- | arch/arm/plat-mxs/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/plat-mxs/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/plat-mxs/clock.c | 48 | ||||
-rw-r--r-- | arch/arm/plat-mxs/cpufreq.c | 62 | ||||
-rw-r--r-- | arch/arm/plat-mxs/device.c | 84 | ||||
-rw-r--r-- | arch/arm/plat-mxs/dma-apbx.c | 3 | ||||
-rw-r--r-- | arch/arm/plat-mxs/dmaengine.c | 14 | ||||
-rw-r--r-- | arch/arm/plat-mxs/gpio.c | 2 | ||||
-rw-r--r-- | arch/arm/plat-mxs/icoll.c | 6 | ||||
-rw-r--r-- | arch/arm/plat-mxs/include/mach/bus_freq.h | 11 | ||||
-rw-r--r-- | arch/arm/plat-mxs/include/mach/clock.h | 21 | ||||
-rw-r--r-- | arch/arm/plat-mxs/include/mach/device.h | 62 | ||||
-rw-r--r-- | arch/arm/plat-mxs/include/mach/dmaengine.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-mxs/include/mach/system.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-mxs/include/mach/timex.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-mxs/iram.c | 5 | ||||
-rw-r--r-- | arch/arm/plat-mxs/timer-nomatch.c | 9 | ||||
-rw-r--r-- | arch/arm/plat-mxs/usb_common.c | 21 | ||||
-rw-r--r-- | arch/arm/plat-mxs/utmixc.c | 4 |
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); |