OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [pcmcia/] [pci_socket.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Generic PCI pccard driver interface.
3
 *
4
 * (C) Copyright 1999 Linus Torvalds
5
 *
6
 * This implements the common parts of PCI pccard drivers,
7
 * notably detection and infrastructure conversion (ie change
8
 * from socket index to "struct pci_dev" etc)
9
 *
10
 * This does NOT implement the actual low-level driver details,
11
 * and this has on purpose been left generic enough that it can
12
 * be used to set up a PCI PCMCIA controller (ie non-cardbus),
13
 * or to set up a controller.
14
 *
15
 * See for example the "yenta" driver for PCI cardbus controllers
16
 * conforming to the yenta cardbus specifications.
17
 */
18
#include <linux/module.h>
19
 
20
#include <linux/init.h>
21
#include <linux/pci.h>
22
#include <linux/sched.h>
23
#include <linux/interrupt.h>
24
 
25
#include <pcmcia/ss.h>
26
 
27
#include <asm/io.h>
28
 
29
#include "pci_socket.h"
30
 
31
 
32
extern struct socket_info_t *pcmcia_register_socket (int slot,
33
                struct pccard_operations *vtable, int use_bus_pm);
34
extern void pcmcia_unregister_socket (struct socket_info_t *socket);
35
extern void pcmcia_suspend_socket (struct socket_info_t *socket);
36
extern void pcmcia_resume_socket (struct socket_info_t *socket);
37
 
38
 
39
/*
40
 * Arbitrary define. This is the array of active cardbus
41
 * entries.
42
 */
43
#define MAX_SOCKETS (8)
44
static pci_socket_t pci_socket_array[MAX_SOCKETS];
45
 
46
static int pci_init_socket(unsigned int sock)
47
{
48
        pci_socket_t *socket = pci_socket_array + sock;
49
 
50
        if (socket->op && socket->op->init)
51
                return socket->op->init(socket);
52
        return -EINVAL;
53
}
54
 
55
static int pci_suspend_socket(unsigned int sock)
56
{
57
        pci_socket_t *socket = pci_socket_array + sock;
58
 
59
        if (socket->op && socket->op->suspend)
60
                return socket->op->suspend(socket);
61
        return -EINVAL;
62
}
63
 
64
static int pci_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
65
{
66
        pci_socket_t *socket = pci_socket_array + sock;
67
 
68
        socket->handler = handler;
69
        socket->info = info;
70
        if (handler)
71
                MOD_INC_USE_COUNT;
72
        else
73
                MOD_DEC_USE_COUNT;
74
        return 0;
75
}
76
 
77
static int pci_inquire_socket(unsigned int sock, socket_cap_t *cap)
78
{
79
        pci_socket_t *socket = pci_socket_array + sock;
80
 
81
        *cap = socket->cap;
82
        return 0;
83
}
84
 
85
static int pci_get_status(unsigned int sock, unsigned int *value)
86
{
87
        pci_socket_t *socket = pci_socket_array + sock;
88
 
89
        if (socket->op && socket->op->get_status)
90
                return socket->op->get_status(socket, value);
91
        *value = 0;
92
        return -EINVAL;
93
}
94
 
95
static int pci_get_socket(unsigned int sock, socket_state_t *state)
96
{
97
        pci_socket_t *socket = pci_socket_array + sock;
98
 
99
        if (socket->op && socket->op->get_socket)
100
                return socket->op->get_socket(socket, state);
101
        return -EINVAL;
102
}
103
 
104
static int pci_set_socket(unsigned int sock, socket_state_t *state)
105
{
106
        pci_socket_t *socket = pci_socket_array + sock;
107
 
108
        if (socket->op && socket->op->set_socket)
109
                return socket->op->set_socket(socket, state);
110
        return -EINVAL;
111
}
112
 
113
static int pci_get_io_map(unsigned int sock, struct pccard_io_map *io)
114
{
115
        pci_socket_t *socket = pci_socket_array + sock;
116
 
117
        if (socket->op && socket->op->get_io_map)
118
                return socket->op->get_io_map(socket, io);
119
        return -EINVAL;
120
}
121
 
122
static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io)
123
{
124
        pci_socket_t *socket = pci_socket_array + sock;
125
 
126
        if (socket->op && socket->op->set_io_map)
127
                return socket->op->set_io_map(socket, io);
128
        return -EINVAL;
129
}
130
 
131
static int pci_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
132
{
133
        pci_socket_t *socket = pci_socket_array + sock;
134
 
135
        if (socket->op && socket->op->get_mem_map)
136
                return socket->op->get_mem_map(socket, mem);
137
        return -EINVAL;
138
}
139
 
