Blame view

arch/sh/mm/ioremap_fixed.c 2.57 KB
4d35b93a6   Matt Fleming   sh: Add fixed ior...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   * Re-map IO memory to kernel address space so that we can access it.
   *
   * These functions should only be used when it is necessary to map a
   * physical address space into the kernel address space before ioremap()
   * can be used, e.g. early in boot before paging_init().
   *
   * Copyright (C) 2009  Matt Fleming
   */
  
  #include <linux/vmalloc.h>
  #include <linux/ioport.h>
  #include <linux/module.h>
  #include <linux/mm.h>
  #include <linux/io.h>
  #include <linux/bootmem.h>
  #include <linux/proc_fs.h>
4d35b93a6   Matt Fleming   sh: Add fixed ior...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  #include <asm/fixmap.h>
  #include <asm/page.h>
  #include <asm/pgalloc.h>
  #include <asm/addrspace.h>
  #include <asm/cacheflush.h>
  #include <asm/tlbflush.h>
  #include <asm/mmu.h>
  #include <asm/mmu_context.h>
  
  struct ioremap_map {
  	void __iomem *addr;
  	unsigned long size;
  	unsigned long fixmap_addr;
  };
  
  static struct ioremap_map ioremap_maps[FIX_N_IOREMAPS];
  
  void __init ioremap_fixed_init(void)
  {
  	struct ioremap_map *map;
  	int i;
  
  	for (i = 0; i < FIX_N_IOREMAPS; i++) {
  		map = &ioremap_maps[i];
  		map->fixmap_addr = __fix_to_virt(FIX_IOREMAP_BEGIN + i);
  	}
  }
  
  void __init __iomem *
90e7d649d   Paul Mundt   sh: reworked dyna...
47
  ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
4d35b93a6   Matt Fleming   sh: Add fixed ior...
48
49
  {
  	enum fixed_addresses idx0, idx;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
50
  	struct ioremap_map *map;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
51
  	unsigned int nrpages;
90e7d649d   Paul Mundt   sh: reworked dyna...
52
  	unsigned long offset;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
53
  	int i, slot;
90e7d649d   Paul Mundt   sh: reworked dyna...
54
55
56
57
58
59
  	/*
  	 * Mappings have to be page-aligned
  	 */
  	offset = phys_addr & ~PAGE_MASK;
  	phys_addr &= PAGE_MASK;
  	size = PAGE_ALIGN(phys_addr + size) - phys_addr;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
60
61
62
63
64
65
66
67
68
69
70
71
  	slot = -1;
  	for (i = 0; i < FIX_N_IOREMAPS; i++) {
  		map = &ioremap_maps[i];
  		if (!map->addr) {
  			map->size = size;
  			slot = i;
  			break;
  		}
  	}
  
  	if (slot < 0)
  		return NULL;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  	/*
  	 * Mappings have to fit in the FIX_IOREMAP area.
  	 */
  	nrpages = size >> PAGE_SHIFT;
  	if (nrpages > FIX_N_IOREMAPS)
  		return NULL;
  
  	/*
  	 * Ok, go for it..
  	 */
  	idx0 = FIX_IOREMAP_BEGIN + slot;
  	idx = idx0;
  	while (nrpages > 0) {
  		pgprot_val(prot) |= _PAGE_WIRED;
  		__set_fixmap(idx, phys_addr, prot);
  		phys_addr += PAGE_SIZE;
  		idx++;
  		--nrpages;
  	}
  
  	map->addr = (void __iomem *)(offset + map->fixmap_addr);
  	return map->addr;
  }
4f744affc   Paul Mundt   sh: Make iounmap_...
95
  int iounmap_fixed(void __iomem *addr)
4d35b93a6   Matt Fleming   sh: Add fixed ior...
96
97
  {
  	enum fixed_addresses idx;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
98
  	struct ioremap_map *map;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
99
100
  	unsigned int nrpages;
  	int i, slot;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
101
102
103
104
105
106
107
108
109
  
  	slot = -1;
  	for (i = 0; i < FIX_N_IOREMAPS; i++) {
  		map = &ioremap_maps[i];
  		if (map->addr == addr) {
  			slot = i;
  			break;
  		}
  	}
4f744affc   Paul Mundt   sh: Make iounmap_...
110
111
112
  	/*
  	 * If we don't match, it's not for us.
  	 */
4d35b93a6   Matt Fleming   sh: Add fixed ior...
113
  	if (slot < 0)
4f744affc   Paul Mundt   sh: Make iounmap_...
114
  		return -EINVAL;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
115

920efaabc   Paul Mundt   sh: Correct iounm...
116
  	nrpages = map->size >> PAGE_SHIFT;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
117

920efaabc   Paul Mundt   sh: Correct iounm...
118
  	idx = FIX_IOREMAP_BEGIN + slot + nrpages - 1;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
119
  	while (nrpages > 0) {
acf2c9685   Paul Mundt   sh: Kill off dupl...
120
  		__clear_fixmap(idx, __pgprot(_PAGE_WIRED));
4d35b93a6   Matt Fleming   sh: Add fixed ior...
121
122
123
124
125
126
  		--idx;
  		--nrpages;
  	}
  
  	map->size = 0;
  	map->addr = NULL;
4f744affc   Paul Mundt   sh: Make iounmap_...
127
128
  
  	return 0;
4d35b93a6   Matt Fleming   sh: Add fixed ior...
129
  }