Here's how I solved this problem in my Windows CE BSP. It probably does apply to the Linux world but may help if only for background info. I went through and indexed all the GPIO used by all the Gumstix peripherals. I did this by studying all the schematics and the PXA255 documentation (I wish the Gumstix people published this info). I have a master hardware configuration DWORD that I set and store persistently in flash from the bootloader. Each bit in the DWORD represents a different peripheral i.e. Audiostix, netCF, USB etc. All the GPIO's and their alternate functions get allocated and set shortly after powerup. The individual drivers gets initialized later but don't do the GPIO allocation. This has two advantages:
1) All the GPIO's are set in one central location as opposed to being spread across a whole bunch of drivers.
2) GPIO normally consumed by a peripheral which is not present (bit not set in hardware DWORD) are free to use for other things.
Setting or clearing bits in the GPIO direction register or ALT function register later at run time is handled by a IOCTL call wish is basically a user mode to kernel mode (thunk) call. The IOCTL function call takes a mask and a set/clear parameter. The kernel has access to the hardware and the function at the lowest level has an Interrupt disable/Interrupt Enable framing the actual AND/OR bit w/mask to make the RMW atomic. The interrupts are only off for <1us so latency is insignificant.