diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-16 15:45:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-16 15:45:55 -0500 |
commit | 71f777ed50e9109c235c14604d5e23d2f8e7453c (patch) | |
tree | 89d68da346c1f0e4de4429af2be36a8a39566064 /arch/arm/mach-imx | |
parent | dd3190ee8142d94c9aa09d278a106544b2e5e7d1 (diff) | |
parent | 6886059f2ef5d62c73e87a905e84fa4f87d56074 (diff) |
Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC fixes from Olof Johansson:
"A first set of batches of fixes for 3.13. The diffstat is large
mostly because we're adding a defconfig for a family that's been
lacking it, and there's some missing clock information added for i.MX
and OMAP.
The at91 new code is around dealing with RTC/RTT reset at boot to fix
possible hangs due to pending wakeup interrupts coming in during early
boot"
* tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (29 commits)
ARM: OMAP2+: Fix build for dra7xx without omap4 and 5
ARM: OMAP2+: omap_device: maintain sane runtime pm status around suspend/resume
doc: devicetree: Add bindings documentation for omap-des driver
ARM: dts: doc: Document missing compatible property for omap-sham driver
ARM: OMAP3: Beagle: fix return value check in beagle_opp_init()
ARM: at91: fix hanged boot due to early rtt-interrupt
ARM: at91: fix hanged boot due to early rtc-interrupt
video: exynos_mipi_dsim: Remove unused variable
ARM: highbank: only select errata 764369 if SMP
ARM: sti: only select errata 764369 if SMP
ARM: tegra: init fuse before setting reset handler
ARM: vt8500: add defconfig for v6/v7 chips
ARM: integrator_cp: Set LCD{0,1} enable lines when turning on CLCD
ARM: OMAP: devicetree: fix SPI node compatible property syntax items
pinctrl: single: call pcs_soc->rearm() whenever IRQ mask is changed
ARM: OMAP2+: smsc911x: fix return value check in gpmc_smsc911x_init()
MAINTAINERS: drop discontinued mailing list
ARM: dts: i.MX51: Fix OTG PHY clock
ARM: imx: set up pllv3 POWER and BYPASS sequentially
ARM: imx: pllv3 needs relock in .set_rate() call
...
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r-- | arch/arm/mach-imx/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-imx/clk-imx6q.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-imx/clk-pllv3.c | 51 | ||||
-rw-r--r-- | arch/arm/mach-imx/common.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/src.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-imx/system.c | 12 |
6 files changed, 48 insertions, 46 deletions
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index bbe1f5bb799c..1789e2b31903 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile | |||
@@ -102,8 +102,8 @@ obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o | |||
102 | 102 | ||
103 | ifeq ($(CONFIG_PM),y) | 103 | ifeq ($(CONFIG_PM),y) |
104 | obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o | 104 | obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o |
105 | # i.MX6SL reuses pm-imx6q.c | 105 | # i.MX6SL reuses i.MX6Q code |
106 | obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o | 106 | obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o |
107 | endif | 107 | endif |
108 | 108 | ||
109 | # i.MX5 based machines | 109 | # i.MX5 based machines |
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index d756d91fd741..04cfd0fcb0e5 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c | |||
@@ -122,13 +122,14 @@ static struct clk_div_table clk_enet_ref_table[] = { | |||
122 | { .val = 1, .div = 10, }, | 122 | { .val = 1, .div = 10, }, |
123 | { .val = 2, .div = 5, }, | 123 | { .val = 2, .div = 5, }, |
124 | { .val = 3, .div = 4, }, | 124 | { .val = 3, .div = 4, }, |
125 | { /* sentinel */ } | ||
125 | }; | 126 | }; |
126 | 127 | ||
127 | static struct clk_div_table post_div_table[] = { | 128 | static struct clk_div_table post_div_table[] = { |
128 | { .val = 2, .div = 1, }, | 129 | { .val = 2, .div = 1, }, |
129 | { .val = 1, .div = 2, }, | 130 | { .val = 1, .div = 2, }, |
130 | { .val = 0, .div = 4, }, | 131 | { .val = 0, .div = 4, }, |
131 | { } | 132 | { /* sentinel */ } |
132 | }; | 133 | }; |
133 | 134 | ||
134 | static struct clk_div_table video_div_table[] = { | 135 | static struct clk_div_table video_div_table[] = { |
@@ -136,7 +137,7 @@ static struct clk_div_table video_div_table[] = { | |||
136 | { .val = 1, .div = 2, }, | 137 | { .val = 1, .div = 2, }, |
137 | { .val = 2, .div = 1, }, | 138 | { .val = 2, .div = 1, }, |
138 | { .val = 3, .div = 4, }, | 139 | { .val = 3, .div = 4, }, |
139 | { } | 140 | { /* sentinel */ } |
140 | }; | 141 | }; |
141 | 142 | ||
142 | static void __init imx6q_clocks_init(struct device_node *ccm_node) | 143 | static void __init imx6q_clocks_init(struct device_node *ccm_node) |
@@ -298,7 +299,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
298 | clk[asrc_podf] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); | 299 | clk[asrc_podf] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); |
299 | clk[spdif_pred] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); | 300 | clk[spdif_pred] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); |
300 | clk[spdif_podf] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); | 301 | clk[spdif_podf] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); |
301 | clk[can_root] = imx_clk_divider("can_root", "pll3_usb_otg", base + 0x20, 2, 6); | 302 | clk[can_root] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6); |
302 | clk[ecspi_root] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); | 303 | clk[ecspi_root] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); |
303 | clk[gpu2d_core_podf] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); | 304 | clk[gpu2d_core_podf] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); |
304 | clk[gpu3d_core_podf] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); | 305 | clk[gpu3d_core_podf] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); |
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index f6640b6a7b31..61364050fccd 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/clk-provider.h> | 14 | #include <linux/clk-provider.h> |
15 | #include <linux/delay.h> | ||
15 | #include <linux/io.h> | 16 | #include <linux/io.h> |
16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
17 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> |
@@ -45,33 +46,49 @@ struct clk_pllv3 { | |||
45 | 46 | ||
46 | #define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) | 47 | #define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) |
47 | 48 | ||
49 | static int clk_pllv3_wait_lock(struct clk_pllv3 *pll) | ||
50 | { | ||
51 | unsigned long timeout = jiffies + msecs_to_jiffies(10); | ||
52 | u32 val = readl_relaxed(pll->base) & BM_PLL_POWER; | ||
53 | |||
54 | /* No need to wait for lock when pll is not powered up */ | ||
55 | if ((pll->powerup_set && !val) || (!pll->powerup_set && val)) | ||
56 | return 0; | ||
57 | |||
58 | /* Wait for PLL to lock */ | ||
59 | do { | ||
60 | if (readl_relaxed(pll->base) & BM_PLL_LOCK) | ||
61 | break; | ||
62 | if (time_after(jiffies, timeout)) | ||
63 | break; | ||
64 | usleep_range(50, 500); | ||
65 | } while (1); | ||
66 | |||
67 | return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT; | ||
68 | } | ||
69 | |||
48 | static int clk_pllv3_prepare(struct clk_hw *hw) | 70 | static int clk_pllv3_prepare(struct clk_hw *hw) |
49 | { | 71 | { |
50 | struct clk_pllv3 *pll = to_clk_pllv3(hw); | 72 | struct clk_pllv3 *pll = to_clk_pllv3(hw); |
51 | unsigned long timeout; | ||
52 | u32 val; | 73 | u32 val; |
74 | int ret; | ||
53 | 75 | ||
54 | val = readl_relaxed(pll->base); | 76 | val = readl_relaxed(pll->base); |
55 | val &= ~BM_PLL_BYPASS; | ||
56 | if (pll->powerup_set) | 77 | if (pll->powerup_set) |
57 | val |= BM_PLL_POWER; | 78 | val |= BM_PLL_POWER; |
58 | else | 79 | else |
59 | val &= ~BM_PLL_POWER; | 80 | val &= ~BM_PLL_POWER; |
60 | writel_relaxed(val, pll->base); | 81 | writel_relaxed(val, pll->base); |
61 | 82 | ||
62 | timeout = jiffies + msecs_to_jiffies(10); | 83 | ret = clk_pllv3_wait_lock(pll); |
63 | /* Wait for PLL to lock */ | 84 | if (ret) |
64 | do { | 85 | return ret; |
65 | if (readl_relaxed(pll->base) & BM_PLL_LOCK) | ||
66 | break; | ||
67 | if (time_after(jiffies, timeout)) | ||
68 | break; | ||
69 | } while (1); | ||
70 | 86 | ||
71 | if (readl_relaxed(pll->base) & BM_PLL_LOCK) | 87 | val = readl_relaxed(pll->base); |
72 | return 0; | 88 | val &= ~BM_PLL_BYPASS; |
73 | else | 89 | writel_relaxed(val, pll->base); |
74 | return -ETIMEDOUT; | 90 | |
91 | return 0; | ||
75 | } | 92 | } |
76 | 93 | ||
77 | static void clk_pllv3_unprepare(struct clk_hw *hw) | 94 | static void clk_pllv3_unprepare(struct clk_hw *hw) |
@@ -146,7 +163,7 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate, | |||
146 | val |= div; | 163 | val |= div; |
147 | writel_relaxed(val, pll->base); | 164 | writel_relaxed(val, pll->base); |
148 | 165 | ||
149 | return 0; | 166 | return clk_pllv3_wait_lock(pll); |
150 | } | 167 | } |
151 | 168 | ||
152 | static const struct clk_ops clk_pllv3_ops = { | 169 | static const struct clk_ops clk_pllv3_ops = { |
@@ -202,7 +219,7 @@ static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate, | |||
202 | val |= div; | 219 | val |= div; |
203 | writel_relaxed(val, pll->base); | 220 | writel_relaxed(val, pll->base); |
204 | 221 | ||
205 | return 0; | 222 | return clk_pllv3_wait_lock(pll); |
206 | } | 223 | } |
207 | 224 | ||
208 | static const struct clk_ops clk_pllv3_sys_ops = { | 225 | static const struct clk_ops clk_pllv3_sys_ops = { |
@@ -276,7 +293,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, | |||
276 | writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); | 293 | writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); |
277 | writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); | 294 | writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); |
278 | 295 | ||
279 | return 0; | 296 | return clk_pllv3_wait_lock(pll); |
280 | } | 297 | } |
281 | 298 | ||
282 | static const struct clk_ops clk_pllv3_av_ops = { | 299 | static const struct clk_ops clk_pllv3_av_ops = { |
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 7cbe22d0c6e9..24a7899e36a8 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h | |||
@@ -127,11 +127,6 @@ static inline void imx_smp_prepare(void) {} | |||
127 | static inline void imx_scu_standby_enable(void) {} | 127 | static inline void imx_scu_standby_enable(void) {} |
128 | #endif | 128 | #endif |
129 | void imx_src_init(void); | 129 | void imx_src_init(void); |
130 | #ifdef CONFIG_HAVE_IMX_SRC | ||
131 | void imx_src_prepare_restart(void); | ||
132 | #else | ||
133 | static inline void imx_src_prepare_restart(void) {} | ||
134 | #endif | ||
135 | void imx_gpc_init(void); | 130 | void imx_gpc_init(void); |
136 | void imx_gpc_pre_suspend(void); | 131 | void imx_gpc_pre_suspend(void); |
137 | void imx_gpc_post_resume(void); | 132 | void imx_gpc_post_resume(void); |
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index 4754373e7e7d..45f7f4e0a447 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c | |||
@@ -115,21 +115,6 @@ void imx_set_cpu_arg(int cpu, u32 arg) | |||
115 | writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); | 115 | writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); |
116 | } | 116 | } |
117 | 117 | ||
118 | void imx_src_prepare_restart(void) | ||
119 | { | ||
120 | u32 val; | ||
121 | |||
122 | /* clear enable bits of secondary cores */ | ||
123 | spin_lock(&scr_lock); | ||
124 | val = readl_relaxed(src_base + SRC_SCR); | ||
125 | val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); | ||
126 | writel_relaxed(val, src_base + SRC_SCR); | ||
127 | spin_unlock(&scr_lock); | ||
128 | |||
129 | /* clear persistent entry register of primary core */ | ||
130 | writel_relaxed(0, src_base + SRC_GPR1); | ||
131 | } | ||
132 | |||
133 | void __init imx_src_init(void) | 118 | void __init imx_src_init(void) |
134 | { | 119 | { |
135 | struct device_node *np; | 120 | struct device_node *np; |
diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index e6edcd38b282..5e3027d3692f 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c | |||
@@ -42,9 +42,6 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) | |||
42 | { | 42 | { |
43 | unsigned int wcr_enable; | 43 | unsigned int wcr_enable; |
44 | 44 | ||
45 | if (cpu_is_imx6q() || cpu_is_imx6dl()) | ||
46 | imx_src_prepare_restart(); | ||
47 | |||
48 | if (wdog_clk) | 45 | if (wdog_clk) |
49 | clk_enable(wdog_clk); | 46 | clk_enable(wdog_clk); |
50 | 47 | ||
@@ -55,7 +52,14 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) | |||
55 | 52 | ||
56 | /* Assert SRS signal */ | 53 | /* Assert SRS signal */ |
57 | __raw_writew(wcr_enable, wdog_base); | 54 | __raw_writew(wcr_enable, wdog_base); |
58 | /* write twice to ensure the request will not get ignored */ | 55 | /* |
56 | * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be | ||
57 | * written twice), we add another two writes to ensure there must be at | ||
58 | * least two writes happen in the same one 32kHz clock period. We save | ||
59 | * the target check here, since the writes shouldn't be a huge burden | ||
60 | * for other platforms. | ||
61 | */ | ||
62 | __raw_writew(wcr_enable, wdog_base); | ||
59 | __raw_writew(wcr_enable, wdog_base); | 63 | __raw_writew(wcr_enable, wdog_base); |
60 | 64 | ||
61 | /* wait for reset to assert... */ | 65 | /* wait for reset to assert... */ |