Hi, We've got a very simple CF interface on our eval board, sitting on localbus with a couple of gpios for control. mem and i/o port ranges are mapped to two mmio ranges, i.e. 0xf0000000 and 0xf1000000 in our case.
I've got a pcmcia driver for the slot to handle all the probing, etc. It ioremaps both the mem and io ranges, and provides that with the registered device: cf->mem_base = ioremap(mem->start, mem->end - mem->start); cf->io_base = ioremap(io->start, io->end - io->start); [...] /* pcmcia layer only remaps "real" memory not iospace */ cf->socket.io_offset = (unsigned long)cf->io_base; /* reserve chip-select regions */ if (!request_mem_region(mem->start, mem->end + 1 - mem->start, [...] if (!request_mem_region(io->start, io->end + 1 - io->start, driver_name)) [...] cf->socket.dev.parent = &ofdev->dev; cf->socket.ops = &electra_cf_ops; cf->socket.resource_ops = &pccard_static_ops; cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP | SS_CAP_MEM_ALIGN; [...] (I'll post the full driver separately, but wanted to bring this up first). Bottom line is that io_offset points to the ioremap()ed memory, i.e a 64-bit kernel address. The problems show up further up the stack, in this case in the pata_pcmcia driver, where pcmcia_request_io() is used to handle the address allocation. That in turn calls alloc_io_space(), which takes an ioaddr_t * as argument and does math on it. ioaddr_t is 32-bit, causing obvious problems since io_offset is 64-bit. There's a compatible kio_addr_t available, but I'm guessing it's already not used because of ABI requiremenets given the big warning at the definition of ioaddr_t. Since ppc64 never has had pcmcia before (We're the first platform with it), changing the type under ifdef like mips/arm shouldn't be a problem, at least it won't lead to regressions -- there's no previous user apps to regress. However, that's not enough in this case: Next thing that will fail is ioport_map() in ppc-specific code, called from devm_ioport_map(). It currently assumes to be passed the bus-local port number and adding it to the ioremap base of the (normally only) bus with I/O ports, i.e. ISA/LPC. Since we already use that for other devices (UARTS, etc), we now have more than one base register. I see two ways to solve this: 1. Create infrastructure to track the various io-port ranges, register them and let the infrastructure take care of the ioremap, pick the right ioport_map(), etc. I.e. create virtual io port ranges. 2. Make ioport_map() detect already mapped arguments (i.e.: + if (port >= IMALLOC_BASE && (port+len) < IMALLOC_END) + return (void __iomem *)port; (1) would be appealing if it was the only change needed, and if that meant that I didn't have to change ioaddr_t. It doesn't though, since the pcmcia code still stores the ioport_map():ed value in an ioaddr_t, so it really just adds complexity without that much benefit. I'm tempted to go with (2) + type change but if someone has a third option I'm all ears. -Olof - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/