diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 301eecf297434fc7d4ab8450e4c8818a23d9d851..d06cfa73d893201714b0becddc5b83fc9f02670a 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -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
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 32c8efc83192dc6132293839f5843b9f57738c12..6e83826cf74effd7d0811c5496f063c82c9ade9b 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -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
 
diff --git a/drivers/pcmcia/bulkmem.c b/drivers/pcmcia/bulkmem.c
index 4419780fb6d6ee874707c6a8da15372a5e96431d..01c843e44b0ac140a58fae07f6b67462041a665b 100644
--- a/drivers/pcmcia/bulkmem.c
+++ b/drivers/pcmcia/bulkmem.c
@@ -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
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index b10a31a7caa1f59d6cf5ae7c9bff5e05631054bd..b512673bd2acf2f19712c83612a89b01dea74813 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -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;
 
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 303ee17d6825eac3ac480939cff071a83399194b..5d27f616dee4f83cbb95a536edab6839a0bb1627 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -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))
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index ba9a69e5c5e2a64c9f532ea680f9afae85d5eb31..be950332b5504c7f2f6c9c18f1921483415e3e7c 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -124,9 +124,11 @@ socket_state_t dead_socket = {
     0, SS_DETECT, 0, 0, 0
 };
 
-/* Table of sockets */
-socket_t sockets = 0;
-socket_info_t *socket_table[MAX_SOCK];
+
+/* List of all sockets, protected by a rwsem */
+LIST_HEAD(pcmcia_socket_list);
+DECLARE_RWSEM(pcmcia_socket_list_rwsem);
+
 
 #ifdef CONFIG_PROC_FS
 struct proc_dir_entry *proc_pccard = NULL;
@@ -235,48 +237,48 @@ static const lookup_t service_table[] = {
 
 ======================================================================*/
 
-static int register_callback(socket_info_t *s, void (*handler)(void *, unsigned int), void * info)
+static int register_callback(struct pcmcia_socket *s, void (*handler)(void *, unsigned int), void * info)
 {
 	int error;
 
 	if (handler && !try_module_get(s->ss_entry->owner))
 		return -ENODEV;
-	error = s->ss_entry->register_callback(s->sock, handler, info);
+	error = s->ss_entry->register_callback(s, handler, info);
 	if (!handler)
 		module_put(s->ss_entry->owner);
 	return error;
 }
 
-static int get_socket_status(socket_info_t *s, int *val)
+static int get_socket_status(struct pcmcia_socket *s, int *val)
 {
-	return s->ss_entry->get_status(s->sock, val);
+	return s->ss_entry->get_status(s, val);
 }
 
-static int set_socket(socket_info_t *s, socket_state_t *state)
+static int set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
-	return s->ss_entry->set_socket(s->sock, state);
+	return s->ss_entry->set_socket(s, state);
 }
 
-static int set_io_map(socket_info_t *s, struct pccard_io_map *io)
+static int set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
 {
-	return s->ss_entry->set_io_map(s->sock, io);
+	return s->ss_entry->set_io_map(s, io);
 }
 
-static int set_mem_map(socket_info_t *s, struct pccard_mem_map *mem)
+static int set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
 {
-	return s->ss_entry->set_mem_map(s->sock, mem);
+	return s->ss_entry->set_mem_map(s, mem);
 }
 
-static int suspend_socket(socket_info_t *s)
+static int suspend_socket(struct pcmcia_socket *s)
 {
 	s->socket = dead_socket;
-	return s->ss_entry->suspend(s->sock);
+	return s->ss_entry->suspend(s);
 }
 
-static int init_socket(socket_info_t *s)
+static int init_socket(struct pcmcia_socket *s)
 {
 	s->socket = dead_socket;
-	return s->ss_entry->init(s->sock);
+	return s->ss_entry->init(s);
 }
 
 /*====================================================================*/
@@ -285,7 +287,7 @@ static int init_socket(socket_info_t *s)
 static int proc_read_clients(char *buf, char **start, off_t pos,
 			     int count, int *eof, void *data)
 {
-    socket_info_t *s = data;
+    struct pcmcia_socket *s = data;
     client_handle_t c;
     char *p = buf;
 
@@ -303,145 +305,226 @@ static int proc_read_clients(char *buf, char **start, off_t pos,
     
 ======================================================================*/
 
-static int pccardd(void *__skt);
-void pcmcia_unregister_socket(struct class_device *dev);
+/**
+ * socket drivers are expected to use the following callbacks in their 
+ * .drv struct:
+ *  - pcmcia_socket_dev_suspend
+ *  - pcmcia_socket_dev_resume
+ * These functions check for the appropriate struct pcmcia_soket arrays,
+ * and pass them to the low-level functions pcmcia_{suspend,resume}_socket
+ */
+static int socket_resume(struct pcmcia_socket *skt);
+static int socket_suspend(struct pcmcia_socket *skt);
+
+int pcmcia_socket_dev_suspend(struct device *dev, u32 state, u32 level)
+{
+	struct pcmcia_socket *socket;
+
+	if (level != SUSPEND_SAVE_STATE)
+		return 0;
+
+	down_read(&pcmcia_socket_list_rwsem);
+	list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
+		if (socket->dev.dev != dev)
+			continue;
+		down(&socket->skt_sem);
+		socket_suspend(socket);
+		up(&socket->skt_sem);
+	}
+	up_read(&pcmcia_socket_list_rwsem);
+
+	return 0;
+}
+EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
+
+int pcmcia_socket_dev_resume(struct device *dev, u32 level)
+{
+	struct pcmcia_socket *socket;
 
+	if (level != RESUME_RESTORE_STATE)
+		return 0;
+
+	down_read(&pcmcia_socket_list_rwsem);
+	list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
+		if (socket->dev.dev != dev)
+			continue;
+		down(&socket->skt_sem);
+		socket_resume(socket);
+		up(&socket->skt_sem);
+	}
+	up_read(&pcmcia_socket_list_rwsem);
+
+	return 0;
+}
+EXPORT_SYMBOL(pcmcia_socket_dev_resume);
+
+
+static int pccardd(void *__skt);
 #define to_class_data(dev) dev->class_data
 
