[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, ¥ta_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 = ¥ta_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 (¥ta_cardbus_driver);
+}
+
+
+static void __exit yenta_socket_exit (void)
+{
+ pci_unregister_driver (¥ta_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