Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 37713
b: refs/heads/master
c: 74588d8
h: refs/heads/master
i:
  37711: 91615db
v: v3
  • Loading branch information
Haavard Skinnemoen authored and Linus Torvalds committed Oct 1, 2006
1 parent 0fe7cbc commit e9008ed
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bc03613decef0cc4d2f3a24f19fa5a868745715f
refs/heads/master: 74588d8ba34ff1bda027cfa737972af01ab00c8b
4 changes: 4 additions & 0 deletions trunk/include/linux/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@
#define _LINUX_IO_H

#include <asm/io.h>
#include <asm/page.h>

void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
void __iowrite64_copy(void __iomem *to, const void *from, size_t count);

int ioremap_page_range(unsigned long addr, unsigned long end,
unsigned long phys_addr, pgprot_t prot);

#endif /* _LINUX_IO_H */
1 change: 1 addition & 0 deletions trunk/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
sha1.o

lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o

lib-y += kobject.o kref.o kobject_uevent.o klist.o
Expand Down
94 changes: 94 additions & 0 deletions trunk/lib/ioremap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Re-map IO memory to kernel address space so that we can access it.
* This is needed for high PCI addresses that aren't mapped in the
* 640k-1MB IO memory area on PC's
*
* (C) Copyright 1995 1996 Linus Torvalds
*/
#include <linux/io.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>

#include <asm/cacheflush.h>
#include <asm/pgtable.h>

static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long phys_addr, pgprot_t prot)
{
pte_t *pte;
unsigned long pfn;

pfn = phys_addr >> PAGE_SHIFT;
pte = pte_alloc_kernel(pmd, addr);
if (!pte)
return -ENOMEM;
do {
BUG_ON(!pte_none(*pte));
set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
pfn++;
} while (pte++, addr += PAGE_SIZE, addr != end);
return 0;
}

static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
unsigned long end, unsigned long phys_addr, pgprot_t prot)
{
pmd_t *pmd;
unsigned long next;

phys_addr -= addr;
pmd = pmd_alloc(&init_mm, pud, addr);
if (!pmd)
return -ENOMEM;
do {
next = pmd_addr_end(addr, end);
if (ioremap_pte_range(pmd, addr, next, phys_addr + addr, prot))
return -ENOMEM;
} while (pmd++, addr = next, addr != end);
return 0;
}

static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr,
unsigned long end, unsigned long phys_addr, pgprot_t prot)
{
pud_t *pud;
unsigned long next;

phys_addr -= addr;
pud = pud_alloc(&init_mm, pgd, addr);
if (!pud)
return -ENOMEM;
do {
next = pud_addr_end(addr, end);
if (ioremap_pmd_range(pud, addr, next, phys_addr + addr, prot))
return -ENOMEM;
} while (pud++, addr = next, addr != end);
return 0;
}

int ioremap_page_range(unsigned long addr,
unsigned long end, unsigned long phys_addr, pgprot_t prot)
{
pgd_t *pgd;
unsigned long start;
unsigned long next;
int err;

BUG_ON(addr >= end);

flush_cache_all();

start = addr;
phys_addr -= addr;
pgd = pgd_offset_k(addr);
do {
next = pgd_addr_end(addr, end);
err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, prot);
if (err)
break;
} while (pgd++, addr = next, addr != end);

flush_tlb_all();

return err;
}

0 comments on commit e9008ed

Please sign in to comment.