140
static int pci_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
141
{
142
        pci_socket_t *socket = pci_socket_array + sock;
143
 
144
        if (socket->op && socket->op->set_mem_map)
145
                return socket->op->set_mem_map(socket, mem);
146
        return -EINVAL;
147
}
148
 
149
static void pci_proc_setup(unsigned int sock, struct proc_dir_entry *base)
150
{
151
        pci_socket_t *socket = pci_socket_array + sock;
152
 
153
        if (socket->op && socket->op->proc_setup)
154
                socket->op->proc_setup(socket, base);
155
}
156
 
157
static struct pccard_operations pci_socket_operations = {
158
        pci_init_socket,
159
        pci_suspend_socket,
160
        pci_register_callback,
161
        pci_inquire_socket,
162
        pci_get_status,
163
        pci_get_socket,
164
        pci_set_socket,
165
        pci_get_io_map,
166
        pci_set_io_map,
167
        pci_get_mem_map,
168
        pci_set_mem_map,
169
        pci_proc_setup
170
};
171
 
172
static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_socket_ops *ops)
173
{
174
        pci_socket_t *socket = nr + pci_socket_array;
175
        int err;
176
 
177
        memset(socket, 0, sizeof(*socket));
178
        socket->dev = dev;
179
        socket->op = ops;
180
        pci_set_drvdata(dev, socket);
181
        spin_lock_init(&socket->event_lock);
182
        err = socket->op->open(socket);
183
        if(err)
184
        {
185
                socket->dev = NULL;
186
                pci_set_drvdata(dev, NULL);
187
        }
188
        return err;
189
}
190
 
191
void cardbus_register(pci_socket_t *socket)
192
{
193
        int nr = socket - pci_socket_array;
194
 
195
        socket->pcmcia_socket = pcmcia_register_socket(nr, &pci_socket_operations, 1);
196
}
197
 
198
static int __devinit
199
cardbus_probe (struct pci_dev *dev, const struct pci_device_id *id)
200
{
201
        int     s;
202
 
203
        for (s = 0; s < MAX_SOCKETS; s++) {
204
                if (pci_socket_array [s].dev == 0) {
205
                        return add_pci_socket (s, dev, &yenta_operations);
206
                }
207
        }
208
        return -ENODEV;
209
}
210
 
211
static void __devexit cardbus_remove (struct pci_dev *dev)
212
{
213
        pci_socket_t *socket = pci_get_drvdata(dev);
214
 
215
        pcmcia_unregister_socket (socket->pcmcia_socket);
216
        if (socket->op && socket->op->close)
217
                socket->op->close(socket);
218
        pci_set_drvdata(dev, NULL);
219
}
220
 
221
static int cardbus_suspend (struct pci_dev *dev, u32 state)
222
{
223
        pci_socket_t *socket = pci_get_drvdata(dev);
224
        pcmcia_suspend_socket (socket->pcmcia_socket);
225
        return 0;
226
}
227
 
228
static int cardbus_resume (struct pci_dev *dev)
229
{
230
        pci_socket_t *socket = pci_get_drvdata(dev);
231
        pcmcia_resume_socket (socket->pcmcia_socket);
232
        return 0;
233
}
234
 
235
 
236
static struct pci_device_id cardbus_table [] __devinitdata = { {
237
        class:          PCI_CLASS_BRIDGE_CARDBUS << 8,
238
        class_mask:     ~0,
239
 
240
        vendor:         PCI_ANY_ID,
241
        device:         PCI_ANY_ID,
242
        subvendor:      PCI_ANY_ID,
243
        subdevice:      PCI_ANY_ID,
244
}, { /* all zeroes */ }
245
};
246
MODULE_DEVICE_TABLE(pci, cardbus_table);
247
 
248
static struct pci_driver pci_cardbus_driver = {
249
        name:           "cardbus",
250
        id_table:       cardbus_table,
251
        probe:          cardbus_probe,
252
        remove:         __devexit_p(cardbus_remove),
253
        suspend:        cardbus_suspend,
254
        resume:         cardbus_resume,
255
};
256
 
257
static int __init pci_socket_init(void)
258
{
259
        return pci_module_init (&pci_cardbus_driver);
260
}
261
 
262
static void __exit pci_socket_exit (void)
263
{
264
        pci_unregister_driver (&pci_cardbus_driver);
265
}
266
 
267
module_init(pci_socket_init);
268
module_exit(pci_socket_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.