diff options
| author | Marc Zyngier <marc.zyngier@arm.com> | 2014-12-02 11:05:26 -0500 |
|---|---|---|
| committer | Olof Johansson <olof@lixom.net> | 2014-12-05 02:24:51 -0500 |
| commit | 65bb688aab9424849e94f74d555542fa76cd3d5a (patch) | |
| tree | 97a06e6f2400b1719748d29e732f8d13ce4ba33e | |
| parent | e2fd06f6be690a1a9697c0c6338843a35cbd70a3 (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>
| -rw-r--r-- | arch/arm/mach-imx/common.h | 4 | ||||
| -rw-r--r-- | arch/arm/mach-imx/gpc.c | 34 | ||||
| -rw-r--r-- | arch/arm/mach-imx/pm-imx6.c | 5 |
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); | |||
| 108 | void imx_gpc_post_resume(void); | 108 | void imx_gpc_post_resume(void); |
| 109 | void imx_gpc_mask_all(void); | 109 | void imx_gpc_mask_all(void); |
| 110 | void imx_gpc_restore_all(void); | 110 | void imx_gpc_restore_all(void); |
| 111 | void imx_gpc_irq_mask(struct irq_data *d); | 111 | void imx_gpc_hwirq_mask(unsigned int hwirq); |
| 112 | void imx_gpc_irq_unmask(struct irq_data *d); | 112 | void imx_gpc_hwirq_unmask(unsigned int hwirq); |
| 113 | void imx_anatop_init(void); | 113 | void imx_anatop_init(void); |
| 114 | void imx_anatop_pre_suspend(void); | 114 | void imx_anatop_pre_suspend(void); |
| 115 | void imx_anatop_post_resume(void); | 115 | void 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 | ||
| 94 | void imx_gpc_irq_unmask(struct irq_data *d) | 94 | void 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 | ||
| 109 | void imx_gpc_irq_mask(struct irq_data *d) | 105 | void 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 | |||
| 116 | static 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 | |||
| 125 | static 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 | ||
| 124 | void __init imx_gpc_init(void) | 134 | void __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 | ||
| 262 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | 262 | int 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 | } |
