diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2019-07-03 06:44:46 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2019-07-03 06:44:46 -0400 |
commit | 1f6db18fbd764ea3079eba289652b622f9c8c5ef (patch) | |
tree | 7483de89a7684b33634190220c15abc3dcf42039 | |
parent | d6c8204659eb1846c444997ee28fe9d7e5442f4e (diff) | |
parent | 0b40deeef6d94ac21f4cdee4b1cda94a69c54ff9 (diff) |
Merge branch 'sa1100-for-next'; commit 'riscpc^{/ARM: riscpc: enable chained scatterlist support}' into for-arm-soc
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | arch/arm/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-rpc/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-rpc/dma.c | 97 | ||||
-rw-r--r-- | arch/arm/mach-rpc/ecard-loader.S (renamed from arch/arm/lib/ecard.S) | 0 | ||||
-rw-r--r-- | arch/arm/mach-rpc/ecard.c | 32 | ||||
-rw-r--r-- | arch/arm/mach-rpc/floppydma.S (renamed from arch/arm/lib/floppydma.S) | 0 | ||||
-rw-r--r-- | arch/arm/mach-rpc/include/mach/uncompress.h | 23 | ||||
-rw-r--r-- | arch/arm/mach-rpc/io-acorn.S (renamed from arch/arm/lib/io-acorn.S) | 0 | ||||
-rw-r--r-- | arch/arm/mach-rpc/irq.c | 136 | ||||
-rw-r--r-- | arch/arm/mach-rpc/time.c | 38 |
12 files changed, 161 insertions, 173 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 429c6c624861..bff3200f0e82 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1229,7 +1229,7 @@ F: include/uapi/drm/panfrost_drm.h | |||
1229 | ARM MFM AND FLOPPY DRIVERS | 1229 | ARM MFM AND FLOPPY DRIVERS |
1230 | M: Ian Molton <spyro@f2s.com> | 1230 | M: Ian Molton <spyro@f2s.com> |
1231 | S: Maintained | 1231 | S: Maintained |
1232 | F: arch/arm/lib/floppydma.S | 1232 | F: arch/arm/mach-rpc/floppydma.S |
1233 | F: arch/arm/include/asm/floppy.h | 1233 | F: arch/arm/include/asm/floppy.h |
1234 | 1234 | ||
1235 | ARM PMU PROFILING AND DEBUGGING | 1235 | ARM PMU PROFILING AND DEBUGGING |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 70aebb6d2905..fe31c97c74ea 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -528,7 +528,7 @@ config ARCH_RPC | |||
528 | select ARCH_ACORN | 528 | select ARCH_ACORN |
529 | select ARCH_MAY_HAVE_PC_FDC | 529 | select ARCH_MAY_HAVE_PC_FDC |
530 | select ARCH_SPARSEMEM_ENABLE | 530 | select ARCH_SPARSEMEM_ENABLE |
531 | select ARCH_USES_GETTIMEOFFSET | 531 | select ARM_HAS_SG_CHAIN |
532 | select CPU_SA110 | 532 | select CPU_SA110 |
533 | select FIQ | 533 | select FIQ |
534 | select HAVE_IDE | 534 | select HAVE_IDE |
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 0bff0176db2c..b25c54585048 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile | |||
@@ -31,7 +31,6 @@ else | |||
31 | endif | 31 | endif |
32 | 32 | ||
33 | ifeq ($(CONFIG_ARCH_RPC),y) | 33 | ifeq ($(CONFIG_ARCH_RPC),y) |
34 | lib-y += ecard.o io-acorn.o floppydma.o | ||
35 | AFLAGS_delay-loop.o += -march=armv4 | 34 | AFLAGS_delay-loop.o += -march=armv4 |
36 | endif | 35 | endif |
37 | 36 | ||
diff --git a/arch/arm/mach-rpc/Makefile b/arch/arm/mach-rpc/Makefile index 056ef5460290..90a645a18444 100644 --- a/arch/arm/mach-rpc/Makefile +++ b/arch/arm/mach-rpc/Makefile | |||
@@ -5,4 +5,5 @@ | |||
5 | 5 | ||
6 | # Object file lists. | 6 | # Object file lists. |
7 | 7 | ||
8 | obj-y := dma.o ecard.o fiq.o irq.o riscpc.o time.o | 8 | obj-y :=dma.o ecard.o ecard-loader.o fiq.o floppydma.o io-acorn.o irq.o \ |
9 | riscpc.o time.o | ||
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c index f2703ca17954..e221f6bb935f 100644 --- a/arch/arm/mach-rpc/dma.c +++ b/arch/arm/mach-rpc/dma.c | |||
@@ -27,10 +27,11 @@ | |||
27 | 27 | ||
28 | struct iomd_dma { | 28 | struct iomd_dma { |
29 | struct dma_struct dma; | 29 | struct dma_struct dma; |
30 | unsigned int state; | 30 | void __iomem *base; /* Controller base address */ |
31 | unsigned long base; /* Controller base address */ | ||
32 | int irq; /* Controller IRQ */ | 31 | int irq; /* Controller IRQ */ |
33 | struct scatterlist cur_sg; /* Current controller buffer */ | 32 | unsigned int state; |
33 | dma_addr_t cur_addr; | ||
34 | unsigned int cur_len; | ||
34 | dma_addr_t dma_addr; | 35 | dma_addr_t dma_addr; |
35 | unsigned int dma_len; | 36 | unsigned int dma_len; |
36 | }; | 37 | }; |
@@ -53,13 +54,13 @@ typedef enum { | |||
53 | #define CR (IOMD_IO0CR - IOMD_IO0CURA) | 54 | #define CR (IOMD_IO0CR - IOMD_IO0CURA) |
54 | #define ST (IOMD_IO0ST - IOMD_IO0CURA) | 55 | #define ST (IOMD_IO0ST - IOMD_IO0CURA) |
55 | 56 | ||
56 | static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma) | 57 | static void iomd_get_next_sg(struct iomd_dma *idma) |
57 | { | 58 | { |
58 | unsigned long end, offset, flags = 0; | 59 | unsigned long end, offset, flags = 0; |
59 | 60 | ||
60 | if (idma->dma.sg) { | 61 | if (idma->dma.sg) { |
61 | sg->dma_address = idma->dma_addr; | 62 | idma->cur_addr = idma->dma_addr; |
62 | offset = sg->dma_address & ~PAGE_MASK; | 63 | offset = idma->cur_addr & ~PAGE_MASK; |
63 | 64 | ||
64 | end = offset + idma->dma_len; | 65 | end = offset + idma->dma_len; |
65 | 66 | ||
@@ -69,7 +70,7 @@ static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma) | |||
69 | if (offset + TRANSFER_SIZE >= end) | 70 | if (offset + TRANSFER_SIZE >= end) |
70 | flags |= DMA_END_L; | 71 | flags |= DMA_END_L; |
71 | 72 | ||
72 | sg->length = end - TRANSFER_SIZE; | 73 | idma->cur_len = end - TRANSFER_SIZE; |
73 | 74 | ||
74 | idma->dma_len -= end - offset; | 75 | idma->dma_len -= end - offset; |
75 | idma->dma_addr += end - offset; | 76 | idma->dma_addr += end - offset; |
@@ -87,52 +88,49 @@ static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma) | |||
87 | } | 88 | } |
88 | } else { | 89 | } else { |
89 | flags = DMA_END_S | DMA_END_L; | 90 | flags = DMA_END_S | DMA_END_L; |
90 | sg->dma_address = 0; | 91 | idma->cur_addr = 0; |
91 | sg->length = 0; | 92 | idma->cur_len = 0; |
92 | } | 93 | } |
93 | 94 | ||
94 | sg->length |= flags; | 95 | idma->cur_len |= flags; |
95 | } | 96 | } |
96 | 97 | ||
97 | static irqreturn_t iomd_dma_handle(int irq, void *dev_id) | 98 | static irqreturn_t iomd_dma_handle(int irq, void *dev_id) |
98 | { | 99 | { |
99 | struct iomd_dma *idma = dev_id; | 100 | struct iomd_dma *idma = dev_id; |
100 | unsigned long base = idma->base; | 101 | void __iomem *base = idma->base; |
102 | unsigned int state = idma->state; | ||
103 | unsigned int status, cur, end; | ||
101 | 104 | ||
102 | do { | 105 | do { |
103 | unsigned int status; | 106 | status = readb(base + ST); |
104 | |||
105 | status = iomd_readb(base + ST); | ||
106 | if (!(status & DMA_ST_INT)) | 107 | if (!(status & DMA_ST_INT)) |
107 | return IRQ_HANDLED; | 108 | goto out; |
108 | 109 | ||
109 | if ((idma->state ^ status) & DMA_ST_AB) | 110 | if ((state ^ status) & DMA_ST_AB) |
110 | iomd_get_next_sg(&idma->cur_sg, idma); | 111 | iomd_get_next_sg(idma); |
111 | 112 | ||
112 | switch (status & (DMA_ST_OFL | DMA_ST_AB)) { | 113 | // This efficiently implements state = OFL != AB ? AB : 0 |
113 | case DMA_ST_OFL: /* OIA */ | 114 | state = ((status >> 2) ^ status) & DMA_ST_AB; |
114 | case DMA_ST_AB: /* .IB */ | 115 | if (state) { |
115 | iomd_writel(idma->cur_sg.dma_address, base + CURA); | 116 | cur = CURA; |
116 | iomd_writel(idma->cur_sg.length, base + ENDA); | 117 | end = ENDA; |
117 | idma->state = DMA_ST_AB; | 118 | } else { |
118 | break; | 119 | cur = CURB; |
119 | 120 | end = ENDB; | |
120 | case DMA_ST_OFL | DMA_ST_AB: /* OIB */ | ||
121 | case 0: /* .IA */ | ||
122 | iomd_writel(idma->cur_sg.dma_address, base + CURB); | ||
123 | iomd_writel(idma->cur_sg.length, base + ENDB); | ||
124 | idma->state = 0; | ||
125 | break; | ||
126 | } | 121 | } |
122 | writel(idma->cur_addr, base + cur); | ||
123 | writel(idma->cur_len, base + end); | ||
127 | 124 | ||
128 | if (status & DMA_ST_OFL && | 125 | if (status & DMA_ST_OFL && |
129 | idma->cur_sg.length == (DMA_END_S|DMA_END_L)) | 126 | idma->cur_len == (DMA_END_S|DMA_END_L)) |
130 | break; | 127 | break; |
131 | } while (1); | 128 | } while (1); |
132 | 129 | ||
133 | idma->state = ~DMA_ST_AB; | 130 | state = ~DMA_ST_AB; |
134 | disable_irq(irq); | 131 | disable_irq_nosync(irq); |
135 | 132 | out: | |
133 | idma->state = state; | ||
136 | return IRQ_HANDLED; | 134 | return IRQ_HANDLED; |
137 | } | 135 | } |
138 | 136 | ||
@@ -160,7 +158,7 @@ static struct device isa_dma_dev = { | |||
160 | static void iomd_enable_dma(unsigned int chan, dma_t *dma) | 158 | static void iomd_enable_dma(unsigned int chan, dma_t *dma) |
161 | { | 159 | { |
162 | struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma); | 160 | struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma); |
163 | unsigned long dma_base = idma->base; | 161 | void __iomem *base = idma->base; |
164 | unsigned int ctrl = TRANSFER_SIZE | DMA_CR_E; | 162 | unsigned int ctrl = TRANSFER_SIZE | DMA_CR_E; |
165 | 163 | ||
166 | if (idma->dma.invalid) { | 164 | if (idma->dma.invalid) { |
@@ -180,27 +178,30 @@ static void iomd_enable_dma(unsigned int chan, dma_t *dma) | |||
180 | DMA_FROM_DEVICE : DMA_TO_DEVICE); | 178 | DMA_FROM_DEVICE : DMA_TO_DEVICE); |
181 | } | 179 | } |
182 | 180 | ||
183 | iomd_writeb(DMA_CR_C, dma_base + CR); | 181 | idma->dma_addr = idma->dma.sg->dma_address; |
182 | idma->dma_len = idma->dma.sg->length; | ||
183 | |||
184 | writeb(DMA_CR_C, base + CR); | ||
184 | idma->state = DMA_ST_AB; | 185 | idma->state = DMA_ST_AB; |
185 | } | 186 | } |
186 | 187 | ||
187 | if (idma->dma.dma_mode == DMA_MODE_READ) | 188 | if (idma->dma.dma_mode == DMA_MODE_READ) |
188 | ctrl |= DMA_CR_D; | 189 | ctrl |= DMA_CR_D; |
189 | 190 | ||
190 | iomd_writeb(ctrl, dma_base + CR); | 191 | writeb(ctrl, base + CR); |
191 | enable_irq(idma->irq); | 192 | enable_irq(idma->irq); |
192 | } | 193 | } |
193 | 194 | ||
194 | static void iomd_disable_dma(unsigned int chan, dma_t *dma) | 195 | static void iomd_disable_dma(unsigned int chan, dma_t *dma) |
195 | { | 196 | { |
196 | struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma); | 197 | struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma); |
197 | unsigned long dma_base = idma->base; | 198 | void __iomem *base = idma->base; |
198 | unsigned long flags; | 199 | unsigned long flags; |
199 | 200 | ||
200 | local_irq_save(flags); | 201 | local_irq_save(flags); |
201 | if (idma->state != ~DMA_ST_AB) | 202 | if (idma->state != ~DMA_ST_AB) |
202 | disable_irq(idma->irq); | 203 | disable_irq(idma->irq); |
203 | iomd_writeb(0, dma_base + CR); | 204 | writeb(0, base + CR); |
204 | local_irq_restore(flags); | 205 | local_irq_restore(flags); |
205 | } | 206 | } |
206 | 207 | ||
@@ -363,17 +364,17 @@ static int __init rpc_dma_init(void) | |||
363 | */ | 364 | */ |
364 | iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT); | 365 | iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT); |
365 | 366 | ||
366 | iomd_dma[DMA_0].base = IOMD_IO0CURA; | 367 | iomd_dma[DMA_0].base = IOMD_BASE + IOMD_IO0CURA; |
367 | iomd_dma[DMA_0].irq = IRQ_DMA0; | 368 | iomd_dma[DMA_0].irq = IRQ_DMA0; |
368 | iomd_dma[DMA_1].base = IOMD_IO1CURA; | 369 | iomd_dma[DMA_1].base = IOMD_BASE + IOMD_IO1CURA; |
369 | iomd_dma[DMA_1].irq = IRQ_DMA1; | 370 | iomd_dma[DMA_1].irq = IRQ_DMA1; |
370 | iomd_dma[DMA_2].base = IOMD_IO2CURA; | 371 | iomd_dma[DMA_2].base = IOMD_BASE + IOMD_IO2CURA; |
371 | iomd_dma[DMA_2].irq = IRQ_DMA2; | 372 | iomd_dma[DMA_2].irq = IRQ_DMA2; |
372 | iomd_dma[DMA_3].base = IOMD_IO3CURA; | 373 | iomd_dma[DMA_3].base = IOMD_BASE + IOMD_IO3CURA; |
373 | iomd_dma[DMA_3].irq = IRQ_DMA3; | 374 | iomd_dma[DMA_3].irq = IRQ_DMA3; |
374 | iomd_dma[DMA_S0].base = IOMD_SD0CURA; | 375 | iomd_dma[DMA_S0].base = IOMD_BASE + IOMD_SD0CURA; |
375 | iomd_dma[DMA_S0].irq = IRQ_DMAS0; | 376 | iomd_dma[DMA_S0].irq = IRQ_DMAS0; |
376 | iomd_dma[DMA_S1].base = IOMD_SD1CURA; | 377 | iomd_dma[DMA_S1].base = IOMD_BASE + IOMD_SD1CURA; |
377 | iomd_dma[DMA_S1].irq = IRQ_DMAS1; | 378 | iomd_dma[DMA_S1].irq = IRQ_DMAS1; |
378 | 379 | ||
379 | for (i = DMA_0; i <= DMA_S1; i++) { | 380 | for (i = DMA_0; i <= DMA_S1; i++) { |
diff --git a/arch/arm/lib/ecard.S b/arch/arm/mach-rpc/ecard-loader.S index e6057fa851bb..e6057fa851bb 100644 --- a/arch/arm/lib/ecard.S +++ b/arch/arm/mach-rpc/ecard-loader.S | |||
diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c index 04b2f22c2739..eec5ecd6e948 100644 --- a/arch/arm/mach-rpc/ecard.c +++ b/arch/arm/mach-rpc/ecard.c | |||
@@ -70,17 +70,21 @@ struct expcard_blacklist { | |||
70 | unsigned short manufacturer; | 70 | unsigned short manufacturer; |
71 | unsigned short product; | 71 | unsigned short product; |
72 | const char *type; | 72 | const char *type; |
73 | void (*init)(ecard_t *ec); | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | static ecard_t *cards; | 76 | static ecard_t *cards; |
76 | static ecard_t *slot_to_expcard[MAX_ECARDS]; | 77 | static ecard_t *slot_to_expcard[MAX_ECARDS]; |
77 | static unsigned int ectcr; | 78 | static unsigned int ectcr; |
78 | 79 | ||
80 | static void atomwide_3p_quirk(ecard_t *ec); | ||
81 | |||
79 | /* List of descriptions of cards which don't have an extended | 82 | /* List of descriptions of cards which don't have an extended |
80 | * identification, or chunk directories containing a description. | 83 | * identification, or chunk directories containing a description. |
81 | */ | 84 | */ |
82 | static struct expcard_blacklist __initdata blacklist[] = { | 85 | static struct expcard_blacklist __initdata blacklist[] = { |
83 | { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" } | 86 | { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }, |
87 | { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL, NULL, atomwide_3p_quirk }, | ||
84 | }; | 88 | }; |
85 | 89 | ||
86 | asmlinkage extern int | 90 | asmlinkage extern int |
@@ -496,18 +500,21 @@ static void ecard_dump_irq_state(void) | |||
496 | printk("Expansion card IRQ state:\n"); | 500 | printk("Expansion card IRQ state:\n"); |
497 | 501 | ||
498 | for (ec = cards; ec; ec = ec->next) { | 502 | for (ec = cards; ec; ec = ec->next) { |
503 | const char *claimed; | ||
504 | |||
499 | if (ec->slot_no == 8) | 505 | if (ec->slot_no == 8) |
500 | continue; | 506 | continue; |
501 | 507 | ||
502 | printk(" %d: %sclaimed, ", | 508 | claimed = ec->claimed ? "" : "not "; |
503 | ec->slot_no, ec->claimed ? "" : "not "); | ||
504 | 509 | ||
505 | if (ec->ops && ec->ops->irqpending && | 510 | if (ec->ops && ec->ops->irqpending && |
506 | ec->ops != &ecard_default_ops) | 511 | ec->ops != &ecard_default_ops) |
507 | printk("irq %spending\n", | 512 | printk(" %d: %sclaimed irq %spending\n", |
513 | ec->slot_no, claimed, | ||
508 | ec->ops->irqpending(ec) ? "" : "not "); | 514 | ec->ops->irqpending(ec) ? "" : "not "); |
509 | else | 515 | else |
510 | printk("irqaddr %p, mask = %02X, status = %02X\n", | 516 | printk(" %d: %sclaimed irqaddr %p, mask = %02X, status = %02X\n", |
517 | ec->slot_no, claimed, | ||
511 | ec->irqaddr, ec->irqmask, readb(ec->irqaddr)); | 518 | ec->irqaddr, ec->irqmask, readb(ec->irqaddr)); |
512 | } | 519 | } |
513 | } | 520 | } |
@@ -868,6 +875,16 @@ void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res, | |||
868 | } | 875 | } |
869 | EXPORT_SYMBOL(ecardm_iomap); | 876 | EXPORT_SYMBOL(ecardm_iomap); |
870 | 877 | ||
878 | static void atomwide_3p_quirk(ecard_t *ec) | ||
879 | { | ||
880 | void __iomem *addr = __ecard_address(ec, ECARD_IOC, ECARD_SYNC); | ||
881 | unsigned int i; | ||
882 | |||
883 | /* Disable interrupts on each port */ | ||
884 | for (i = 0x2000; i <= 0x2800; i += 0x0400) | ||
885 | writeb(0, addr + i + 4); | ||
886 | } | ||
887 | |||
871 | /* | 888 | /* |
872 | * Probe for an expansion card. | 889 | * Probe for an expansion card. |
873 | * | 890 | * |
@@ -924,7 +941,10 @@ static int __init ecard_probe(int slot, unsigned irq, card_type_t type) | |||
924 | for (i = 0; i < ARRAY_SIZE(blacklist); i++) | 941 | for (i = 0; i < ARRAY_SIZE(blacklist); i++) |
925 | if (blacklist[i].manufacturer == ec->cid.manufacturer && | 942 | if (blacklist[i].manufacturer == ec->cid.manufacturer && |
926 | blacklist[i].product == ec->cid.product) { | 943 | blacklist[i].product == ec->cid.product) { |
927 | ec->card_desc = blacklist[i].type; | 944 | if (blacklist[i].type) |
945 | ec->card_desc = blacklist[i].type; | ||
946 | if (blacklist[i].init) | ||
947 | blacklist[i].init(ec); | ||
928 | break; | 948 | break; |
929 | } | 949 | } |
930 | 950 | ||
diff --git a/arch/arm/lib/floppydma.S b/arch/arm/mach-rpc/floppydma.S index de68d3b343e3..de68d3b343e3 100644 --- a/arch/arm/lib/floppydma.S +++ b/arch/arm/mach-rpc/floppydma.S | |||
diff --git a/arch/arm/mach-rpc/include/mach/uncompress.h b/arch/arm/mach-rpc/include/mach/uncompress.h index 654a6f3f2547..edc1961e8d1e 100644 --- a/arch/arm/mach-rpc/include/mach/uncompress.h +++ b/arch/arm/mach-rpc/include/mach/uncompress.h | |||
@@ -118,29 +118,22 @@ static void arch_decomp_setup(void) | |||
118 | struct tag *t = (struct tag *)params; | 118 | struct tag *t = (struct tag *)params; |
119 | unsigned int nr_pages = 0, page_size = PAGE_SIZE; | 119 | unsigned int nr_pages = 0, page_size = PAGE_SIZE; |
120 | 120 | ||
121 | if (t->hdr.tag == ATAG_CORE) | 121 | if (t->hdr.tag == ATAG_CORE) { |
122 | { | 122 | for (; t->hdr.size; t = tag_next(t)) { |
123 | for (; t->hdr.size; t = tag_next(t)) | 123 | if (t->hdr.tag == ATAG_VIDEOTEXT) { |
124 | { | ||
125 | if (t->hdr.tag == ATAG_VIDEOTEXT) | ||
126 | { | ||
127 | video_num_rows = t->u.videotext.video_lines; | 124 | video_num_rows = t->u.videotext.video_lines; |
128 | video_num_cols = t->u.videotext.video_cols; | 125 | video_num_cols = t->u.videotext.video_cols; |
129 | bytes_per_char_h = t->u.videotext.video_points; | ||
130 | bytes_per_char_v = t->u.videotext.video_points; | ||
131 | video_x = t->u.videotext.x; | 126 | video_x = t->u.videotext.x; |
132 | video_y = t->u.videotext.y; | 127 | video_y = t->u.videotext.y; |
133 | } | 128 | } else if (t->hdr.tag == ATAG_VIDEOLFB) { |
134 | 129 | bytes_per_char_h = t->u.videolfb.lfb_depth; | |
135 | if (t->hdr.tag == ATAG_MEM) | 130 | bytes_per_char_v = 8; |
136 | { | 131 | } else if (t->hdr.tag == ATAG_MEM) { |
137 | page_size = PAGE_SIZE; | 132 | page_size = PAGE_SIZE; |
138 | nr_pages += (t->u.mem.size / PAGE_SIZE); | 133 | nr_pages += (t->u.mem.size / PAGE_SIZE); |
139 | } | 134 | } |
140 | } | 135 | } |
141 | } | 136 | } else { |
142 | else | ||
143 | { | ||
144 | nr_pages = params->nr_pages; | 137 | nr_pages = params->nr_pages; |
145 | page_size = params->page_size; | 138 | page_size = params->page_size; |
146 | video_num_rows = params->video_num_rows; | 139 | video_num_rows = params->video_num_rows; |
diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/mach-rpc/io-acorn.S index 69719bad674d..69719bad674d 100644 --- a/arch/arm/lib/io-acorn.S +++ b/arch/arm/mach-rpc/io-acorn.S | |||
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c index b8a61cb11207..803aeb126f0e 100644 --- a/arch/arm/mach-rpc/irq.c +++ b/arch/arm/mach-rpc/irq.c | |||
@@ -8,117 +8,71 @@ | |||
8 | #include <asm/irq.h> | 8 | #include <asm/irq.h> |
9 | #include <asm/fiq.h> | 9 | #include <asm/fiq.h> |
10 | 10 | ||
11 | static void iomd_ack_irq_a(struct irq_data *d) | 11 | // These are offsets from the stat register for each IRQ bank |
12 | { | 12 | #define STAT 0x00 |
13 | unsigned int val, mask; | 13 | #define REQ 0x04 |
14 | 14 | #define CLR 0x04 | |
15 | mask = 1 << d->irq; | 15 | #define MASK 0x08 |
16 | val = iomd_readb(IOMD_IRQMASKA); | ||
17 | iomd_writeb(val & ~mask, IOMD_IRQMASKA); | ||
18 | iomd_writeb(mask, IOMD_IRQCLRA); | ||
19 | } | ||
20 | |||
21 | static void iomd_mask_irq_a(struct irq_data *d) | ||
22 | { | ||
23 | unsigned int val, mask; | ||
24 | 16 | ||
25 | mask = 1 << d->irq; | 17 | static void __iomem *iomd_get_base(struct irq_data *d) |
26 | val = iomd_readb(IOMD_IRQMASKA); | ||
27 | iomd_writeb(val & ~mask, IOMD_IRQMASKA); | ||
28 | } | ||
29 | |||
30 | static void iomd_unmask_irq_a(struct irq_data *d) | ||
31 | { | 18 | { |
32 | unsigned int val, mask; | 19 | void *cd = irq_data_get_irq_chip_data(d); |
33 | 20 | ||
34 | mask = 1 << d->irq; | 21 | return (void __iomem *)(unsigned long)cd; |
35 | val = iomd_readb(IOMD_IRQMASKA); | ||
36 | iomd_writeb(val | mask, IOMD_IRQMASKA); | ||
37 | } | 22 | } |
38 | 23 | ||
39 | static struct irq_chip iomd_a_chip = { | 24 | static void iomd_set_base_mask(unsigned int irq, void __iomem *base, u32 mask) |
40 | .irq_ack = iomd_ack_irq_a, | ||
41 | .irq_mask = iomd_mask_irq_a, | ||
42 | .irq_unmask = iomd_unmask_irq_a, | ||
43 | }; | ||
44 | |||
45 | static void iomd_mask_irq_b(struct irq_data *d) | ||
46 | { | 25 | { |
47 | unsigned int val, mask; | 26 | struct irq_data *d = irq_get_irq_data(irq); |
48 | 27 | ||
49 | mask = 1 << (d->irq & 7); | 28 | d->mask = mask; |
50 | val = iomd_readb(IOMD_IRQMASKB); | 29 | irq_set_chip_data(irq, (void *)(unsigned long)base); |
51 | iomd_writeb(val & ~mask, IOMD_IRQMASKB); | ||
52 | } | 30 | } |
53 | 31 | ||
54 | static void iomd_unmask_irq_b(struct irq_data *d) | 32 | static void iomd_irq_mask_ack(struct irq_data *d) |
55 | { | 33 | { |
56 | unsigned int val, mask; | 34 | void __iomem *base = iomd_get_base(d); |
35 | unsigned int val, mask = d->mask; | ||
57 | 36 | ||
58 | mask = 1 << (d->irq & 7); | 37 | val = readb(base + MASK); |
59 | val = iomd_readb(IOMD_IRQMASKB); | 38 | writeb(val & ~mask, base + MASK); |
60 | iomd_writeb(val | mask, IOMD_IRQMASKB); | 39 | writeb(mask, base + CLR); |
61 | } | 40 | } |
62 | 41 | ||
63 | static struct irq_chip iomd_b_chip = { | 42 | static void iomd_irq_mask(struct irq_data *d) |
64 | .irq_ack = iomd_mask_irq_b, | ||
65 | .irq_mask = iomd_mask_irq_b, | ||
66 | .irq_unmask = iomd_unmask_irq_b, | ||
67 | }; | ||
68 | |||
69 | static void iomd_mask_irq_dma(struct irq_data *d) | ||
70 | { | 43 | { |
71 | unsigned int val, mask; | 44 | void __iomem *base = iomd_get_base(d); |
45 | unsigned int val, mask = d->mask; | ||
72 | 46 | ||
73 | mask = 1 << (d->irq & 7); | 47 | val = readb(base + MASK); |
74 | val = iomd_readb(IOMD_DMAMASK); | 48 | writeb(val & ~mask, base + MASK); |
75 | iomd_writeb(val & ~mask, IOMD_DMAMASK); | ||
76 | } | 49 | } |
77 | 50 | ||
78 | static void iomd_unmask_irq_dma(struct irq_data *d) | 51 | static void iomd_irq_unmask(struct irq_data *d) |
79 | { | 52 | { |
80 | unsigned int val, mask; | 53 | void __iomem *base = iomd_get_base(d); |
54 | unsigned int val, mask = d->mask; | ||
81 | 55 | ||
82 | mask = 1 << (d->irq & 7); | 56 | val = readb(base + MASK); |
83 | val = iomd_readb(IOMD_DMAMASK); | 57 | writeb(val | mask, base + MASK); |
84 | iomd_writeb(val | mask, IOMD_DMAMASK); | ||
85 | } | 58 | } |
86 | 59 | ||
87 | static struct irq_chip iomd_dma_chip = { | 60 | static struct irq_chip iomd_chip_clr = { |
88 | .irq_ack = iomd_mask_irq_dma, | 61 | .irq_mask_ack = iomd_irq_mask_ack, |
89 | .irq_mask = iomd_mask_irq_dma, | 62 | .irq_mask = iomd_irq_mask, |
90 | .irq_unmask = iomd_unmask_irq_dma, | 63 | .irq_unmask = iomd_irq_unmask, |
91 | }; | 64 | }; |
92 | 65 | ||
93 | static void iomd_mask_irq_fiq(struct irq_data *d) | 66 | static struct irq_chip iomd_chip_noclr = { |
94 | { | 67 | .irq_mask = iomd_irq_mask, |
95 | unsigned int val, mask; | 68 | .irq_unmask = iomd_irq_unmask, |
96 | |||
97 | mask = 1 << (d->irq & 7); | ||
98 | val = iomd_readb(IOMD_FIQMASK); | ||
99 | iomd_writeb(val & ~mask, IOMD_FIQMASK); | ||
100 | } | ||
101 | |||
102 | static void iomd_unmask_irq_fiq(struct irq_data *d) | ||
103 | { | ||
104 | unsigned int val, mask; | ||
105 | |||
106 | mask = 1 << (d->irq & 7); | ||
107 | val = iomd_readb(IOMD_FIQMASK); | ||
108 | iomd_writeb(val | mask, IOMD_FIQMASK); | ||
109 | } | ||
110 | |||
111 | static struct irq_chip iomd_fiq_chip = { | ||
112 | .irq_ack = iomd_mask_irq_fiq, | ||
113 | .irq_mask = iomd_mask_irq_fiq, | ||
114 | .irq_unmask = iomd_unmask_irq_fiq, | ||
115 | }; | 69 | }; |
116 | 70 | ||
117 | extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; | 71 | extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; |
118 | 72 | ||
119 | void __init rpc_init_irq(void) | 73 | void __init rpc_init_irq(void) |
120 | { | 74 | { |
121 | unsigned int irq, clr, set = 0; | 75 | unsigned int irq, clr, set; |
122 | 76 | ||
123 | iomd_writeb(0, IOMD_IRQMASKA); | 77 | iomd_writeb(0, IOMD_IRQMASKA); |
124 | iomd_writeb(0, IOMD_IRQMASKB); | 78 | iomd_writeb(0, IOMD_IRQMASKB); |
@@ -130,6 +84,7 @@ void __init rpc_init_irq(void) | |||
130 | 84 | ||
131 | for (irq = 0; irq < NR_IRQS; irq++) { | 85 | for (irq = 0; irq < NR_IRQS; irq++) { |
132 | clr = IRQ_NOREQUEST; | 86 | clr = IRQ_NOREQUEST; |
87 | set = 0; | ||
133 | 88 | ||
134 | if (irq <= 6 || (irq >= 9 && irq <= 15)) | 89 | if (irq <= 6 || (irq >= 9 && irq <= 15)) |
135 | clr |= IRQ_NOPROBE; | 90 | clr |= IRQ_NOPROBE; |
@@ -140,30 +95,37 @@ void __init rpc_init_irq(void) | |||
140 | 95 | ||
141 | switch (irq) { | 96 | switch (irq) { |
142 | case 0 ... 7: | 97 | case 0 ... 7: |
143 | irq_set_chip_and_handler(irq, &iomd_a_chip, | 98 | irq_set_chip_and_handler(irq, &iomd_chip_clr, |
144 | handle_level_irq); | 99 | handle_level_irq); |
145 | irq_modify_status(irq, clr, set); | 100 | irq_modify_status(irq, clr, set); |
101 | iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATA, | ||
102 | BIT(irq)); | ||
146 | break; | 103 | break; |
147 | 104 | ||
148 | case 8 ... 15: | 105 | case 8 ... 15: |
149 | irq_set_chip_and_handler(irq, &iomd_b_chip, | 106 | irq_set_chip_and_handler(irq, &iomd_chip_noclr, |
150 | handle_level_irq); | 107 | handle_level_irq); |
151 | irq_modify_status(irq, clr, set); | 108 | irq_modify_status(irq, clr, set); |
109 | iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATB, | ||
110 | BIT(irq - 8)); | ||
152 | break; | 111 | break; |
153 | 112 | ||
154 | case 16 ... 21: | 113 | case 16 ... 21: |
155 | irq_set_chip_and_handler(irq, &iomd_dma_chip, | 114 | irq_set_chip_and_handler(irq, &iomd_chip_noclr, |
156 | handle_level_irq); | 115 | handle_level_irq); |
157 | irq_modify_status(irq, clr, set); | 116 | irq_modify_status(irq, clr, set); |
117 | iomd_set_base_mask(irq, IOMD_BASE + IOMD_DMASTAT, | ||
118 | BIT(irq - 16)); | ||
158 | break; | 119 | break; |
159 | 120 | ||
160 | case 64 ... 71: | 121 | case 64 ... 71: |
161 | irq_set_chip(irq, &iomd_fiq_chip); | 122 | irq_set_chip(irq, &iomd_chip_noclr); |
162 | irq_modify_status(irq, clr, set); | 123 | irq_modify_status(irq, clr, set); |
124 | iomd_set_base_mask(irq, IOMD_BASE + IOMD_FIQSTAT, | ||
125 | BIT(irq - 64)); | ||
163 | break; | 126 | break; |
164 | } | 127 | } |
165 | } | 128 | } |
166 | 129 | ||
167 | init_FIQ(FIQ_START); | 130 | init_FIQ(FIQ_START); |
168 | } | 131 | } |
169 | |||
diff --git a/arch/arm/mach-rpc/time.c b/arch/arm/mach-rpc/time.c index 2689771c1d38..1c84efc9db1f 100644 --- a/arch/arm/mach-rpc/time.c +++ b/arch/arm/mach-rpc/time.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * 04-Dec-1997 RMK Updated for new arch/arm/time.c | 13 | * 04-Dec-1997 RMK Updated for new arch/arm/time.c |
14 | * 13=Jun-2004 DS Moved to arch/arm/common b/c shared w/CLPS7500 | 14 | * 13=Jun-2004 DS Moved to arch/arm/common b/c shared w/CLPS7500 |
15 | */ | 15 | */ |
16 | #include <linux/timex.h> | 16 | #include <linux/clocksource.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
@@ -27,11 +27,15 @@ | |||
27 | #define RPC_CLOCK_FREQ 2000000 | 27 | #define RPC_CLOCK_FREQ 2000000 |
28 | #define RPC_LATCH DIV_ROUND_CLOSEST(RPC_CLOCK_FREQ, HZ) | 28 | #define RPC_LATCH DIV_ROUND_CLOSEST(RPC_CLOCK_FREQ, HZ) |
29 | 29 | ||
30 | static u32 ioc_timer_gettimeoffset(void) | 30 | static u32 ioc_time; |
31 | |||
32 | static u64 ioc_timer_read(struct clocksource *cs) | ||
31 | { | 33 | { |
32 | unsigned int count1, count2, status; | 34 | unsigned int count1, count2, status; |
33 | long offset; | 35 | unsigned long flags; |
36 | u32 ticks; | ||
34 | 37 | ||
38 | local_irq_save(flags); | ||
35 | ioc_writeb (0, IOC_T0LATCH); | 39 | ioc_writeb (0, IOC_T0LATCH); |
36 | barrier (); | 40 | barrier (); |
37 | count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); | 41 | count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); |
@@ -41,27 +45,34 @@ static u32 ioc_timer_gettimeoffset(void) | |||
41 | ioc_writeb (0, IOC_T0LATCH); | 45 | ioc_writeb (0, IOC_T0LATCH); |
42 | barrier (); | 46 | barrier (); |
43 | count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); | 47 | count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); |
48 | ticks = ioc_time + RPC_LATCH - count2; | ||
49 | local_irq_restore(flags); | ||
44 | 50 | ||
45 | offset = count2; | ||
46 | if (count2 < count1) { | 51 | if (count2 < count1) { |
47 | /* | 52 | /* |
48 | * We have not had an interrupt between reading count1 | 53 | * The timer has not reloaded between reading count1 and |
49 | * and count2. | 54 | * count2, check whether an interrupt was actually pending. |
50 | */ | 55 | */ |
51 | if (status & (1 << 5)) | 56 | if (status & (1 << 5)) |
52 | offset -= RPC_LATCH; | 57 | ticks += RPC_LATCH; |
53 | } else if (count2 > count1) { | 58 | } else if (count2 > count1) { |
54 | /* | 59 | /* |
55 | * We have just had another interrupt between reading | 60 | * The timer has reloaded, so count2 indicates the new |
56 | * count1 and count2. | 61 | * count since the wrap. The interrupt would not have |
62 | * been processed, so add the missed ticks. | ||
57 | */ | 63 | */ |
58 | offset -= RPC_LATCH; | 64 | ticks += RPC_LATCH; |
59 | } | 65 | } |
60 | 66 | ||
61 | offset = (RPC_LATCH - offset) * (tick_nsec / 1000); | 67 | return ticks; |
62 | return DIV_ROUND_CLOSEST(offset, RPC_LATCH) * 1000; | ||
63 | } | 68 | } |
64 | 69 | ||
70 | static struct clocksource ioctime_clocksource = { | ||
71 | .read = ioc_timer_read, | ||
72 | .mask = CLOCKSOURCE_MASK(32), | ||
73 | .rating = 100, | ||
74 | }; | ||
75 | |||
65 | void __init ioctime_init(void) | 76 | void __init ioctime_init(void) |
66 | { | 77 | { |
67 | ioc_writeb(RPC_LATCH & 255, IOC_T0LTCHL); | 78 | ioc_writeb(RPC_LATCH & 255, IOC_T0LTCHL); |
@@ -72,6 +83,7 @@ void __init ioctime_init(void) | |||
72 | static irqreturn_t | 83 | static irqreturn_t |
73 | ioc_timer_interrupt(int irq, void *dev_id) | 84 | ioc_timer_interrupt(int irq, void *dev_id) |
74 | { | 85 | { |
86 | ioc_time += RPC_LATCH; | ||
75 | timer_tick(); | 87 | timer_tick(); |
76 | return IRQ_HANDLED; | 88 | return IRQ_HANDLED; |
77 | } | 89 | } |
@@ -86,7 +98,7 @@ static struct irqaction ioc_timer_irq = { | |||
86 | */ | 98 | */ |
87 | void __init ioc_timer_init(void) | 99 | void __init ioc_timer_init(void) |
88 | { | 100 | { |
89 | arch_gettimeoffset = ioc_timer_gettimeoffset; | 101 | WARN_ON(clocksource_register_hz(&ioctime_clocksource, RPC_CLOCK_FREQ)); |
90 | ioctime_init(); | 102 | ioctime_init(); |
91 | setup_irq(IRQ_TIMER0, &ioc_timer_irq); | 103 | setup_irq(IRQ_TIMER0, &ioc_timer_irq); |
92 | } | 104 | } |