summaryrefslogtreecommitdiff
path: root/arch/sh/boards/titan/io.c
blob: b886fd233a66cf24e77d13e901f60f3d89a9231d (plain)
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
143
144
145
146
147
148
149
/*
 *	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)
{
	if (PXSEG(port) || CHECK_SH7751_PCIMEMIO(port))
		return (void __iomem *)port;
	else if (CHECK_SH7751_PCIIO(port))
		return (void __iomem *)PCI_IOMAP(port);

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