* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
From: Paul Walmsley @ 2011-10-06 23:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111006222912.GA27281@n2100.arm.linux.org.uk>
The way that we detect which OMAP3 chips support I/O wakeup and
software I/O chain clock control is broken.
Currently, I/O wakeup is marked as present for all OMAP3 SoCs other
than the AM3505/3517. The TI81xx family of SoCs are at present
considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve
this, convert the existing blacklist approach to an explicit,
whitelist support, in which only SoCs which are known to support I/O
wakeup are listed. (At present, this only includes OMAP34xx,
OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.)
Also, the current code incorrectly detects the presence of a
software-controllable I/O chain clock on several chips that don't
support it. This results in writes to reserved bitfields, unnecessary
delays, and console messages on kernels running on those chips:
http://www.spinics.net/lists/linux-omap/msg58735.html
Convert this test to a feature test with a chip-by-chip whitelist.
Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem
and doing some testing to help isolate the cause. Thanks to Steve
Sakoman <sakoman@gmail.com> for catching a bug in the first version of
this patch. Thanks to Russell King <linux@arm.linux.org.uk> for
comments.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Dave Hylands <dhylands@gmail.com>
Cc: Steve Sakoman <sakoman@gmail.com>
Tested-by: Steve Sakoman <sakoman@gmail.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
---
This version incorporates some comments from RMK - an unnecessary
set of parentheses are removed and a two-part error message string is
joined. Also, the printk(KERN_ERR has been converted into a pr_err(.
arch/arm/mach-omap2/id.c | 5 +++-
arch/arm/mach-omap2/pm34xx.c | 43 +++++++++++++++++----------------
arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++----
3 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 37efb86..a1ccb66 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -201,8 +201,11 @@ static void __init omap3_check_features(void)
OMAP3_CHECK_FEATURE(status, ISP);
if (cpu_is_omap3630())
omap_features |= OMAP3_HAS_192MHZ_CLK;
- if (!cpu_is_omap3505() && !cpu_is_omap3517())
+ if (cpu_is_omap3430() || cpu_is_omap3630())
omap_features |= OMAP3_HAS_IO_WAKEUP;
+ if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
+ omap_rev() == OMAP3430_REV_ES3_1_2)
+ omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
omap_features |= OMAP3_HAS_SDRC;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 7255d9b..979ed39 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -99,31 +99,27 @@ static void omap3_enable_io_chain(void)
{
int timeout = 0;
- if (omap_rev() >= OMAP3430_REV_ES3_1) {
- omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
- PM_WKEN);
- /* Do a readback to assure write has been done */
- omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
-
- while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
- OMAP3430_ST_IO_CHAIN_MASK)) {
- timeout++;
- if (timeout > 1000) {
- printk(KERN_ERR "Wake up daisy chain "
- "activation failed.\n");
- return;
- }
- omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
- WKUP_MOD, PM_WKEN);
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
+ /* Do a readback to assure write has been done */
+ omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+
+ while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
+ OMAP3430_ST_IO_CHAIN_MASK)) {
+ timeout++;
+ if (timeout > 1000) {
+ pr_err("Wake up daisy chain activation failed.\n");
+ return;
}
+ omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
+ WKUP_MOD, PM_WKEN);
}
}
static void omap3_disable_io_chain(void)
{
- if (omap_rev() >= OMAP3430_REV_ES3_1)
- omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
- PM_WKEN);
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
}
static void omap3_core_save_context(void)
@@ -376,7 +372,8 @@ void omap_sram_idle(void)
(per_next_state < PWRDM_POWER_ON ||
core_next_state < PWRDM_POWER_ON)) {
omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
- omap3_enable_io_chain();
+ if (omap3_has_io_chain_ctrl())
+ omap3_enable_io_chain();
}
/* Block console output in case it is on one of the OMAP UARTs */
@@ -475,7 +472,8 @@ console_still_active:
core_next_state < PWRDM_POWER_ON)) {
omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
PM_WKEN);
- omap3_disable_io_chain();
+ if (omap3_has_io_chain_ctrl())
+ omap3_disable_io_chain();
}
pwrdm_post_transition();
@@ -870,6 +868,9 @@ static int __init omap3_pm_init(void)
if (!cpu_is_omap34xx())
return -ENODEV;
+ if (!omap3_has_io_chain_ctrl())
+ pr_warning("PM: no software I/O chain control; some wakeups may be lost\n");
+
pm_errata_configure();
/* XXX prcm_setup_regs needs to be before enabling hw
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 67b3d75..3a280aa 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -477,6 +477,13 @@ void omap2_check_revision(void);
/*
* Runtime detection of OMAP3 features
+ *
+ * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip
+ * family have OS-level control over the I/O chain clock. This is
+ * to avoid a window during which wakeups could potentially be lost
+ * during powerdomain transitions. If this bit is set, it
+ * indicates that the chip does support OS-level control of this
+ * feature.
*/
extern u32 omap_features;
@@ -488,9 +495,10 @@ extern u32 omap_features;
#define OMAP3_HAS_192MHZ_CLK BIT(5)
#define OMAP3_HAS_IO_WAKEUP BIT(6)
#define OMAP3_HAS_SDRC BIT(7)
-#define OMAP4_HAS_MPU_1GHZ BIT(8)
-#define OMAP4_HAS_MPU_1_2GHZ BIT(9)
-#define OMAP4_HAS_MPU_1_5GHZ BIT(10)
+#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8)
+#define OMAP4_HAS_MPU_1GHZ BIT(9)
+#define OMAP4_HAS_MPU_1_2GHZ BIT(10)
+#define OMAP4_HAS_MPU_1_5GHZ BIT(11)
#define OMAP3_HAS_FEATURE(feat,flag) \
@@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP)
OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
OMAP3_HAS_FEATURE(sdrc, SDRC)
+OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
/*
* Runtime detection of OMAP4 features
*/
-extern u32 omap_features;
-
#define OMAP4_HAS_FEATURE(feat, flag) \
static inline unsigned int omap4_has_ ##feat(void) \
{ \
--
1.7.6.3
^ permalink raw reply related
* [PATCH] ARM: OMAP3: hwmod: fix variant registration and remove SmartReflex from common list
From: Paul Walmsley @ 2011-10-06 23:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111006223545.GB27281@n2100.arm.linux.org.uk>
On Thu, 6 Oct 2011, Russell King - ARM Linux wrote:
> On Thu, Oct 06, 2011 at 02:39:28PM -0600, Paul Walmsley wrote:
> > @@ -3240,7 +3240,7 @@ int __init omap3xxx_hwmod_init(void)
> >
> > /* Register hwmods common to all OMAP3 */
> > r = omap_hwmod_register(omap3xxx_hwmods);
> > - if (!r)
> > + if (IS_ERR_VALUE(r))
> > return r;
> >
> > rev = omap_rev();
> > @@ -3265,7 +3265,7 @@ int __init omap3xxx_hwmod_init(void)
> > };
> >
> > r = omap_hwmod_register(h);
> > - if (!r)
> > + if (IS_ERR_VALUE(r))
> > return r;
>
> What _really_ is the return value meaning of omap_hwmod_register() ?
>
> If it's zero for success, negative for error codes, then don't be
> clever and try to use IS_ERR_VALUE() for that - just use a standard
> < 0 test instead.
>
> You only need to use IS_ERR_VALUE() for stuff that may return negative
> errno values _and_ which may return valid addresses which may be
> misinterpreted as negative numbers.
Thanks, that's a good point - fixed.
- Paul
^ permalink raw reply
* [PATCH v2] ARM: OMAP3: hwmod: fix variant registration and remove SmartReflex from common list
From: Paul Walmsley @ 2011-10-06 23:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111006223545.GB27281@n2100.arm.linux.org.uk>
Commit d6504acd2125984c61dce24727dd3842d0144015 ("OMAP2+: hwmod:
remove OMAP_CHIP*") tests the inverse condition of what it should be
testing for the return value from omap_hwmod_register(). This causes
several IP blocks to not be registered on several OMAP3 family devices.
Fixing that bug also unmasked another bug, originally reported by
Chase Maupin <chase.maupin@ti.com> and then subsequently by Abhilash K
V <abhilash.kv@ti.com>, which caused SmartReflex IP blocks to be
registered on SoCs that don't support them.
Thanks to Russell King - ARM Linux <linux@arm.linux.org.uk> for comments
on a previous version of the patch.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Chase Maupin <chase.maupin@ti.com>
Cc: Abhilash K V <abhilash.kv@ti.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
---
This version incorporates some comments from RMK.
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index ab35acb..0771dc6 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -3161,8 +3161,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_i2c1_hwmod,
&omap3xxx_i2c2_hwmod,
&omap3xxx_i2c3_hwmod,
- &omap34xx_sr1_hwmod,
- &omap34xx_sr2_hwmod,
/* gpio class */
&omap3xxx_gpio1_hwmod,
@@ -3240,7 +3238,7 @@ int __init omap3xxx_hwmod_init(void)
/* Register hwmods common to all OMAP3 */
r = omap_hwmod_register(omap3xxx_hwmods);
- if (!r)
+ if (r < 0)
return r;
rev = omap_rev();
@@ -3265,7 +3263,7 @@ int __init omap3xxx_hwmod_init(void)
};
r = omap_hwmod_register(h);
- if (!r)
+ if (r < 0)
return r;
/*
--
1.7.6.3
^ permalink raw reply related
* [PATCH v2] ARM: OMAP3: hwmod: fix variant registration and remove SmartReflex from common list
From: Tony Lindgren @ 2011-10-06 23:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1110061723550.4611@utopia.booyaka.com>
* Paul Walmsley <paul@pwsan.com> [111006 15:50]:
>
> Commit d6504acd2125984c61dce24727dd3842d0144015 ("OMAP2+: hwmod:
> remove OMAP_CHIP*") tests the inverse condition of what it should be
> testing for the return value from omap_hwmod_register(). This causes
> several IP blocks to not be registered on several OMAP3 family devices.
>
> Fixing that bug also unmasked another bug, originally reported by
> Chase Maupin <chase.maupin@ti.com> and then subsequently by Abhilash K
> V <abhilash.kv@ti.com>, which caused SmartReflex IP blocks to be
> registered on SoCs that don't support them.
>
> Thanks to Russell King - ARM Linux <linux@arm.linux.org.uk> for comments
> on a previous version of the patch.
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Chase Maupin <chase.maupin@ti.com>
> Cc: Abhilash K V <abhilash.kv@ti.com>
> Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
> ---
>
> This version incorporates some comments from RMK.
Thanks, updating in fixes-part2.
Tony
^ permalink raw reply
* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
From: Kevin Hilman @ 2011-10-06 23:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1110061525240.4611@utopia.booyaka.com>
Paul Walmsley <paul@pwsan.com> writes:
> The way that we detect which OMAP3 chips support I/O wakeup and
> software I/O chain clock control is broken.
>
> Currently, I/O wakeup is marked as present for all OMAP3 SoCs other
> than the AM3505/3517. The TI81xx family of SoCs are at present
> considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve
> this, convert the existing blacklist approach to an explicit,
> whitelist support, in which only SoCs which are known to support I/O
> wakeup are listed. (At present, this only includes OMAP34xx,
> OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.)
>
> Also, the current code incorrectly detects the presence of a
> software-controllable I/O chain clock on several chips that don't
> support it. This results in writes to reserved bitfields, unnecessary
> delays, and console messages on kernels running on those chips:
>
> http://www.spinics.net/lists/linux-omap/msg58735.html
>
> Convert this test to a feature test with a chip-by-chip whitelist.
>
> Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem
> and doing some testing to help isolate the cause. Thanks to Steve
> Sakoman <sakoman@gmail.com> for catching a bug in the first version of
> this patch.
Based on the comments from Russell, I made a couple minor changes.
Here's the updated version (also in my for_3.1/pm-fixes-3 branch.)
Other than that, it looks like a good cleanup, queueing for v3.2 and
will submit to stable as well.
Tony, do you think we can still queue this as a fix for v3.1?
Kevin
^ permalink raw reply
* [PATCH] ARM: OMAP3: PM: restrict erratum i443 handling to OMAP3430 only
From: Kevin Hilman @ 2011-10-06 23:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1110061341460.4611@utopia.booyaka.com>
Paul Walmsley <paul@pwsan.com> writes:
> Based on the documents that I have here, there doesn't appear to be an
> equivalent to erratum i443 for OMAP3630, so restrict this one to OMAP34xx
> chips.
>
> Also, explicitly restrict this erratum to EMU and HS devices.
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@ti.com>
> ---
> Unfortunately, I don't have any HS/EMU devices in my testbed, so it's not
> possible for me to test this one on anything but GP chips.
I don't have any 36xx HS/EMU device either, but this erratum does indeed
seem to be 34xx specific.
Barring any objections, I'll queue this for v3.2 (branch: for_3.2/pm-cleanup-2)
Kevin
> arch/arm/mach-omap2/pm34xx.c | 20 +++++++++++---------
> 1 files changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index a6156bd..9e14ae5 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -407,13 +407,14 @@ void omap_sram_idle(void)
> omap3_intc_prepare_idle();
>
> /*
> - * On EMU/HS devices ROM code restores a SRDC value
> - * from scratchpad which has automatic self refresh on timeout
> - * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443.
> - * Hence store/restore the SDRC_POWER register here.
> - */
> - if (omap_rev() >= OMAP3430_REV_ES3_0 &&
> - omap_type() != OMAP2_DEVICE_TYPE_GP &&
> + * On EMU/HS devices ROM code restores a SRDC value
> + * from scratchpad which has automatic self refresh on timeout
> + * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443.
> + * Hence store/restore the SDRC_POWER register here.
> + */
> + if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
> + (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
> + omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
> core_next_state == PWRDM_POWER_OFF)
> sdrc_pwr = sdrc_read_reg(SDRC_POWER);
>
> @@ -430,8 +431,9 @@ void omap_sram_idle(void)
> omap34xx_do_sram_idle(save_state);
>
> /* Restore normal SDRC POWER settings */
> - if (omap_rev() >= OMAP3430_REV_ES3_0 &&
> - omap_type() != OMAP2_DEVICE_TYPE_GP &&
> + if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
> + (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
> + omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
> core_next_state == PWRDM_POWER_OFF)
> sdrc_write_reg(sdrc_pwr, SDRC_POWER);
^ permalink raw reply
* [PATCH 1/2] arm: samsung: move timer irq numbers to end of linux irq space
From: Thomas Abraham @ 2011-10-06 23:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111006221517.GC21464@n2100.arm.linux.org.uk>
Hi Russell,
On 7 October 2011 03:45, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Fri, Oct 07, 2011 at 02:41:42AM +0530, Thomas Abraham wrote:
>> All of Samsung's s5p platforms have timer irqs statically mapped from linux
>> irq numbers 11 to 15. These timer irqs are moved to end of the statically
>> mapped linux irq space and the hardware irqs, which were statically mapped
>> starting from 32 is moved to start from 0. The NR_IRQS macro is consolidated
>> for all the s5p platforms in this process.
>
> Am I reading this patch correctly - in that on platforms with the GIC,
> you add 32 to the GIC IRQ number _just_ to avoid the possibility that
> IRQs 11-15 are seen as valid?
>
> Or to put it another way, you're trying to ensure that if these timer
> IRQs are requested, they will fail?
>
This patch is applicable for s5p64x0, s5pc100, s5pv210 and exynos4.
Exynos4 has GIC and the rest use VIC.
For all these platforms, the five hardware timer irqs are connected to
GIC/VIC at some hardware irq number (in exynos it is GIC_ID 69 to 73
for five timers). When any of these hardware interrupt occurs, its
interrupt handler calls generic_handle_irq() with linux irq number
11/12/13/14/15 for timer 0/1/2/3/4 as the parameter. The code that
needs to be notified about the timer interrupts would have already
registered its handler for either of the interrupts 11 to 15. I am not
sure why such remapping is used. I think it is not needed but did not
intend to change it. All this is included in the file
"arch/arm/plat-samsung/irq-vic-timer.c".
Instead of using linux irq number 11 to 15 to which consumers of timer
interrupt attach their handler, this interrupt range is moved to the
end of linux irq space used. So there will be no interrupts statically
mapped between 0 to 31.
The GIC/VIC hardware interrupts, which were previously statically
mapped to start from linux irq 32 are now moved to start from linux
irq 0. In case of exynos, GIC_ID[0] (which is SGI[0]) which was
previously at linux irq 32, will not be at linux irq 0.
This was the intended change. This was required to use Rob Herring's
GIC OF bindings patches for Exynos4.
Thanks,
Thomas.
^ permalink raw reply
* [PATCH 1/2] arm: samsung: move timer irq numbers to end of linux irq space
From: Thomas Abraham @ 2011-10-06 23:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJuYYwQh30k-7+uZk8XLUBhzRxHDu7xObC=-z70WtXe5WSJSrQ@mail.gmail.com>
On 7 October 2011 05:26, Thomas Abraham <thomas.abraham@linaro.org> wrote:
> Hi Russell,
>
> On 7 October 2011 03:45, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
>> On Fri, Oct 07, 2011 at 02:41:42AM +0530, Thomas Abraham wrote:
>>> All of Samsung's s5p platforms have timer irqs statically mapped from linux
>>> irq numbers 11 to 15. These timer irqs are moved to end of the statically
>>> mapped linux irq space and the hardware irqs, which were statically mapped
>>> starting from 32 is moved to start from 0. The NR_IRQS macro is consolidated
>>> for all the s5p platforms in this process.
>>
>> Am I reading this patch correctly - in that on platforms with the GIC,
>> you add 32 to the GIC IRQ number _just_ to avoid the possibility that
>> IRQs 11-15 are seen as valid?
>>
>> Or to put it another way, you're trying to ensure that if these timer
>> IRQs are requested, they will fail?
>>
>
> This patch is applicable for s5p64x0, s5pc100, s5pv210 and exynos4.
> Exynos4 has GIC and the rest use VIC.
>
> For all these platforms, the five hardware timer irqs are connected to
> GIC/VIC at some hardware irq number (in exynos it is GIC_ID 69 to 73
> for five timers). When any of these hardware interrupt occurs, its
> interrupt handler calls generic_handle_irq() with linux irq number
> 11/12/13/14/15 for timer 0/1/2/3/4 as the parameter. The code that
> needs to be notified about the timer interrupts would have already
> registered its handler for either of the interrupts 11 to 15. I am not
> sure why such remapping is used. I think it is not needed but did not
> intend to change it. All this is included in the file
> "arch/arm/plat-samsung/irq-vic-timer.c".
>
> Instead of using linux irq number 11 to 15 to which consumers of timer
> interrupt attach their handler, this interrupt range is moved to the
> end of linux irq space used. So there will be no interrupts statically
> mapped between 0 to 31.
>
> The GIC/VIC hardware interrupts, which were previously statically
> mapped to start from linux irq 32 are now moved to start from linux
> irq 0. In case of exynos, GIC_ID[0] (which is SGI[0]) which was
> previously at linux irq 32, will not be at linux irq 0.
Correcting the line above:
previously at linux irq 32, will _now_ be at linux irq 0.
>
> This was the intended change. This was required to use Rob Herring's
> GIC OF bindings patches for Exynos4.
>
> Thanks,
> Thomas.
>
^ permalink raw reply
* [GIT PULL] ARM: OMAP: DSS hwmod/reset fixes for 3.2
From: Paul Walmsley @ 2011-10-07 0:07 UTC (permalink / raw)
To: linux-arm-kernel
Hi Tony,
The following changes since commit be73246058737beec52ae232bcab7776332a9e06:
ARM: OMAP2+: Remove custom init_irq for remaining boards (2011-09-26 17:50:37 -0700)
are available in the git repository at:
git://git.pwsan.com/linux-2.6 hwmod_dss_fixes_3.2
Archit Taneja (1):
ARM: OMAP2PLUS: DSS: Ensure DSS works correctly if display is enabled in bootloader
Tomi Valkeinen (9):
ARM: OMAP2xxx: HWMOD: Fix DSS reset
ARM: OMAP2xxx: HWMOD: fix DSS clock data
ARM: OMAP3: HWMOD: Fix DSS reset
ARM: OMAP3: HWMOD: fix DSS clock data
ARM: OMAP4: HWMOD: remove extra clocks
ARM: OMAP4: HWMOD: Add HWMOD_CONTROL_OPT_CLKS_IN_RESET for dss_core
ARM: OMAP4: HWMOD: fix DSS clock data
ARM: OMAP2/3: HWMOD: Add SYSS_HAS_RESET_STATUS for dss
ARM: OMAP: HWMOD: Unify DSS resets for OMAPs
arch/arm/mach-omap2/Makefile | 5 +-
arch/arm/mach-omap2/display.c | 160 ++++++++++++++++++++
arch/arm/mach-omap2/display.h | 29 ++++
arch/arm/mach-omap2/omap_hwmod_2420_data.c | 17 ++-
arch/arm/mach-omap2/omap_hwmod_2430_data.c | 17 ++-
.../mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c | 5 +-
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 37 ++++-
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 24 ++--
arch/arm/mach-omap2/omap_hwmod_common_data.c | 4 +
arch/arm/mach-omap2/omap_hwmod_common_data.h | 4 +
arch/arm/plat-omap/include/plat/common.h | 3 +
include/video/omapdss.h | 7 -
12 files changed, 277 insertions(+), 35 deletions(-)
create mode 100644 arch/arm/mach-omap2/display.h
^ permalink raw reply
* [PATCH] ARM: OMAP1: Fix warnings about enabling 32 KiHz timer
From: Tony Lindgren @ 2011-10-07 0:12 UTC (permalink / raw)
To: linux-arm-kernel
Fix "Enable 32kHz OS timer in order to allow sleep states in idle"
warning. We are now compiling in bothe MPU timer and 32 KiHz timer,
so this warning is only valid when CONFIG_OMAP_32K_TIMER is not set.
Signed-off-by: Tony Lindgren <tony@atomide.com>
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 495b398..6badc29 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -116,7 +116,7 @@ void omap1_pm_idle(void)
return;
}
-#ifdef CONFIG_OMAP_MPU_TIMER
+#if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_32K_TIMER)
#warning Enable 32kHz OS timer in order to allow sleep states in idle
use_idlect1 = use_idlect1 & ~(1 << 9);
#else
^ permalink raw reply related
* [PATCH/RFC] mm: add vm_area_add_early()
From: Nicolas Pitre @ 2011-10-07 0:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111006161056.e1cf56ec.akpm@linux-foundation.org>
On Thu, 6 Oct 2011, Andrew Morton wrote:
> On Wed, 14 Sep 2011 14:35:21 -0400 (EDT)
> Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
>
> >
> > The existing vm_area_register_early() allows for early vmalloc space
> > allocation. However upcoming cleanups in the ARM architecture require
> > that some fixed locations in the vmalloc area be reserved also very early.
> >
> > The name "vm_area_register_early" would have been a good name for the
> > reservation part without the allocation. Since it is already in use with
> > different semantics, let's create vm_area_add_early() instead.
> >
> > Both vm_area_register_early() and vm_area_add_early() can be used together
> > meaning that the former is now implemented using the later where it is
> > ensured that no conflicting areas are added, but no attempt is made to
> > make the allocation scheme in vm_area_register_early() more sophisticated.
> > After all, you must know what you're doing when using those functions.
> >
> > Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
> > ---
> >
> > Comments / ACKs appreciated.
>
> Deafening silence?
I interpreted it as "no objections".
> > diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
> > index 9332e52ea8..e7d2cba995 100644
> > --- a/include/linux/vmalloc.h
> > +++ b/include/linux/vmalloc.h
> > @@ -130,6 +130,7 @@ extern long vwrite(char *buf, char *addr, unsigned long count);
> > */
> > extern rwlock_t vmlist_lock;
> > extern struct vm_struct *vmlist;
> > +extern __init void vm_area_add_early(struct vm_struct *vm);
> > extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
> >
> > #ifdef CONFIG_SMP
> > diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> > index 7ef0903058..bf20a0ff95 100644
> > --- a/mm/vmalloc.c
> > +++ b/mm/vmalloc.c
> > @@ -1118,6 +1118,31 @@ void *vm_map_ram(struct page **pages, unsigned int count, int node, pgprot_t pro
> > EXPORT_SYMBOL(vm_map_ram);
> >
> > /**
> > + * vm_area_add_early - add vmap area early during boot
> > + * @vm: vm_struct to add
> > + *
> > + * This function is used to add fixed kernel vm area to vmlist before
> > + * vmalloc_init() is called. @vm->addr, @vm->size, and @vm->flags
> > + * should contain proper values and the other fields should be zero.
> > + *
> > + * DO NOT USE THIS FUNCTION UNLESS YOU KNOW WHAT YOU'RE DOING.
> > + */
> > +void __init vm_area_add_early(struct vm_struct *vm)
> > +{
> > + struct vm_struct *tmp, **p;
> > +
> > + for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) {
> > + if (tmp->addr >= vm->addr) {
> > + BUG_ON(tmp->addr < vm->addr + vm->size);
> > + break;
> > + } else
> > + BUG_ON(tmp->addr + tmp->size > vm->addr);
> > + }
> > + vm->next = *p;
> > + *p = vm;
> > +}
> > +
> > +/**
> > * vm_area_register_early - register vmap area early during boot
> > * @vm: vm_struct to register
> > * @align: requested alignment
> > @@ -1139,8 +1164,7 @@ void __init vm_area_register_early(struct vm_struct *vm, size_t align)
> >
> > vm->addr = (void *)addr;
> >
> > - vm->next = vmlist;
> > - vmlist = vm;
> > + vm_area_add_early(vm);
> > }
> >
> > void __init vmalloc_init(void)
>
> I tossed this into my tree for a bit of testing, assuming it's
> up-to-date and still desired?
Yes it is, on both counts.
> Feel free to add it to some ARM tree. I'll drop my copy when that
> turns up in linux-next.
So I did, however I'm postponing the whole series that depend on this to
the next cycle because of other prerequisite cleanups that are going in
this cycle from different paths.
> Yes, the naming scheme in there is gruseome.
I didn't want to go as far as renaming it across the tree, in case other
people are relying on the current name in their own tree.
Nicolas
^ permalink raw reply
* [PATCH v2 5/6] OMAP3+: Update DPLL Fint range for OMAP36xx and OMAP4xxx devices
From: Paul Walmsley @ 2011-10-07 1:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316195322-15062-1-git-send-email-jon-hunter@ti.com>
On Fri, 16 Sep 2011, Jon Hunter wrote:
> From: Jon Hunter <jon-hunter@ti.com>
>
> The OMAP36xx and OMAP4xxx DPLLs have a different internal reference
> clock frequency (fint) operating range than OMAP3430. Update the
> dpll_test_fint() function to check for the correct frequency ranges
> for OMAP36xx and OMAP4xxx.
>
> For OMAP36xx and OMAP4xxx devices, DPLLs fint range is 0.5MHz to
> 2.5MHz for j-type DPLLs and otherwise it is 32KHz to 52MHz for all
> other DPLLs.
>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
This looks okay to me for now - queued for 3.2. Ideally we would move the
Fint DPLL data to the struct dpll_data, but this would be a fairly
significant undertaking, since we don't have a clean way to use different
dpll_data for different OMAP3 variants. Something good to keep in mind
for the common clock conversion.
thanks,
- Paul
^ permalink raw reply
* [PATCH v2 6/6] OMAP4: Clock: Correct the name of SLIMBUS interface clocks
From: Paul Walmsley @ 2011-10-07 1:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316195330-15099-1-git-send-email-jon-hunter@ti.com>
+ Beno?t
On Fri, 16 Sep 2011, Jon Hunter wrote:
> From: Jon Hunter <jon-hunter@ti.com>
>
> Currently the interface clocks for the two SLIMBUS peripherals are
> named slimbus1_fck and slimbus2_fck. Rename these clocks to be
> slimbus1_ick and slimbus2_ick so it is clear that these are
> interface clocks and not functional clocks.
>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
This one, I don't quite understand. We should probably be removing these
MODULEMODE-only clocks from the OMAP4 tree, and using their parent clock
as the main_clk. That would be a good cleanup for 3.3...
- Paul
^ permalink raw reply
* [PATCH] ARM: tegra: fix compilation error due to mach/hardware.h removal
From: Olof Johansson @ 2011-10-07 2:23 UTC (permalink / raw)
To: linux-arm-kernel
From: Marc Dietrich <marvin24@gmx.de>
This fixes a compilation error in cpu-tegra.c which was introduced
in commit dc8d966bccde0b8b6c9e8c6e663c747030c17435 which removed
the now obsolete mach/hardware.h from the mach-tegra subtree.
Signed-off-by: Marc Dietrich <marvin24@gmx.de>
Signed-off-by: Olof Johansson <olof@lixom.net>
---
Linus, last minute build fix. Not sure of Arnd is planning another merge
before release so sending directly.
arch/arm/mach-tegra/cpu-tegra.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
index 0e1016a..0e0fd4d 100644
--- a/arch/arm/mach-tegra/cpu-tegra.c
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -32,7 +32,6 @@
#include <asm/system.h>
-#include <mach/hardware.h>
#include <mach/clk.h>
/* Frequency table index must be sequential starting at 0 */
--
1.7.4.1
^ permalink raw reply related
* [PATCH 01/26] usb/gadget/pxa25x: is_vbus_present is gone
From: Eric Miao @ 2011-10-07 2:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317499438-14058-2-git-send-email-arnd@arndb.de>
On Sun, Oct 2, 2011 at 4:03 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> A recent commit obsoleted the is_vbus_present function, so
> we must not use it any more.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Cc: Felipe Balbi <balbi@ti.com>
Acked-by: Eric Miao <eric.y.miao@gmail.com>
> ---
> ?drivers/usb/gadget/pxa25x_udc.h | ? ?8 +-------
> ?1 files changed, 1 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/usb/gadget/pxa25x_udc.h b/drivers/usb/gadget/pxa25x_udc.h
> index f572c56..6119900 100644
> --- a/drivers/usb/gadget/pxa25x_udc.h
> +++ b/drivers/usb/gadget/pxa25x_udc.h
> @@ -161,8 +161,6 @@ static struct pxa25x_udc *the_controller;
>
> ?#ifdef DEBUG
>
> -static int is_vbus_present(void);
> -
> ?static const char *state_name[] = {
> ? ? ? ?"EP0_IDLE",
> ? ? ? ?"EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE",
> @@ -214,8 +212,7 @@ dump_state(struct pxa25x_udc *dev)
> ? ? ? ?u32 ? ? ? ? ? ? tmp;
> ? ? ? ?unsigned ? ? ? ?i;
>
> - ? ? ? DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
> - ? ? ? ? ? ? ? is_vbus_present() ? "host " : "disconnected",
> + ? ? ? DMSG("%s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
> ? ? ? ? ? ? ? ?state_name[dev->ep0state],
> ? ? ? ? ? ? ? ?UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL);
> ? ? ? ?dump_udccr("udccr");
> @@ -232,9 +229,6 @@ dump_state(struct pxa25x_udc *dev)
> ? ? ? ?} else
> ? ? ? ? ? ? ? ?DMSG("ep0 driver '%s'\n", dev->driver->driver.name);
>
> - ? ? ? if (!is_vbus_present())
> - ? ? ? ? ? ? ? return;
> -
> ? ? ? ?dump_udccs0 ("udccs0");
> ? ? ? ?DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n",
> ? ? ? ? ? ? ? ?dev->stats.write.bytes, dev->stats.write.ops,
> --
> 1.7.5.4
>
>
^ permalink raw reply
* [RFC/PATCH v2 0/7] ARM11 MPCore: preemption/task migration cache coherency fixups
From: gdavis at mvista.com @ 2011-10-07 2:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317877714-11355-1-git-send-email-gdavis@mvista.com>
Greetings,
On ARM11 MPCore, the "SCU does not handle coherency consequences of CP15
cache operations" [1]. ?So cache maintenance functions have to insure
that memory is globally consistent. ?Although the current Linux kernel
works reasonably well on ARM11 MPCore machines, PREEMPT stress testing,
e.g. parallel module loading and hackbench, results in crashes which
exhibit non-sense oops traces where machine state does not make sense
relative to the code executing at the time of the oops.
Review and analysis of the various ARM11 MPCore cache maintenance
functions reveal that there are a number critical sections in which
ARM11 MPCore caches and/or memory may become inconsistent, i.e. a
cache line on CPU A contains a modified entry but preemption and task
migration occurs after which the same cache line is cleaned/flushed
on CPU B. ?This can obviously lead to inconsistent memory and/or
cache state as cache ops on ARM11 MPCore are non-coherent.
The following is a partial series of ARM11 MPCore preemption/task
migration fixes to resolve cache coherency problems on these machines:
George G. Davis (6):
ARM: ARM11 MPCore: pte_alloc_one{,_kernel} are not preempt safe
ARM: ARM11 MPCore: {clean,flush}_pmd_entry are not preempt safe
ARM: ARM11 MPCore: clean_dcache_area is not preempt safe
ARM: Move get_thread_info macro definition to <asm/assembler.h>
ARM: ARM11 MPCore: DMA_CACHE_RWFO operations are not preempt safe
ARM: ARM11 MPCore: cpu_v6_set_pte_ext is not preempt safe
Konstantin Baidarov (1):
ARM: ARM11 MPCore: pgd_alloc is not preempt safe
arch/arm/include/asm/assembler.h | 13 +++++++++++++
arch/arm/include/asm/pgalloc.h | 23 ++++++++++++++++++++---
arch/arm/include/asm/pgtable.h | 9 +++++++++
arch/arm/include/asm/smp_plat.h | 2 ++
arch/arm/kernel/entry-header.S | 11 -----------
arch/arm/mm/cache-v6.S | 27 +++++++++++++++++++++++++++
arch/arm/mm/idmap.c | 5 +++++
arch/arm/mm/ioremap.c | 9 +++++++++
arch/arm/mm/mmu.c | 12 ++++++++++++
arch/arm/mm/pgd.c | 7 +++++++
arch/arm/mm/proc-v6.S | 11 +++++++++++
arch/arm/plat-omap/iommu.c | 10 ++++++++++
arch/arm/vfp/entry.S | 5 ++++-
arch/arm/vfp/vfphw.S | 5 ++++-
14 files changed, 133 insertions(+), 16 deletions(-)
ChangeLog:
V2:
- Substitute {get,put}_cpu() with preempt_{disable,enable}().
- Fixed preempt {dis,en}able assembler code sequences to not
use r11 since it is reserved for frame pointer use. Also
optimised these sequences to use r2, r3; ip scratch registers
in most cases to eliminate stack push/pop. In one case,
cpu_v6_set_pte_ext, there are only two scratch registers
available, r3 and ip. However, both of these are used within
the armv6_set_pte_ext macro. So for this case, r3 is used
as a temporary scratch when disabling preemption and r4 and
r5 are pushed/popped as needed for other uses to avoid
conflict with scratch register usage in armv6_set_pte_ext.
- Remove incorrect use of ALT_SMP macros in cpu_v6_set_pte_ext,
making the preempt {dis,en}able assembler code sequences
compile time dependent upon CONFIG_SMP instead. This code
is safe on UP machines anyway.
The above changes are among the "low hanging fruit" where the
workarounds are relatively low impact from a performance and/or
implementation effort perspective. ?I'm still working on fixes
for the harder problems. ?Also, I believe that Catalin's "ARM: Allow
lazy cache flushing on ARM11MPCore" [2][3] is required for ARM11
MPCore machines and would like to see that or similar/alternative
solution applied.
Comments/feedback greatly appreciated.
TIA!
--
Regards,
George
[1] http://infocenter.arm.com/help/topic/com.arm.doc.dai0228a/index.html#arm_toc9
[2] http://www.spinics.net/lists/arm-kernel/msg129403.html
[3] http://lists.infradead.org/pipermail/linux-arm-kernel/2010-May/014990.html
^ permalink raw reply
* [RFC/PATCH 1/7] ARM: ARM11 MPCore: pgd_alloc is not preempt safe
From: gdavis at mvista.com @ 2011-10-07 2:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317955121-28047-1-git-send-email-gdavis@mvista.com>
From: Konstantin Baidarov <kbaidarov@mvista.com>
If preemption and subsequent task migration occurs during a call to
pgd_alloc on ARM11 MPCore machines, global memory state can become
inconsistent. To prevent inconsistent memory state on these
machines, disable preemption around initialization and flushing
of new PGDs.
Signed-off-by: Konstantin Baidarov <kbaidarov@mvista.com>
Signed-off-by: George G. Davis <gdavis@mvista.com>
---
arch/arm/mm/pgd.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index b2027c1..e608981 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -14,6 +14,7 @@
#include <asm/pgalloc.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
+#include <asm/smp_plat.h>
#include "mm.h"
@@ -31,6 +32,9 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
if (!new_pgd)
goto no_pgd;
+ if (cache_ops_need_broadcast())
+ preempt_disable();
+
memset(new_pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
/*
@@ -42,6 +46,9 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
+ if (cache_ops_need_broadcast())
+ preempt_enable();
+
if (!vectors_high()) {
/*
* On ARM, first page must always be allocated since it
--
1.7.4.4
^ permalink raw reply related
* [RFC/PATCH 2/7] ARM: ARM11 MPCore: pte_alloc_one{, _kernel} are not preempt safe
From: gdavis at mvista.com @ 2011-10-07 2:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317955121-28047-1-git-send-email-gdavis@mvista.com>
From: George G. Davis <gdavis@mvista.com>
If preemption and subsequent task migration occurs during a call to
pte_alloc_one{,_kernel} on ARM11 MPCore machines, global memory state
can become inconsistent. To prevent inconsistent memory state on
these machines, disable preemption around initialization and flushing
of new PTEs.
Signed-off-by: George G. Davis <gdavis@mvista.com>
---
arch/arm/include/asm/pgalloc.h | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 22de005..2154ccab 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -17,6 +17,7 @@
#include <asm/processor.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
+#include <asm/smp_plat.h>
#define check_pgt_cache() do { } while (0)
@@ -35,7 +36,7 @@
extern pgd_t *pgd_alloc(struct mm_struct *mm);
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
-#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
+#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT)
static inline void clean_pte_table(pte_t *pte)
{
@@ -64,8 +65,14 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
pte_t *pte;
pte = (pte_t *)__get_free_page(PGALLOC_GFP);
- if (pte)
+ if (pte) {
+ if (cache_ops_need_broadcast())
+ preempt_disable();
+ memset(pte, 0, PAGE_SIZE);
clean_pte_table(pte);
+ if (cache_ops_need_broadcast())
+ preempt_enable();
+ }
return pte;
}
@@ -81,8 +88,14 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
pte = alloc_pages(PGALLOC_GFP, 0);
#endif
if (pte) {
+ void *p = page_address(pte);
+ if (cache_ops_need_broadcast())
+ preempt_disable();
+ memset(p, 0, PAGE_SIZE);
if (!PageHighMem(pte))
- clean_pte_table(page_address(pte));
+ clean_pte_table(p);
+ if (cache_ops_need_broadcast())
+ preempt_enable();
pgtable_page_ctor(pte);
}
--
1.7.4.4
^ permalink raw reply related
* [RFC/PATCH 3/7] ARM: ARM11 MPCore: {clean, flush}_pmd_entry are not preempt safe
From: gdavis at mvista.com @ 2011-10-07 2:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317955121-28047-1-git-send-email-gdavis@mvista.com>
From: George G. Davis <gdavis@mvista.com>
If preemption and subsequent task migration occurs during calls to
{clean,flush}_pmd_entry on ARM11 MPCore machines, global memory state
can become inconsistent. To prevent inconsistent memory state on
these machines, disable preemption in callers of these functions around
PMD modifications and subsequent {clean,flush}_pmd_entry calls.
Signed-off-by: George G. Davis <gdavis@mvista.com>
---
arch/arm/include/asm/pgalloc.h | 4 ++++
arch/arm/include/asm/pgtable.h | 9 +++++++++
arch/arm/include/asm/smp_plat.h | 2 ++
arch/arm/mm/idmap.c | 5 +++++
arch/arm/mm/ioremap.c | 9 +++++++++
arch/arm/mm/mmu.c | 12 ++++++++++++
6 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 2154ccab..e3c45b1 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -121,9 +121,13 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
unsigned long prot)
{
unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
+ if (cache_ops_need_broadcast())
+ preempt_disable();
pmdp[0] = __pmd(pmdval);
pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
flush_pmd_entry(pmdp);
+ if (cache_ops_need_broadcast())
+ preempt_enable();
}
/*
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 5750704..00068dc 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -13,6 +13,7 @@
#include <linux/const.h>
#include <asm-generic/4level-fixup.h>
#include <asm/proc-fns.h>
+#include <asm/smp_plat.h>
#ifndef CONFIG_MMU
@@ -313,16 +314,24 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define copy_pmd(pmdpd,pmdps) \
do { \
+ if (cache_ops_need_broadcast()) \
+ preempt_disable(); \
pmdpd[0] = pmdps[0]; \
pmdpd[1] = pmdps[1]; \
flush_pmd_entry(pmdpd); \
+ if (cache_ops_need_broadcast()) \
+ preempt_enable(); \
} while (0)
#define pmd_clear(pmdp) \
do { \
+ if (cache_ops_need_broadcast()) \
+ preempt_disable(); \
pmdp[0] = __pmd(0); \
pmdp[1] = __pmd(0); \
clean_pmd_entry(pmdp); \
+ if (cache_ops_need_broadcast()) \
+ preempt_enable(); \
} while (0)
static inline pte_t *pmd_page_vaddr(pmd_t pmd)
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
index f24c1b9..5a8d3df 100644
--- a/arch/arm/include/asm/smp_plat.h
+++ b/arch/arm/include/asm/smp_plat.h
@@ -5,6 +5,7 @@
#ifndef __ASMARM_SMP_PLAT_H
#define __ASMARM_SMP_PLAT_H
+#ifndef __ASSEMBLY__
#include <asm/cputype.h>
/*
@@ -42,5 +43,6 @@ static inline int cache_ops_need_broadcast(void)
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
}
#endif
+#endif
#endif
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 2be9139..c04face 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -3,17 +3,22 @@
#include <asm/cputype.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
+#include <asm/smp_plat.h>
static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
unsigned long prot)
{
pmd_t *pmd = pmd_offset(pud, addr);
+ if (cache_ops_need_broadcast())
+ preempt_disable();
addr = (addr & PMD_MASK) | prot;
pmd[0] = __pmd(addr);
addr += SECTION_SIZE;
pmd[1] = __pmd(addr);
flush_pmd_entry(pmd);
+ if (cache_ops_need_broadcast())
+ preempt_enable();
}
static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index ab50627..b56d78a 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -32,6 +32,7 @@
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/sizes.h>
+#include <asm/smp_plat.h>
#include <asm/mach/map.h>
#include "mm.h"
@@ -135,11 +136,15 @@ remap_area_sections(unsigned long virt, unsigned long pfn,
do {
pmd_t *pmd = pmd_offset(pgd, addr);
+ if (cache_ops_need_broadcast())
+ preempt_disable();
pmd[0] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
pfn += SZ_1M >> PAGE_SHIFT;
pmd[1] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
pfn += SZ_1M >> PAGE_SHIFT;
flush_pmd_entry(pmd);
+ if (cache_ops_need_broadcast())
+ preempt_enable();
addr += PGDIR_SIZE;
pgd++;
@@ -172,9 +177,13 @@ remap_area_supersections(unsigned long virt, unsigned long pfn,
for (i = 0; i < 8; i++) {
pmd_t *pmd = pmd_offset(pgd, addr);
+ if (cache_ops_need_broadcast())
+ preempt_disable();
pmd[0] = __pmd(super_pmd_val);
pmd[1] = __pmd(super_pmd_val);
flush_pmd_entry(pmd);
+ if (cache_ops_need_broadcast())
+ preempt_enable();
addr += PGDIR_SIZE;
pgd++;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 594d677..3c8253f 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -567,12 +567,24 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
if (addr & SECTION_SIZE)
pmd++;
+ if (cache_ops_need_broadcast())
+ preempt_disable();
do {
*pmd = __pmd(phys | type->prot_sect);
phys += SECTION_SIZE;
} while (pmd++, addr += SECTION_SIZE, addr != end);
+ /* FIXME: Multiple PMD entries may be written above
+ * but only one cache line, up to 8 PMDs depending
+ * on the alignment of this mapping, is flushed below.
+ * IFF this mapping spans >8MiB, then only the first
+ * 8MiB worth of entries will be flushed. Entries
+ * above the 8MiB limit will not be flushed if I
+ * read this correctly.
+ */
flush_pmd_entry(p);
+ if (cache_ops_need_broadcast())
+ preempt_enable();
} else {
/*
* No need to loop; pte's aren't interested in the
--
1.7.4.4
^ permalink raw reply related
* [RFC/PATCH 4/7] ARM: ARM11 MPCore: clean_dcache_area is not preempt safe
From: gdavis at mvista.com @ 2011-10-07 2:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317955121-28047-1-git-send-email-gdavis@mvista.com>
From: George G. Davis <gdavis@mvista.com>
If preemption and subsequent task migration occurs during calls to
clean_dcache_area on ARM11 MPCore machines, global memory state
can become inconsistent. To prevent inconsistent memory state on
these machines, disable preemption in callers of these functions
around memory modifications and subsequent clean_dcache_area calls.
Signed-off-by: George G. Davis <gdavis@mvista.com>
---
arch/arm/plat-omap/iommu.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index 34fc31e..59836d1 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -1014,8 +1014,12 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
err = -ENOMEM;
goto err_pgd;
}
+ if (cache_ops_need_broadcast())
+ preempt_disable();
memset(p, 0, IOPGD_TABLE_SIZE);
clean_dcache_area(p, IOPGD_TABLE_SIZE);
+ if (cache_ops_need_broadcast())
+ preempt_enable();
obj->iopgd = p;
BUG_ON(!IS_ALIGNED((unsigned long)obj->iopgd, IOPGD_TABLE_SIZE));
@@ -1069,7 +1073,13 @@ static struct platform_driver omap_iommu_driver = {
static void iopte_cachep_ctor(void *iopte)
{
+ if (cache_ops_need_broadcast())
+ preempt_disable();
+ /* FIXME: This will not work on ARM11 MPCore.
+ */
clean_dcache_area(iopte, IOPTE_TABLE_SIZE);
+ if (cache_ops_need_broadcast())
+ preempt_enable();
}
static int __init omap_iommu_init(void)
--
1.7.4.4
^ permalink raw reply related
* [RFC/PATCH 5/7] ARM: Move get_thread_info macro definition to <asm/assembler.h>
From: gdavis at mvista.com @ 2011-10-07 2:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317955121-28047-1-git-send-email-gdavis@mvista.com>
From: George G. Davis <gdavis@mvista.com>
The get_thread_info assembler macro is currently defined in
arch/arm/kernel/entry-header.S and used in the following
files:
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-common.S
arch/arm/vfp/vfphw.S
arch/arm/vfp/entry.S
The first two cases above use #include "entry-header.S" while
the later two cases use #include "../kernel/entry-header.S"
to obtain the get_thread_info assembler macro definition.
Move the get_thread_info assembler macro definition into
arch/arm/include/asm/assember.h and clean up inclusion
of this macro definition to use #include <asm/assember.h>.
This change facilitates use of the get_thread_info assembler
macro in other assembler functions without more of the same
path relative include directives.
Signed-off-by: George G. Davis <gdavis@mvista.com>
---
arch/arm/include/asm/assembler.h | 13 +++++++++++++
| 11 -----------
arch/arm/vfp/entry.S | 5 ++++-
arch/arm/vfp/vfphw.S | 5 ++++-
4 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 29035e8..78397d0 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -23,6 +23,19 @@
#include <asm/ptrace.h>
#include <asm/domain.h>
+#ifndef CONFIG_THUMB2_KERNEL
+ .macro get_thread_info, rd
+ mov \rd, sp, lsr #13
+ mov \rd, \rd, lsl #13
+ .endm
+#else /* CONFIG_THUMB2_KERNEL */
+ .macro get_thread_info, rd
+ mov \rd, sp
+ lsr \rd, \rd, #13
+ mov \rd, \rd, lsl #13
+ .endm
+#endif /* !CONFIG_THUMB2_KERNEL */
+
/*
* Endian independent macros for shifting bytes within registers.
*/
--git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 9a8531e..d03b6a9 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -108,11 +108,6 @@
movs pc, lr @ return & move spsr_svc into cpsr
.endm
- .macro get_thread_info, rd
- mov \rd, sp, lsr #13
- mov \rd, \rd, lsl #13
- .endm
-
@
@ 32-bit wide "mov pc, reg"
@
@@ -148,12 +143,6 @@
movs pc, lr @ return & move spsr_svc into cpsr
.endm
- .macro get_thread_info, rd
- mov \rd, sp
- lsr \rd, \rd, #13
- mov \rd, \rd, lsl #13
- .endm
-
@
@ 32-bit wide "mov pc, reg"
@
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index 4fa9903..e475a5a 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -15,9 +15,12 @@
* r10 = thread_info structure
* lr = failure return
*/
+#include <linux/init.h>
+#include <linux/linkage.h>
#include <asm/thread_info.h>
#include <asm/vfpmacros.h>
-#include "../kernel/entry-header.S"
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
ENTRY(do_vfp)
#ifdef CONFIG_PREEMPT
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 2d30c7f..68ca5af 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -14,9 +14,12 @@
* r10 points at the start of the private FP workspace in the thread structure
* sp points to a struct pt_regs (as defined in include/asm/proc/ptrace.h)
*/
+#include <linux/init.h>
+#include <linux/linkage.h>
#include <asm/thread_info.h>
#include <asm/vfpmacros.h>
-#include "../kernel/entry-header.S"
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
.macro DBGSTR, str
#ifdef DEBUG
--
1.7.4.4
^ permalink raw reply related
* [RFC/PATCH 6/7] ARM: ARM11 MPCore: DMA_CACHE_RWFO operations are not preempt safe
From: gdavis at mvista.com @ 2011-10-07 2:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317955121-28047-1-git-send-email-gdavis@mvista.com>
From: George G. Davis <gdavis@mvista.com>
The DMA_CACHE_RWFO operations are not preempt safe. If preemption
occurs immediately following a RWFO operation on a cache line of
CPU A, it is possible for task migration to occur on resume at
which point the subsequent cache maintenance operation on the
same cache line of CPU B will have no affect on the CPU A cache
line leading to inconsistent memory and/or cache state. To prevent
this, disable preemption during RWFO operations.
This change depends on "ARM: Move get_thread_info macro definition
to <asm/assembler.h>".
Signed-off-by: George G. Davis <gdavis@mvista.com>
---
arch/arm/mm/cache-v6.S | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 74c2e5a..9c44752 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -205,6 +205,12 @@ ENTRY(v6_flush_kern_dcache_area)
*/
v6_dma_inv_range:
#ifdef CONFIG_DMA_CACHE_RWFO
+#ifdef CONFIG_PREEMPT
+ get_thread_info ip
+ ldr r3, [ip, #TI_PREEMPT] @ get preempt count
+ add r2, r3, #1 @ increment it
+ str r2, [ip, #TI_PREEMPT] @ disable preempt
+#endif
ldrb r2, [r0] @ read for ownership
strb r2, [r0] @ write for ownership
#endif
@@ -241,6 +247,9 @@ v6_dma_inv_range:
blo 1b
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+#if defined(CONFIG_DMA_CACHE_RWFO) && defined(CONFIG_PREEMPT)
+ str r3, [ip, #TI_PREEMPT] @ restore preempt count
+#endif
mov pc, lr
/*
@@ -249,6 +258,12 @@ v6_dma_inv_range:
* - end - virtual end address of region
*/
v6_dma_clean_range:
+#if defined(CONFIG_DMA_CACHE_RWFO) && defined(CONFIG_PREEMPT)
+ get_thread_info ip
+ ldr r3, [ip, #TI_PREEMPT] @ get preempt count
+ add r2, r3, #1 @ increment it
+ str r2, [ip, #TI_PREEMPT] @ disable preempt
+#endif
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
#ifdef CONFIG_DMA_CACHE_RWFO
@@ -264,6 +279,9 @@ v6_dma_clean_range:
blo 1b
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+#if defined(CONFIG_DMA_CACHE_RWFO) && defined(CONFIG_PREEMPT)
+ str r3, [ip, #TI_PREEMPT] @ restore preempt count
+#endif
mov pc, lr
/*
@@ -273,6 +291,12 @@ v6_dma_clean_range:
*/
ENTRY(v6_dma_flush_range)
#ifdef CONFIG_DMA_CACHE_RWFO
+#ifdef CONFIG_PREEMPT
+ get_thread_info ip
+ ldr r3, [ip, #TI_PREEMPT] @ get preempt count
+ add r2, r3, #1 @ increment it
+ str r2, [ip, #TI_PREEMPT] @ disable preempt
+#endif
ldrb r2, [r0] @ read for ownership
strb r2, [r0] @ write for ownership
#endif
@@ -292,6 +316,9 @@ ENTRY(v6_dma_flush_range)
blo 1b
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+#if defined(CONFIG_DMA_CACHE_RWFO) && defined(CONFIG_PREEMPT)
+ str r3, [ip, #TI_PREEMPT] @ restore preempt count
+#endif
mov pc, lr
/*
--
1.7.4.4
^ permalink raw reply related
* [RFC/PATCH 7/7] ARM: ARM11 MPCore: cpu_v6_set_pte_ext is not preempt safe
From: gdavis at mvista.com @ 2011-10-07 2:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317955121-28047-1-git-send-email-gdavis@mvista.com>
From: George G. Davis <gdavis@mvista.com>
If preemption and subsequent task migration occurs during calls to
cpu_v6_set_pte_ext on ARM11 MPCore machines, global memory state
can become inconsistent. To prevent inconsistent memory state on
these machines, disable preemption in cpu_v6_set_pte_ext.
This change depends on "ARM: Move get_thread_info macro definition
to <asm/assembler.h>".
Signed-off-by: George G. Davis <gdavis@mvista.com>
---
arch/arm/mm/proc-v6.S | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index a923aa0..57b359d 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -122,7 +122,18 @@ ENTRY(cpu_v6_switch_mm)
ENTRY(cpu_v6_set_pte_ext)
#ifdef CONFIG_MMU
+#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
+ stmdb sp!, {r4, r5}
+ get_thread_info r5
+ ldr r4, [r5, #TI_PREEMPT] @ get preempt count
+ add r3, r4, #1 @ increment it
+ str r3, [r5, #TI_PREEMPT] @ disable preempt
+#endif
armv6_set_pte_ext cpu_v6
+#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
+ str r4, [r5, #TI_PREEMPT] @ restore preempt count
+ ldmia sp!, {r4, r5}
+#endif
#endif
mov pc, lr
--
1.7.4.4
^ permalink raw reply related
* [PATCH 0/14] Sparse fixes for tegra
From: Olof Johansson @ 2011-10-07 2:54 UTC (permalink / raw)
To: linux-arm-kernel
Some trivial fixes removing sparse warnings on tegra code.
-Olof
^ permalink raw reply
* [PATCH 01/14] ARM: tegra: add __force to IO_ADDRESS
From: Olof Johansson @ 2011-10-07 2:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317956064-17650-1-git-send-email-olof@lixom.net>
Kills loads of sparse errors such as:
arch/arm/mach-tegra/fuse.c:44:12: warning: incorrect type in argument 1 (different base types)
arch/arm/mach-tegra/fuse.c:44:12: expected void const volatile [noderef] <asn:2>*<noident>
arch/arm/mach-tegra/fuse.c:44:12: got unsigned int
Signed-off-by: Olof Johansson <olof@lixom.net>
---
arch/arm/mach-tegra/include/mach/io.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
index 4cea2230..d27e340 100644
--- a/arch/arm/mach-tegra/include/mach/io.h
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -71,7 +71,7 @@
void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type);
void tegra_iounmap(volatile void __iomem *addr);
-#define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n))
+#define IO_ADDRESS(n) ((void __force __iomem *) IO_TO_VIRT(n))
#ifdef CONFIG_TEGRA_PCI
extern void __iomem *tegra_pcie_io_base;
--
1.7.4.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox