static int __init setup_hd64465(void) { int i; unsigned short rev; unsigned short smscr; if (!MACH_HD64465) return 0; printk(KERN_INFO "HD64465 configured at 0x%x on irq %d(mapped into %d to %d)\n", CONFIG_HD64465_IOBASE, CONFIG_HD64465_IRQ, HD64465_IRQ_BASE, HD64465_IRQ_BASE+HD64465_IRQ_NUM-1); if (inw(HD64465_REG_SDID) != HD64465_SDID) { printk(KERN_ERR "HD64465 device ID not found, check base address\n"); } rev = inw(HD64465_REG_SRR); printk(KERN_INFO "HD64465 hardware revision %d.%d\n", (rev >> 8) & 0xff, rev & 0xff); outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */ for (i = 0; i < HD64465_IRQ_NUM ; i++) { irq_desc[HD64465_IRQ_BASE + i].chip = &hd64465_irq_type; } setup_irq(CONFIG_HD64465_IRQ, &irq0); #ifdef CONFIG_SERIAL /* wake up the UART from STANDBY at this point */ smscr = inw(HD64465_REG_SMSCR); outw(smscr & (~HD64465_SMSCR_UARTST), HD64465_REG_SMSCR); /* remap IO ports for first ISA serial port to HD64465 UART */ hd64465_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1); #endif return 0; }
static int hs_set_io_map(unsigned int sock, struct pccard_io_map *io) { hs_socket_t *sp = &hs_sockets[sock]; int map = io->map; struct pccard_io_map *sio; pgprot_t prot; DPRINTK("hs_set_io_map(sock=%d, map=%d, flags=0x%x, speed=%dns, start=0x%04x, stop=0x%04x)\n", sock, map, io->flags, io->speed, io->start, io->stop); if (map >= MAX_IO_WIN) return -EINVAL; sio = &sp->io_maps[map]; /* check for null changes */ if (io->flags == sio->flags && io->start == sio->start && io->stop == sio->stop) return 0; if (io->flags & MAP_AUTOSZ) prot = PAGE_KERNEL_PCC(sock, _PAGE_PCC_IODYN); else if (io->flags & MAP_16BIT) prot = PAGE_KERNEL_PCC(sock, _PAGE_PCC_IO16); else prot = PAGE_KERNEL_PCC(sock, _PAGE_PCC_IO8); /* TODO: handle MAP_USE_WAIT */ if (io->flags & MAP_USE_WAIT) printk(KERN_INFO MODNAME ": MAP_USE_WAIT unimplemented\n"); /* TODO: handle MAP_PREFETCH */ if (io->flags & MAP_PREFETCH) printk(KERN_INFO MODNAME ": MAP_PREFETCH unimplemented\n"); /* TODO: handle MAP_WRPROT */ if (io->flags & MAP_WRPROT) printk(KERN_INFO MODNAME ": MAP_WRPROT unimplemented\n"); /* TODO: handle MAP_0WS */ if (io->flags & MAP_0WS) printk(KERN_INFO MODNAME ": MAP_0WS unimplemented\n"); if (io->flags & MAP_ACTIVE) { unsigned long pstart, psize, paddrbase, vaddrbase; paddrbase = virt_to_phys((void*)(sp->mem_base + 2 * HD64465_PCC_WINDOW)); vaddrbase = (unsigned long)sp->io_vma->addr; pstart = io->start & PAGE_MASK; psize = ((io->stop + PAGE_SIZE) & PAGE_MASK) - pstart; /* * Change PTEs in only that portion of the mapping requested * by the caller. This means that most of the time, most of * the PTEs in the io_vma will be unmapped and only the bottom * page will be mapped. But the code allows for weird cards * that might want IO ports > 4K. */ DPRINTK("remap_page_range(vaddr=0x%08lx, paddr=0x%08lx, size=0x%08lxx)\n", vaddrbase + pstart, paddrbase + pstart, psize); remap_page_range(vaddrbase + pstart, paddrbase + pstart, psize, prot); /* * Change the mapping used by inb() outb() etc */ hd64465_port_map( io->start, io->stop - io->start + 1, vaddrbase + io->start,0); } else { hd64465_port_unmap( sio->start, sio->stop - sio->start + 1); /* TODO: remap_page_range() to mark pages not present ? */ } *sio = *io; return 0; }