| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  linux/arch/arm/mach-ebsa110/isamem.c | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Copyright (C) 2001 Russell King | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Perform "ISA" memory and IO accesses.  The EBSA110 has some "peculiarities" | 
					
						
							|  |  |  |  * in the way it handles accesses to odd IO ports on 16-bit devices.  These | 
					
						
							|  |  |  |  * devices have their D0-D15 lines connected to the processors D0-D15 lines. | 
					
						
							|  |  |  |  * Since they expect all byte IO operations to be performed on D0-D7, and the | 
					
						
							|  |  |  |  * StrongARM expects to transfer the byte to these odd addresses on D8-D15, | 
					
						
							|  |  |  |  * we must use a trick to get the required behaviour. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The trick employed here is to use long word stores to odd address -1.  The | 
					
						
							|  |  |  |  * glue logic picks this up as a "trick" access, and asserts the LSB of the | 
					
						
							|  |  |  |  * peripherals address bus, thereby accessing the odd IO port.  Meanwhile, the | 
					
						
							|  |  |  |  * StrongARM transfers its data on D0-D7 as expected. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Things get more interesting on the pass-1 EBSA110 - the PCMCIA controller | 
					
						
							|  |  |  |  * wiring was screwed in such a way that it had limited memory space access. | 
					
						
							|  |  |  |  * Luckily, the work-around for this is not too horrible.  See | 
					
						
							|  |  |  |  * __isamem_convert_addr for the details. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <linux/module.h>
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/types.h>
 | 
					
						
							| 
									
										
										
										
											2008-09-06 12:10:45 +01:00
										 |  |  | #include <linux/io.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-05 16:14:15 +01:00
										 |  |  | #include <mach/hardware.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #include <asm/page.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-20 15:59:10 +00:00
										 |  |  | static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	u32 ret, a = (u32 __force) addr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The PCMCIA controller is wired up as follows: | 
					
						
							|  |  |  | 	 *        +---------+---------+---------+---------+---------+---------+ | 
					
						
							|  |  |  | 	 * PCMCIA | 2 2 2 2 | 1 1 1 1 | 1 1 1 1 | 1 1     |         |         | | 
					
						
							|  |  |  | 	 *        | 3 2 1 0 | 9 8 7 6 | 5 4 3 2 | 1 0 9 8 | 7 6 5 4 | 3 2 1 0 | | 
					
						
							|  |  |  | 	 *        +---------+---------+---------+---------+---------+---------+ | 
					
						
							|  |  |  | 	 *  CPU   | 2 2 2 2 | 2 1 1 1 | 1 1 1 1 | 1 1 1   |         |         | | 
					
						
							|  |  |  | 	 *        | 4 3 2 1 | 0 9 9 8 | 7 6 5 4 | 3 2 0 9 | 8 7 6 5 | 4 3 2 x | | 
					
						
							|  |  |  | 	 *        +---------+---------+---------+---------+---------+---------+ | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * This means that we can access PCMCIA regions as follows: | 
					
						
							|  |  |  | 	 *	0x*10000 -> 0x*1ffff | 
					
						
							|  |  |  | 	 *	0x*70000 -> 0x*7ffff | 
					
						
							|  |  |  | 	 *	0x*90000 -> 0x*9ffff | 
					
						
							|  |  |  | 	 *	0x*f0000 -> 0x*fffff | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	ret  = (a & 0xf803fe) << 1; | 
					
						
							|  |  |  | 	ret |= (a & 0x03fc00) << 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret += 0xe8000000; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((a & 0x20000) == (a & 0x40000) >> 1) | 
					
						
							|  |  |  | 		return (void __iomem *)ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BUG(); | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * read[bwl] and write[bwl] | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2006-11-20 15:59:10 +00:00
										 |  |  | u8 __readb(const volatile void __iomem *addr) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 	u32 ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((unsigned long)addr & 1) | 
					
						
							|  |  |  | 		ret = __raw_readl(a); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		ret = __raw_readb(a); | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-20 15:59:10 +00:00
										 |  |  | u16 __readw(const volatile void __iomem *addr) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((unsigned long)addr & 1) | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return __raw_readw(a); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-20 15:59:10 +00:00
										 |  |  | u32 __readl(const volatile void __iomem *addr) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 	u32 ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((unsigned long)addr & 3) | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = __raw_readw(a); | 
					
						
							|  |  |  | 	ret |= __raw_readw(a + 4) << 16; | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EXPORT_SYMBOL(__readb); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__readw); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__readl); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-09 20:18:05 +01:00
										 |  |  | void readsw(const void __iomem *addr, void *data, int len) | 
					
						
							| 
									
										
										
										
											2007-03-03 11:51:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON((unsigned long)addr & 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_readsw(a, data, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(readsw); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-09 20:18:05 +01:00
										 |  |  | void readsl(const void __iomem *addr, void *data, int len) | 
					
						
							| 
									
										
										
										
											2007-03-03 11:51:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON((unsigned long)addr & 3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_readsl(a, data, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(readsl); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | void __writeb(u8 val, void __iomem *addr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((unsigned long)addr & 1) | 
					
						
							|  |  |  | 		__raw_writel(val, a); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		__raw_writeb(val, a); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __writew(u16 val, void __iomem *addr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((unsigned long)addr & 1) | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_writew(val, a); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __writel(u32 val, void __iomem *addr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((unsigned long)addr & 3) | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_writew(val, a); | 
					
						
							|  |  |  | 	__raw_writew(val >> 16, a + 4); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EXPORT_SYMBOL(__writeb); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__writew); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__writel); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-09 20:18:05 +01:00
										 |  |  | void writesw(void __iomem *addr, const void *data, int len) | 
					
						
							| 
									
										
										
										
											2007-03-03 11:51:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON((unsigned long)addr & 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_writesw(a, data, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(writesw); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-09 20:18:05 +01:00
										 |  |  | void writesl(void __iomem *addr, const void *data, int len) | 
					
						
							| 
									
										
										
										
											2007-03-03 11:51:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a = __isamem_convert_addr(addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON((unsigned long)addr & 3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_writesl(a, data, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(writesl); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-10 11:13:05 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * The EBSA110 has a weird "ISA IO" region: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Region 0 (addr = 0xf0000000 + io << 2) | 
					
						
							|  |  |  |  * -------------------------------------------------------- | 
					
						
							|  |  |  |  * Physical region	IO region | 
					
						
							|  |  |  |  * f0000fe0 - f0000ffc	3f8 - 3ff  ttyS0 | 
					
						
							|  |  |  |  * f0000e60 - f0000e64	398 - 399 | 
					
						
							|  |  |  |  * f0000de0 - f0000dfc	378 - 37f  lp0 | 
					
						
							|  |  |  |  * f0000be0 - f0000bfc	2f8 - 2ff  ttyS1 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1)) | 
					
						
							|  |  |  |  * -------------------------------------------------------- | 
					
						
							|  |  |  |  * Physical region	IO region | 
					
						
							|  |  |  |  * f00014f1             a79        pnp write data | 
					
						
							|  |  |  |  * f00007c0 - f00007c1	3e0 - 3e1  pcmcia | 
					
						
							|  |  |  |  * f00004f1		279        pnp address | 
					
						
							|  |  |  |  * f0000440 - f000046c  220 - 236  eth0 | 
					
						
							|  |  |  |  * f0000405		203        pnp read data | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #define SUPERIO_PORT(p) \
 | 
					
						
							|  |  |  | 	(((p) >> 3) == (0x3f8 >> 3) || \ | 
					
						
							|  |  |  | 	 ((p) >> 3) == (0x2f8 >> 3) || \ | 
					
						
							|  |  |  | 	 ((p) >> 3) == (0x378 >> 3)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * We're addressing an 8 or 16-bit peripheral which tranfers | 
					
						
							|  |  |  |  * odd addresses on the low ISA byte lane. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | u8 __inb8(unsigned int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The SuperIO registers use sane addressing techniques... | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		ret = __raw_readb((void __iomem *)ISAIO_BASE + (port << 2)); | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Shame nothing else does | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		if (port & 1) | 
					
						
							|  |  |  | 			ret = __raw_readl(a); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			ret = __raw_readb(a); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * We're addressing a 16-bit peripheral which transfers odd | 
					
						
							|  |  |  |  * addresses on the high ISA byte lane. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | u8 __inb16(unsigned int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The SuperIO registers use sane addressing techniques... | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		offset = port << 2; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		offset = (port & ~1) << 1 | (port & 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return __raw_readb((void __iomem *)ISAIO_BASE + offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u16 __inw(unsigned int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The SuperIO registers use sane addressing techniques... | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		offset = port << 2; | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		offset = port << 1; | 
					
						
							|  |  |  | 		BUG_ON(port & 1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return __raw_readw((void __iomem *)ISAIO_BASE + offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Fake a 32-bit read with two 16-bit reads.  Needed for 3c589. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | u32 __inl(unsigned int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	void __iomem *a; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port) || port & 3) | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return __raw_readw(a) | __raw_readw(a + 4) << 16; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EXPORT_SYMBOL(__inb8); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__inb16); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__inw); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__inl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __outb8(u8 val, unsigned int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The SuperIO registers use sane addressing techniques... | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		__raw_writeb(val, (void __iomem *)ISAIO_BASE + (port << 2)); | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Shame nothing else does | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		if (port & 1) | 
					
						
							|  |  |  | 			__raw_writel(val, a); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			__raw_writeb(val, a); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __outb16(u8 val, unsigned int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The SuperIO registers use sane addressing techniques... | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		offset = port << 2; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		offset = (port & ~1) << 1 | (port & 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_writeb(val, (void __iomem *)ISAIO_BASE + offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __outw(u16 val, unsigned int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The SuperIO registers use sane addressing techniques... | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		offset = port << 2; | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		offset = port << 1; | 
					
						
							|  |  |  | 		BUG_ON(port & 1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	__raw_writew(val, (void __iomem *)ISAIO_BASE + offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __outl(u32 val, unsigned int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BUG(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EXPORT_SYMBOL(__outb8); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__outb16); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__outw); | 
					
						
							|  |  |  | EXPORT_SYMBOL(__outl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void outsb(unsigned int port, const void *from, int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 off; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		off = port << 2; | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		off = (port & ~1) << 1; | 
					
						
							|  |  |  | 		if (port & 1) | 
					
						
							|  |  |  | 			BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_writesb((void __iomem *)ISAIO_BASE + off, from, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void insb(unsigned int port, void *from, int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 off; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		off = port << 2; | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		off = (port & ~1) << 1; | 
					
						
							|  |  |  | 		if (port & 1) | 
					
						
							|  |  |  | 			BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_readsb((void __iomem *)ISAIO_BASE + off, from, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EXPORT_SYMBOL(outsb); | 
					
						
							|  |  |  | EXPORT_SYMBOL(insb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void outsw(unsigned int port, const void *from, int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 off; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		off = port << 2; | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		off = (port & ~1) << 1; | 
					
						
							|  |  |  | 		if (port & 1) | 
					
						
							|  |  |  | 			BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_writesw((void __iomem *)ISAIO_BASE + off, from, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void insw(unsigned int port, void *from, int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 off; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port)) | 
					
						
							|  |  |  | 		off = port << 2; | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		off = (port & ~1) << 1; | 
					
						
							|  |  |  | 		if (port & 1) | 
					
						
							|  |  |  | 			BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_readsw((void __iomem *)ISAIO_BASE + off, from, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EXPORT_SYMBOL(outsw); | 
					
						
							|  |  |  | EXPORT_SYMBOL(insw); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * We implement these as 16-bit insw/outsw, mainly for | 
					
						
							|  |  |  |  * 3c589 cards. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void outsl(unsigned int port, const void *from, int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 off = port << 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port) || port & 3) | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_writesw((void __iomem *)ISAIO_BASE + off, from, len << 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void insl(unsigned int port, void *from, int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 off = port << 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (SUPERIO_PORT(port) || port & 3) | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__raw_readsw((void __iomem *)ISAIO_BASE + off, from, len << 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EXPORT_SYMBOL(outsl); | 
					
						
							|  |  |  | EXPORT_SYMBOL(insl); |