Commit 782ed19e authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.5-pcmcia

into home.transmeta.com:/home/torvalds/v2.5/linux
parents ad80d2d1 ea814ca7
......@@ -29,8 +29,8 @@ config PCMCIA
and ds. If you want to compile it as a module, say M here and
read <file:Documentation/modules.txt>.
config CARDBUS
bool "CardBus support"
config YENTA
tristate "CardBus yenta-compatible bridge support"
depends on PCMCIA && PCI
---help---
CardBus is a bus mastering architecture for PC-cards, which allows
......@@ -48,6 +48,11 @@ config CARDBUS
If unsure, say Y.
config CARDBUS
bool
depends on YENTA
default y if YENTA
config I82092
tristate "i82092 compatible bridge support"
depends on PCMCIA && PCI
......@@ -58,7 +63,7 @@ config I82092
config I82365
tristate "i82365 compatible bridge support"
depends on PCMCIA
depends on PCMCIA && ISA
help
Say Y here to include support for ISA-bus PCMCIA host bridges that
are register compatible with the Intel i82365. These are found on
......
......@@ -3,9 +3,7 @@
#
obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o
ifeq ($(CONFIG_CARDBUS),y)
obj-$(CONFIG_PCMCIA) += yenta_socket.o
endif
obj-$(CONFIG_YENTA) += yenta.o
obj-$(CONFIG_I82365) += i82365.o
obj-$(CONFIG_I82092) += i82092.o
......@@ -14,8 +12,6 @@ obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
yenta_socket-y += pci_socket.o yenta.o
pcmcia_core-y += cistpl.o rsrc_mgr.o bulkmem.o cs.o
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
......
......@@ -63,7 +63,7 @@ static int do_mtd_request(memory_handle_t handle, mtd_request_t *req,
{
int ret, tries;
client_t *mtd;
socket_info_t *s;
struct pcmcia_socket *s;
mtd = handle->mtd;
if (mtd == NULL)
......@@ -130,7 +130,7 @@ static void retry_erase(erase_busy_t *busy, u_int cause)
eraseq_entry_t *erase = busy->erase;
mtd_request_t req;
client_t *mtd;
socket_info_t *s;
struct pcmcia_socket *s;
int ret;
DEBUG(2, "cs: trying erase request 0x%p...\n", busy);
......@@ -259,27 +259,27 @@ static int mtd_modify_window(window_handle_t win, mtd_mod_win_t *req)
win->ctl.flags |= MAP_ATTRIB;
win->ctl.speed = req->AccessSpeed;
win->ctl.card_start = req->CardOffset;
win->sock->ss_entry->set_mem_map(win->sock->sock, &win->ctl);
win->sock->ss_entry->set_mem_map(win->sock, &win->ctl);
return CS_SUCCESS;
}
static int mtd_set_vpp(client_handle_t handle, mtd_vpp_req_t *req)
{
socket_info_t *s;
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
if (req->Vpp1 != req->Vpp2)
return CS_BAD_VPP;
s = SOCKET(handle);
s->socket.Vpp = req->Vpp1;
if (s->ss_entry->set_socket(s->sock, &s->socket))
if (s->ss_entry->set_socket(s, &s->socket))
return CS_BAD_VPP;
return CS_SUCCESS;
}
static int mtd_rdy_mask(client_handle_t handle, mtd_rdy_req_t *req)
{
socket_info_t *s;
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
......@@ -287,7 +287,7 @@ static int mtd_rdy_mask(client_handle_t handle, mtd_rdy_req_t *req)
s->socket.csc_mask |= SS_READY;
else
s->socket.csc_mask &= ~SS_READY;
if (s->ss_entry->set_socket(s->sock, &s->socket))
if (s->ss_entry->set_socket(s, &s->socket))
return CS_GENERAL_FAILURE;
return CS_SUCCESS;
}
......@@ -417,7 +417,7 @@ static int match_region(client_handle_t handle, memory_handle_t list,
int pcmcia_get_first_region(client_handle_t handle, region_info_t *rgn)
{
socket_info_t *s = SOCKET(handle);
struct pcmcia_socket *s = SOCKET(handle);
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
......@@ -450,7 +450,7 @@ int pcmcia_get_next_region(client_handle_t handle, region_info_t *rgn)
int pcmcia_register_mtd(client_handle_t handle, mtd_reg_t *reg)
{
memory_handle_t list;
socket_info_t *s;
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
......@@ -533,12 +533,12 @@ int pcmcia_check_erase_queue(eraseq_handle_t eraseq)
int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open, memory_handle_t *mh)
{
socket_info_t *s;
struct pcmcia_socket *s;
memory_handle_t region;
if ((handle == NULL) || CHECK_HANDLE(*handle))
return CS_BAD_HANDLE;
s = SOCKET(*handle);
s = (*handle)->Socket;
if (open->Attributes & MEMORY_TYPE_AM)
region = s->a_region;
else
......
......@@ -119,11 +119,11 @@ static u_int xlate_rom_addr(u_char * b, u_int addr)
These are similar to setup_cis_mem and release_cis_mem for 16-bit
cards. The "result" that is used externally is the cb_cis_virt
pointer in the socket_info_t structure.
pointer in the struct pcmcia_socket structure.
=====================================================================*/
static void cb_release_cis_mem(socket_info_t * s)
static void cb_release_cis_mem(struct pcmcia_socket * s)
{
if (s->cb_cis_virt) {
DEBUG(1, "cs: cb_release_cis_mem()\n");
......@@ -133,7 +133,7 @@ static void cb_release_cis_mem(socket_info_t * s)
}
}
static int cb_setup_cis_mem(socket_info_t * s, struct resource *res)
static int cb_setup_cis_mem(struct pcmcia_socket * s, struct resource *res)
{
unsigned int start, size;
......@@ -162,7 +162,7 @@ static int cb_setup_cis_mem(socket_info_t * s, struct resource *res)
=====================================================================*/
int read_cb_mem(socket_info_t * s, int space, u_int addr, u_int len, void *ptr)
int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void *ptr)
{
struct pci_dev *dev;
struct resource *res;
......@@ -237,7 +237,7 @@ static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
}
}
int cb_alloc(socket_info_t * s)
int cb_alloc(struct pcmcia_socket * s)
{
struct pci_bus *bus = s->cap.cb_dev->subordinate;
struct pci_dev *dev;
......@@ -266,7 +266,7 @@ int cb_alloc(socket_info_t * s)
return CS_SUCCESS;
}
void cb_free(socket_info_t * s)
void cb_free(struct pcmcia_socket * s)
{
struct pci_dev *bridge = s->cap.cb_dev;
......
......@@ -82,11 +82,11 @@ static const u_int exponent[] = {
INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */
void release_cis_mem(socket_info_t *s)
void release_cis_mem(struct pcmcia_socket *s)
{
if (s->cis_mem.sys_start != 0) {
s->cis_mem.flags &= ~MAP_ACTIVE;
s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
s->ss_entry->set_mem_map(s, &s->cis_mem);
if (!(s->cap.features & SS_CAP_STATIC_MAP))
release_mem_region(s->cis_mem.sys_start, s->cap.map_size);
iounmap(s->cis_virt);
......@@ -101,7 +101,7 @@ void release_cis_mem(socket_info_t *s)
* map the memory space.
*/
static unsigned char *
set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags)
set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)
{
pccard_mem_map *mem = &s->cis_mem;
if (!(s->cap.features & SS_CAP_STATIC_MAP) &&
......@@ -119,7 +119,7 @@ set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags)
}
mem->card_start = card_offset;
mem->flags = flags;
s->ss_entry->set_mem_map(s->sock, mem);
s->ss_entry->set_mem_map(s, mem);
if (s->cap.features & SS_CAP_STATIC_MAP) {
if (s->cis_virt)
iounmap(s->cis_virt);
......@@ -139,7 +139,7 @@ set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags)
#define IS_ATTR 1
#define IS_INDIRECT 8
int read_cis_mem(socket_info_t *s, int attr, u_int addr,
int read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr)
{
u_char *sys, *end, *buf = ptr;
......@@ -202,7 +202,7 @@ int read_cis_mem(socket_info_t *s, int attr, u_int addr,
return 0;
}
void write_cis_mem(socket_info_t *s, int attr, u_int addr,
void write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr)
{
u_char *sys, *end, *buf = ptr;
......@@ -266,7 +266,7 @@ void write_cis_mem(socket_info_t *s, int attr, u_int addr,
======================================================================*/
static void read_cis_cache(socket_info_t *s, int attr, u_int addr,
static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr)
{
struct cis_cache_entry *cis;
......@@ -306,7 +306,7 @@ static void read_cis_cache(socket_info_t *s, int attr, u_int addr,
}
static void
remove_cis_cache(socket_info_t *s, int attr, u_int addr, u_int len)
remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len)
{
struct cis_cache_entry *cis;
......@@ -318,7 +318,7 @@ remove_cis_cache(socket_info_t *s, int attr, u_int addr, u_int len)
}
}
void destroy_cis_cache(socket_info_t *s)
void destroy_cis_cache(struct pcmcia_socket *s)
{
struct list_head *l, *n;
......@@ -337,7 +337,7 @@ void destroy_cis_cache(socket_info_t *s)
======================================================================*/
int verify_cis_cache(socket_info_t *s)
int verify_cis_cache(struct pcmcia_socket *s)
{
struct cis_cache_entry *cis;
char buf[256];
......@@ -369,7 +369,7 @@ int verify_cis_cache(socket_info_t *s)
int pcmcia_replace_cis(client_handle_t handle, cisdump_t *cis)
{
socket_info_t *s;
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
......@@ -409,7 +409,7 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple);
int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
{
socket_info_t *s;
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
......@@ -445,7 +445,7 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
return pcmcia_get_next_tuple(handle, tuple);
}
static int follow_link(socket_info_t *s, tuple_t *tuple)
static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
{
u_char link[5];
u_int ofs;
......@@ -487,7 +487,7 @@ static int follow_link(socket_info_t *s, tuple_t *tuple)
int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
{
socket_info_t *s;
struct pcmcia_socket *s;
u_char link[2], tmp;
int ofs, i, attr;
......@@ -588,7 +588,7 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
{
socket_info_t *s;
struct pcmcia_socket *s;
u_int len;
if (CHECK_HANDLE(handle))
......
This diff is collapsed.
......@@ -21,13 +21,6 @@
#include <linux/config.h>
typedef struct erase_busy_t {
eraseq_entry_t *erase;
client_handle_t client;
struct timer_list timeout;
struct erase_busy_t *prev, *next;
} erase_busy_t;
#define ERASEQ_MAGIC 0xFA67
typedef struct eraseq_t {
u_short eraseq_magic;
......@@ -39,7 +32,7 @@ typedef struct eraseq_t {
#define CLIENT_MAGIC 0x51E6
typedef struct client_t {
u_short client_magic;
socket_t Socket;
struct pcmcia_socket *Socket;
u_char Function;
dev_info_t dev_info;
u_int Attributes;
......@@ -63,23 +56,6 @@ typedef struct client_t {
#define CLIENT_WIN_REQ(i) (0x20<<(i))
#define CLIENT_CARDBUS 0x8000
typedef struct io_window_t {
u_int Attributes;
ioaddr_t BasePort, NumPorts;
ioaddr_t InUse, Config;
} io_window_t;
#define WINDOW_MAGIC 0xB35C
typedef struct window_t {
u_short magic;
u_short index;
client_handle_t handle;
struct socket_info_t *sock;
u_long base;
u_long size;
pccard_mem_map ctl;
} window_t;
#define REGION_MAGIC 0xE3C9
typedef struct region_t {
u_short region_magic;
......@@ -108,12 +84,6 @@ typedef struct config_t {
} irq;
} config_t;
/* Maximum number of IO windows per socket */
#define MAX_IO_WIN 2
/* Maximum number of memory windows per socket */
#define MAX_WIN 4
struct cis_cache_entry {
struct list_head node;
unsigned int addr;
......@@ -122,48 +92,6 @@ struct cis_cache_entry {
unsigned char cache[0];
};
typedef struct socket_info_t {
spinlock_t lock;
struct pccard_operations * ss_entry;
u_int sock;
socket_state_t socket;
socket_cap_t cap;
u_int state;
u_short functions;
u_short lock_count;
client_handle_t clients;
u_int real_clients;
pccard_mem_map cis_mem;
u_char *cis_virt;
config_t *config;
#ifdef CONFIG_CARDBUS
struct resource * cb_cis_res;
u_char *cb_cis_virt;
#endif
struct {
u_int AssignedIRQ;
u_int Config;
} irq;
io_window_t io[MAX_IO_WIN];
window_t win[MAX_WIN];
region_t *c_region, *a_region;
erase_busy_t erase_busy;
struct list_head cis_cache;
u_int fake_cis_len;
char *fake_cis;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc;
#endif
struct semaphore skt_sem; /* protects socket h/w state */
struct task_struct *thread;
struct completion thread_done;
wait_queue_head_t thread_wait;
spinlock_t thread_lock; /* protects thread_events */
unsigned int thread_events;
} socket_info_t;
/* Flags in config state */
#define CONFIG_LOCKED 0x01
#define CONFIG_IRQ_REQ 0x02
......@@ -187,7 +115,7 @@ typedef struct socket_info_t {
#define CHECK_SOCKET(s) \
(((s) >= sockets) || (socket_table[s]->ss_entry == NULL))
#define SOCKET(h) (socket_table[(h)->Socket])
#define SOCKET(h) (h->Socket)
#define CONFIG(h) (&SOCKET(h)->config[(h)->Function])
#define CHECK_REGION(r) \
......@@ -200,19 +128,19 @@ typedef struct socket_info_t {
((h)->event_handler((e), (p), &(h)->event_callback_args))
/* In cardbus.c */
int cb_alloc(socket_info_t *s);
void cb_free(socket_info_t *s);
int read_cb_mem(socket_info_t *s, int space, u_int addr, u_int len, void *ptr);
int cb_alloc(struct pcmcia_socket *s);
void cb_free(struct pcmcia_socket *s);
int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr);
/* In cistpl.c */
int read_cis_mem(socket_info_t *s, int attr,
int read_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr);
void write_cis_mem(socket_info_t *s, int attr,
void write_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr);
void release_cis_mem(socket_info_t *s);
void destroy_cis_cache(socket_info_t *s);
int verify_cis_cache(socket_info_t *s);
void preload_cis_cache(socket_info_t *s);
void release_cis_mem(struct pcmcia_socket *s);
void destroy_cis_cache(struct pcmcia_socket *s);
int verify_cis_cache(struct pcmcia_socket *s);
void preload_cis_cache(struct pcmcia_socket *s);
int get_first_tuple(client_handle_t handle, tuple_t *tuple);
int get_next_tuple(client_handle_t handle, tuple_t *tuple);
int get_tuple_data(client_handle_t handle, tuple_t *tuple);
......@@ -236,11 +164,11 @@ int write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf);
int copy_memory(memory_handle_t handle, copy_op_t *req);
/* In rsrc_mgr */
void validate_mem(socket_info_t *s);
void validate_mem(struct pcmcia_socket *s);
int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
char *name, socket_info_t *s);
char *name, struct pcmcia_socket *s);
int find_mem_region(u_long *base, u_long num, u_long align,
int force_low, char *name, socket_info_t *s);
int force_low, char *name, struct pcmcia_socket *s);
int try_irq(u_int Attributes, int irq, int specific);
void undo_irq(u_int Attributes, int irq);
int adjust_resource_info(client_handle_t handle, adjust_t *adj);
......@@ -250,9 +178,8 @@ int proc_read_io(char *buf, char **start, off_t pos,
int proc_read_mem(char *buf, char **start, off_t pos,
int count, int *eof, void *data);
#define MAX_SOCK 8
extern socket_t sockets;
extern socket_info_t *socket_table[MAX_SOCK];
extern struct rw_semaphore pcmcia_socket_list_rwsem;
extern struct list_head pcmcia_socket_list;
#ifdef CONFIG_PROC_FS
extern struct proc_dir_entry *proc_pccard;
......
......@@ -107,8 +107,7 @@ struct pcmcia_bus_socket {
struct work_struct removal;
socket_bind_t *bind;
struct device *socket_dev;
struct list_head socket_list;
unsigned int socket_no; /* deprecated */
struct pcmcia_socket *parent;
};
#define SOCKET_PRESENT 0x01
......@@ -122,10 +121,6 @@ static dev_info_t dev_info = "Driver Services";
static int major_dev = -1;
/* list of all sockets registered with the pcmcia bus driver */
static DECLARE_RWSEM(bus_socket_list_rwsem);
static LIST_HEAD(bus_socket_list);
extern struct proc_dir_entry *proc_pccard;
/*====================================================================*/
......@@ -164,20 +159,6 @@ EXPORT_SYMBOL(pcmcia_register_driver);
*/
void pcmcia_unregister_driver(struct pcmcia_driver *driver)
{
socket_bind_t *b;
struct pcmcia_bus_socket *bus_sock;
if (driver->use_count > 0) {
/* Blank out any left-over device instances */
driver->attach = NULL; driver->detach = NULL;
down_read(&bus_socket_list_rwsem);
list_for_each_entry(bus_sock, &bus_socket_list, socket_list) {
for (b = bus_sock->bind; b; b = b->next)
if (b->driver == driver)
b->instance = NULL;
}
up_read(&bus_socket_list_rwsem);
}
driver_unregister(&driver->drv);
}
EXPORT_SYMBOL(pcmcia_unregister_driver);
......@@ -319,14 +300,14 @@ static int bind_mtd(struct pcmcia_bus_socket *bus_sock, mtd_info_t *mtd_info)
bind_req.dev_info = &mtd_info->dev_info;
bind_req.Attributes = mtd_info->Attributes;
bind_req.Socket = bus_sock->socket_no;
bind_req.Socket = bus_sock->parent;
bind_req.CardOffset = mtd_info->CardOffset;
ret = pcmcia_bind_mtd(&bind_req);
if (ret != CS_SUCCESS) {
cs_error(NULL, BindMTD, ret);
printk(KERN_NOTICE "ds: unable to bind MTD '%s' to socket %d"
" offset 0x%x\n",
(char *)bind_req.dev_info, bus_sock->socket_no, bind_req.CardOffset);
(char *)bind_req.dev_info, bus_sock->parent->sock, bind_req.CardOffset);
return -ENODEV;
}
return 0;
......@@ -351,7 +332,7 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
if (!s)
return -EINVAL;
DEBUG(2, "bind_request(%d, '%s')\n", s->socket_no,
DEBUG(2, "bind_request(%d, '%s')\n", s->parent->sock,
(char *)bind_info->dev_info);
driver = get_pcmcia_driver(&bind_info->dev_info);
if (!driver)
......@@ -366,14 +347,18 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
return -EBUSY;
}
bind_req.Socket = s->socket_no;
if (!try_module_get(driver->owner))
return -EINVAL;
bind_req.Socket = s->parent;
bind_req.Function = bind_info->function;
bind_req.dev_info = (dev_info_t *) driver->drv.name;
ret = pcmcia_bind_device(&bind_req);
if (ret != CS_SUCCESS) {
cs_error(NULL, BindDevice, ret);
printk(KERN_NOTICE "ds: unable to bind '%s' to socket %d\n",
(char *)dev_info, s->socket_no);
(char *)dev_info, s->parent->sock);
module_put(driver->owner);
return -ENODEV;
}
......@@ -383,6 +368,7 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
if (!b)
{
driver->use_count--;
module_put(driver->owner);
return -ENOMEM;
}
b->driver = driver;
......@@ -396,6 +382,7 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
if (b->instance == NULL) {
printk(KERN_NOTICE "ds: unable to create instance "
"of '%s'!\n", (char *)bind_info->dev_info);
module_put(driver->owner);
return -ENODEV;
}
}
......@@ -476,7 +463,7 @@ static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
{
socket_bind_t **b, *c;
DEBUG(2, "unbind_request(%d, '%s')\n", s->socket_no,
DEBUG(2, "unbind_request(%d, '%s')\n", s->parent->sock,
(char *)bind_info->dev_info);
for (b = &s->bind; *b; b = &(*b)->next)
if ((strcmp((char *)(*b)->driver->drv.name,
......@@ -492,9 +479,9 @@ static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
if (c->instance)
c->driver->detach(c->instance);
}
module_put(c->driver->owner);
*b = c->next;
kfree(c);
return 0;
} /* unbind_request */
......@@ -832,13 +819,13 @@ static struct file_operations ds_fops = {
.poll = ds_poll,
};
static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int socket_nr)
static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
{
struct pcmcia_socket *socket = class_dev->class_data;
client_reg_t client_reg;
bind_req_t bind;
struct pcmcia_bus_socket *s, *tmp_s;
struct pcmcia_bus_socket *s;
int ret;
int i;
s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL);
if(!s)
......@@ -855,28 +842,15 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock
init_waitqueue_head(&s->queue);
init_waitqueue_head(&s->request);
/* find the lowest, unused socket no. Please note that this is a
* temporary workaround until "struct pcmcia_socket" is introduced
* into cs.c which will include this number, and which will be
* accessible to ds.c directly */
i = 0;
next_try:
list_for_each_entry(tmp_s, &bus_socket_list, socket_list) {
if (tmp_s->socket_no == i) {
i++;
goto next_try;
}
}
s->socket_no = i;
/* initialize data */
s->socket_dev = dev;
s->socket_dev = socket->dev.dev;
INIT_WORK(&s->removal, handle_removal, s);
s->parent = socket;
/* Set up hotline to Card Services */
client_reg.dev_info = bind.dev_info = &dev_info;
bind.Socket = s->socket_no;
bind.Socket = socket;
bind.Function = BIND_FN_ALL;
ret = pcmcia_bind_device(&bind);
if (ret != CS_SUCCESS) {
......@@ -901,50 +875,26 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock
return -EINVAL;
}
list_add(&s->socket_list, &bus_socket_list);
socket->pcmcia = s;
return 0;
}
static int pcmcia_bus_add_socket_dev(struct class_device *class_dev)
{
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
unsigned int i;
unsigned int ret = 0;
if (!cls_d)
return -ENODEV;
down_write(&bus_socket_list_rwsem);
for (i = 0; i < cls_d->nsock; i++)
ret += pcmcia_bus_add_socket(class_dev->dev, i);
up_write(&bus_socket_list_rwsem);
return ret;
}
static void pcmcia_bus_remove_socket_dev(struct class_device *class_dev)
static void pcmcia_bus_remove_socket(struct class_device *class_dev)
{
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
struct list_head *list_loop;
struct list_head *tmp_storage;
struct pcmcia_socket *socket = class_dev->class_data;
if (!cls_d)
if (!socket || !socket->pcmcia)
return;
flush_scheduled_work();
down_write(&bus_socket_list_rwsem);
list_for_each_safe(list_loop, tmp_storage, &bus_socket_list) {
struct pcmcia_bus_socket *bus_sock = container_of(list_loop, struct pcmcia_bus_socket, socket_list);
if (bus_sock->socket_dev == class_dev->dev) {
pcmcia_deregister_client(bus_sock->handle);
list_del(&bus_sock->socket_list);
kfree(bus_sock);
}
}
up_write(&bus_socket_list_rwsem);
pcmcia_deregister_client(socket->pcmcia->handle);
kfree(socket->pcmcia);
socket->pcmcia = NULL;
return;
}
......@@ -952,8 +902,8 @@ static void pcmcia_bus_remove_socket_dev(struct class_device *class_dev)
/* the pcmcia_bus_interface is used to handle pcmcia socket devices */
static struct class_interface pcmcia_bus_interface = {
.class = &pcmcia_socket_class,
.add = &pcmcia_bus_add_socket_dev,
.remove = &pcmcia_bus_remove_socket_dev,
.add = &pcmcia_bus_add_socket,
.remove = &pcmcia_bus_remove_socket,
};
......@@ -1008,18 +958,13 @@ module_exit(exit_pcmcia_bus);
/* helpers for backwards-compatible functions */
static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr)
{
struct pcmcia_bus_socket * s;
down_read(&bus_socket_list_rwsem);
list_for_each_entry(s, &bus_socket_list, socket_list)
if (s->socket_no == nr) {
up_read(&bus_socket_list_rwsem);
return s;
}
up_read(&bus_socket_list_rwsem);
return NULL;
struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr);
if (s && s->pcmcia)
return s->pcmcia;
else
return NULL;
}
/* backwards-compatible accessing of driver --- by name! */
......
......@@ -44,14 +44,12 @@ MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
static int i82092aa_socket_suspend (struct pci_dev *dev, u32 state)
{
struct pcmcia_socket_class_data *cls_d = pci_get_drvdata(dev);
return pcmcia_socket_dev_suspend(cls_d, state, 0);
return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
}
static int i82092aa_socket_resume (struct pci_dev *dev)
{
struct pcmcia_socket_class_data *cls_d = pci_get_drvdata(dev);
return pcmcia_socket_dev_resume(cls_d, RESUME_RESTORE_STATE);
return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
}
static struct pci_driver i82092aa_pci_drv = {
......@@ -82,6 +80,7 @@ static struct pccard_operations i82092aa_operations = {
/* The card can do upto 4 sockets, allocate a structure for each of them */
struct socket_info {
int number;
int card_state; /* 0 = no socket,
1 = empty socket,
2 = card but not initialized,
......@@ -95,6 +94,7 @@ struct socket_info {
/* callback to the driver of the card */
void *info; /* to be passed to the handler */
struct pcmcia_socket socket;
struct pci_dev *dev; /* The PCI device for the socket */
};
......@@ -107,7 +107,6 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
{
unsigned char configbyte;
int i, ret;
struct pcmcia_socket_class_data *cls_d;
enter("i82092aa_pci_probe");
......@@ -146,6 +145,8 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
sockets[i].cap.map_size = 0x1000;
sockets[i].cap.irq_mask = 0;
sockets[i].cap.pci_irq = dev->irq;
sockets[i].number = i;
if (card_present(i)) {
sockets[i].card_state = 3;
......@@ -166,26 +167,26 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
goto err_out_free_res;
}
cls_d = kmalloc(sizeof(*cls_d), GFP_KERNEL);
if (!cls_d) {
printk(KERN_ERR "i82092aa: kmalloc failed\n");
goto err_out_free_irq;
pci_set_drvdata(dev, &sockets[i].socket);
for (i = 0; i<socket_count; i++) {
sockets[i].socket.dev.dev = &dev->dev;
sockets[i].socket.ss_entry = &i82092aa_operations;
ret = pcmcia_register_socket(&sockets[i].socket);
if (ret) {
goto err_out_free_sockets;
}
}
memset(cls_d, 0, sizeof(*cls_d));
cls_d->nsock = socket_count;
cls_d->ops = &i82092aa_operations;
pci_set_drvdata(dev, &cls_d);
cls_d->class_dev.class = &pcmcia_socket_class;
cls_d->class_dev.dev = &dev->dev;
strlcpy(cls_d->class_dev.class_id, dev->dev.name, BUS_ID_SIZE);
class_set_devdata(&cls_d->class_dev, cls_d);
class_device_register(&cls_d->class_dev);
leave("i82092aa_pci_probe");
return 0;
err_out_free_irq:
err_out_free_sockets:
if (i) {
for (i--;i>=0;i--) {
pcmcia_unregister_socket(&sockets[i].socket);
}
}
free_irq(dev->irq, i82092aa_interrupt);
err_out_free_res:
release_region(pci_resource_start(dev, 0), 2);
......@@ -196,16 +197,14 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
static void __devexit i82092aa_pci_remove(struct pci_dev *dev)
{
struct pcmcia_socket_class_data *cls_d = pci_get_drvdata(dev);
struct pcmcia_socket *socket = pci_get_drvdata(dev);
enter("i82092aa_pci_remove");
free_irq(dev->irq, i82092aa_interrupt);
if (cls_d) {
class_device_unregister(&cls_d->class_dev);
kfree(cls_d);
}
if (socket)
pcmcia_unregister_socket(socket);
leave("i82092aa_pci_remove");
}
......@@ -447,7 +446,7 @@ static void set_bridge_state(int sock)
static int i82092aa_init(unsigned int s)
static int i82092aa_init(struct pcmcia_socket *sock)
{
int i;
pccard_io_map io = { 0, 0, 0, 0, 1 };
......@@ -456,21 +455,21 @@ static int i82092aa_init(unsigned int s)
enter("i82092aa_init");
mem.sys_stop = 0x0fff;
i82092aa_set_socket(s, &dead_socket);
i82092aa_set_socket(sock, &dead_socket);
for (i = 0; i < 2; i++) {
io.map = i;
i82092aa_set_io_map(s, &io);
i82092aa_set_io_map(sock, &io);
}
for (i = 0; i < 5; i++) {
mem.map = i;
i82092aa_set_mem_map(s, &mem);
i82092aa_set_mem_map(sock, &mem);
}
leave("i82092aa_init");
return 0;
}
static int i82092aa_suspend(unsigned int sock)
static int i82092aa_suspend(struct pcmcia_socket *sock)
{
int retval;
enter("i82092aa_suspend");
......@@ -479,8 +478,9 @@ static int i82092aa_suspend(unsigned int sock)
return retval;
}
static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
static int i82092aa_register_callback(struct pcmcia_socket *socket, void (*handler)(void *, unsigned int), void * info)
{
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
enter("i82092aa_register_callback");
sockets[sock].handler = handler;
sockets[sock].info = info;
......@@ -488,8 +488,9 @@ static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *,
return 0;
} /* i82092aa_register_callback */
static int i82092aa_inquire_socket(unsigned int sock, socket_cap_t *cap)
static int i82092aa_inquire_socket(struct pcmcia_socket *socket, socket_cap_t *cap)
{
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
enter("i82092aa_inquire_socket");
*cap = sockets[sock].cap;
leave("i82092aa_inquire_socket");
......@@ -497,8 +498,9 @@ static int i82092aa_inquire_socket(unsigned int sock, socket_cap_t *cap)
} /* i82092aa_inquire_socket */
static int i82092aa_get_status(unsigned int sock, u_int *value)
static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)
{
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned int status;
enter("i82092aa_get_status");
......@@ -539,8 +541,9 @@ static int i82092aa_get_status(unsigned int sock, u_int *value)
}
static int i82092aa_get_socket(unsigned int sock, socket_state_t *state)
static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state)
{
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned char reg,vcc,vpp;
enter("i82092aa_get_socket");
......@@ -610,8 +613,9 @@ static int i82092aa_get_socket(unsigned int sock, socket_state_t *state)
return 0;
}
static int i82092aa_set_socket(unsigned int sock, socket_state_t *state)
static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state)
{
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned char reg;
enter("i82092aa_set_socket");
......@@ -706,8 +710,9 @@ static int i82092aa_set_socket(unsigned int sock, socket_state_t *state)
return 0;
}
static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io)
static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io)
{
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned char map, ioctl;
enter("i82092aa_set_io_map");
......@@ -749,8 +754,9 @@ static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io)
return 0;
}
static int i82092aa_set_mem_map(unsigned sock, struct pccard_mem_map *mem)
static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem)
{
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned short base, i;
unsigned char map;
......@@ -826,7 +832,7 @@ static int i82092aa_set_mem_map(unsigned sock, struct pccard_mem_map *mem)
return 0;
}
static void i82092aa_proc_setup(unsigned int sock, struct proc_dir_entry *base)
static void i82092aa_proc_setup(struct pcmcia_socket *socket, struct proc_dir_entry *base)
{
}
......
......@@ -28,16 +28,16 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs);
static int i82092aa_get_status(unsigned int sock, u_int *value);
static int i82092aa_get_socket(unsigned int sock, socket_state_t *state);
static int i82092aa_set_socket(unsigned int sock, socket_state_t *state);
static int i82092aa_set_io_map(unsigned int sock, struct pccard_io_map *io);
static int i82092aa_set_mem_map(unsigned int sock, struct pccard_mem_map *mem);
static int i82092aa_init(unsigned int s);
static int i82092aa_suspend(unsigned int sock);
static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info);
static int i82092aa_inquire_socket(unsigned int sock, socket_cap_t *cap);
static void i82092aa_proc_setup(unsigned int sock, struct proc_dir_entry *base);
static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value);
static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state);
static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state);
static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io);
static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem);
static int i82092aa_init(struct pcmcia_socket *socket);
static int i82092aa_suspend(struct pcmcia_socket *socket);
static int i82092aa_register_callback(struct pcmcia_socket *socket, void (*handler)(void *, unsigned int), void * info);
static int i82092aa_inquire_socket(struct pcmcia_socket *socket, socket_cap_t *cap);
static void i82092aa_proc_setup(struct pcmcia_socket *socket, struct proc_dir_entry *base);
#endif
This diff is collapsed.
/*
* Generic PCI pccard driver interface.
*
* (C) Copyright 1999 Linus Torvalds
*
* This implements the common parts of PCI pccard drivers,
* notably detection and infrastructure conversion (ie change
* from socket index to "struct pci_dev" etc)
*
* This does NOT implement the actual low-level driver details,
* and this has on purpose been left generic enough that it can
* be used to set up a PCI PCMCIA controller (ie non-cardbus),
* or to set up a controller.
*
* See for example the "yenta" driver for PCI cardbus controllers
* conforming to the yenta cardbus specifications.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <pcmcia/ss.h>
#include <asm/io.h>
#include "pci_socket.h"
/*
* Arbitrary define. This is the array of active cardbus
* entries.
*/
#define MAX_SOCKETS (8)
static pci_socket_t pci_socket_array[MAX_SOCKETS];
static int pci_init_socket(unsigned int sock)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->init)
return socket->op->init(socket);
return -EINVAL;
}
static int pci_suspend_socket(unsigned int sock)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->suspend)
return socket->op->suspend(socket);
return -EINVAL;
}
static int pci_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
{
pci_socket_t *socket = pci_socket_array + sock;
socket->handler = handler;
socket->info = info;
return 0;
}
static int pci_inquire_socket(unsigned int sock, socket_cap_t *cap)
{
pci_socket_t *socket = pci_socket_array + sock;
*cap = socket->cap;
return 0;
}
static int pci_get_status(unsigned int sock, unsigned int *value)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->get_status)
return socket->op->get_status(socket, value);
*value = 0;
return -EINVAL;
}
static int pci_get_socket(unsigned int sock, socket_state_t *state)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->get_socket)
return socket->op->get_socket(socket, state);
return -EINVAL;
}
static int pci_set_socket(unsigned int sock, socket_state_t *state)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->set_socket)
return socket->op->set_socket(socket, state);
return -EINVAL;
}
static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->set_io_map)
return socket->op->set_io_map(socket, io);
return -EINVAL;
}
static int pci_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->set_mem_map)
return socket->op->set_mem_map(socket, mem);
return -EINVAL;
}
static void pci_proc_setup(unsigned int sock, struct proc_dir_entry *base)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->proc_setup)
socket->op->proc_setup(socket, base);
}
static struct pccard_operations pci_socket_operations = {
.owner = THIS_MODULE,
.init = pci_init_socket,
.suspend = pci_suspend_socket,
.register_callback = pci_register_callback,
.inquire_socket = pci_inquire_socket,
.get_status = pci_get_status,
.get_socket = pci_get_socket,
.set_socket = pci_set_socket,
.set_io_map = pci_set_io_map,
.set_mem_map = pci_set_mem_map,
.proc_setup = pci_proc_setup,
};
static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_socket_ops *ops)
{
pci_socket_t *socket = nr + pci_socket_array;
int err;
memset(socket, 0, sizeof(*socket));
/* prepare class_data */
socket->cls_d.sock_offset = nr;
socket->cls_d.nsock = 1; /* yenta is 1, no other low-level driver uses
this yet */
socket->cls_d.ops = &pci_socket_operations;
socket->cls_d.class_dev.class = &pcmcia_socket_class;
socket->cls_d.class_dev.dev = &dev->dev;
strlcpy(socket->cls_d.class_dev.class_id, dev->dev.bus_id, BUS_ID_SIZE);
class_set_devdata(&socket->cls_d.class_dev, &socket->cls_d);
/* prepare pci_socket_t */
socket->dev = dev;
socket->op = ops;
pci_set_drvdata(dev, socket);
spin_lock_init(&socket->event_lock);
err = socket->op->open(socket);
if (err) {
socket->dev = NULL;
pci_set_drvdata(dev, NULL);
} else {
class_device_register(&socket->cls_d.class_dev);
}
return err;
}
int cardbus_register(struct pci_dev *p_dev)
{
return 0;
}
static int __devinit
cardbus_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
int s;
for (s = 0; s < MAX_SOCKETS; s++) {
if (pci_socket_array [s].dev == 0) {
return add_pci_socket (s, dev, &yenta_operations);
}
}
return -ENODEV;
}
static void __devexit cardbus_remove (struct pci_dev *dev)
{
pci_socket_t *socket = pci_get_drvdata(dev);
/* note: we are already unregistered from the cs core */
class_device_unregister(&socket->cls_d.class_dev);
if (socket->op && socket->op->close)
socket->op->close(socket);
pci_set_drvdata(dev, NULL);
}
static int cardbus_suspend (struct pci_dev *dev, u32 state)
{
pci_socket_t *socket = pci_get_drvdata(dev);
return pcmcia_socket_dev_suspend(&socket->cls_d, state, 0);
}
static int cardbus_resume (struct pci_dev *dev)
{
pci_socket_t *socket = pci_get_drvdata(dev);
return pcmcia_socket_dev_resume(&socket->cls_d, RESUME_RESTORE_STATE);
}
static struct pci_device_id cardbus_table [] __devinitdata = { {
.class = PCI_CLASS_BRIDGE_CARDBUS << 8,
.class_mask = ~0,
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
}, { /* all zeroes */ }
};
MODULE_DEVICE_TABLE(pci, cardbus_table);
static struct pci_driver pci_cardbus_driver = {
.name = "cardbus",
.id_table = cardbus_table,
.probe = cardbus_probe,
.remove = __devexit_p(cardbus_remove),
.suspend = cardbus_suspend,
.resume = cardbus_resume,
};
static int __init pci_socket_init(void)
{
return pci_register_driver (&pci_cardbus_driver);
}
static void __exit pci_socket_exit (void)
{
pci_unregister_driver (&pci_cardbus_driver);
}
module_init(pci_socket_init);
module_exit(pci_socket_exit);
/*
* drivers/pcmcia/pci_socket.h
*
* (C) Copyright 1999 Linus Torvalds
*/
#ifndef __PCI_SOCKET_H
#define __PCI_SOCKET_H
struct pci_socket_ops;
struct socket_info_t;
typedef struct pci_socket {
struct pci_dev *dev;
int cb_irq, io_irq;
void *base;
void (*handler)(void *, unsigned int);
void *info;
struct pci_socket_ops *op;
socket_cap_t cap;
spinlock_t event_lock;
unsigned int events;
struct work_struct tq_task;
struct timer_list poll_timer;
struct pcmcia_socket_class_data cls_d;
/* A few words of private data for the low-level driver.. */
unsigned int private[8];
} pci_socket_t;
struct pci_socket_ops {
int (*open)(struct pci_socket *);
void (*close)(struct pci_socket *);
int (*init)(struct pci_socket *);
int (*suspend)(struct pci_socket *);
int (*get_status)(struct pci_socket *, unsigned int *);
int (*get_socket)(struct pci_socket *, socket_state_t *);
int (*set_socket)(struct pci_socket *, socket_state_t *);
int (*set_io_map)(struct pci_socket *, struct pccard_io_map *);
int (*set_mem_map)(struct pci_socket *, struct pccard_mem_map *);
void (*proc_setup)(struct pci_socket *, struct proc_dir_entry *base);
};
extern struct pci_socket_ops yenta_operations;
extern struct pci_socket_ops ricoh_operations;
#endif
......@@ -125,11 +125,26 @@
#define rl_mem(socket) ((socket)->private[3])
#define rl_config(socket) ((socket)->private[4])
static int ricoh_init(struct pcmcia_socket *sock)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
config_writew(socket, RL5C4XX_MISC, rl_misc(socket));
config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(socket));
config_writew(socket, RL5C4XX_16BIT_IO_0, rl_io(socket));
config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket));
config_writew(socket, RL5C4XX_CONFIG, rl_config(socket));
return 0;
}
/*
* Magic Ricoh initialization code.. Save state at
* beginning, re-initialize it after suspend.
*/
static int ricoh_open(pci_socket_t *socket)
static int ricoh_override(struct yenta_socket *socket)
{
rl_misc(socket) = config_readw(socket, RL5C4XX_MISC);
rl_ctl(socket) = config_readw(socket, RL5C4XX_16BIT_CTL);
......@@ -146,35 +161,11 @@ static int ricoh_open(pci_socket_t *socket)
rl_config(socket) |= RL5C4XX_CONFIG_PREFETCH;
}
return 0;
}
static int ricoh_init(pci_socket_t *socket)
{
yenta_init(socket);
socket->socket.ss_entry->init = ricoh_init;
config_writew(socket, RL5C4XX_MISC, rl_misc(socket));
config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(socket));
config_writew(socket, RL5C4XX_16BIT_IO_0, rl_io(socket));
config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket));
config_writew(socket, RL5C4XX_CONFIG, rl_config(socket));
return 0;
}
static struct pci_socket_ops ricoh_ops = {
ricoh_open,
yenta_close,
ricoh_init,
yenta_suspend,
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
yenta_set_io_map,
yenta_set_mem_map,
yenta_proc_setup
};
#endif /* CONFIG_CARDBUS */
#endif /* _LINUX_RICOH_H */
......@@ -90,7 +90,7 @@ static DECLARE_MUTEX(rsrc_sem);
typedef struct irq_info_t {
u_int Attributes;
int time_share, dyn_share;
struct socket_info_t *Socket;
struct pcmcia_socket *Socket;
} irq_info_t;
/* Table of IRQ assignments */
......@@ -341,7 +341,7 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num)
======================================================================*/
/* Validation function for cards with a valid CIS */
static int cis_readable(socket_info_t *s, u_long base)
static int cis_readable(struct pcmcia_socket *s, u_long base)
{
cisinfo_t info1, info2;
int ret;
......@@ -364,7 +364,7 @@ static int cis_readable(socket_info_t *s, u_long base)
}
/* Validation function for simple memory cards */
static int checksum(socket_info_t *s, u_long base)
static int checksum(struct pcmcia_socket *s, u_long base)
{
int i, a, b, d;
s->cis_mem.sys_start = base;
......@@ -372,7 +372,7 @@ static int checksum(socket_info_t *s, u_long base)
s->cis_virt = ioremap(base, s->cap.map_size);
s->cis_mem.card_start = 0;
s->cis_mem.flags = MAP_ACTIVE;
s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
s->ss_entry->set_mem_map(s, &s->cis_mem);
/* Don't bother checking every word... */
a = 0; b = -1;
for (i = 0; i < s->cap.map_size; i += 44) {
......@@ -383,7 +383,7 @@ static int checksum(socket_info_t *s, u_long base)
return (b == -1) ? -1 : (a>>1);
}
static int checksum_match(socket_info_t *s, u_long base)
static int checksum_match(struct pcmcia_socket *s, u_long base)
{
int a = checksum(s, base), b = checksum(s, base+s->cap.map_size);
return ((a == b) && (a >= 0));
......@@ -397,7 +397,7 @@ static int checksum_match(socket_info_t *s, u_long base)
======================================================================*/
static int do_mem_probe(u_long base, u_long num, socket_info_t *s)
static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
{
u_long i, j, bad, fail, step;
......@@ -435,7 +435,7 @@ static int do_mem_probe(u_long base, u_long num, socket_info_t *s)
#ifdef CONFIG_PCMCIA_PROBE
static u_long inv_probe(resource_map_t *m, socket_info_t *s)
static u_long inv_probe(resource_map_t *m, struct pcmcia_socket *s)
{
u_long ok;
if (m == &mem_db)
......@@ -451,7 +451,7 @@ static u_long inv_probe(resource_map_t *m, socket_info_t *s)
return do_mem_probe(m->base, m->num, s);
}
void validate_mem(socket_info_t *s)
void validate_mem(struct pcmcia_socket *s)
{
resource_map_t *m, *n;
static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
......@@ -497,7 +497,7 @@ void validate_mem(socket_info_t *s)
#else /* CONFIG_PCMCIA_PROBE */
void validate_mem(socket_info_t *s)
void validate_mem(struct pcmcia_socket *s)
{
resource_map_t *m, *n;
static int done = 0;
......@@ -529,7 +529,7 @@ void validate_mem(socket_info_t *s)
======================================================================*/
int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
char *name, socket_info_t *s)
char *name, struct pcmcia_socket *s)
{
ioaddr_t try;
resource_map_t *m;
......@@ -556,7 +556,7 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
}
int find_mem_region(u_long *base, u_long num, u_long align,
int force_low, char *name, socket_info_t *s)
int force_low, char *name, struct pcmcia_socket *s)
{
u_long try;
resource_map_t *m;
......@@ -726,7 +726,7 @@ void undo_irq(u_int Attributes, int irq)
static int adjust_memory(adjust_t *adj)
{
u_long base, num;
int i, ret;
int ret;
base = adj->resource.memory.Base;
num = adj->resource.memory.Size;
......@@ -743,9 +743,11 @@ static int adjust_memory(adjust_t *adj)
case REMOVE_MANAGED_RESOURCE:
ret = sub_interval(&mem_db, base, num);
if (ret == CS_SUCCESS) {
for (i = 0; i < sockets; i++) {
release_cis_mem(socket_table[i]);
}
struct pcmcia_socket *socket;
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
release_cis_mem(socket);
up_read(&pcmcia_socket_list_rwsem);
}
break;
default:
......
......@@ -106,19 +106,10 @@ static struct device_driver sa11x0_pcmcia_driver = {
.remove = sa11xx_drv_pcmcia_remove,
.name = "sa11x0-pcmcia",
.bus = &platform_bus_type,
.devclass = &pcmcia_socket_class,
.suspend = pcmcia_socket_dev_suspend,
.resume = pcmcia_socket_dev_resume,
};
static struct platform_device sa11x0_pcmcia_device = {
.name = "sa11x0-pcmcia",
.id = 0,
.dev = {
.name = "Intel Corporation SA11x0 [PCMCIA]",
},
};
/* sa11x0_pcmcia_init()
* ^^^^^^^^^^^^^^^^^^^^
*
......@@ -129,16 +120,7 @@ static struct platform_device sa11x0_pcmcia_device = {
*/
static int __init sa11x0_pcmcia_init(void)
{
int ret;
ret = driver_register(&sa11x0_pcmcia_driver);
if (ret == 0) {
ret = platform_device_register(&sa11x0_pcmcia_device);
if (ret)
driver_unregister(&sa11x0_pcmcia_driver);
}
return ret;
return driver_register(&sa11x0_pcmcia_driver);
}
/* sa11x0_pcmcia_exit()
......@@ -148,7 +130,6 @@ static int __init sa11x0_pcmcia_init(void)
*/
static void __exit sa11x0_pcmcia_exit(void)
{
platform_device_unregister(&sa11x0_pcmcia_device);
driver_unregister(&sa11x0_pcmcia_driver);
}
......
......@@ -69,6 +69,8 @@ static struct sa1100_pcmcia_socket sa1100_pcmcia_socket[SA1100_PCMCIA_MAX_SOCK];
#define PCMCIA_SOCKET(x) (sa1100_pcmcia_socket + (x))
#define to_sa1100_socket(x) container_of(x, struct sa1100_pcmcia_socket, socket)
/*
* sa1100_pcmcia_default_mecr_timing
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -226,9 +228,9 @@ sa1100_pcmcia_config_skt(struct sa1100_pcmcia_socket *skt, socket_state_t *state
*
* Returns: 0
*/
static int sa1100_pcmcia_sock_init(unsigned int sock)
static int sa1100_pcmcia_sock_init(struct pcmcia_socket *sock)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, skt->nr);
......@@ -248,9 +250,9 @@ static int sa1100_pcmcia_sock_init(unsigned int sock)
*
* Returns: 0
*/
static int sa1100_pcmcia_suspend(unsigned int sock)
static int sa1100_pcmcia_suspend(struct pcmcia_socket *sock)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
int ret;
DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, skt->nr);
......@@ -348,11 +350,11 @@ static irqreturn_t sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *r
* Returns: 0
*/
static int
sa1100_pcmcia_register_callback(unsigned int sock,
sa1100_pcmcia_register_callback(struct pcmcia_socket *sock,
void (*handler)(void *, unsigned int),
void *info)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
if (handler) {
if (!try_module_get(skt->ops->owner))
......@@ -392,9 +394,9 @@ sa1100_pcmcia_register_callback(unsigned int sock,
* Return value is irrelevant; the pcmcia subsystem ignores it.
*/
static int
sa1100_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
sa1100_pcmcia_inquire_socket(struct pcmcia_socket *sock, socket_cap_t *cap)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
int ret = -1;
if (skt) {
......@@ -430,9 +432,9 @@ sa1100_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
* Returns: 0
*/
static int
sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status)
sa1100_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
skt->status = sa1100_pcmcia_skt_state(skt);
*status = skt->status;
......@@ -450,9 +452,9 @@ sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status)
* Returns: 0
*/
static int
sa1100_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
sa1100_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
......@@ -472,9 +474,9 @@ sa1100_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
* Returns: 0
*/
static int
sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
sa1100_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
......@@ -508,9 +510,9 @@ sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
* Returns: 0 on success, -1 on error
*/
static int
sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
sa1100_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
unsigned short speed = map->speed;
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
......@@ -564,9 +566,9 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
* Returns: 0 on success, -1 on error
*/
static int
sa1100_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
sa1100_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
struct resource *res;
unsigned short speed = map->speed;
......@@ -708,7 +710,7 @@ sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
* Returns: 0 on success, -1 on error
*/
static void
sa1100_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
sa1100_pcmcia_proc_setup(struct pcmcia_socket *sock, struct proc_dir_entry *base)
{
struct proc_dir_entry *entry;
......@@ -717,7 +719,7 @@ sa1100_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
return;
}
entry->read_proc = sa1100_pcmcia_proc_status;
entry->data = PCMCIA_SOCKET(sock);
entry->data = to_sa1100_socket(sock);
}
#else
#define sa1100_pcmcia_proc_setup NULL
......@@ -800,22 +802,16 @@ static const char *skt_names[] = {
"PCMCIA socket 1",
};
struct skt_dev_info {
int nskt;
};
int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
{
struct pcmcia_socket_class_data *cls;
struct skt_dev_info *sinfo;
unsigned int cpu_clock;
int ret, i;
cls = kmalloc(sizeof(struct pcmcia_socket_class_data), GFP_KERNEL);
if (!cls) {
ret = -ENOMEM;
goto out;
}
memset(cls, 0, sizeof(struct pcmcia_socket_class_data));
cls->ops = &sa11xx_pcmcia_operations;
cls->nsock = nr;
/*
* set default MECR calculation if the board specific
* code did not specify one...
......@@ -823,6 +819,15 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
if (!ops->socket_get_timing)
ops->socket_get_timing = sa1100_pcmcia_default_mecr_timing;
sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
if (!sinfo) {
ret = -ENOMEM;
goto out;
}
memset(sinfo, 0, sizeof(struct skt_dev_info));
sinfo->nskt = nr;
cpu_clock = cpufreq_get(0);
/*
......@@ -832,6 +837,9 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
memset(skt, 0, sizeof(*skt));
skt->socket.ss_entry = &sa11xx_pcmcia_operations;
skt->socket.dev.dev = dev;
INIT_WORK(&skt->work, sa1100_pcmcia_task_handler, skt);
init_timer(&skt->poll_timer);
......@@ -898,16 +906,26 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
goto out_err_6;
skt->status = sa1100_pcmcia_skt_state(skt);
ret = pcmcia_register_socket(&skt->socket);
if (ret)
goto out_err_7;
WARN_ON(skt->socket.sock != i);
add_timer(&skt->poll_timer);
}
dev->class_data = cls;
dev_set_drvdata(dev, sinfo);
return 0;
do {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
out_err_7:
flush_scheduled_work();
ops->hw_shutdown(skt);
......@@ -925,7 +943,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
i--;
} while (i > 0);
kfree(cls);
kfree(sinfo);
out:
return ret;
......@@ -934,19 +952,22 @@ EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
int sa11xx_drv_pcmcia_remove(struct device *dev)
{
struct pcmcia_socket_class_data *cls = dev->class_data;
struct skt_dev_info *sinfo = dev_get_drvdata(dev);
int i;
dev->class_data = NULL;
for (i = 0; i < cls->nsock; i++) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(cls->sock_offset + i);
dev_set_drvdata(dev, NULL);
skt->ops->hw_shutdown(skt);
for (i = 0; i < sinfo->nskt; i++) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
flush_scheduled_work();
skt->ops->hw_shutdown(skt);
sa1100_pcmcia_config_skt(skt, &dead_socket);
iounmap(skt->virt_io);
......@@ -957,7 +978,7 @@ int sa11xx_drv_pcmcia_remove(struct device *dev)
release_resource(&skt->res_skt);
}
kfree(cls);
kfree(sinfo);
return 0;
}
......@@ -977,7 +998,8 @@ static void sa1100_pcmcia_update_mecr(unsigned int clock)
for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
sa1100_pcmcia_set_mecr(skt, clock);
if (skt->ops)
sa1100_pcmcia_set_mecr(skt, clock);
}
}
......
......@@ -44,6 +44,8 @@ struct pcmcia_state {
* use when responding to a Card Services query of some kind.
*/
struct sa1100_pcmcia_socket {
struct pcmcia_socket socket;
/*
* Info from low level handler
*/
......
......@@ -115,19 +115,20 @@ static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs);
static void tcic_timer(u_long data);
static struct pccard_operations tcic_operations;
typedef struct socket_info_t {
struct tcic_socket {
u_short psock;
void (*handler)(void *info, u_int events);
void *info;
u_char last_sstat;
u_char id;
} socket_info_t;
struct pcmcia_socket socket;
};
static struct timer_list poll_timer;
static int tcic_timer_pending;
static int sockets;
static socket_info_t socket_table[2];
static struct tcic_socket socket_table[2];
static socket_cap_t tcic_cap = {
/* only 16-bit cards, memory windows must be size-aligned */
......@@ -372,15 +373,11 @@ static int __init get_tcic_id(void)
/*====================================================================*/
static struct pcmcia_socket_class_data tcic_data = {
.ops = &tcic_operations,
};
static struct device_driver tcic_driver = {
.name = "tcic-pcmcia",
.bus = &platform_bus_type,
/* .suspend = pcmcia_socket_dev_suspend, FIXME? */
/* .resume = pcmcia_socket_dev_resume, FIXME? */
.suspend = pcmcia_socket_dev_suspend,
.resume = pcmcia_socket_dev_resume,
};
static struct platform_device tcic_device = {
......@@ -391,13 +388,10 @@ static struct platform_device tcic_device = {
},
};
static struct class_device tcic_class_data = {
.class = &pcmcia_socket_class,
};
static int __init init_tcic(void)
{
int i, sock;
int i, sock, ret = 0;
u_int mask, scan;
servinfo_t serv;
......@@ -524,13 +518,17 @@ static int __init init_tcic(void)
/* jump start interrupt handler, if needed */
tcic_interrupt(0, NULL, NULL);
tcic_data.nsock = sockets;
tcic_class_data.dev = &tcic_device.dev;
tcic_class_data.class_data = &tcic_data;
strlcpy(tcic_class_data.class_id, "tcic-pcmcia", BUS_ID_SIZE);
platform_device_register(&tcic_device);
class_device_register(&tcic_class_data);
for (i = 0; i < sockets; i++) {
socket_table[i].socket.ss_entry = &tcic_operations;
socket_table[i].socket.dev.dev = &tcic_device.dev;
ret = pcmcia_register_socket(&socket_table[i].socket);
if (ret && i)
pcmcia_unregister_socket(&socket_table[0].socket);
}
return ret;
return 0;
......@@ -540,13 +538,19 @@ static int __init init_tcic(void)
static void __exit exit_tcic(void)
{
int i;
del_timer_sync(&poll_timer);
if (cs_irq != 0) {
tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
free_irq(cs_irq, tcic_interrupt);
}
release_region(tcic_base, 16);
class_device_unregister(&tcic_class_data);
for (i = 0; i < sockets; i++) {
pcmcia_unregister_socket(&socket_table[i].socket);
}
platform_device_unregister(&tcic_device);
driver_unregister(&tcic_driver);
} /* exit_tcic */
......@@ -640,18 +644,19 @@ static void tcic_timer(u_long data)
/*====================================================================*/
static int tcic_register_callback(unsigned int lsock, void (*handler)(void *, unsigned int), void * info)
static int tcic_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
{
socket_table[lsock].handler = handler;
socket_table[lsock].info = info;
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
socket_table[psock].handler = handler;
socket_table[psock].info = info;
return 0;
} /* tcic_register_callback */
/*====================================================================*/
static int tcic_get_status(unsigned int lsock, u_int *value)
static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
{
u_short psock = socket_table[lsock].psock;
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_char reg;
tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
......@@ -675,7 +680,7 @@ static int tcic_get_status(unsigned int lsock, u_int *value)
/*====================================================================*/
static int tcic_inquire_socket(unsigned int lsock, socket_cap_t *cap)
static int tcic_inquire_socket(struct pcmcia_socket *sock, socket_cap_t *cap)
{
*cap = tcic_cap;
return 0;
......@@ -683,9 +688,9 @@ static int tcic_inquire_socket(unsigned int lsock, socket_cap_t *cap)
/*====================================================================*/
static int tcic_get_socket(unsigned int lsock, socket_state_t *state)
static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
{
u_short psock = socket_table[lsock].psock;
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_char reg;
u_short scf1, scf2;
......@@ -736,9 +741,9 @@ static int tcic_get_socket(unsigned int lsock, socket_state_t *state)
/*====================================================================*/
static int tcic_set_socket(unsigned int lsock, socket_state_t *state)
static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
{
u_short psock = socket_table[lsock].psock;
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_char reg;
u_short scf1, scf2;
......@@ -811,9 +816,9 @@ static int tcic_set_socket(unsigned int lsock, socket_state_t *state)
/*====================================================================*/
static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io)
static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
{
u_short psock = socket_table[lsock].psock;
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_int addr;
u_short base, len, ioctl;
......@@ -848,9 +853,9 @@ static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io)
/*====================================================================*/
static int tcic_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
{
u_short psock = socket_table[lsock].psock;
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_short addr, ctl;
u_long base, len, mmap;
......@@ -892,11 +897,11 @@ static int tcic_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
/*====================================================================*/
static void tcic_proc_setup(unsigned int sock, struct proc_dir_entry *base)
static void tcic_proc_setup(struct pcmcia_socket *sock, struct proc_dir_entry *base)
{
}
static int tcic_init(unsigned int s)
static int tcic_init(struct pcmcia_socket *s)
{
int i;
pccard_io_map io = { 0, 0, 0, 0, 1 };
......@@ -915,7 +920,7 @@ static int tcic_init(unsigned int s)
return 0;
}
static int tcic_suspend(unsigned int sock)
static int tcic_suspend(struct pcmcia_socket *sock)
{
return tcic_set_socket(sock, &dead_socket);
}
......
......@@ -136,6 +136,26 @@
#ifdef CONFIG_CARDBUS
static int ti_intctl(struct yenta_socket *socket)
{
u8 new, reg = exca_readb(socket, I365_INTCTL);
new = reg & ~I365_INTR_ENA;
if (socket->cb_irq)
new |= I365_INTR_ENA;
if (new != reg)
exca_writeb(socket, I365_INTCTL, new);
return 0;
}
static int ti_init(struct pcmcia_socket *sock)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
ti_intctl(socket);
return 0;
}
/*
* Generic TI init - TI has an extension for the
* INTCTL register that sets the PCI CSC interrupt.
......@@ -148,70 +168,28 @@
* This makes us correctly get PCI CSC interrupt
* events.
*/
static int ti_open(pci_socket_t *socket)
static int ti_override(struct yenta_socket *socket)
{
u8 new, reg = exca_readb(socket, I365_INTCTL);
new = reg & ~I365_INTR_ENA;
if (new != reg)
exca_writeb(socket, I365_INTCTL, new);
socket->socket.ss_entry->init = ti_init;
return 0;
}
static int ti_intctl(pci_socket_t *socket)
{
u8 new, reg = exca_readb(socket, I365_INTCTL);
new = reg & ~I365_INTR_ENA;
if (socket->cb_irq)
new |= I365_INTR_ENA;
if (new != reg)
exca_writeb(socket, I365_INTCTL, new);
return 0;
}
static int ti_init(pci_socket_t *socket)
{
yenta_init(socket);
ti_intctl(socket);
return 0;
}
static struct pci_socket_ops ti_ops = {
ti_open,
yenta_close,
ti_init,
yenta_suspend,
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
yenta_set_io_map,
yenta_set_mem_map,
yenta_proc_setup
};
#define ti_sysctl(socket) ((socket)->private[0])
#define ti_cardctl(socket) ((socket)->private[1])
#define ti_devctl(socket) ((socket)->private[2])
#define ti_diag(socket) ((socket)->private[3])
#define ti_irqmux(socket) ((socket)->private[4])
static int ti113x_open(pci_socket_t *socket)
{
ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL);
ti_cardctl(socket) = config_readb(socket, TI113X_CARD_CONTROL);
ti_devctl(socket) = config_readb(socket, TI113X_DEVICE_CONTROL);
ti_cardctl(socket) &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
if (socket->cb_irq)
ti_cardctl(socket) |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
ti_open(socket);
return 0;
}
static int ti113x_init(pci_socket_t *socket)
static int ti113x_init(struct pcmcia_socket *sock)
{
yenta_init(socket);
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket));
config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket));
......@@ -220,35 +198,26 @@ static int ti113x_init(pci_socket_t *socket)
return 0;
}
static struct pci_socket_ops ti113x_ops = {
ti113x_open,
yenta_close,
ti113x_init,
yenta_suspend,
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
yenta_set_io_map,
yenta_set_mem_map,
yenta_proc_setup
};
static int ti1250_open(pci_socket_t *socket)
static int ti113x_override(struct yenta_socket *socket)
{
ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC);
ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL);
ti_cardctl(socket) = config_readb(socket, TI113X_CARD_CONTROL);
ti_devctl(socket) = config_readb(socket, TI113X_DEVICE_CONTROL);
ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ);
ti_cardctl(socket) &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
if (socket->cb_irq)
ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
ti113x_open(socket);
ti_cardctl(socket) |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
ti_override(socket);
socket->socket.ss_entry->init = ti113x_init;
return 0;
}
static int ti1250_init(pci_socket_t *socket)
static int ti1250_init(struct pcmcia_socket *sock)
{
yenta_init(socket);
ti113x_init(socket);
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
ti113x_init(sock);
ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX);
ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */
if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE))
......@@ -260,18 +229,17 @@ static int ti1250_init(pci_socket_t *socket)
return 0;
}
static struct pci_socket_ops ti1250_ops = {
ti1250_open,
yenta_close,
ti1250_init,
yenta_suspend,
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
yenta_set_io_map,
yenta_set_mem_map,
yenta_proc_setup
};
static int ti1250_override(struct yenta_socket *socket)
{
ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC);
ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ);
if (socket->cb_irq)
ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
ti113x_override(socket);
socket->socket.ss_entry->init = ti1250_init;
return 0;
}
#endif /* CONFIG_CARDBUS */
......
This diff is collapsed.
......@@ -2,7 +2,6 @@
#define __YENTA_H
#include <asm/io.h>
#include "pci_socket.h"
#define CB_SOCKET_EVENT 0x00
#define CB_CSTSEVENT 0x00000001 /* Card status event */
......@@ -96,4 +95,23 @@
*/
#define CB_MEM_PAGE(map) (0x40 + (map))
struct yenta_socket {
struct pci_dev *dev;
int cb_irq, io_irq;
void *base;
void (*handler)(void *, unsigned int);
void *info;
socket_cap_t cap;
spinlock_t event_lock;
unsigned int events;
struct work_struct tq_task;
struct timer_list poll_timer;
struct pcmcia_socket socket;
/* A few words of private data for special stuff of overrides... */
unsigned int private[8];
};
#endif
......@@ -316,7 +316,7 @@ typedef struct error_info_t {
/* Special stuff for binding drivers to sockets */
typedef struct bind_req_t {
socket_t Socket;
struct pcmcia_socket *Socket;
u_char Function;
dev_info_t *dev_info;
} bind_req_t;
......@@ -325,7 +325,7 @@ typedef struct bind_req_t {
#define BIND_FN_ALL 0xff
typedef struct mtd_bind_t {
socket_t Socket;
struct pcmcia_socket *Socket;
u_int Attributes;
u_int CardOffset;
dev_info_t *dev_info;
......
......@@ -31,6 +31,8 @@
#define _LINUX_SS_H
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <linux/device.h>
/* Definitions for card status flags for GetStatus */
......@@ -124,37 +126,138 @@ typedef struct cb_bridge_map {
/*
* Socket operations.
*/
struct pcmcia_socket;
struct pccard_operations {
struct module *owner;
int (*init)(unsigned int sock);
int (*suspend)(unsigned int sock);
int (*register_callback)(unsigned int sock, void (*handler)(void *, unsigned int), void * info);
int (*inquire_socket)(unsigned int sock, socket_cap_t *cap);
int (*get_status)(unsigned int sock, u_int *value);
int (*get_socket)(unsigned int sock, socket_state_t *state);
int (*set_socket)(unsigned int sock, socket_state_t *state);
int (*set_io_map)(unsigned int sock, struct pccard_io_map *io);
int (*set_mem_map)(unsigned int sock, struct pccard_mem_map *mem);
void (*proc_setup)(unsigned int sock, struct proc_dir_entry *base);
int (*init)(struct pcmcia_socket *sock);
int (*suspend)(struct pcmcia_socket *sock);
int (*register_callback)(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info);
int (*inquire_socket)(struct pcmcia_socket *sock, socket_cap_t *cap);
int (*get_status)(struct pcmcia_socket *sock, u_int *value);
int (*get_socket)(struct pcmcia_socket *sock, socket_state_t *state);
int (*set_socket)(struct pcmcia_socket *sock, socket_state_t *state);
int (*set_io_map)(struct pcmcia_socket *sock, struct pccard_io_map *io);
int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem);
void (*proc_setup)(struct pcmcia_socket *sock, struct proc_dir_entry *base);
};
/*
* Calls to set up low-level "Socket Services" drivers
*/
struct pcmcia_socket;
struct pcmcia_socket_class_data {
unsigned int nsock; /* number of sockets */
unsigned int sock_offset; /* socket # (which is
* returned to driver) = sock_offset + (0, 1, .. , (nsock-1) */
struct pccard_operations *ops; /* see above */
void *s_info; /* socket_info_t */
struct pcmcia_socket *s_info;
struct class_device class_dev; /* generic class structure */
};
typedef struct erase_busy_t {
eraseq_entry_t *erase;
client_handle_t client;
struct timer_list timeout;
struct erase_busy_t *prev, *next;
} erase_busy_t;
typedef struct io_window_t {
u_int Attributes;
ioaddr_t BasePort, NumPorts;
ioaddr_t InUse, Config;
} io_window_t;
#define WINDOW_MAGIC 0xB35C
typedef struct window_t {
u_short magic;
u_short index;
client_handle_t handle;
struct pcmcia_socket *sock;
u_long base;
u_long size;
pccard_mem_map ctl;
} window_t;
/* Maximum number of IO windows per socket */
#define MAX_IO_WIN 2
/* Maximum number of memory windows per socket */
#define MAX_WIN 4
struct config_t;
struct region_t;
struct pcmcia_socket {
spinlock_t lock;
struct pccard_operations * ss_entry;
socket_state_t socket;
socket_cap_t cap;
u_int state;
u_short functions;
u_short lock_count;
client_handle_t clients;
u_int real_clients;
pccard_mem_map cis_mem;
u_char *cis_virt;
struct config_t *config;
struct {
u_int AssignedIRQ;
u_int Config;
} irq;
io_window_t io[MAX_IO_WIN];
window_t win[MAX_WIN];
struct region_t *c_region, *a_region;
erase_busy_t erase_busy;
struct list_head cis_cache;
u_int fake_cis_len;
char *fake_cis;
struct list_head socket_list;
/* deprecated */
unsigned int sock; /* socket number */
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc;
#endif
/* state thread */
struct semaphore skt_sem; /* protects socket h/w state */
struct task_struct *thread;
struct completion thread_done;
wait_queue_head_t thread_wait;
spinlock_t thread_lock; /* protects thread_events */
unsigned int thread_events;
/* pcmcia (16-bit) */
struct pcmcia_bus_socket *pcmcia;
/* cardbus (32-bit) */
#ifdef CONFIG_CARDBUS
struct resource * cb_cis_res;
u_char *cb_cis_virt;
#endif
/* socket device */
struct class_device dev;
void *driver_data; /* data internal to the socket driver */
};
struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr);
extern int pcmcia_register_socket(struct pcmcia_socket *socket);
extern void pcmcia_unregister_socket(struct pcmcia_socket *socket);
extern struct class pcmcia_socket_class;
/* socket drivers are expected to use these callbacks in their .drv struct */
extern int pcmcia_socket_dev_suspend(struct pcmcia_socket_class_data *cls_d, u32 state, u32 level);
extern int pcmcia_socket_dev_resume(struct pcmcia_socket_class_data *cls_d, u32 level);
extern int pcmcia_socket_dev_suspend(struct device *dev, u32 state, u32 level);
extern int pcmcia_socket_dev_resume(struct device *dev, u32 level);
#endif /* _LINUX_SS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment