[PATCH] ARM: vic: fix support for PL192
Jocelyn Falempe
xhp836 at motorola.com
Mon Oct 11 07:37:39 EDT 2010
Current code works with PL192, but it writes to PL190 registers which
are removed on PL192.
---
arch/arm/common/vic.c | 46 ++++++++++++++++++++++-------------
arch/arm/include/asm/hardware/vic.h | 2 +
2 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index ba65f6e..0c2b335 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -53,6 +53,7 @@ struct vic_device {
u32 int_enable;
u32 soft_int;
u32 protect;
+ u32 id;
};
/* we cannot allocate memory when VICs are initially registered */
@@ -73,10 +74,13 @@ static inline struct vic_device *to_vic(struct
sys_device *sys)
* Common initialisation code for registeration
* and resume.
*/
-static void vic_init2(void __iomem *base)
+static void vic_init2(void __iomem *base, u32 id)
{
int i;
+ if ((id & 0xFFF) == VIC_PL192_PARTNUMBER)
+ return;
+
for (i = 0; i < 16; i++) {
void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
writel(VIC_VECT_CNTL_ENABLE | i, reg);
@@ -94,7 +98,7 @@ static int vic_class_resume(struct sys_device *dev)
printk(KERN_DEBUG "%s: resuming vic at %p\n", __func__, base);
/* re-initialise static settings */
- vic_init2(base);
+ vic_init2(base, vic->id);
writel(vic->int_select, base + VIC_INT_SELECT);
writel(vic->protect, base + VIC_PROTECT);
@@ -186,7 +190,7 @@ late_initcall(vic_pm_init);
* of suspend and resume requests and ensure that the correct actions are
* taken to re-instate the settings on resume.
*/
-static void __init vic_pm_register(void __iomem *base, unsigned int
irq, u32 resume_sources)
+static void __init vic_pm_register(void __iomem *base, unsigned int
irq, u32 resume_sources, u32 id)
{
struct vic_device *v;
@@ -197,11 +201,12 @@ static void __init vic_pm_register(void __iomem
*base, unsigned int irq, u32 res
v->base = base;
v->resume_sources = resume_sources;
v->irq = irq;
+ v->id = id;
vic_id++;
}
}
#else
-static inline void vic_pm_register(void __iomem *base, unsigned int
irq, u32 arg1) { }
+static inline void vic_pm_register(void __iomem *base, unsigned int
irq, u32 arg1, u32 id) { }
#endif /* CONFIG_PM */
static void vic_ack_irq(unsigned int irq)
@@ -283,16 +288,23 @@ static void __init vic_disable(void __iomem *base)
writel(~0, base + VIC_INT_SOFT_CLEAR);
}
-static void __init vic_clear_interrupts(void __iomem *base)
+static void __init vic_clear_interrupts(void __iomem *base, u32 id)
{
unsigned int i;
- writel(0, base + VIC_PL190_VECT_ADDR);
- for (i = 0; i < 19; i++) {
- unsigned int value;
-
- value = readl(base + VIC_PL190_VECT_ADDR);
- writel(value, base + VIC_PL190_VECT_ADDR);
+ if ((id & 0xFFF) == VIC_PL192_PARTNUMBER) {
+ /* reset priority stack by writing to the VICADDRESS
+ * register 16 times */
+ for (i = 0; i < 16; i++)
+ writel(0, base + VIC_PL192_VECT_ADDR);
+ } else {
+ writel(0, base + VIC_PL190_VECT_ADDR);
+ for (i = 0; i < 19; i++) {
+ unsigned int value;
+
+ value = readl(base + VIC_PL190_VECT_ADDR);
+ writel(value, base + VIC_PL190_VECT_ADDR);
+ }
}
}
@@ -321,7 +333,7 @@ static void __init vic_set_irq_sources(void __iomem *base,
* and 020 within the page. We call this "second block".
*/
static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
- u32 vic_sources)
+ u32 vic_sources, u32 id)
{
unsigned int i;
int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
@@ -336,7 +348,7 @@ static void __init vic_init_st(void __iomem *base,
unsigned int irq_start,
* the second base address, which is 0x20 in the page
*/
if (vic_2nd_block) {
- vic_clear_interrupts(base);
+ vic_clear_interrupts(base, id);
/* ST has 16 vectors as well, but we don't enable them by now */
for (i = 0; i < 16; i++) {
@@ -375,7 +387,7 @@ void __init vic_init(void __iomem *base, unsigned
int irq_start,
switch(vendor) {
case AMBA_VENDOR_ST:
- vic_init_st(base, irq_start, vic_sources);
+ vic_init_st(base, irq_start, vic_sources, cellid);
return;
default:
printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
@@ -388,11 +400,11 @@ void __init vic_init(void __iomem *base,
unsigned int irq_start,
vic_disable(base);
/* Make sure we clear all existing interrupts */
- vic_clear_interrupts(base);
+ vic_clear_interrupts(base, cellid);
- vic_init2(base);
+ vic_init2(base, cellid);
vic_set_irq_sources(base, irq_start, vic_sources);
- vic_pm_register(base, irq_start, resume_sources);
+ vic_pm_register(base, irq_start, resume_sources, cellid);
}
diff --git a/arch/arm/include/asm/hardware/vic.h
b/arch/arm/include/asm/hardware/vic.h
index 5d72550..260dc43 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -40,6 +40,8 @@
#define VIC_PL192_VECT_ADDR 0xF00
+#define VIC_PL192_PARTNUMBER 0x192
+
#ifndef __ASSEMBLY__
void vic_init(void __iomem *base, unsigned int irq_start, u32
vic_sources, u32 resume_sources);
#endif
--
1.7.0.4
More information about the linux-arm-kernel
mailing list