|
@@ -672,3 +672,138 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * IO map support.
|
|
|
|
+ */
|
|
|
|
+void __iomem *
|
|
|
|
+marvel_ioremap(unsigned long addr, unsigned long size)
|
|
|
|
+{
|
|
|
|
+ struct pci_controller *hose;
|
|
|
|
+ unsigned long baddr, last;
|
|
|
|
+ struct vm_struct *area;
|
|
|
|
+ unsigned long vaddr;
|
|
|
|
+ unsigned long *ptes;
|
|
|
|
+ unsigned long pfn;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Adjust the address.
|
|
|
|
+ */
|
|
|
|
+ FIXUP_MEMADDR_VGA(addr);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Find the hose.
|
|
|
|
+ */
|
|
|
|
+ for (hose = hose_head; hose; hose = hose->next) {
|
|
|
|
+ if ((addr >> 32) == (hose->mem_space->start >> 32))
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (!hose)
|
|
|
|
+ return NULL;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * We have the hose - calculate the bus limits.
|
|
|
|
+ */
|
|
|
|
+ baddr = addr - hose->mem_space->start;
|
|
|
|
+ last = baddr + size - 1;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Is it direct-mapped?
|
|
|
|
+ */
|
|
|
|
+ if ((baddr >= __direct_map_base) &&
|
|
|
|
+ ((baddr + size - 1) < __direct_map_base + __direct_map_size)) {
|
|
|
|
+ addr = IDENT_ADDR | (baddr - __direct_map_base);
|
|
|
|
+ return (void __iomem *) addr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Check the scatter-gather arena.
|
|
|
|
+ */
|
|
|
|
+ if (hose->sg_pci &&
|
|
|
|
+ baddr >= (unsigned long)hose->sg_pci->dma_base &&
|
|
|
|
+ last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size) {
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Adjust the limits (mappings must be page aligned)
|
|
|
|
+ */
|
|
|
|
+ baddr -= hose->sg_pci->dma_base;
|
|
|
|
+ last -= hose->sg_pci->dma_base;
|
|
|
|
+ baddr &= PAGE_MASK;
|
|
|
|
+ size = PAGE_ALIGN(last) - baddr;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Map it.
|
|
|
|
+ */
|
|
|
|
+ area = get_vm_area(size, VM_IOREMAP);
|
|
|
|
+ if (!area)
|
|
|
|
+ return NULL;
|
|
|
|
+
|
|
|
|
+ ptes = hose->sg_pci->ptes;
|
|
|
|
+ for (vaddr = (unsigned long)area->addr;
|
|
|
|
+ baddr <= last;
|
|
|
|
+ baddr += PAGE_SIZE, vaddr += PAGE_SIZE) {
|
|
|
|
+ pfn = ptes[baddr >> PAGE_SHIFT];
|
|
|
|
+ if (!(pfn & 1)) {
|
|
|
|
+ printk("ioremap failed... pte not valid...\n");
|
|
|
|
+ vfree(area->addr);
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+ pfn >>= 1; /* make it a true pfn */
|
|
|
|
+
|
|
|
|
+ if (__alpha_remap_area_pages(vaddr,
|
|
|
|
+ pfn << PAGE_SHIFT,
|
|
|
|
+ PAGE_SIZE, 0)) {
|
|
|
|
+ printk("FAILED to map...\n");
|
|
|
|
+ vfree(area->addr);
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ flush_tlb_all();
|
|
|
|
+
|
|
|
|
+ vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);
|
|
|
|
+
|
|
|
|
+ return (void __iomem *) vaddr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Assume it was already a reasonable address */
|
|
|
|
+ vaddr = baddr + hose->mem_space->start;
|
|
|
|
+ return (void __iomem *) vaddr;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+marvel_iounmap(volatile void __iomem *xaddr)
|
|
|
|
+{
|
|
|
|
+ unsigned long addr = (unsigned long) xaddr;
|
|
|
|
+ if (addr >= VMALLOC_START)
|
|
|
|
+ vfree((void *)(PAGE_MASK & addr));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int
|
|
|
|
+marvel_is_mmio(const volatile void __iomem *xaddr)
|
|
|
|
+{
|
|
|
|
+ unsigned long addr = (unsigned long) xaddr;
|
|
|
|
+
|
|
|
|
+ if (addr >= VMALLOC_START)
|
|
|
|
+ return 1;
|
|
|
|
+ else
|
|
|
|
+ return (addr & 0xFF000000UL) == 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define __marvel_is_port_kbd(a) (((a) == 0x60) || ((a) == 0x64))
|
|
|
|
+#define __marvel_is_port_rtc(a) (((a) == 0x70) || ((a) == 0x71))
|
|
|
|
+
|
|
|
|
+void __iomem *marvel_ioportmap (unsigned long addr)
|
|
|
|
+{
|
|
|
|
+ FIXUP_IOADDR_VGA(addr);
|
|
|
|
+ return (void __iomem *)addr;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+unsigned int
|
|
|
|
+marvel_ioread8(void __iomem *xaddr)
|
|
|
|
+{
|
|
|
|
+ unsigned long addr = (unsigned long) xaddr;
|
|
|
|
+ if (__marvel_is_port_kbd(addr))
|
|
|
|
+ return 0;
|
|
|
|
+ else if (__marvel_is_port_rtc(addr))
|
|
|
|
+ return __marvel_rtc_io(0, addr, 0);
|
|
|
|
+ else if (marvel_is_ioaddr(addr))
|