-/**
- * pcmcia_register_socket - add a new pcmcia socket device
- */
-int pcmcia_register_socket(struct class_device *class_dev)
+static int pcmcia_add_socket(struct class_device *class_dev)
 {
-	struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
-	socket_info_t *s_info;
-	unsigned int i, j, ret;
+	struct pcmcia_socket *socket = class_get_devdata(class_dev);
+	int ret = 0;
 
-	if (!cls_d)
-		return -EINVAL;
+	/* base address = 0, map = 0 */
+	socket->cis_mem.flags = 0;
+	socket->cis_mem.speed = cis_speed;
+	socket->erase_busy.next = socket->erase_busy.prev = &socket->erase_busy;
+	INIT_LIST_HEAD(&socket->cis_cache);
+	spin_lock_init(&socket->lock);
 
-	DEBUG(0, "cs: pcmcia_register_socket(0x%p)\n", cls_d->ops);
-
-	s_info = kmalloc(cls_d->nsock * sizeof(struct socket_info_t), GFP_KERNEL);
-	if (!s_info)
-		return -ENOMEM;
-	memset(s_info, 0, cls_d->nsock * sizeof(socket_info_t));
-
-	cls_d->s_info = s_info;
-	ret = 0;
-
-	/* socket initialization */
-	for (i = 0; i < cls_d->nsock; i++) {
-		socket_info_t *s = &s_info[i];
-
-		s->ss_entry = cls_d->ops;
-		s->sock = i + cls_d->sock_offset;
-
-		/* base address = 0, map = 0 */
-		s->cis_mem.flags = 0;
-		s->cis_mem.speed = cis_speed;
-		s->erase_busy.next = s->erase_busy.prev = &s->erase_busy;
-		INIT_LIST_HEAD(&s->cis_cache);
-		spin_lock_init(&s->lock);
-
-		/* TBD: remove usage of socket_table, use class_for_each_dev instead */
-		for (j = 0; j < sockets; j++)
-			if (socket_table[j] == NULL) break;
-		socket_table[j] = s;
-		if (j == sockets) sockets++;
-
-		init_socket(s);
-		s->ss_entry->inquire_socket(s->sock, &s->cap);
-
-		init_completion(&s->thread_done);
-		init_waitqueue_head(&s->thread_wait);
-		init_MUTEX(&s->skt_sem);
-		spin_lock_init(&s->thread_lock);
-		ret = kernel_thread(pccardd, s, CLONE_KERNEL);
-		if (ret < 0) {
-			pcmcia_unregister_socket(class_dev);
-			break;
-		}
+	init_socket(socket);
+	socket->ss_entry->inquire_socket(socket, &socket->cap);
+
+	init_completion(&socket->thread_done);
+	init_waitqueue_head(&socket->thread_wait);
+	init_MUTEX(&socket->skt_sem);
+	spin_lock_init(&socket->thread_lock);
+	ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
+	if (ret < 0)
+		return ret;
 
-		wait_for_completion(&s->thread_done);
-		BUG_ON(!s->thread);
+	wait_for_completion(&socket->thread_done);
+	BUG_ON(!socket->thread);
 
 #ifdef CONFIG_PROC_FS
-		if (proc_pccard) {
-			char name[3];
-			sprintf(name, "%02d", j);
-			s->proc = proc_mkdir(name, proc_pccard);
-			if (s->proc)
-				s->ss_entry->proc_setup(i, s->proc);
+	if (proc_pccard) {
+		char name[3];
+		sprintf(name, "%02d", socket->sock);
+		socket->proc = proc_mkdir(name, proc_pccard);
+		if (socket->proc)
+			socket->ss_entry->proc_setup(socket, socket->proc);
 #ifdef PCMCIA_DEBUG
-			if (s->proc)
-				create_proc_read_entry("clients", 0, s->proc,
-				       proc_read_clients, s);
+		if (socket->proc)
+			create_proc_read_entry("clients", 0, socket->proc,
+					       proc_read_clients, socket);
 #endif
-		}
+	}
+#endif
+	return 0;
+}
+
+static void pcmcia_remove_socket(struct class_device *class_dev)
+{
+	struct pcmcia_socket *socket = class_get_devdata(class_dev);
+	client_t *client;
+
+#ifdef CONFIG_PROC_FS
+	if (proc_pccard) {
+		char name[3];
+		sprintf(name, "%02d", socket->sock);
+#ifdef PCMCIA_DEBUG
+		remove_proc_entry("clients", socket->proc);
 #endif
+		remove_proc_entry(name, proc_pccard);
 	}
-	return ret;
+#endif
+	if (socket->thread) {
+		init_completion(&socket->thread_done);
+		socket->thread = NULL;
+		wake_up(&socket->thread_wait);
+		wait_for_completion(&socket->thread_done);
+	}
+	release_cis_mem(socket);
+	while (socket->clients) {
+		client = socket->clients;
+		socket->clients = socket->clients->next;
+		kfree(client);
+	}
+	socket->ss_entry = NULL;
+}
+
+
+/**
+ * pcmcia_register_socket - add a new pcmcia socket device
+ */
+int pcmcia_register_socket(struct pcmcia_socket *socket)
+{
+	if (!socket || !socket->ss_entry || !socket->dev.dev)
+		return -EINVAL;
+
+	DEBUG(0, "cs: pcmcia_register_socket(0x%p)\n", socket->ss_entry);
+
+	/* try to obtain a socket number [yes, it gets ugly if we
+	 * register more than 2^sizeof(unsigned int) pcmcia 
+	 * sockets... but the socket number is deprecated 
+	 * anyways, so I don't care] */
+	down_write(&pcmcia_socket_list_rwsem);
+	if (list_empty(&pcmcia_socket_list))
+		socket->sock = 0;
+	else {
+		unsigned int found, i = 1;
+		struct pcmcia_socket *tmp;
+		do {
+			found = 1;
+			list_for_each_entry(tmp, &pcmcia_socket_list, socket_list) {
+				if (tmp->sock == i)
+					found = 0;
+			}
+			i++;
+		} while (!found);
+		socket->sock = i - 1;
+	}
+	list_add_tail(&socket->socket_list, &pcmcia_socket_list);
+	up_write(&pcmcia_socket_list_rwsem);
+
+
+	/* set proper values in socket->dev */
+	socket->dev.class_data = socket;
+	socket->dev.class = &pcmcia_socket_class;
+	snprintf(socket->dev.class_id, BUS_ID_SIZE, "pcmcia_socket%u\n", socket->sock);
+
+	/* register with the device core */
+	if (class_device_register(&socket->dev)) {
+		down_write(&pcmcia_socket_list_rwsem);
+		list_del(&socket->socket_list);
+		up_write(&pcmcia_socket_list_rwsem);
+		return -EINVAL;
+	}
+
+	return 0;
 } /* pcmcia_register_socket */
+EXPORT_SYMBOL(pcmcia_register_socket);
 
 
 /**
  * pcmcia_unregister_socket - remove a pcmcia socket device
  */
-void pcmcia_unregister_socket(struct class_device *class_dev)
+void pcmcia_unregister_socket(struct pcmcia_socket *socket)
 {
-	struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
-	unsigned int i;
-	int j, socket = -1;
-	client_t *client;
-	socket_info_t *s;
-
-	if (!cls_d)
+	if (!socket)
 		return;
 
-	s = (socket_info_t *) cls_d->s_info;
+	DEBUG(0, "cs: pcmcia_unregister_socket(0x%p)\n", socket->ss_entry);
 
-	for (i = 0; i < cls_d->nsock; i++) {
-		for (j = 0; j < MAX_SOCK; j++)
-			if (socket_table [j] == s) {
-				socket = j;
-				break;
-			}
-		if (socket < 0)
-			continue;
-		
-#ifdef CONFIG_PROC_FS
-		if (proc_pccard) {
-			char name[3];
-			sprintf(name, "%02d", socket);
-#ifdef PCMCIA_DEBUG
-			remove_proc_entry("clients", s->proc);
-#endif
-			remove_proc_entry(name, proc_pccard);
-		}
-#endif
-		if (s->thread) {
-			init_completion(&s->thread_done);
-			s->thread = NULL;
-			wake_up(&s->thread_wait);
-			wait_for_completion(&s->thread_done);
-		}
-		release_cis_mem(s);
-		while (s->clients) {
-			client = s->clients;
-			s->clients = s->clients->next;
-			kfree(client);
-		}
-		s->ss_entry = NULL;
-		socket_table[socket] = NULL;
-		for (j = socket; j < sockets-1; j++)
-			socket_table[j] = socket_table[j+1];
-		sockets--;
+	/* remove from the device core */
+	class_device_unregister(&socket->dev);
 
-		s++;
-	}
-	kfree(cls_d->s_info);
+	/* remove from our own list */
+	down_write(&pcmcia_socket_list_rwsem);
+	list_del(&socket->socket_list);
+	up_write(&pcmcia_socket_list_rwsem);
 } /* pcmcia_unregister_socket */
+EXPORT_SYMBOL(pcmcia_unregister_socket);
+
+
+struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)
+{
+	struct pcmcia_socket *s;
+
+	down_read(&pcmcia_socket_list_rwsem);
+	list_for_each_entry(s, &pcmcia_socket_list, socket_list)
+		if (s->sock == nr) {
+			up_read(&pcmcia_socket_list_rwsem);
+			return s;
+		}
+	up_read(&pcmcia_socket_list_rwsem);
+
+	return NULL;
+
+}
+EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
 
 
 /*======================================================================
@@ -465,9 +548,9 @@ static void free_regions(memory_handle_t *list)
     }
 }
 
-static int send_event(socket_info_t *s, event_t event, int priority);
+static int send_event(struct pcmcia_socket *s, event_t event, int priority);
 
-static void shutdown_socket(socket_info_t *s)
+static void shutdown_socket(struct pcmcia_socket *s)
 {
     client_t **c;
     
@@ -522,7 +605,7 @@ static void shutdown_socket(socket_info_t *s)
     
 ======================================================================*/
 
-static int send_event(socket_info_t *s, event_t event, int priority)
+static int send_event(struct pcmcia_socket *s, event_t event, int priority)
 {
     client_t *client = s->clients;
     int ret;
@@ -543,7 +626,7 @@ static int send_event(socket_info_t *s, event_t event, int priority)
     return ret;
 } /* send_event */
 
