.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/arch/arm/kernel/ecard.c |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 1995-2001 Russell King |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License version 2 as |
---|
8 | | - * published by the Free Software Foundation. |
---|
9 | 6 | * |
---|
10 | 7 | * Find all installed expansion cards, and handle interrupts from them. |
---|
11 | 8 | * |
---|
.. | .. |
---|
66 | 63 | struct completion *complete; |
---|
67 | 64 | }; |
---|
68 | 65 | |
---|
69 | | -struct expcard_blacklist { |
---|
| 66 | +struct expcard_quirklist { |
---|
70 | 67 | unsigned short manufacturer; |
---|
71 | 68 | unsigned short product; |
---|
72 | 69 | const char *type; |
---|
| 70 | + void (*init)(ecard_t *ec); |
---|
73 | 71 | }; |
---|
74 | 72 | |
---|
75 | 73 | static ecard_t *cards; |
---|
76 | 74 | static ecard_t *slot_to_expcard[MAX_ECARDS]; |
---|
77 | 75 | static unsigned int ectcr; |
---|
78 | 76 | |
---|
| 77 | +static void atomwide_3p_quirk(ecard_t *ec); |
---|
| 78 | + |
---|
79 | 79 | /* List of descriptions of cards which don't have an extended |
---|
80 | 80 | * identification, or chunk directories containing a description. |
---|
81 | 81 | */ |
---|
82 | | -static struct expcard_blacklist __initdata blacklist[] = { |
---|
83 | | - { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" } |
---|
| 82 | +static struct expcard_quirklist quirklist[] __initdata = { |
---|
| 83 | + { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }, |
---|
| 84 | + { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL, NULL, atomwide_3p_quirk }, |
---|
84 | 85 | }; |
---|
85 | 86 | |
---|
86 | 87 | asmlinkage extern int |
---|
.. | .. |
---|
496 | 497 | printk("Expansion card IRQ state:\n"); |
---|
497 | 498 | |
---|
498 | 499 | for (ec = cards; ec; ec = ec->next) { |
---|
| 500 | + const char *claimed; |
---|
| 501 | + |
---|
499 | 502 | if (ec->slot_no == 8) |
---|
500 | 503 | continue; |
---|
501 | 504 | |
---|
502 | | - printk(" %d: %sclaimed, ", |
---|
503 | | - ec->slot_no, ec->claimed ? "" : "not "); |
---|
| 505 | + claimed = ec->claimed ? "" : "not "; |
---|
504 | 506 | |
---|
505 | 507 | if (ec->ops && ec->ops->irqpending && |
---|
506 | 508 | ec->ops != &ecard_default_ops) |
---|
507 | | - printk("irq %spending\n", |
---|
| 509 | + printk(" %d: %sclaimed irq %spending\n", |
---|
| 510 | + ec->slot_no, claimed, |
---|
508 | 511 | ec->ops->irqpending(ec) ? "" : "not "); |
---|
509 | 512 | else |
---|
510 | | - printk("irqaddr %p, mask = %02X, status = %02X\n", |
---|
| 513 | + printk(" %d: %sclaimed irqaddr %p, mask = %02X, status = %02X\n", |
---|
| 514 | + ec->slot_no, claimed, |
---|
511 | 515 | ec->irqaddr, ec->irqmask, readb(ec->irqaddr)); |
---|
512 | 516 | } |
---|
513 | 517 | } |
---|
.. | .. |
---|
868 | 872 | } |
---|
869 | 873 | EXPORT_SYMBOL(ecardm_iomap); |
---|
870 | 874 | |
---|
| 875 | +static void atomwide_3p_quirk(ecard_t *ec) |
---|
| 876 | +{ |
---|
| 877 | + void __iomem *addr = __ecard_address(ec, ECARD_IOC, ECARD_SYNC); |
---|
| 878 | + unsigned int i; |
---|
| 879 | + |
---|
| 880 | + /* Disable interrupts on each port */ |
---|
| 881 | + for (i = 0x2000; i <= 0x2800; i += 0x0400) |
---|
| 882 | + writeb(0, addr + i + 4); |
---|
| 883 | +} |
---|
| 884 | + |
---|
871 | 885 | /* |
---|
872 | 886 | * Probe for an expansion card. |
---|
873 | 887 | * |
---|
.. | .. |
---|
921 | 935 | ec->fiqmask = 4; |
---|
922 | 936 | } |
---|
923 | 937 | |
---|
924 | | - for (i = 0; i < ARRAY_SIZE(blacklist); i++) |
---|
925 | | - if (blacklist[i].manufacturer == ec->cid.manufacturer && |
---|
926 | | - blacklist[i].product == ec->cid.product) { |
---|
927 | | - ec->card_desc = blacklist[i].type; |
---|
| 938 | + for (i = 0; i < ARRAY_SIZE(quirklist); i++) |
---|
| 939 | + if (quirklist[i].manufacturer == ec->cid.manufacturer && |
---|
| 940 | + quirklist[i].product == ec->cid.product) { |
---|
| 941 | + if (quirklist[i].type) |
---|
| 942 | + ec->card_desc = quirklist[i].type; |
---|
| 943 | + if (quirklist[i].init) |
---|
| 944 | + quirklist[i].init(ec); |
---|
928 | 945 | break; |
---|
929 | 946 | } |
---|
930 | 947 | |
---|