cregit-Linux how code gets into the kernel

Release 4.11 arch/arm/mach-ebsa110/io.c

/*
 *  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>
#include <linux/io.h>

#include <mach/hardware.h>
#include <asm/page.h>


static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr) { 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; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds6883.95%133.33%
Russell King1316.05%266.67%
Total81100.00%3100.00%

/* * read[bwl] and write[bwl] */
u8 __readb(const volatile void __iomem *addr) { 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; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds4075.47%125.00%
Russell King1324.53%375.00%
Total53100.00%4100.00%


u16 __readw(const volatile void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); if ((unsigned long)addr & 1) BUG(); return __raw_readw(a); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds3278.05%125.00%
Russell King921.95%375.00%
Total41100.00%4100.00%


u32 __readl(const volatile void __iomem *addr) { 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; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds4677.97%125.00%
Russell King1322.03%375.00%
Total59100.00%4100.00%

EXPORT_SYMBOL(__readb); EXPORT_SYMBOL(__readw); EXPORT_SYMBOL(__readl);
void readsw(const volatile void __iomem *addr, void *data, int len) { void __iomem *a = __isamem_convert_addr(addr); BUG_ON((unsigned long)addr & 1); __raw_readsw(a, data, len); }

Contributors

PersonTokensPropCommitsCommitProp
Russell King4897.96%266.67%
Thierry Reding12.04%133.33%
Total49100.00%3100.00%

EXPORT_SYMBOL(readsw);
void readsl(const volatile void __iomem *addr, void *data, int len) { void __iomem *a = __isamem_convert_addr(addr); BUG_ON((unsigned long)addr & 3); __raw_readsl(a, data, len); }

Contributors

PersonTokensPropCommitsCommitProp
Russell King4897.96%266.67%
Thierry Reding12.04%133.33%
Total49100.00%3100.00%

EXPORT_SYMBOL(readsl);
void __writeb(u8 val, volatile void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); if ((unsigned long)addr & 1) __raw_writel(val, a); else __raw_writeb(val, a); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds4081.63%125.00%
Russell King816.33%250.00%
Thierry Reding12.04%125.00%
Total49100.00%4100.00%


void __writew(u16 val, volatile void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); if ((unsigned long)addr & 1) BUG(); __raw_writew(val, a); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds3681.82%125.00%
Russell King715.91%250.00%
Thierry Reding12.27%125.00%
Total44100.00%4100.00%


void __writel(u32 val, volatile 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); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds4683.64%125.00%
Russell King814.55%250.00%
Thierry Reding11.82%125.00%
Total55100.00%4100.00%

EXPORT_SYMBOL(__writeb); EXPORT_SYMBOL(__writew); EXPORT_SYMBOL(__writel);
void writesw(volatile void __iomem *addr, const void *data, int len) { void __iomem *a = __isamem_convert_addr(addr); BUG_ON((unsigned long)addr & 1); __raw_writesw(a, data, len); }

Contributors

PersonTokensPropCommitsCommitProp
Russell King4897.96%266.67%
Thierry Reding12.04%133.33%
Total49100.00%3100.00%

EXPORT_SYMBOL(writesw);
void writesl(volatile void __iomem *addr, const void *data, int len) { void __iomem *a = __isamem_convert_addr(addr); BUG_ON((unsigned long)addr & 3); __raw_writesl(a, data, len); }

Contributors

PersonTokensPropCommitsCommitProp
Russell King4897.96%266.67%
Thierry Reding12.04%133.33%
Total49100.00%3100.00%

EXPORT_SYMBOL(writesl); /* * 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 */ #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; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds7179.78%120.00%
Russell King1820.22%480.00%
Total89100.00%5100.00%

/* * 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); }

Contributors

PersonTokensPropCommitsCommitProp
Russell King58100.00%2100.00%
Total58100.00%2100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds3562.50%133.33%
Russell King2137.50%266.67%
Total56100.00%3100.00%

/* * 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; }

Contributors

PersonTokensPropCommitsCommitProp
Russell King5079.37%360.00%
Linus Torvalds1320.63%240.00%
Total63100.00%5100.00%

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); } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds6879.07%120.00%
Russell King1820.93%480.00%
Total86100.00%5100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
Russell King62100.00%2100.00%
Total62100.00%2100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds4473.33%125.00%
Russell King1626.67%375.00%
Total60100.00%4100.00%


void __outl(u32 val, unsigned int port) { BUG(); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds1493.33%150.00%
Russell King16.67%150.00%
Total15100.00%2100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds6793.06%266.67%
Russell King56.94%133.33%
Total72100.00%3100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds6692.96%266.67%
Russell King57.04%133.33%
Total71100.00%3100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds6793.06%266.67%
Russell King56.94%133.33%
Total72100.00%3100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds6692.96%266.67%
Russell King57.04%133.33%
Total71100.00%3100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Russell King3664.29%266.67%
Linus Torvalds2035.71%133.33%
Total56100.00%3100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
Russell King3665.45%266.67%
Linus Torvalds1934.55%133.33%
Total55100.00%3100.00%

EXPORT_SYMBOL(outsl); EXPORT_SYMBOL(insl);

Overall Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds96059.37%426.67%
Russell King65040.20%1066.67%
Thierry Reding70.43%16.67%
Total1617100.00%15100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.