aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-12-02 11:05:26 -0500
committerOlof Johansson <olof@lixom.net>2014-12-05 02:24:51 -0500
commit65bb688aab9424849e94f74d555542fa76cd3d5a (patch)
tree97a06e6f2400b1719748d29e732f8d13ce4ba33e /arch/arm/mach-imx
parente2fd06f6be690a1a9697c0c6338843a35cbd70a3 (diff)
ARM: imx6: fix bogus use of irq_get_irq_data
The imx6 PM code seems to be quite creative in its use of irq_data, using something that is very much a hardware interrupt number where we expect a virtual one. Yes, it worked so far, but that's only luck, and it will definitely explode in 3.19. Fix it by using a pair of helper functions that deal with the actual hardware. Tested-by: Fabio Estevam <fabio.estevam@freescale.com> Acked-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/common.h4
-rw-r--r--arch/arm/mach-imx/gpc.c34
-rw-r--r--arch/arm/mach-imx/pm-imx6.c5
3 files changed, 26 insertions, 17 deletions
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 1dabf435c592..66662a1e36de 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -108,8 +108,8 @@ void imx_gpc_pre_suspend(bool arm_power_off);
108void imx_gpc_post_resume(void); 108void imx_gpc_post_resume(void);
109void imx_gpc_mask_all(void); 109void imx_gpc_mask_all(void);
110void imx_gpc_restore_all(void); 110void imx_gpc_restore_all(void);
111void imx_gpc_irq_mask(struct irq_data *d); 111void imx_gpc_hwirq_mask(unsigned int hwirq);
112void imx_gpc_irq_unmask(struct irq_data *d); 112void imx_gpc_hwirq_unmask(unsigned int hwirq);
113void imx_anatop_init(void); 113void imx_anatop_init(void);
114void imx_anatop_pre_suspend(void); 114void imx_anatop_pre_suspend(void);
115void imx_anatop_post_resume(void); 115void imx_anatop_post_resume(void);
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 1455829c735e..5f3602ec74fa 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -91,34 +91,44 @@ void imx_gpc_restore_all(void)
91 writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); 91 writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
92} 92}
93 93
94void imx_gpc_irq_unmask(struct irq_data *d) 94void imx_gpc_hwirq_unmask(unsigned int hwirq)
95{ 95{
96 void __iomem *reg; 96 void __iomem *reg;
97 u32 val; 97 u32 val;
98 98
99 /* Sanity check for SPI irq */ 99 reg = gpc_base + GPC_IMR1 + (hwirq / 32 - 1) * 4;
100 if (d->hwirq < 32)
101 return;
102
103 reg = gpc_base + GPC_IMR1 + (d->hwirq / 32 - 1) * 4;
104 val = readl_relaxed(reg); 100 val = readl_relaxed(reg);
105 val &= ~(1 << d->hwirq % 32); 101 val &= ~(1 << hwirq % 32);
106 writel_relaxed(val, reg); 102 writel_relaxed(val, reg);
107} 103}
108 104
109void imx_gpc_irq_mask(struct irq_data *d) 105void imx_gpc_hwirq_mask(unsigned int hwirq)
110{ 106{
111 void __iomem *reg; 107 void __iomem *reg;
112 u32 val; 108 u32 val;
113 109
110 reg = gpc_base + GPC_IMR1 + (hwirq / 32 - 1) * 4;
111 val = readl_relaxed(reg);
112 val |= 1 << (hwirq % 32);
113 writel_relaxed(val, reg);
114}
115
116static void imx_gpc_irq_unmask(struct irq_data *d)
117{
118 /* Sanity check for SPI irq */
119 if (d->hwirq < 32)
120 return;
121
122 imx_gpc_hwirq_unmask(d->hwirq);
123}
124
125static void imx_gpc_irq_mask(struct irq_data *d)
126{
114 /* Sanity check for SPI irq */ 127 /* Sanity check for SPI irq */
115 if (d->hwirq < 32) 128 if (d->hwirq < 32)
116 return; 129 return;
117 130
118 reg = gpc_base + GPC_IMR1 + (d->hwirq / 32 - 1) * 4; 131 imx_gpc_hwirq_mask(d->hwirq);
119 val = readl_relaxed(reg);
120 val |= 1 << (d->hwirq % 32);
121 writel_relaxed(val, reg);
122} 132}
123 133
124void __init imx_gpc_init(void) 134void __init imx_gpc_init(void)
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 5c3af8f993d0..d815d1ba27a5 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -261,7 +261,6 @@ static void imx6q_enable_wb(bool enable)
261 261
262int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) 262int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
263{ 263{
264 struct irq_data *iomuxc_irq_data = irq_get_irq_data(32);
265 u32 val = readl_relaxed(ccm_base + CLPCR); 264 u32 val = readl_relaxed(ccm_base + CLPCR);
266 265
267 val &= ~BM_CLPCR_LPM; 266 val &= ~BM_CLPCR_LPM;
@@ -316,9 +315,9 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
316 * 3) Software should mask IRQ #32 right after CCM Low-Power mode 315 * 3) Software should mask IRQ #32 right after CCM Low-Power mode
317 * is set (set bits 0-1 of CCM_CLPCR). 316 * is set (set bits 0-1 of CCM_CLPCR).
318 */ 317 */
319 imx_gpc_irq_unmask(iomuxc_irq_data); 318 imx_gpc_hwirq_unmask(32);
320 writel_relaxed(val, ccm_base + CLPCR); 319 writel_relaxed(val, ccm_base + CLPCR);
321 imx_gpc_irq_mask(iomuxc_irq_data); 320 imx_gpc_hwirq_mask(32);
322 321
323 return 0; 322 return 0;
324} 323}