-static void pcmcia_error(socket_info_t *skt, const char *fmt, ...)
+static void pcmcia_error(struct pcmcia_socket *skt, const char *fmt, ...)
 {
 	static char buf[128];
 	va_list ap;
@@ -559,7 +642,7 @@ static void pcmcia_error(socket_info_t *skt, const char *fmt, ...)
 
 #define cs_to_timeout(cs) (((cs) * HZ + 99) / 100)
 
-static void socket_remove_drivers(socket_info_t *skt)
+static void socket_remove_drivers(struct pcmcia_socket *skt)
 {
 	client_t *client;
 
@@ -570,7 +653,7 @@ static void socket_remove_drivers(socket_info_t *skt)
 			client->state |= CLIENT_STALE;
 }
 
-static void socket_shutdown(socket_info_t *skt)
+static void socket_shutdown(struct pcmcia_socket *skt)
 {
 	socket_remove_drivers(skt);
 	set_current_state(TASK_UNINTERRUPTIBLE);
@@ -579,7 +662,7 @@ static void socket_shutdown(socket_info_t *skt)
 	shutdown_socket(skt);
 }
 
-static int socket_reset(socket_info_t *skt)
+static int socket_reset(struct pcmcia_socket *skt)
 {
 	int status, i;
 
@@ -609,7 +692,7 @@ static int socket_reset(socket_info_t *skt)
 	return CS_GENERAL_FAILURE;
 }
 
-static int socket_setup(socket_info_t *skt, int initial_delay)
+static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
 {
 	int status, i;
 
@@ -673,7 +756,7 @@ static int socket_setup(socket_info_t *skt, int initial_delay)
  * Handle card insertion.  Setup the socket, reset the card,
  * and then tell the rest of PCMCIA that a card is present.
  */
-static int socket_insert(socket_info_t *skt)
+static int socket_insert(struct pcmcia_socket *skt)
 {
 	int ret;
 
@@ -693,7 +776,7 @@ static int socket_insert(socket_info_t *skt)
 	return ret;
 }
 
-static int socket_suspend(socket_info_t *skt)
+static int socket_suspend(struct pcmcia_socket *skt)
 {
 	if (skt->state & SOCKET_SUSPEND)
 		return CS_IN_USE;
@@ -710,7 +793,7 @@ static int socket_suspend(socket_info_t *skt)
  * our cached copy.  If they are different, the card has been
  * replaced, and we need to tell the drivers.
  */
-static int socket_resume(socket_info_t *skt)
+static int socket_resume(struct pcmcia_socket *skt)
 {
 	int ret;
 
@@ -742,7 +825,7 @@ static int socket_resume(socket_info_t *skt)
 
 static int pccardd(void *__skt)
 {
-	socket_info_t *skt = __skt;
+	struct pcmcia_socket *skt = __skt;
 	DECLARE_WAITQUEUE(wait, current);
 
 	daemonize("pccardd");
@@ -799,7 +882,7 @@ static int pccardd(void *__skt)
 
 static void parse_events(void *info, u_int events)
 {
-	socket_info_t *s = info;
+	struct pcmcia_socket *s = info;
 
 	spin_lock(&s->thread_lock);
 	s->thread_events |= events;
@@ -808,68 +891,6 @@ static void parse_events(void *info, u_int events)
 	wake_up(&s->thread_wait);
 } /* parse_events */
 
-/*======================================================================
-
-    Another event handler, for power management events.
-
-    This does not comply with the latest PC Card spec for handling
-    power management events.
-    
-======================================================================*/
-
-void pcmcia_suspend_socket (socket_info_t *skt)
-{
-	down(&skt->skt_sem);
-	socket_suspend(skt);
-	up(&skt->skt_sem);
-}
-
-void pcmcia_resume_socket (socket_info_t *skt)
-{
-	down(&skt->skt_sem);
-	socket_resume(skt);
-	up(&skt->skt_sem);
-}
-
-
-int pcmcia_socket_dev_suspend(struct pcmcia_socket_class_data *cls_d, u32 state, u32 level)
-{
-	socket_info_t *s;
-	int i;
-
-	if ((!cls_d) || (level != SUSPEND_SAVE_STATE))
-		return 0;
-
-	s = (socket_info_t *) cls_d->s_info;
-
-	for (i = 0; i < cls_d->nsock; i++) {
-		pcmcia_suspend_socket(s);
-		s++;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
-
-int pcmcia_socket_dev_resume(struct pcmcia_socket_class_data *cls_d, u32 level)
-{
-	socket_info_t *s;
-	int i;
-
-	if ((!cls_d) || (level != RESUME_RESTORE_STATE))
-		return 0;
-
-	s = (socket_info_t *) cls_d->s_info;
-
-	for (i = 0; i < cls_d->nsock; i++) {
-		pcmcia_resume_socket(s);
-		s++;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_resume);
-
 
 /*======================================================================
 
@@ -877,7 +898,7 @@ EXPORT_SYMBOL(pcmcia_socket_dev_resume);
     
 ======================================================================*/
 
-static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base,
+static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
 			  ioaddr_t num, u_int lines, char *name)
 {
     int i;
@@ -941,7 +962,7 @@ static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base,
     return (i == MAX_IO_WIN);
 } /* alloc_io_space */
 
-static void release_io_space(socket_info_t *s, ioaddr_t base,
+static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
 			     ioaddr_t num)
 {
     int i;
@@ -969,7 +990,7 @@ static void release_io_space(socket_info_t *s, ioaddr_t base,
 int pcmcia_access_configuration_register(client_handle_t handle,
 					 conf_reg_t *reg)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     config_t *c;
     int addr;
     u_char val;
@@ -1020,18 +1041,18 @@ int pcmcia_access_configuration_register(client_handle_t handle,
 int pcmcia_bind_device(bind_req_t *req)
 {
     client_t *client;
-    socket_info_t *s;
+    struct pcmcia_socket *s;
 
-    if (CHECK_SOCKET(req->Socket))
-	return CS_BAD_SOCKET;
-    s = SOCKET(req);
+    s = req->Socket;
+    if (!s)
+	    return CS_BAD_SOCKET;
 
     client = (client_t *)kmalloc(sizeof(client_t), GFP_KERNEL);
     if (!client) return CS_OUT_OF_RESOURCE;
     memset(client, '\0', sizeof(client_t));
     client->client_magic = CLIENT_MAGIC;
     strlcpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
-    client->Socket = req->Socket;
+    client->Socket = s;
     client->Function = req->Function;
     client->state = CLIENT_UNBOUND;
     client->erase_busy.next = &client->erase_busy;
@@ -1055,12 +1076,12 @@ int pcmcia_bind_device(bind_req_t *req)
 
 int pcmcia_bind_mtd(mtd_bind_t *req)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     memory_handle_t region;
     
-    if (CHECK_SOCKET(req->Socket))
-	return CS_BAD_SOCKET;
-    s = SOCKET(req);
+    s = req->Socket;
+    if (!s)
+	    return CS_BAD_SOCKET;
     
     if (req->Attributes & REGION_TYPE_AM)
 	region = s->a_region;
@@ -1085,10 +1106,10 @@ int pcmcia_bind_mtd(mtd_bind_t *req)
 int pcmcia_deregister_client(client_handle_t handle)
 {
     client_t **client;
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     memory_handle_t region;
     u_long flags;
-    int i, sn;
+    int i;
     
     DEBUG(1, "cs: deregister_client(%p)\n", handle);
     if (CHECK_HANDLE(handle))
@@ -1109,8 +1130,6 @@ int pcmcia_deregister_client(client_handle_t handle)
 	    if (region->mtd == handle) region->mtd = NULL;
     }
     
-    sn = handle->Socket; s = socket_table[sn];
-
     if ((handle->state & CLIENT_STALE) ||
 	(handle->Attributes & INFO_MASTER_CLIENT)) {
 	spin_lock_irqsave(&s->lock, flags);
@@ -1142,7 +1161,7 @@ int pcmcia_deregister_client(client_handle_t handle)
 int pcmcia_get_configuration_info(client_handle_t handle,
 				  config_info_t *config)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     config_t *c;
     
     if (CHECK_HANDLE(handle))
@@ -1212,9 +1231,15 @@ int pcmcia_get_configuration_info(client_handle_t handle,
 
 int pcmcia_get_card_services_info(servinfo_t *info)
 {
+    unsigned int socket_count = 0;
+    struct list_head *tmp;
     info->Signature[0] = 'C';
     info->Signature[1] = 'S';
-    info->Count = sockets;
+    down_read(&pcmcia_socket_list_rwsem);
+    list_for_each(tmp, &pcmcia_socket_list)
+	    socket_count++;
+    up_read(&pcmcia_socket_list_rwsem);
+    info->Count = socket_count;
     info->Revision = CS_RELEASE_CODE;
     info->CSLevel = 0x0210;
     info->VendorString = (char *)release;
@@ -1231,15 +1256,17 @@ int pcmcia_get_card_services_info(servinfo_t *info)
 int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
 {
     socket_t s;
+    struct pcmcia_socket *socket;
     if (req->Attributes & CLIENT_THIS_SOCKET)
 	s = req->Socket;
     else
 	s = 0;
-    if (CHECK_SOCKET(req->Socket))
+    socket = pcmcia_get_socket_by_nr(s);
+    if (!socket)
 	return CS_BAD_SOCKET;
-    if (socket_table[s]->clients == NULL)
+    if (socket->clients == NULL)
 	return CS_NO_MORE_ITEMS;
-    *handle = socket_table[s]->clients;
+    *handle = socket->clients;
     return CS_SUCCESS;
 } /* get_first_client */
 
@@ -1247,13 +1274,13 @@ int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
 
 int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     if ((handle == NULL) || CHECK_HANDLE(*handle))
 	return CS_BAD_HANDLE;
     if ((*handle)->next == NULL) {
 	if (req->Attributes & CLIENT_THIS_SOCKET)
 	    return CS_NO_MORE_ITEMS;
-	s = SOCKET(*handle);
+	s = (*handle)->Socket;
 	if (s->clients == NULL)
 	    return CS_NO_MORE_ITEMS;
 	*handle = s->clients;
@@ -1266,12 +1293,12 @@ int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req)
 
 int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     window_t *win;
     int w;
 
     if (idx == 0)
-	s = SOCKET((client_handle_t)*handle);
+	s = ((client_handle_t)*handle)->Socket;
     else
 	s = (*handle)->sock;
     if (!(s->state & SOCKET_PRESENT))
@@ -1321,7 +1348,7 @@ int pcmcia_get_next_window(window_handle_t *win, win_req_t *req)
 
 struct pci_bus *pcmcia_lookup_bus(client_handle_t handle)
 {
-	socket_info_t *s;
+	struct pcmcia_socket *s;
 
 	if (CHECK_HANDLE(handle))
 		return NULL;
@@ -1345,7 +1372,7 @@ EXPORT_SYMBOL(pcmcia_lookup_bus);
 
 int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     config_t *c;
     int val;
     
@@ -1424,7 +1451,7 @@ int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
 
 int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     if ((win == NULL) || (win->magic != WINDOW_MAGIC))
 	return CS_BAD_HANDLE;
     if (req->Page != 0)
@@ -1445,7 +1472,7 @@ int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
 int pcmcia_modify_configuration(client_handle_t handle,
 				modconf_t *mod)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     config_t *c;
     
     if (CHECK_HANDLE(handle))
@@ -1522,14 +1549,13 @@ int pcmcia_modify_window(window_handle_t win, modwin_t *req)
 
 int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
 {
-    client_t *client;
-    socket_info_t *s;
-    socket_t ns;
+    client_t *client = NULL;
+    struct pcmcia_socket *s;
     
     /* Look for unbound client with matching dev_info */
-    client = NULL;
-    for (ns = 0; ns < sockets; ns++) {
-	client = socket_table[ns]->clients;
+    down_read(&pcmcia_socket_list_rwsem);
+    list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
+	client = s->clients;
 	while (client != NULL) {
 	    if ((strcmp(client->dev_info, (char *)req->dev_info) == 0)
 		&& (client->state & CLIENT_UNBOUND)) break;
@@ -1537,10 +1563,10 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
 	}
 	if (client != NULL) break;
     }
+    up_read(&pcmcia_socket_list_rwsem);
     if (client == NULL)
 	return CS_OUT_OF_RESOURCE;
 
-    s = socket_table[ns];
     if (++s->real_clients == 1) {
 	register_callback(s, &parse_events, s);
 	parse_events(s, SS_DETECT);
@@ -1548,7 +1574,7 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
 
     *handle = client;
     client->state &= ~CLIENT_UNBOUND;
-    client->Socket = ns;
+    client->Socket = s;
     client->Attributes = req->Attributes;
     client->EventMask = req->EventMask;
     client->event_handler = req->event_handler;
@@ -1577,8 +1603,8 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
 	  client, client->Socket, client->dev_info);
     if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
 	EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
-    if ((socket_table[ns]->state & SOCKET_PRESENT) &&
-	!(socket_table[ns]->state & SOCKET_SETUP_PENDING)) {
+    if ((s->state & SOCKET_PRESENT) &&
+	!(s->state & SOCKET_SETUP_PENDING)) {
 	if (client->EventMask & CS_EVENT_CARD_INSERTION)
 	    EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
 	else
@@ -1592,7 +1618,7 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
 int pcmcia_release_configuration(client_handle_t handle)
 {
     pccard_io_map io = { 0, 0, 0, 0, 1 };
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     int i;
     
     if (CHECK_HANDLE(handle) ||
@@ -1642,7 +1668,7 @@ int pcmcia_release_configuration(client_handle_t handle)
 
 int pcmcia_release_io(client_handle_t handle, io_req_t *req)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     
     if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))
 	return CS_BAD_HANDLE;
@@ -1677,7 +1703,7 @@ int pcmcia_release_io(client_handle_t handle, io_req_t *req)
 
 int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))
 	return CS_BAD_HANDLE;
     handle->state &= ~CLIENT_IRQ_REQ;
@@ -1713,7 +1739,7 @@ int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
 
 int pcmcia_release_window(window_handle_t win)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     
     if ((win == NULL) || (win->magic != WINDOW_MAGIC))
 	return CS_BAD_HANDLE;
@@ -1743,13 +1769,13 @@ int pcmcia_request_configuration(client_handle_t handle,
 {
     int i;
     u_int base;
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     config_t *c;
     pccard_io_map iomap;
     
     if (CHECK_HANDLE(handle))
 	return CS_BAD_HANDLE;
-    i = handle->Socket; s = socket_table[i];
+    s = SOCKET(handle);
     if (!(s->state & SOCKET_PRESENT))
 	return CS_NO_CARD;
     
@@ -1872,7 +1898,7 @@ int pcmcia_request_configuration(client_handle_t handle,
 
 int pcmcia_request_io(client_handle_t handle, io_req_t *req)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     config_t *c;
     
     if (CHECK_HANDLE(handle))
@@ -1936,7 +1962,7 @@ int pcmcia_request_io(client_handle_t handle, io_req_t *req)
 
 int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     config_t *c;
     int ret = 0, irq = 0;
     
@@ -2011,14 +2037,14 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
 
 int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)
 {
-    socket_info_t *s;
+    struct pcmcia_socket *s;
     window_t *win;
     u_long align;
     int w;
     
     if (CHECK_HANDLE(*handle))
 	return CS_BAD_HANDLE;
-    s = SOCKET(*handle);
+    s = (*handle)->Socket;
     if (!(s->state & SOCKET_PRESENT))
 	return CS_NO_CARD;
     if (req->Attributes & (WIN_PAGED | WIN_SHARED))
@@ -2096,7 +2122,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
 
 int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
 {
-	socket_info_t *skt;
+	struct pcmcia_socket *skt;
 	int ret;
     
 	if (CHECK_HANDLE(handle))
@@ -2145,7 +2171,7 @@ int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
 
 int pcmcia_suspend_card(client_handle_t handle, client_req_t *req)
 {
-	socket_info_t *skt;
+	struct pcmcia_socket *skt;
 	int ret;
     
 	if (CHECK_HANDLE(handle))
@@ -2172,7 +2198,7 @@ int pcmcia_suspend_card(client_handle_t handle, client_req_t *req)
 
 int pcmcia_resume_card(client_handle_t handle, client_req_t *req)
 {
-	socket_info_t *skt;
+	struct pcmcia_socket *skt;
 	int ret;
     
 	if (CHECK_HANDLE(handle))
@@ -2205,7 +2231,7 @@ int pcmcia_resume_card(client_handle_t handle, client_req_t *req)
 
 int pcmcia_eject_card(client_handle_t handle, client_req_t *req)
 {
-	socket_info_t *skt;
+	struct pcmcia_socket *skt;
 	int ret;
     
 	if (CHECK_HANDLE(handle))
@@ -2234,7 +2260,7 @@ int pcmcia_eject_card(client_handle_t handle, client_req_t *req)
 
 int pcmcia_insert_card(client_handle_t handle, client_req_t *req)
 {
-	socket_info_t *skt;
+	struct pcmcia_socket *skt;
 	int ret;
 
 	if (CHECK_HANDLE(handle))
@@ -2519,11 +2545,6 @@ EXPORT_SYMBOL(MTDHelperEntry);
 EXPORT_SYMBOL(proc_pccard);
 #endif
 
-EXPORT_SYMBOL(pcmcia_register_socket);
-EXPORT_SYMBOL(pcmcia_unregister_socket);
-EXPORT_SYMBOL(pcmcia_suspend_socket);
-EXPORT_SYMBOL(pcmcia_resume_socket);
-
 struct class pcmcia_socket_class = {
 	.name = "pcmcia_socket",
 };
@@ -2531,8 +2552,8 @@ EXPORT_SYMBOL(pcmcia_socket_class);
 
 static struct class_interface pcmcia_socket = {
 	.class = &pcmcia_socket_class,
-	.add = &pcmcia_register_socket,
-	.remove = &pcmcia_unregister_socket,
+	.add = &pcmcia_add_socket,
+	.remove = &pcmcia_remove_socket,
 };
 
 
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index ffe7980fe1617cdf76ec03ade8d359087cd96a36..11c50e4a6049e4a8ad4a4ef9d7e513af24c062d2 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -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;
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 8f4e8c2e8476f2c8814f4203dc6b0cd5066e4bef..b06d677a1dc3920fdc5fc1933935843fa9f82b4e 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -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! */
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index f998ba48db4c1d40b33e98ca3c625c142720d3e5..d3591ae10ebee6a5e43a2a5b3d507b64265ffd53 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -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)
 {
 	
 }
diff --git a/drivers/pcmcia/i82092aa.h b/drivers/pcmcia/i82092aa.h
index 191a3bd920971b519849095d82aede6888c9317f..eb1c307fbeff7109217bea407c1cc391e6df431a 100644
--- a/drivers/pcmcia/i82092aa.h
+++ b/drivers/pcmcia/i82092aa.h
@@ -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
 
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 560503d3917d9aa8e3e4b4f9a954af6299fab48d..c5536fe45702ab67954ceac6b2d84a064430fc64 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -91,7 +91,6 @@ static inline int _check_irq(int irq, int flags)
 
 /* Parameters that can be set with 'insmod' */
 
-#ifdef CONFIG_ISA
 /* Default base address for i82365sl and other ISA chips */
 static int i365_base = 0x3e0;
 /* Should we probe at 0x3e2 for an extra ISA controller? */
@@ -103,7 +102,6 @@ static u_int irq_mask = 0xffff;
 static int irq_list[16] = { -1 };
 /* The card status change interrupt -- 0 means autoselect */
 static int cs_irq = 0;
-#endif
 
 /* Probe for safe interrupts? */
 static int do_scan = 1;
@@ -122,14 +120,11 @@ static int setup_time = -1;
 static int cmd_time = -1;
 static int recov_time = -1;
 
-#ifdef CONFIG_ISA
 /* Vadem options */
 static int async_clock = -1;
 static int cable_mode = -1;
 static int wakeup = 0;
-#endif
 
-#ifdef CONFIG_ISA
 MODULE_PARM(i365_base, "i");
 MODULE_PARM(ignore, "i");
 MODULE_PARM(extra_sockets, "i");
@@ -139,7 +134,6 @@ MODULE_PARM(cs_irq, "i");
 MODULE_PARM(async_clock, "i");
 MODULE_PARM(cable_mode, "i");
 MODULE_PARM(wakeup, "i");
-#endif
 
 MODULE_PARM(do_scan, "i");
 MODULE_PARM(poll_interval, "i");
@@ -164,8 +158,10 @@ typedef struct vg46x_state_t {
     u_char		ctl, ema;
 } vg46x_state_t;
 
-typedef struct socket_info_t {
+struct i82365_socket {
     u_short		type, flags;
+    struct pcmcia_socket	socket;
+    unsigned int	number;
     socket_cap_t	cap;
     ioaddr_t		ioaddr;
     u_short		psock;
@@ -179,26 +175,21 @@ typedef struct socket_info_t {
 	cirrus_state_t		cirrus;
 	vg46x_state_t		vg46x;
     } state;
-} socket_info_t;
+};
 
 /* Where we keep track of our sockets... */
 static int sockets = 0;
-static socket_info_t socket[8] = {
+static struct i82365_socket socket[8] = {
     { 0, }, /* ... */
 };
 
 /* Default ISA interrupt mask */
 #define I365_MASK	0xdeb8	/* irq 15,14,12,11,10,9,7,5,4,3 */
 
-#ifdef CONFIG_ISA
 static int grab_irq;
 static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED;
 #define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f)
 #define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f)
-#else
-#define ISA_LOCK(n, f) do { } while (0)
-#define ISA_UNLOCK(n, f) do { } while (0)
-#endif
 
 static struct timer_list poll_timer;
 
@@ -209,13 +200,11 @@ static struct timer_list poll_timer;
 		  PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
 
 /* These definitions must match the pcic table! */
-#ifdef CONFIG_ISA
 typedef enum pcic_id {
     IS_I82365A, IS_I82365B, IS_I82365DF,
     IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
     IS_PD6710, IS_PD672X, IS_VT83C469,
 } pcic_id;
-#endif
 
 /* Flags for classifying groups of controllers */
 #define IS_VADEM	0x0001
@@ -237,7 +226,6 @@ typedef struct pcic_t {
 } pcic_t;
 
 static pcic_t pcic[] = {
-#ifdef CONFIG_ISA
     { "Intel i82365sl A step", 0 },
     { "Intel i82365sl B step", 0 },
     { "Intel i82365sl DF", IS_DF_PWR },
@@ -249,7 +237,6 @@ static pcic_t pcic[] = {
     { "Cirrus PD6710", IS_CIRRUS },
     { "Cirrus PD672x", IS_CIRRUS },
     { "VIA VT83C469", IS_CIRRUS|IS_VIA },
-#endif
 };
 
 #define PCIC_COUNT	(sizeof(pcic)/sizeof(pcic_t))
@@ -364,7 +351,7 @@ static void cirrus_set_state(u_short s)
 
 static u_int __init cirrus_set_opts(u_short s, char *buf)
 {
-    socket_info_t *t = &socket[s];
+    struct i82365_socket *t = &socket[s];
     cirrus_state_t *p = &socket[s].state.cirrus;
     u_int mask = 0xffff;
 
@@ -421,8 +408,6 @@ static u_int __init cirrus_set_opts(u_short s, char *buf)
     
 ======================================================================*/
 
-#ifdef CONFIG_ISA
-
 static void vg46x_get_state(u_short s)
 {
     vg46x_state_t *p = &socket[s].state.vg46x;
@@ -464,9 +449,6 @@ static u_int __init vg46x_set_opts(u_short s, char *buf)
     return 0xffff;
 }
 
-#endif
-
-
 /*======================================================================
 
     Generic routines to get and set controller options
@@ -475,18 +457,16 @@ static u_int __init vg46x_set_opts(u_short s, char *buf)
 
 static void get_bridge_state(u_short s)
 {
-    socket_info_t *t = &socket[s];
+    struct i82365_socket *t = &socket[s];
     if (t->flags & IS_CIRRUS)
 	cirrus_get_state(s);
-#ifdef CONFIG_ISA
     else if (t->flags & IS_VADEM)
 	vg46x_get_state(s);
-#endif
 }
 
 static void set_bridge_state(u_short s)
 {
-    socket_info_t *t = &socket[s];
+    struct i82365_socket *t = &socket[s];
     if (t->flags & IS_CIRRUS)
 	cirrus_set_state(s);
     else {
@@ -494,10 +474,8 @@ static void set_bridge_state(u_short s)
 	i365_set(s, I365_GENCTL, 0x00);
     }
     i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr);
-#ifdef CONFIG_ISA
     if (t->flags & IS_VADEM)
 	vg46x_set_state(s);
-#endif
 }
 
 static u_int __init set_bridge_opts(u_short s, u_short ns)
@@ -515,10 +493,8 @@ static u_int __init set_bridge_opts(u_short s, u_short ns)
 	get_bridge_state(i);
 	if (socket[i].flags & IS_CIRRUS)
 	    m = cirrus_set_opts(i, buf);
-#ifdef CONFIG_ISA
 	else if (socket[i].flags & IS_VADEM)
 	    m = vg46x_set_opts(i, buf);
-#endif
 	set_bridge_state(i);
 	printk(KERN_INFO "    host opts [%d]:%s\n", i,
 	       (*buf) ? buf : " none");
@@ -571,7 +547,6 @@ static u_int __init test_irq(u_short sock, int irq)
     return (irq_hits != 1);
 }
 
-#ifdef CONFIG_ISA
 
 static u_int __init isa_scan(u_short sock, u_int mask0)
 {
@@ -617,7 +592,6 @@ static u_int __init isa_scan(u_short sock, u_int mask0)
     return mask1;
 }
 
-#endif /* CONFIG_ISA */
 
 /*====================================================================*/
 
@@ -630,7 +604,6 @@ static int to_cycles(int ns)
 
 /*====================================================================*/
 
-#ifdef CONFIG_ISA
 
 static int __init identify(u_short port, u_short sock)
 {
@@ -691,8 +664,6 @@ static int __init identify(u_short port, u_short sock)
     return type;
 } /* identify */
 
-#endif
-
 /*======================================================================
 
     See if a card is present, powered up, in IO mode, and already
@@ -737,7 +708,7 @@ static void __init add_pcic(int ns, int type)
 {
     u_int mask = 0, i, base;
     int use_pci = 0, isa_irq = 0;
-    socket_info_t *t = &socket[sockets-ns];
+    struct i82365_socket *t = &socket[sockets-ns];
 
     base = sockets-ns;
     if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365");
@@ -748,23 +719,17 @@ static void __init add_pcic(int ns, int type)
 	       t->ioaddr, t->psock*0x40);
     printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
 
-#ifdef CONFIG_ISA
     /* Set host options, build basic interrupt mask */
     if (irq_list[0] == -1)
 	mask = irq_mask;
     else
 	for (i = mask = 0; i < 16; i++)
 	    mask |= (1<<irq_list[i]);
-#endif
     mask &= I365_MASK & set_bridge_opts(base, ns);
-#ifdef CONFIG_ISA
     /* Scan for ISA interrupts */
     mask = isa_scan(base, mask);
-#else
     printk(KERN_INFO "    PCI card interrupts,");
-#endif
         
-#ifdef CONFIG_ISA
     /* Poll if only two interrupts available */
     if (!use_pci && !poll_interval) {
 	u_int tmp = (mask & 0xff20);
@@ -786,7 +751,6 @@ static void __init add_pcic(int ns, int type)
 	    printk(" status change on irq %d\n", cs_irq);
 	}
     }
-#endif
     
     if (!use_pci && !isa_irq) {
 	if (poll_interval == 0)
@@ -809,7 +773,6 @@ static void __init add_pcic(int ns, int type)
 
 /*====================================================================*/
 
-#ifdef CONFIG_ISA
 
 #ifdef CONFIG_PNP
 static struct isapnp_device_id id_table[] __initdata = {
@@ -902,7 +865,6 @@ static void __init isa_probe(void)
     }
 }
 
-#endif
 
 /*====================================================================*/
 
@@ -940,9 +902,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev,
 {
     int i, j, csc;
     u_int events, active;
-#ifdef CONFIG_ISA
     u_long flags = 0;
-#endif
     int handled = 0;
 
     DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq);
@@ -1013,8 +973,9 @@ static void pcic_interrupt_wrapper(u_long data)
 
 /*====================================================================*/
 
-static int pcic_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
+static int pcic_register_callback(struct pcmcia_socket *s, void (*handler)(void *, unsigned int), void * info)
 {
+    unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
     socket[sock].handler = handler;
     socket[sock].info = info;
     return 0;
@@ -1022,8 +983,9 @@ static int pcic_register_callback(unsigned int sock, void (*handler)(void *, uns
 
 /*====================================================================*/
 
-static int pcic_inquire_socket(unsigned int sock, socket_cap_t *cap)
+static int pcic_inquire_socket(struct pcmcia_socket *s, socket_cap_t *cap)
 {
+    unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
     *cap = socket[sock].cap;
     return 0;
 } /* pcic_inquire_socket */
@@ -1048,7 +1010,6 @@ static int i365_get_status(u_short sock, u_int *value)
     *value |= (status & I365_CS_READY) ? SS_READY : 0;
     *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
 
-#ifdef CONFIG_ISA
     if (socket[sock].type == IS_VG469) {
 	status = i365_get(sock, VG469_VSENSE);
 	if (socket[sock].psock & 1) {
@@ -1059,7 +1020,6 @@ static int i365_get_status(u_short sock, u_int *value)
 	    *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
 	}
     }
-#endif
     
     DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", sock, *value);
     return 0;
@@ -1069,7 +1029,7 @@ static int i365_get_status(u_short sock, u_int *value)
 
 static int i365_get_socket(u_short sock, socket_state_t *state)
 {
-    socket_info_t *t = &socket[sock];
+    struct i82365_socket *t = &socket[sock];
     u_char reg, vcc, vpp;
     
     reg = i365_get(sock, I365_POWER);
@@ -1141,7 +1101,7 @@ static int i365_get_socket(u_short sock, socket_state_t *state)
 
 static int i365_set_socket(u_short sock, socket_state_t *state)
 {
-    socket_info_t *t = &socket[sock];
+    struct i82365_socket *t = &socket[sock];
     u_char reg;
     
     DEBUG(1, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
@@ -1337,7 +1297,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
 static int proc_read_info(char *buf, char **start, off_t pos,
 			  int count, int *eof, void *data)
 {
-    socket_info_t *s = data;
+    struct i82365_socket *s = data;
     char *p = buf;
     p += sprintf(p, "type:     %s\npsock:    %d\n",
 		 pcic[s->type].name, s->psock);
@@ -1347,13 +1307,11 @@ static int proc_read_info(char *buf, char **start, off_t pos,
 static int proc_read_exca(char *buf, char **start, off_t pos,
 			  int count, int *eof, void *data)
 {
-    u_short sock = (socket_info_t *)data - socket;
+    u_short sock = (struct i82365_socket *)data - socket;
     char *p = buf;
     int i, top;
     
-#ifdef CONFIG_ISA
     u_long flags = 0;
-#endif
     ISA_LOCK(sock, flags);
     top = 0x40;
     for (i = 0; i < top; i += 4) {
@@ -1370,9 +1328,9 @@ static int proc_read_exca(char *buf, char **start, off_t pos,
     return (p - buf);
 }
 
-static void pcic_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+static void pcic_proc_setup(struct pcmcia_socket *sock, struct proc_dir_entry *base)
 {
-    socket_info_t *s = &socket[sock];
+    struct i82365_socket *s = container_of(sock, struct i82365_socket, socket);
 
     if (s->flags & IS_ALIVE)
     	return;
@@ -1398,15 +1356,8 @@ static void pcic_proc_remove(u_short sock)
 
 /*====================================================================*/
 
-/*
- * The locking is rather broken. Why do we only lock for ISA, not for
- * all other cases? If there are reasons to lock, we should lock. Not
- * this silly conditional.
- *
- * Plan: make it bug-for-bug compatible with the old stuff, and clean
- * it up when the infrastructure is done.
- */
-#ifdef CONFIG_ISA
+/* this is horribly ugly... proper locking needs to be done here at 
+ * some time... */
 #define LOCKED(x) do { \
 	int retval; \
 	unsigned long flags; \
@@ -1415,13 +1366,12 @@ static void pcic_proc_remove(u_short sock)
 	spin_unlock_irqrestore(&isa_lock, flags); \
 	return retval; \
 } while (0)
-#else
-#define LOCKED(x) return x
-#endif
 	
 
-static int pcic_get_status(unsigned int sock, u_int *value)
+static int pcic_get_status(struct pcmcia_socket *s, u_int *value)
 {
+	unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
+
 	if (socket[sock].flags & IS_ALIVE) {
 		*value = 0;
 		return -EINVAL;
@@ -1430,39 +1380,45 @@ static int pcic_get_status(unsigned int sock, u_int *value)
 	LOCKED(i365_get_status(sock, value));
 }
 
-static int pcic_get_socket(unsigned int sock, socket_state_t *state)
+static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
+	unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
+
 	if (socket[sock].flags & IS_ALIVE)
 		return -EINVAL;
 
 	LOCKED(i365_get_socket(sock, state));
 }
 
-static int pcic_set_socket(unsigned int sock, socket_state_t *state)
+static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
+	unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
+
 	if (socket[sock].flags & IS_ALIVE)
 		return -EINVAL;
 
 	LOCKED(i365_set_socket(sock, state));
 }
 
-static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io)
+static int pcic_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
 {
+	unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
 	if (socket[sock].flags & IS_ALIVE)
 		return -EINVAL;
 
 	LOCKED(i365_set_io_map(sock, io));
 }
 
-static int pcic_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
+static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
 {
+	unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
 	if (socket[sock].flags & IS_ALIVE)
 		return -EINVAL;
 
 	LOCKED(i365_set_mem_map(sock, mem));
 }
 
-static int pcic_init(unsigned int s)
+static int pcic_init(struct pcmcia_socket *s)
 {
 	int i;
 	pccard_io_map io = { 0, 0, 0, 0, 1 };
@@ -1481,7 +1437,7 @@ static int pcic_init(unsigned int s)
 	return 0;
 }
 
-static int pcic_suspend(unsigned int sock)
+static int pcic_suspend(struct pcmcia_socket *sock)
 {
 	return pcic_set_socket(sock, &dead_socket);
 }
@@ -1502,15 +1458,11 @@ static struct pccard_operations pcic_operations = {
 
 /*====================================================================*/
 
-static struct pcmcia_socket_class_data i82365_data = {
-	.ops = &pcic_operations,
-};
-
 static struct device_driver i82365_driver = {
 	.name = "i82365",
 	.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 i82365_device = {
@@ -1521,13 +1473,11 @@ static struct platform_device i82365_device = {
 	},
 };
 
-static struct class_device i82365_class_data = {
-	.class = &pcmcia_socket_class,
-};
-
 static int __init init_i82365(void)
 {
     servinfo_t serv;
+    int i, ret;
+
     pcmcia_get_card_services_info(&serv);
     if (serv.Revision != CS_RELEASE_CODE) {
 	printk(KERN_NOTICE "i82365: Card Services release "
@@ -1541,9 +1491,7 @@ static int __init init_i82365(void)
     printk(KERN_INFO "Intel PCIC probe: ");
     sockets = 0;
 
-#ifdef CONFIG_ISA
     isa_probe();
-#endif
 
     if (sockets == 0) {
 	printk("not found.\n");
@@ -1551,19 +1499,24 @@ static int __init init_i82365(void)
 	return -ENODEV;
     }
 
+    platform_device_register(&i82365_device);
+
     /* Set up interrupt handler(s) */
-#ifdef CONFIG_ISA
     if (grab_irq != 0)
 	request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
-#endif
     
-    i82365_data.nsock = sockets;
-    i82365_class_data.dev = &i82365_device.dev;
-    i82365_class_data.class_data = &i82365_data;
-    strlcpy(i82365_class_data.class_id, "i82365", BUS_ID_SIZE);
-    
-    platform_device_register(&i82365_device);
-    class_device_register(&i82365_class_data);
+    /* register sockets with the pcmcia core */
+    for (i = 0; i < sockets; i++) {
+	    socket[i].socket.dev.dev = &i82365_device.dev;
+	    socket[i].socket.ss_entry = &pcic_operations;
+	    socket[i].number = i;
+	    ret = pcmcia_register_socket(&socket[i].socket);	    
+	    if (ret && i--) {
+		    for (; i>= 0; i--)
+			    pcmcia_unregister_socket(&socket[i].socket);
+		    break;
+	    }
+    }
 
     /* Finally, schedule a polling interrupt */
     if (poll_interval != 0) {
@@ -1581,23 +1534,23 @@ static int __init init_i82365(void)
 static void __exit exit_i82365(void)
 {
     int i;
+    for (i = 0; i < sockets; i++) {
+	    pcmcia_unregister_socket(&socket[i].socket);
 #ifdef CONFIG_PROC_FS
-    for (i = 0; i < sockets; i++) pcic_proc_remove(i);
+	    pcic_proc_remove(i);
 #endif
-    class_device_unregister(&i82365_class_data);
+    }
     platform_device_unregister(&i82365_device);
     if (poll_interval != 0)
 	del_timer_sync(&poll_timer);
-#ifdef CONFIG_ISA
     if (grab_irq != 0)
 	free_irq(cs_irq, pcic_interrupt);
-#endif
     for (i = 0; i < sockets; i++) {
 	/* Turn off all interrupt sources! */
 	i365_set(i, I365_CSCINT, 0);
 	release_region(socket[i].ioaddr, 2);
     }
-#if defined(CONFIG_ISA) && defined(__ISAPNP__)
+#ifdef __ISAPNP__
     if (i82365_pnpdev)
     		pnp_disable_dev(i82365_pnpdev);
 #endif
diff --git a/drivers/pcmcia/pci_socket.c b/drivers/pcmcia/pci_socket.c
deleted file mode 100644
index 915a6af9facab1feacfb81497a1bb28c7cd034e1..0000000000000000000000000000000000000000
--- a/drivers/pcmcia/pci_socket.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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);
diff --git a/drivers/pcmcia/pci_socket.h b/drivers/pcmcia/pci_socket.h
deleted file mode 100644
index 206eddd05c11a7976885c98f651974dfae0f5f35..0000000000000000000000000000000000000000
--- a/drivers/pcmcia/pci_socket.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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
diff --git a/drivers/pcmcia/ricoh.h b/drivers/pcmcia/ricoh.h
index 14573f8d3646eae1f5be429318efd85a4edd1994..a36f2f339d4245f6686e523c06fcbff43256d809 100644
--- a/drivers/pcmcia/ricoh.h
+++ b/drivers/pcmcia/ricoh.h
@@ -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 */
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index 36e15cfdd73c42e698745bdaa797c33a3376e41b..9d962c2c1545b6bb69ce5fd455eed89ba5e2ec40 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -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:
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 6ddba61ba2d843b40312590c45494222329ed6b4..dee5cdcf82d72a68510f1ae1831e20c8ad6964ec 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -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);
 }
 
diff --git a/drivers/pcmcia/sa11xx_core.c b/drivers/pcmcia/sa11xx_core.c
index 102203779a22f16c20784b77f15388b1e22d683d..cfe9b4e2368e746a62caeef54fbc26133f1af19b 100644
--- a/drivers/pcmcia/sa11xx_core.c
+++ b/drivers/pcmcia/sa11xx_core.c
@@ -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);
 	}
 }
 
diff --git a/drivers/pcmcia/sa11xx_core.h b/drivers/pcmcia/sa11xx_core.h
index 570491f2d96de211a8137e9ff8d8f6f7c324abf7..210228ddf75285c4d5404981e5426eab9b28d7a2 100644
--- a/drivers/pcmcia/sa11xx_core.h
+++ b/drivers/pcmcia/sa11xx_core.h
@@ -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
 	 */
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index b85d5c8468d6018a6754de718c732a1a52394cd9..648d38c57583295cecbbb6b286c7359bb7bd8143 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -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);
 }
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 353cc02b81819a965775f8387649ea8205eb3881..4e3a3768b22f5dec1b5f242b52e8439e193291cf 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -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 */
 
diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c
index 2a3a49d0b72f940d55a88ffea7afb899de4a6292..67eabeb40090943b87a999bd32f123859599ccb1 100644
--- a/drivers/pcmcia/yenta.c
+++ b/drivers/pcmcia/yenta.c
@@ -1,5 +1,5 @@
 /*
- * Regular lowlevel cardbus driver ("yenta")
+ * Regular cardbus driver ("yenta")
  *
  * (C) Copyright 1999, 2000 Linus Torvalds
  *
@@ -7,6 +7,8 @@
  * Aug 2002: Manfred Spraul <manfred@colorfullife.com>
  * 	Dynamically adjust the size of the bridge resource
  * 	
+ * May 2003: Dominik Brodowski <linux@brodo.de>
+ * 	Merge pci_socket.c and yenta.c into one file
  */
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -26,6 +28,7 @@
 #include "yenta.h"
 #include "i82365.h"
 
+
 #if 0
 #define DEBUG(x,args...)	printk("%s: " x, __FUNCTION__, ##args)
 #else
@@ -41,20 +44,20 @@
  * regular memory space ("cb_xxx"), configuration space
  * ("config_xxx") and compatibility space ("exca_xxxx")
  */
-static inline u32 cb_readl(pci_socket_t *socket, unsigned reg)
+static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
 {
 	u32 val = readl(socket->base + reg);
 	DEBUG("%p %04x %08x\n", socket, reg, val);
 	return val;
 }
 
-static inline void cb_writel(pci_socket_t *socket, unsigned reg, u32 val)
+static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
 {
 	DEBUG("%p %04x %08x\n", socket, reg, val);
 	writel(val, socket->base + reg);
 }
 
-static inline u8 config_readb(pci_socket_t *socket, unsigned offset)
+static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
 {
 	u8 val;
 	pci_read_config_byte(socket->dev, offset, &val);
@@ -62,7 +65,7 @@ static inline u8 config_readb(pci_socket_t *socket, unsigned offset)
 	return val;
 }
 
-static inline u16 config_readw(pci_socket_t *socket, unsigned offset)
+static inline u16 config_readw(struct yenta_socket *socket, unsigned offset)
 {
 	u16 val;
 	pci_read_config_word(socket->dev, offset, &val);
@@ -70,7 +73,7 @@ static inline u16 config_readw(pci_socket_t *socket, unsigned offset)
 	return val;
 }
 
-static inline u32 config_readl(pci_socket_t *socket, unsigned offset)
+static inline u32 config_readl(struct yenta_socket *socket, unsigned offset)
 {
 	u32 val;
 	pci_read_config_dword(socket->dev, offset, &val);
@@ -78,32 +81,32 @@ static inline u32 config_readl(pci_socket_t *socket, unsigned offset)
 	return val;
 }
 
-static inline void config_writeb(pci_socket_t *socket, unsigned offset, u8 val)
+static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
 {
 	DEBUG("%p %04x %02x\n", socket, offset, val);
 	pci_write_config_byte(socket->dev, offset, val);
 }
 
-static inline void config_writew(pci_socket_t *socket, unsigned offset, u16 val)
+static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
 {
 	DEBUG("%p %04x %04x\n", socket, offset, val);
 	pci_write_config_word(socket->dev, offset, val);
 }
 
-static inline void config_writel(pci_socket_t *socket, unsigned offset, u32 val)
+static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
 {
 	DEBUG("%p %04x %08x\n", socket, offset, val);
 	pci_write_config_dword(socket->dev, offset, val);
 }
 
-static inline u8 exca_readb(pci_socket_t *socket, unsigned reg)
+static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
 {
 	u8 val = readb(socket->base + 0x800 + reg);
 	DEBUG("%p %04x %02x\n", socket, reg, val);
 	return val;
 }
 
-static inline u8 exca_readw(pci_socket_t *socket, unsigned reg)
+static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg)
 {
 	u16 val;
 	val = readb(socket->base + 0x800 + reg);
@@ -112,13 +115,13 @@ static inline u8 exca_readw(pci_socket_t *socket, unsigned reg)
 	return val;
 }
 
-static inline void exca_writeb(pci_socket_t *socket, unsigned reg, u8 val)
+static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
 {
 	DEBUG("%p %04x %02x\n", socket, reg, val);
 	writeb(val, socket->base + 0x800 + reg);
 }
 
-static void exca_writew(pci_socket_t *socket, unsigned reg, u16 val)
+static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
 {
 	DEBUG("%p %04x %04x\n", socket, reg, val);
 	writeb(val, socket->base + 0x800 + reg);
@@ -129,8 +132,9 @@ static void exca_writew(pci_socket_t *socket, unsigned reg, u16 val)
  * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
  * on what kind of card is inserted..
  */
-static int yenta_get_status(pci_socket_t *socket, unsigned int *value)
+static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
 {
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
 	unsigned int val;
 	u32 state = cb_readl(socket, CB_SOCKET_STATE);
 
@@ -181,8 +185,9 @@ static int yenta_Vpp_power(u32 control)
 	}
 }
 
-static int yenta_get_socket(pci_socket_t *socket, socket_state_t *state)
+static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
 	u8 reg;
 	u32 control;
 
@@ -221,7 +226,7 @@ static int yenta_get_socket(pci_socket_t *socket, socket_state_t *state)
 	return 0;
 }
 
-static void yenta_set_power(pci_socket_t *socket, socket_state_t *state)
+static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)
 {
 	u32 reg = 0;	/* CB_SC_STPCLK? */
 	switch (state->Vcc) {
@@ -238,8 +243,9 @@ static void yenta_set_power(pci_socket_t *socket, socket_state_t *state)
 		cb_writel(socket, CB_SOCKET_CONTROL, reg);
 }
 
-static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state)
+static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
 	u16 bridge;
 
 	if (state->flags & SS_DEBOUNCED) {
@@ -300,8 +306,9 @@ static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state)
 	return 0;
 }
 
-static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io)
+static int yenta_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
 {
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
 	int map;
 	unsigned char ioctl, addr, enable;
 
@@ -333,8 +340,9 @@ static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io)
 	return 0;
 }
 
-static int yenta_set_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem)
+static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
 {
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
 	int map;
 	unsigned char addr, enable;
 	unsigned int start, stop, card_start;
@@ -386,12 +394,12 @@ static int yenta_set_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem)
 	return 0;
 }
 
-static void yenta_proc_setup(pci_socket_t *socket, struct proc_dir_entry *base)
+static void yenta_proc_setup(struct pcmcia_socket *sock, struct proc_dir_entry *base)
 {
 	/* Not done yet */
 }
 
-static unsigned int yenta_events(pci_socket_t *socket)
+static unsigned int yenta_events(struct yenta_socket *socket)
 {
 	u8 csc;
 	u32 cb_event;
@@ -418,7 +426,7 @@ static unsigned int yenta_events(pci_socket_t *socket)
 
 static void yenta_bh(void *data)
 {
-	pci_socket_t *socket = data;
+	struct yenta_socket *socket = data;
 	unsigned int events;
 
 	spin_lock_irq(&socket->event_lock);
@@ -432,7 +440,7 @@ static void yenta_bh(void *data)
 static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned int events;
-	pci_socket_t *socket = (pci_socket_t *) dev_id;
+	struct yenta_socket *socket = (struct yenta_socket *) dev_id;
 
 	events = yenta_events(socket);
 	if (events) {
@@ -447,7 +455,7 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static void yenta_interrupt_wrapper(unsigned long data)
 {
-	pci_socket_t *socket = (pci_socket_t *) data;
+	struct yenta_socket *socket = (struct yenta_socket *) data;
 
 	yenta_interrupt(0, (void *)socket, NULL);
 	socket->poll_timer.expires = jiffies + HZ;
@@ -465,7 +473,7 @@ static void yenta_interrupt_wrapper(unsigned long data)
  */
 static u32 isa_interrupts = 0x0ef8;
 
-static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask)
+static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
 {
 	int i;
 	unsigned long val;
@@ -509,7 +517,7 @@ static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask)
 /*
  * Set static data that doesn't need re-initializing..
  */
-static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask)
+static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
 {
 	socket->cap.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
 	socket->cap.map_size = 0x1000;
@@ -520,28 +528,38 @@ static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask
 	printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq);
 }
 
-static void yenta_clear_maps(pci_socket_t *socket)
+static int yenta_inquire_socket(struct pcmcia_socket *sock, socket_cap_t *cap)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+
+	*cap = socket->cap;
+
+	return 0;
+}
+
+
+static void yenta_clear_maps(struct yenta_socket *socket)
 {
 	int i;
 	pccard_io_map io = { 0, 0, 0, 0, 1 };
 	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
 
 	mem.sys_stop = 0x0fff;
-	yenta_set_socket(socket, &dead_socket);
+	yenta_set_socket(&socket->socket, &dead_socket);
 	for (i = 0; i < 2; i++) {
 		io.map = i;
-		yenta_set_io_map(socket, &io);
+		yenta_set_io_map(&socket->socket, &io);
 	}
 	for (i = 0; i < 5; i++) {
 		mem.map = i;
-		yenta_set_mem_map(socket, &mem);
+		yenta_set_mem_map(&socket->socket, &mem);
 	}
 }
 
 /*
  * Initialize the standard cardbus registers
  */
-static void yenta_config_init(pci_socket_t *socket)
+static void yenta_config_init(struct yenta_socket *socket)
 {
 	u16 bridge;
 	struct pci_dev *dev = socket->dev;
@@ -586,8 +604,9 @@ static void yenta_config_init(pci_socket_t *socket)
 }
 
 /* Called at resume and initialization events */
-static int yenta_init(pci_socket_t *socket)
+static int yenta_init(struct pcmcia_socket *sock)
 {
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
 	yenta_config_init(socket);
 	yenta_clear_maps(socket);
 
@@ -596,9 +615,11 @@ static int yenta_init(pci_socket_t *socket)
 	return 0;
 }
 
-static int yenta_suspend(pci_socket_t *socket)
+static int yenta_suspend(struct pcmcia_socket *sock)
 {
-	yenta_set_socket(socket, &dead_socket);
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+
+	yenta_set_socket(sock, &dead_socket);
 
 	/* Disable interrupts */
 	cb_writel(socket, CB_SOCKET_MASK, 0x0);
@@ -630,7 +651,7 @@ static int yenta_suspend(pci_socket_t *socket)
 #define BRIDGE_IO_MAX 256
 #define BRIDGE_IO_MIN 32
 
-static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type)
+static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
 {
 	struct pci_bus *bus;
 	struct resource *root, *res;
@@ -711,7 +732,7 @@ static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type)
 /*
  * Allocate the bridge mappings for the device..
  */
-static void yenta_allocate_resources(pci_socket_t *socket)
+static void yenta_allocate_resources(struct yenta_socket *socket)
 {
 	yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
 	yenta_allocate_res(socket, 1, IORESOURCE_MEM);
@@ -719,10 +740,11 @@ static void yenta_allocate_resources(pci_socket_t *socket)
 	yenta_allocate_res(socket, 3, IORESOURCE_IO);	/* PCI isn't clever enough to use this one yet */
 }
 
+
 /*
  * Free the bridge mappings for the device..
  */
-static void yenta_free_resources(pci_socket_t *socket)
+static void yenta_free_resources(struct yenta_socket *socket)
 {
 	int i;
 	for (i=0;i<4;i++) {
@@ -733,11 +755,15 @@ static void yenta_free_resources(pci_socket_t *socket)
 		res->start = res->end = 0;
 	}
 }
+
+
 /*
  * Close it down - release our resources and go home..
  */
-static void yenta_close(pci_socket_t *sock)
+static void yenta_close(struct pci_dev *dev)
 {
+	struct yenta_socket *sock = pci_get_drvdata(dev);
+
 	/* Disable all events so we don't die in an IRQ storm */
 	cb_writel(sock, CB_SOCKET_MASK, 0x0);
 	exca_writeb(sock, I365_CSCINT, 0);
@@ -750,8 +776,37 @@ static void yenta_close(pci_socket_t *sock)
 	if (sock->base)
 		iounmap(sock->base);
 	yenta_free_resources(sock);
+
+	pcmcia_unregister_socket(&sock->socket);
+	pci_set_drvdata(dev, NULL);
 }
 
+
+static int yenta_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+
+	socket->handler = handler;
+	socket->info = info;
+	return 0;
+}
+
+
+static struct pccard_operations yenta_socket_operations = {
+	.owner			= THIS_MODULE,
+	.init			= yenta_init,
+	.suspend		= yenta_suspend,
+	.register_callback	= yenta_register_callback,
+	.inquire_socket		= yenta_inquire_socket,
+	.get_status		= yenta_get_status,
+	.get_socket		= yenta_get_socket,
+	.set_socket		= yenta_set_socket,
+	.set_io_map		= yenta_set_io_map,
+	.set_mem_map		= yenta_set_mem_map,
+	.proc_setup		= yenta_proc_setup,
+};
+
+
 #include "ti113x.h"
 #include "ricoh.h"
 
@@ -760,49 +815,62 @@ static void yenta_close(pci_socket_t *sock)
  * initialization sequences etc details. List them here..
  */
 #define PD(x,y) PCI_VENDOR_ID_##x, PCI_DEVICE_ID_##x##_##y
-static struct cardbus_override_struct {
+struct cardbus_override_struct {
 	unsigned short vendor;
 	unsigned short device;
-	struct pci_socket_ops *op;
+	int (*override) (struct yenta_socket *socket);
 } cardbus_override[] = {
-	{ PD(TI,1130),	&ti113x_ops },
-	{ PD(TI,1031),	&ti_ops },
-	{ PD(TI,1131),	&ti113x_ops },
-	{ PD(TI,1250),	&ti1250_ops },
-	{ PD(TI,1220),	&ti_ops },
-	{ PD(TI,1221),	&ti_ops },
-	{ PD(TI,1210),	&ti_ops },
-	{ PD(TI,1450),	&ti_ops },
-	{ PD(TI,1225),	&ti_ops },
-	{ PD(TI,1251A),	&ti_ops },
-	{ PD(TI,1211),	&ti_ops },
-	{ PD(TI,1251B),	&ti_ops },
-	{ PD(TI,1410),	&ti1250_ops },
-	{ PD(TI,1420),	&ti_ops },
-	{ PD(TI,4410),	&ti_ops },
-	{ PD(TI,4451),	&ti_ops },
-
-	{ PD(RICOH,RL5C465), &ricoh_ops },
-	{ PD(RICOH,RL5C466), &ricoh_ops },
-	{ PD(RICOH,RL5C475), &ricoh_ops },
-	{ PD(RICOH,RL5C476), &ricoh_ops },
-	{ PD(RICOH,RL5C478), &ricoh_ops }
+	{ PD(TI,1130),	&ti113x_override },
+	{ PD(TI,1031),	&ti_override },
+	{ PD(TI,1131),	&ti113x_override },
+	{ PD(TI,1250),	&ti1250_override },
+	{ PD(TI,1220),	&ti_override },
+	{ PD(TI,1221),	&ti_override },
+	{ PD(TI,1210),	&ti_override },
+	{ PD(TI,1450),	&ti_override },
+	{ PD(TI,1225),	&ti_override },
+	{ PD(TI,1251A),	&ti_override },
+	{ PD(TI,1211),	&ti_override },
+	{ PD(TI,1251B),	&ti_override },
+	{ PD(TI,1410),	ti1250_override },
+	{ PD(TI,1420),	&ti_override },
+	{ PD(TI,4410),	&ti_override },
+	{ PD(TI,4451),	&ti_override },
+
+	{ PD(RICOH,RL5C465), &ricoh_override },
+	{ PD(RICOH,RL5C466), &ricoh_override },
+	{ PD(RICOH,RL5C475), &ricoh_override },
+	{ PD(RICOH,RL5C476), &ricoh_override },
+	{ PD(RICOH,RL5C478), &ricoh_override },
+
+	{ }, /* all zeroes */
 };
 
-#define NR_OVERRIDES (sizeof(cardbus_override)/sizeof(struct cardbus_override_struct))
-
-
-extern int cardbus_register(struct pci_dev *p_dev);
 
 /*
  * Initialize a cardbus controller. Make sure we have a usable
  * interrupt, and that we can map the cardbus area. Fill in the
  * socket information structure..
  */
-static int yenta_open(pci_socket_t *socket)
+static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id)
 {
-	int i;
-	struct pci_dev *dev = socket->dev;
+	struct yenta_socket *socket;
+	struct cardbus_override_struct *d;
+	
+	socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
+	if (!socket)
+		return -ENOMEM;
+	memset(socket, 0, sizeof(*socket));
+
+	/* prepare pcmcia_socket */
+	socket->socket.ss_entry = &yenta_socket_operations;
+	socket->socket.dev.dev = &dev->dev;
+	socket->socket.driver_data = socket;
+
+	/* prepare struct yenta_socket */
+	socket->dev = dev;
+	pci_set_drvdata(dev, socket);
+	spin_lock_init(&socket->event_lock);
 
 	/*
 	 * Do some basic sanity checking..
@@ -833,16 +901,14 @@ static int yenta_open(pci_socket_t *socket)
 	socket->cb_irq = dev->irq;
 
 	/* Do we have special options for the device? */
-	for (i = 0; i < NR_OVERRIDES; i++) {
-		struct cardbus_override_struct *d = cardbus_override+i;
-		if (dev->vendor == d->vendor && dev->device == d->device) {
-			socket->op = d->op;
-			if (d->op->open) {
-				int retval = d->op->open(socket);
-				if (retval < 0)
-					return retval;
-			}
+	d = cardbus_override;
+	while (d->override) {
+		if ((dev->vendor == d->vendor) && (dev->device == d->device)) {
+			int retval = d->override(socket);
+			if (retval < 0)
+				return retval;
 		}
+		d++;
 	}
 
 	/* We must finish initialization here */
@@ -864,23 +930,58 @@ static int yenta_open(pci_socket_t *socket)
 	printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
 
 	/* Register it with the pcmcia layer.. */
-	return cardbus_register(dev);
+	return pcmcia_register_socket(&socket->socket);
 }
 
-/*
- * Standard plain cardbus - no frills, no extensions
- */
-struct pci_socket_ops yenta_operations = {
-	yenta_open,
-	yenta_close,
-	yenta_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 yenta_dev_suspend (struct pci_dev *dev, u32 state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
+}
+
+
+static int yenta_dev_resume (struct pci_dev *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
+}
+
+
+static struct pci_device_id yenta_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 */ }
 };
-EXPORT_SYMBOL(yenta_operations);
+MODULE_DEVICE_TABLE(pci, yenta_table);
+
+
+static struct pci_driver yenta_cardbus_driver = {
+	.name		= "yenta_cardbus",
+	.id_table	= yenta_table,
+	.probe		= yenta_probe,
+	.remove		= __devexit_p(yenta_close),
+	.suspend	= yenta_dev_suspend,
+	.resume		= yenta_dev_resume,
+};
+
+
+static int __init yenta_socket_init(void)
+{
+	return pci_register_driver (&yenta_cardbus_driver);
+}
+
+
+static void __exit yenta_socket_exit (void)
+{
+	pci_unregister_driver (&yenta_cardbus_driver);
+}
+
+
+module_init(yenta_socket_init);
+module_exit(yenta_socket_exit);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/yenta.h b/drivers/pcmcia/yenta.h
index c8d61c4093c7b9395cf39e6efacaff94f0502cfb..9c5c0a35df6aabaa6fa723e5f7c37e70e03597bc 100644
--- a/drivers/pcmcia/yenta.h
+++ b/drivers/pcmcia/yenta.h
@@ -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
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
index e29dfbb82a991be6d2e8e580f4c0a7ca0a85fde2..4e0f3cf69b354216dd83af3adf5e79d6ca106cb9 100644
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -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;
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 2a3917ce1814146d66f73612ab32f443784c7c4c..f69b5a8c4bb74bced63d9b9c3ae910b4c97826ee 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -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 */