Source
149
149
150
150
if (ioremap_try_huge_pud(pud, addr, next, phys_addr, prot))
151
151
continue;
152
152
153
153
if (ioremap_pmd_range(pud, addr, next, phys_addr, prot))
154
154
return -ENOMEM;
155
155
} while (pud++, phys_addr += (next - addr), addr = next, addr != end);
156
156
return 0;
157
157
}
158
158
159
+
static int ioremap_try_huge_p4d(p4d_t *p4d, unsigned long addr,
160
+
unsigned long end, phys_addr_t phys_addr,
161
+
pgprot_t prot)
162
+
{
163
+
if (!ioremap_p4d_enabled())
164
+
return 0;
165
+
166
+
if ((end - addr) != P4D_SIZE)
167
+
return 0;
168
+
169
+
if (!IS_ALIGNED(phys_addr, P4D_SIZE))
170
+
return 0;
171
+
172
+
if (p4d_present(*p4d) && !p4d_free_pud_page(p4d, addr))
173
+
return 0;
174
+
175
+
return p4d_set_huge(p4d, phys_addr, prot);
176
+
}
177
+
159
178
static inline int ioremap_p4d_range(pgd_t *pgd, unsigned long addr,
160
179
unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
161
180
{
162
181
p4d_t *p4d;
163
182
unsigned long next;
164
183
165
184
p4d = p4d_alloc(&init_mm, pgd, addr);
166
185
if (!p4d)
167
186
return -ENOMEM;
168
187
do {
169
188
next = p4d_addr_end(addr, end);
170
189
171
-
if (ioremap_p4d_enabled() &&
172
-
((next - addr) == P4D_SIZE) &&
173
-
IS_ALIGNED(phys_addr, P4D_SIZE)) {
174
-
if (p4d_set_huge(p4d, phys_addr, prot))
175
-
continue;
176
-
}
190
+
if (ioremap_try_huge_p4d(p4d, addr, next, phys_addr, prot))
191
+
continue;
177
192
178
193
if (ioremap_pud_range(p4d, addr, next, phys_addr, prot))
179
194
return -ENOMEM;
180
195
} while (p4d++, phys_addr += (next - addr), addr = next, addr != end);
181
196
return 0;
182
197
}
183
198
184
199
int ioremap_page_range(unsigned long addr,
185
200
unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
186
201
{