Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/lib/iomap.c
26299 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* iomap.c - Implement iomap interface for PA-RISC
4
* Copyright (c) 2004 Matthew Wilcox
5
*/
6
7
#include <linux/ioport.h>
8
#include <linux/pci.h>
9
#include <linux/export.h>
10
#include <asm/io.h>
11
12
/*
13
* The iomap space on 32-bit PA-RISC is intended to look like this:
14
* 00000000-7fffffff virtual mapped IO
15
* 80000000-8fffffff ISA/EISA port space that can't be virtually mapped
16
* 90000000-9fffffff Dino port space
17
* a0000000-afffffff Astro port space
18
* b0000000-bfffffff PAT port space
19
* c0000000-cfffffff non-swapped memory IO
20
* f0000000-ffffffff legacy IO memory pointers
21
*
22
* For the moment, here's what it looks like:
23
* 80000000-8fffffff All ISA/EISA port space
24
* f0000000-ffffffff legacy IO memory pointers
25
*
26
* On 64-bit, everything is extended, so:
27
* 8000000000000000-8fffffffffffffff All ISA/EISA port space
28
* f000000000000000-ffffffffffffffff legacy IO memory pointers
29
*/
30
31
/*
32
* Technically, this should be 'if (VMALLOC_START < addr < VMALLOC_END),
33
* but that's slow and we know it'll be within the first 2GB.
34
*/
35
#ifdef CONFIG_64BIT
36
#define INDIRECT_ADDR(addr) (((unsigned long)(addr) & 1UL<<63) != 0)
37
#define ADDR_TO_REGION(addr) (((unsigned long)addr >> 60) & 7)
38
#define IOPORT_MAP_BASE (8UL << 60)
39
#else
40
#define INDIRECT_ADDR(addr) (((unsigned long)(addr) & 1UL<<31) != 0)
41
#define ADDR_TO_REGION(addr) (((unsigned long)addr >> 28) & 7)
42
#define IOPORT_MAP_BASE (8UL << 28)
43
#endif
44
45
struct iomap_ops {
46
unsigned int (*read8)(const void __iomem *);
47
unsigned int (*read16)(const void __iomem *);
48
unsigned int (*read16be)(const void __iomem *);
49
unsigned int (*read32)(const void __iomem *);
50
unsigned int (*read32be)(const void __iomem *);
51
#ifdef CONFIG_64BIT
52
u64 (*read64)(const void __iomem *);
53
u64 (*read64be)(const void __iomem *);
54
#endif
55
void (*write8)(u8, void __iomem *);
56
void (*write16)(u16, void __iomem *);
57
void (*write16be)(u16, void __iomem *);
58
void (*write32)(u32, void __iomem *);
59
void (*write32be)(u32, void __iomem *);
60
#ifdef CONFIG_64BIT
61
void (*write64)(u64, void __iomem *);
62
void (*write64be)(u64, void __iomem *);
63
#endif
64
void (*read8r)(const void __iomem *, void *, unsigned long);
65
void (*read16r)(const void __iomem *, void *, unsigned long);
66
void (*read32r)(const void __iomem *, void *, unsigned long);
67
void (*write8r)(void __iomem *, const void *, unsigned long);
68
void (*write16r)(void __iomem *, const void *, unsigned long);
69
void (*write32r)(void __iomem *, const void *, unsigned long);
70
};
71
72
/* Generic ioport ops. To be replaced later by specific dino/elroy/wax code */
73
74
#define ADDR2PORT(addr) ((unsigned long __force)(addr) & 0xffffff)
75
76
static unsigned int ioport_read8(const void __iomem *addr)
77
{
78
return inb(ADDR2PORT(addr));
79
}
80
81
static unsigned int ioport_read16(const void __iomem *addr)
82
{
83
return inw(ADDR2PORT(addr));
84
}
85
86
static unsigned int ioport_read32(const void __iomem *addr)
87
{
88
return inl(ADDR2PORT(addr));
89
}
90
91
static void ioport_write8(u8 datum, void __iomem *addr)
92
{
93
outb(datum, ADDR2PORT(addr));
94
}
95
96
static void ioport_write16(u16 datum, void __iomem *addr)
97
{
98
outw(datum, ADDR2PORT(addr));
99
}
100
101
static void ioport_write32(u32 datum, void __iomem *addr)
102
{
103
outl(datum, ADDR2PORT(addr));
104
}
105
106
static void ioport_read8r(const void __iomem *addr, void *dst, unsigned long count)
107
{
108
insb(ADDR2PORT(addr), dst, count);
109
}
110
111
static void ioport_read16r(const void __iomem *addr, void *dst, unsigned long count)
112
{
113
insw(ADDR2PORT(addr), dst, count);
114
}
115
116
static void ioport_read32r(const void __iomem *addr, void *dst, unsigned long count)
117
{
118
insl(ADDR2PORT(addr), dst, count);
119
}
120
121
static void ioport_write8r(void __iomem *addr, const void *s, unsigned long n)
122
{
123
outsb(ADDR2PORT(addr), s, n);
124
}
125
126
static void ioport_write16r(void __iomem *addr, const void *s, unsigned long n)
127
{
128
outsw(ADDR2PORT(addr), s, n);
129
}
130
131
static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n)
132
{
133
outsl(ADDR2PORT(addr), s, n);
134
}
135
136
static const struct iomap_ops ioport_ops = {
137
.read8 = ioport_read8,
138
.read16 = ioport_read16,
139
.read16be = ioport_read16,
140
.read32 = ioport_read32,
141
.read32be = ioport_read32,
142
.write8 = ioport_write8,
143
.write16 = ioport_write16,
144
.write16be = ioport_write16,
145
.write32 = ioport_write32,
146
.write32be = ioport_write32,
147
.read8r = ioport_read8r,
148
.read16r = ioport_read16r,
149
.read32r = ioport_read32r,
150
.write8r = ioport_write8r,
151
.write16r = ioport_write16r,
152
.write32r = ioport_write32r,
153
};
154
155
/* Legacy I/O memory ops */
156
157
static unsigned int iomem_read8(const void __iomem *addr)
158
{
159
return readb(addr);
160
}
161
162
static unsigned int iomem_read16(const void __iomem *addr)
163
{
164
return readw(addr);
165
}
166
167
static unsigned int iomem_read16be(const void __iomem *addr)
168
{
169
return __raw_readw(addr);
170
}
171
172
static unsigned int iomem_read32(const void __iomem *addr)
173
{
174
return readl(addr);
175
}
176
177
static unsigned int iomem_read32be(const void __iomem *addr)
178
{
179
return __raw_readl(addr);
180
}
181
182
#ifdef CONFIG_64BIT
183
static u64 iomem_read64(const void __iomem *addr)
184
{
185
return readq(addr);
186
}
187
188
static u64 iomem_read64be(const void __iomem *addr)
189
{
190
return __raw_readq(addr);
191
}
192
#endif
193
194
static void iomem_write8(u8 datum, void __iomem *addr)
195
{
196
writeb(datum, addr);
197
}
198
199
static void iomem_write16(u16 datum, void __iomem *addr)
200
{
201
writew(datum, addr);
202
}
203
204
static void iomem_write16be(u16 datum, void __iomem *addr)
205
{
206
__raw_writew(datum, addr);
207
}
208
209
static void iomem_write32(u32 datum, void __iomem *addr)
210
{
211
writel(datum, addr);
212
}
213
214
static void iomem_write32be(u32 datum, void __iomem *addr)
215
{
216
__raw_writel(datum, addr);
217
}
218
219
#ifdef CONFIG_64BIT
220
static void iomem_write64(u64 datum, void __iomem *addr)
221
{
222
writeq(datum, addr);
223
}
224
225
static void iomem_write64be(u64 datum, void __iomem *addr)
226
{
227
__raw_writeq(datum, addr);
228
}
229
#endif
230
231
static void iomem_read8r(const void __iomem *addr, void *dst, unsigned long count)
232
{
233
while (count--) {
234
*(u8 *)dst = __raw_readb(addr);
235
dst++;
236
}
237
}
238
239
static void iomem_read16r(const void __iomem *addr, void *dst, unsigned long count)
240
{
241
while (count--) {
242
*(u16 *)dst = __raw_readw(addr);
243
dst += 2;
244
}
245
}
246
247
static void iomem_read32r(const void __iomem *addr, void *dst, unsigned long count)
248
{
249
while (count--) {
250
*(u32 *)dst = __raw_readl(addr);
251
dst += 4;
252
}
253
}
254
255
static void iomem_write8r(void __iomem *addr, const void *s, unsigned long n)
256
{
257
while (n--) {
258
__raw_writeb(*(u8 *)s, addr);
259
s++;
260
}
261
}
262
263
static void iomem_write16r(void __iomem *addr, const void *s, unsigned long n)
264
{
265
while (n--) {
266
__raw_writew(*(u16 *)s, addr);
267
s += 2;
268
}
269
}
270
271
static void iomem_write32r(void __iomem *addr, const void *s, unsigned long n)
272
{
273
while (n--) {
274
__raw_writel(*(u32 *)s, addr);
275
s += 4;
276
}
277
}
278
279
static const struct iomap_ops iomem_ops = {
280
.read8 = iomem_read8,
281
.read16 = iomem_read16,
282
.read16be = iomem_read16be,
283
.read32 = iomem_read32,
284
.read32be = iomem_read32be,
285
#ifdef CONFIG_64BIT
286
.read64 = iomem_read64,
287
.read64be = iomem_read64be,
288
#endif
289
.write8 = iomem_write8,
290
.write16 = iomem_write16,
291
.write16be = iomem_write16be,
292
.write32 = iomem_write32,
293
.write32be = iomem_write32be,
294
#ifdef CONFIG_64BIT
295
.write64 = iomem_write64,
296
.write64be = iomem_write64be,
297
#endif
298
.read8r = iomem_read8r,
299
.read16r = iomem_read16r,
300
.read32r = iomem_read32r,
301
.write8r = iomem_write8r,
302
.write16r = iomem_write16r,
303
.write32r = iomem_write32r,
304
};
305
306
static const struct iomap_ops *iomap_ops[8] = {
307
[0] = &ioport_ops,
308
[7] = &iomem_ops
309
};
310
311
312
unsigned int ioread8(const void __iomem *addr)
313
{
314
if (unlikely(INDIRECT_ADDR(addr)))
315
return iomap_ops[ADDR_TO_REGION(addr)]->read8(addr);
316
return *((u8 *)addr);
317
}
318
319
unsigned int ioread16(const void __iomem *addr)
320
{
321
if (unlikely(INDIRECT_ADDR(addr)))
322
return iomap_ops[ADDR_TO_REGION(addr)]->read16(addr);
323
return le16_to_cpup((u16 *)addr);
324
}
325
326
unsigned int ioread16be(const void __iomem *addr)
327
{
328
if (unlikely(INDIRECT_ADDR(addr)))
329
return iomap_ops[ADDR_TO_REGION(addr)]->read16be(addr);
330
return *((u16 *)addr);
331
}
332
333
unsigned int ioread32(const void __iomem *addr)
334
{
335
if (unlikely(INDIRECT_ADDR(addr)))
336
return iomap_ops[ADDR_TO_REGION(addr)]->read32(addr);
337
return le32_to_cpup((u32 *)addr);
338
}
339
340
unsigned int ioread32be(const void __iomem *addr)
341
{
342
if (unlikely(INDIRECT_ADDR(addr)))
343
return iomap_ops[ADDR_TO_REGION(addr)]->read32be(addr);
344
return *((u32 *)addr);
345
}
346
347
#ifdef CONFIG_64BIT
348
u64 ioread64(const void __iomem *addr)
349
{
350
if (unlikely(INDIRECT_ADDR(addr)))
351
return iomap_ops[ADDR_TO_REGION(addr)]->read64(addr);
352
return le64_to_cpup((u64 *)addr);
353
}
354
355
u64 ioread64be(const void __iomem *addr)
356
{
357
if (unlikely(INDIRECT_ADDR(addr)))
358
return iomap_ops[ADDR_TO_REGION(addr)]->read64be(addr);
359
return *((u64 *)addr);
360
}
361
#endif
362
363
void iowrite8(u8 datum, void __iomem *addr)
364
{
365
if (unlikely(INDIRECT_ADDR(addr))) {
366
iomap_ops[ADDR_TO_REGION(addr)]->write8(datum, addr);
367
} else {
368
*((u8 *)addr) = datum;
369
}
370
}
371
372
void iowrite16(u16 datum, void __iomem *addr)
373
{
374
if (unlikely(INDIRECT_ADDR(addr))) {
375
iomap_ops[ADDR_TO_REGION(addr)]->write16(datum, addr);
376
} else {
377
*((u16 *)addr) = cpu_to_le16(datum);
378
}
379
}
380
381
void iowrite16be(u16 datum, void __iomem *addr)
382
{
383
if (unlikely(INDIRECT_ADDR(addr))) {
384
iomap_ops[ADDR_TO_REGION(addr)]->write16be(datum, addr);
385
} else {
386
*((u16 *)addr) = datum;
387
}
388
}
389
390
void iowrite32(u32 datum, void __iomem *addr)
391
{
392
if (unlikely(INDIRECT_ADDR(addr))) {
393
iomap_ops[ADDR_TO_REGION(addr)]->write32(datum, addr);
394
} else {
395
*((u32 *)addr) = cpu_to_le32(datum);
396
}
397
}
398
399
void iowrite32be(u32 datum, void __iomem *addr)
400
{
401
if (unlikely(INDIRECT_ADDR(addr))) {
402
iomap_ops[ADDR_TO_REGION(addr)]->write32be(datum, addr);
403
} else {
404
*((u32 *)addr) = datum;
405
}
406
}
407
408
#ifdef CONFIG_64BIT
409
void iowrite64(u64 datum, void __iomem *addr)
410
{
411
if (unlikely(INDIRECT_ADDR(addr))) {
412
iomap_ops[ADDR_TO_REGION(addr)]->write64(datum, addr);
413
} else {
414
*((u64 *)addr) = cpu_to_le64(datum);
415
}
416
}
417
418
void iowrite64be(u64 datum, void __iomem *addr)
419
{
420
if (unlikely(INDIRECT_ADDR(addr))) {
421
iomap_ops[ADDR_TO_REGION(addr)]->write64be(datum, addr);
422
} else {
423
*((u64 *)addr) = datum;
424
}
425
}
426
#endif
427
428
/* Repeating interfaces */
429
430
void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
431
{
432
if (unlikely(INDIRECT_ADDR(addr))) {
433
iomap_ops[ADDR_TO_REGION(addr)]->read8r(addr, dst, count);
434
} else {
435
while (count--) {
436
*(u8 *)dst = *(u8 *)addr;
437
dst++;
438
}
439
}
440
}
441
442
void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
443
{
444
if (unlikely(INDIRECT_ADDR(addr))) {
445
iomap_ops[ADDR_TO_REGION(addr)]->read16r(addr, dst, count);
446
} else {
447
while (count--) {
448
*(u16 *)dst = *(u16 *)addr;
449
dst += 2;
450
}
451
}
452
}
453
454
void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
455
{
456
if (unlikely(INDIRECT_ADDR(addr))) {
457
iomap_ops[ADDR_TO_REGION(addr)]->read32r(addr, dst, count);
458
} else {
459
while (count--) {
460
*(u32 *)dst = *(u32 *)addr;
461
dst += 4;
462
}
463
}
464
}
465
466
void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
467
{
468
if (unlikely(INDIRECT_ADDR(addr))) {
469
iomap_ops[ADDR_TO_REGION(addr)]->write8r(addr, src, count);
470
} else {
471
while (count--) {
472
*(u8 *)addr = *(u8 *)src;
473
src++;
474
}
475
}
476
}
477
478
void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
479
{
480
if (unlikely(INDIRECT_ADDR(addr))) {
481
iomap_ops[ADDR_TO_REGION(addr)]->write16r(addr, src, count);
482
} else {
483
while (count--) {
484
*(u16 *)addr = *(u16 *)src;
485
src += 2;
486
}
487
}
488
}
489
490
void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
491
{
492
if (unlikely(INDIRECT_ADDR(addr))) {
493
iomap_ops[ADDR_TO_REGION(addr)]->write32r(addr, src, count);
494
} else {
495
while (count--) {
496
*(u32 *)addr = *(u32 *)src;
497
src += 4;
498
}
499
}
500
}
501
502
/* Mapping interfaces */
503
504
void __iomem *ioport_map(unsigned long port, unsigned int nr)
505
{
506
return (void __iomem *)(IOPORT_MAP_BASE | port);
507
}
508
509
void ioport_unmap(void __iomem *addr)
510
{
511
if (!INDIRECT_ADDR(addr)) {
512
iounmap(addr);
513
}
514
}
515
516
#ifdef CONFIG_PCI
517
void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
518
{
519
if (!INDIRECT_ADDR(addr)) {
520
iounmap(addr);
521
}
522
}
523
EXPORT_SYMBOL(pci_iounmap);
524
#endif
525
526
EXPORT_SYMBOL(ioread8);
527
EXPORT_SYMBOL(ioread16);
528
EXPORT_SYMBOL(ioread16be);
529
EXPORT_SYMBOL(ioread32);
530
EXPORT_SYMBOL(ioread32be);
531
#ifdef CONFIG_64BIT
532
EXPORT_SYMBOL(ioread64);
533
EXPORT_SYMBOL(ioread64be);
534
#endif
535
EXPORT_SYMBOL(iowrite8);
536
EXPORT_SYMBOL(iowrite16);
537
EXPORT_SYMBOL(iowrite16be);
538
EXPORT_SYMBOL(iowrite32);
539
EXPORT_SYMBOL(iowrite32be);
540
#ifdef CONFIG_64BIT
541
EXPORT_SYMBOL(iowrite64);
542
EXPORT_SYMBOL(iowrite64be);
543
#endif
544
EXPORT_SYMBOL(ioread8_rep);
545
EXPORT_SYMBOL(ioread16_rep);
546
EXPORT_SYMBOL(ioread32_rep);
547
EXPORT_SYMBOL(iowrite8_rep);
548
EXPORT_SYMBOL(iowrite16_rep);
549
EXPORT_SYMBOL(iowrite32_rep);
550
EXPORT_SYMBOL(ioport_map);
551
EXPORT_SYMBOL(ioport_unmap);
552
553