[PATCH] pcmcia: unify yenta.c and pci_socket.c

Dominik Brodowski linux at brodo.de
Sun May 18 00:43:49 BST 2003


As discussed a few weeks ago with Linus, merge yenta.c and
pci_socket.c as the pcmcia core now passes a "struct pcmcia_socket" as
argument. Also, allow to build it as a module, and clean yenta.c up
some (typedefs etc.)

 Kconfig      |    9 +
 Makefile     |    6 -
 pci_socket.c |  242 -------------------------------------------------
 pci_socket.h |   48 ---------
 ricoh.h      |   43 +++-----
 ti113x.h     |  130 ++++++++++----------------
 yenta.c      |  289 +++++++++++++++++++++++++++++++++++++++--------------------
 yenta.h      |   20 +++-
 8 files changed, 288 insertions(+), 499 deletions(-)

diff -ruN linux-original/drivers/pcmcia/Kconfig linux/drivers/pcmcia/Kconfig
--- linux-original/drivers/pcmcia/Kconfig	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/Kconfig	2003-05-17 23:31:27.000000000 +0200
@@ -29,8 +29,8 @@
 	  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 @@
 
 	  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
diff -ruN linux-original/drivers/pcmcia/Makefile linux/drivers/pcmcia/Makefile
--- linux-original/drivers/pcmcia/Makefile	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/Makefile	2003-05-17 23:22:08.000000000 +0200
@@ -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_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 -ruN linux-original/drivers/pcmcia/pci_socket.c linux/drivers/pcmcia/pci_socket.c
--- linux-original/drivers/pcmcia/pci_socket.c	2003-05-17 23:13:38.000000000 +0200
+++ linux/drivers/pcmcia/pci_socket.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,242 +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(struct pcmcia_socket *sock)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	if (socket->op && socket->op->init)
-		return socket->op->init(socket);
-	return -EINVAL;
-}
-
-static int pci_suspend_socket(struct pcmcia_socket *sock)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	if (socket->op && socket->op->suspend)
-		return socket->op->suspend(socket);
-	return -EINVAL;
-}
-
-static int pci_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	socket->handler = handler;
-	socket->info = info;
-	return 0;
-}
-
-static int pci_inquire_socket(struct pcmcia_socket *sock, socket_cap_t *cap)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	*cap = socket->cap;
-	return 0;
-}
-
-static int pci_get_status(struct pcmcia_socket *sock, unsigned int *value)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	if (socket->op && socket->op->get_status)
-		return socket->op->get_status(socket, value);
-	*value = 0;
-	return -EINVAL;
-}
-
-static int pci_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	if (socket->op && socket->op->get_socket)
-		return socket->op->get_socket(socket, state);
-	return -EINVAL;
-}
-
-static int pci_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	if (socket->op && socket->op->set_socket)
-		return socket->op->set_socket(socket, state);
-	return -EINVAL;
-}
-
-static int pci_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	if (socket->op && socket->op->set_io_map)
-		return socket->op->set_io_map(socket, io);
-	return -EINVAL;
-}
-
-static int pci_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	if (socket->op && socket->op->set_mem_map)
-		return socket->op->set_mem_map(socket, mem);
-	return -EINVAL;
-}
-
-static void pci_proc_setup(struct pcmcia_socket *sock, struct proc_dir_entry *base)
-{
-	pci_socket_t *socket = container_of(sock, struct pci_socket, socket);
-
-	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 pcmcia_socket */
-	socket->socket.ops = &pci_socket_operations;
-	socket->socket.dev.dev = &dev->dev;
-	socket->socket.driver_data = socket;
-
-	/* 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 {
-		pcmcia_register_socket(&socket->socket);
-	}
-	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 */
-	if (socket->op && socket->op->close)
-		socket->op->close(socket);
-	pcmcia_unregister_socket(&socket->socket);
-	pci_set_drvdata(dev, NULL);
-}
-
-static int cardbus_suspend (struct pci_dev *dev, u32 state)
-{
-	return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
-}
-
-static int cardbus_resume (struct pci_dev *dev)
-{
-	return pcmcia_socket_dev_resume(&dev->dev, 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 -ruN linux-original/drivers/pcmcia/pci_socket.h linux/drivers/pcmcia/pci_socket.h
--- linux-original/drivers/pcmcia/pci_socket.h	2003-05-17 22:03:15.000000000 +0200
+++ linux/drivers/pcmcia/pci_socket.h	1970-01-01 01:00:00.000000000 +0100
@@ -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 socket;
-	/* 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 -ruN linux-original/drivers/pcmcia/ricoh.h linux/drivers/pcmcia/ricoh.h
--- linux-original/drivers/pcmcia/ricoh.h	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/ricoh.h	2003-05-17 23:26:16.000000000 +0200
@@ -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 @@
 		rl_config(socket) |= RL5C4XX_CONFIG_PREFETCH;
 	}
 
-	return 0;
-}
-
-static int ricoh_init(pci_socket_t *socket)
-{
-	yenta_init(socket);
+	socket->socket.ops->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 -ruN linux-original/drivers/pcmcia/ti113x.h linux/drivers/pcmcia/ti113x.h
--- linux-original/drivers/pcmcia/ti113x.h	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/ti113x.h	2003-05-17 23:26:16.000000000 +0200
@@ -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.ops->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 @@
 	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.ops->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 @@
 	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.ops->init = ti1250_init;
+	return 0;
+}
 
 #endif /* CONFIG_CARDBUS */
 
diff -ruN linux-original/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- linux-original/drivers/pcmcia/yenta.c	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/yenta.c	2003-05-17 23:26:16.000000000 +0200
@@ -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 at colorfullife.com>
  * 	Dynamically adjust the size of the bridge resource
  * 	
+ * May 2003: Dominik Brodowski <linux at 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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
  * 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_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 @@
 	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 @@
 		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 @@
 	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 @@
 	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 @@
 	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 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 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 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 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 @@
 /*
  * 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 @@
 	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 @@
 }
 
 /* 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 @@
 	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 @@
 #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 @@
 /*
  * 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 @@
 	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 @@
 		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 @@
 	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 @@
  * 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 }
-};
-
-#define NR_OVERRIDES (sizeof(cardbus_override)/sizeof(struct cardbus_override_struct))
+	{ 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 */
+};
 
-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.ops = &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 @@
 	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 @@
 	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 -ruN linux-original/drivers/pcmcia/yenta.h linux/drivers/pcmcia/yenta.h
--- linux-original/drivers/pcmcia/yenta.h	2003-05-17 18:27:21.000000000 +0200
+++ linux/drivers/pcmcia/yenta.h	2003-05-17 23:19:50.000000000 +0200
@@ -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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/linux-pcmcia/attachments/20030517/7b589b32/attachment.bin


More information about the linux-pcmcia mailing list