io.c 3.8 KB
Newer Older
J
Jamie Lenehan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/*
 *	I/O routines for Titan
 */

#include <linux/pci.h>
#include <asm/machvec.h>
#include <asm/addrspace.h>
#include <asm/titan.h>
#include <asm/io.h>
#include "../../drivers/pci/pci-sh7751.h"

#define PCIIOBR         (volatile long *)PCI_REG(SH7751_PCIIOBR)
#define PCIMBR          (volatile long *)PCI_REG(SH7751_PCIMBR)
#define PCI_IO_AREA     SH7751_PCI_IO_BASE
#define PCI_MEM_AREA    SH7751_PCI_CONFIG_BASE

#define PCI_IOMAP(adr)  (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))

#if defined(CONFIG_PCI)
#define CHECK_SH7751_PCIIO(port) \
  ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
#define CHECK_SH7751_PCIMEMIO(port) \
  ((port >= PCIBIOS_MIN_MEM) && (port < (PCIBIOS_MIN_MEM + SH7751_PCI_MEM_SIZE)))
#else
#define CHECK_SH7751_PCIIO(port) (0)
#endif

static inline void delay(void)
{
        ctrl_inw(0xa0000000);
}

static inline volatile u16 *port2adr(unsigned int port)
{
        maybebadio((unsigned long)port);
        return (volatile u16*)port;
}

u8 titan_inb(unsigned long port)
{
        if (PXSEG(port))
                return ctrl_inb(port);
        else if (CHECK_SH7751_PCIIO(port))
                return ctrl_inb(PCI_IOMAP(port));
        return ctrl_inw(port2adr(port)) & 0xff;
}

u8 titan_inb_p(unsigned long port)
{
        u8 v;

        if (PXSEG(port))
                v = ctrl_inb(port);
        else if (CHECK_SH7751_PCIIO(port))
                v = ctrl_inb(PCI_IOMAP(port));
        else
                v = ctrl_inw(port2adr(port)) & 0xff;
        delay();
        return v;
}

u16 titan_inw(unsigned long port)
{
        if (PXSEG(port))
                return ctrl_inw(port);
        else if (CHECK_SH7751_PCIIO(port))
                return ctrl_inw(PCI_IOMAP(port));
        else if (port >= 0x2000)
                return ctrl_inw(port2adr(port));
        else
                maybebadio(port);
        return 0;
}

u32 titan_inl(unsigned long port)
{
        if (PXSEG(port))
                return ctrl_inl(port);
        else if (CHECK_SH7751_PCIIO(port))
                return ctrl_inl(PCI_IOMAP(port));
        else if (port >= 0x2000)
                return ctrl_inw(port2adr(port));
        else
                maybebadio(port);
        return 0;
}

void titan_outb(u8 value, unsigned long port)
{
        if (PXSEG(port))
                ctrl_outb(value, port);
        else if (CHECK_SH7751_PCIIO(port))
                ctrl_outb(value, PCI_IOMAP(port));
        else
                ctrl_outw(value, port2adr(port));
}

void titan_outb_p(u8 value, unsigned long port)
{
        if (PXSEG(port))
                ctrl_outb(value, port);
        else if (CHECK_SH7751_PCIIO(port))
                ctrl_outb(value, PCI_IOMAP(port));
        else
                ctrl_outw(value, port2adr(port));
        delay();
}

void titan_outw(u16 value, unsigned long port)
{
        if (PXSEG(port))
                ctrl_outw(value, port);
        else if (CHECK_SH7751_PCIIO(port))
                ctrl_outw(value, PCI_IOMAP(port));
        else if (port >= 0x2000)
                ctrl_outw(value, port2adr(port));
        else
                maybebadio(port);
}

void titan_outl(u32 value, unsigned long port)
{
        if (PXSEG(port))
                ctrl_outl(value, port);
        else if (CHECK_SH7751_PCIIO(port))
                ctrl_outl(value, PCI_IOMAP(port));
        else
                maybebadio(port);
}

void titan_insl(unsigned long port, void *dst, unsigned long count)
{
        maybebadio(port);
}

void titan_outsl(unsigned long port, const void *src, unsigned long count)
{
        maybebadio(port);
}

void __iomem *titan_ioport_map(unsigned long port, unsigned int size)
{
P
Paul Mundt 已提交
143
	if (PXSEG(port) || CHECK_SH7751_PCIMEMIO(port))
J
Jamie Lenehan 已提交
144 145 146 147 148 149
		return (void __iomem *)port;
	else if (CHECK_SH7751_PCIIO(port))
		return (void __iomem *)PCI_IOMAP(port);

	return (void __iomem *)port2adr(port);
}