コード例 #1
0
ファイル: setup.c プロジェクト: 3sOx/asuswrt-merlin
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;
}