summaryrefslogtreecommitdiff
path: root/arch/arm/mach-rpc
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2019-05-01 14:10:42 +0300
committerRussell King <rmk+kernel@armlinux.org.uk>2019-06-11 19:40:50 +0300
commit1eac59d731ca7ead31f57ea2b8c82e0ba117f6cf (patch)
tree45cb37dbb5c1aff1fef2e8483a730b8fb84cb2db /arch/arm/mach-rpc
parent090a37ceda3ecb02061a1415239aa1a64c184833 (diff)
downloadlinux-1eac59d731ca7ead31f57ea2b8c82e0ba117f6cf.tar.xz
ARM: riscpc: add ecard quirk for Atomwide 3port serial card
Atomwide 3port serial cards seem to leave their interrupts active when exiting RISC OS, resulting in an interrupt storm during boot, and the expansion card interrupt being disabled. Avoid this by manually disabling the interrupt on each serial port via a custom quirk function. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'arch/arm/mach-rpc')
-rw-r--r--arch/arm/mach-rpc/ecard.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c
index 3e7b81cc4274..eec5ecd6e948 100644
--- a/arch/arm/mach-rpc/ecard.c
+++ b/arch/arm/mach-rpc/ecard.c
@@ -70,17 +70,21 @@ struct expcard_blacklist {
unsigned short manufacturer;
unsigned short product;
const char *type;
+ void (*init)(ecard_t *ec);
};
static ecard_t *cards;
static ecard_t *slot_to_expcard[MAX_ECARDS];
static unsigned int ectcr;
+static void atomwide_3p_quirk(ecard_t *ec);
+
/* List of descriptions of cards which don't have an extended
* identification, or chunk directories containing a description.
*/
static struct expcard_blacklist __initdata blacklist[] = {
- { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
+ { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" },
+ { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL, NULL, atomwide_3p_quirk },
};
asmlinkage extern int
@@ -871,6 +875,16 @@ void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
}
EXPORT_SYMBOL(ecardm_iomap);
+static void atomwide_3p_quirk(ecard_t *ec)
+{
+ void __iomem *addr = __ecard_address(ec, ECARD_IOC, ECARD_SYNC);
+ unsigned int i;
+
+ /* Disable interrupts on each port */
+ for (i = 0x2000; i <= 0x2800; i += 0x0400)
+ writeb(0, addr + i + 4);
+}
+
/*
* Probe for an expansion card.
*
@@ -927,7 +941,10 @@ static int __init ecard_probe(int slot, unsigned irq, card_type_t type)
for (i = 0; i < ARRAY_SIZE(blacklist); i++)
if (blacklist[i].manufacturer == ec->cid.manufacturer &&
blacklist[i].product == ec->cid.product) {
- ec->card_desc = blacklist[i].type;
+ if (blacklist[i].type)
+ ec->card_desc = blacklist[i].type;
+ if (blacklist[i].init)
+ blacklist[i].init(ec);
break;
}