Commit 03ecd4d4 authored by Russell King's avatar Russell King

[PCMCIA] Move socket initialisation to the quirk table.

This removes the horrible side effect where we modify the generic
yenta_socket_operations structure (which of course other sockets
may be using.)

We move the socket init quirks into our cardbus_type quirk
structure, and call it during the generic socket initialisation.
parent 32eb05b1
...@@ -142,27 +142,22 @@ static void ricoh_zoom_video(struct pcmcia_socket *sock, int onoff) ...@@ -142,27 +142,22 @@ static void ricoh_zoom_video(struct pcmcia_socket *sock, int onoff)
config_writeb(socket, RL5C4XX_MISC_CONTROL, reg); config_writeb(socket, RL5C4XX_MISC_CONTROL, reg);
} }
static void ricoh_set_zv(struct pcmcia_socket *sock) static void ricoh_set_zv(struct yenta_socket *socket)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
if(socket->dev->vendor == PCI_VENDOR_ID_RICOH) if(socket->dev->vendor == PCI_VENDOR_ID_RICOH)
{ {
switch(socket->dev->device) switch(socket->dev->device)
{ {
/* There may be more .. */ /* There may be more .. */
case PCI_DEVICE_ID_RICOH_RL5C478: case PCI_DEVICE_ID_RICOH_RL5C478:
sock->zoom_video = ricoh_zoom_video; socket->socket.zoom_video = ricoh_zoom_video;
break; break;
} }
} }
} }
static int ricoh_init(struct pcmcia_socket *sock) static int ricoh_init(struct yenta_socket *socket)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
ricoh_set_zv(sock);
config_writew(socket, RL5C4XX_MISC, rl_misc(socket)); config_writew(socket, RL5C4XX_MISC, rl_misc(socket));
config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(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_IO_0, rl_io(socket));
...@@ -194,7 +189,7 @@ static int ricoh_override(struct yenta_socket *socket) ...@@ -194,7 +189,7 @@ static int ricoh_override(struct yenta_socket *socket)
rl_config(socket) |= RL5C4XX_CONFIG_PREFETCH; rl_config(socket) |= RL5C4XX_CONFIG_PREFETCH;
} }
socket->socket.ops->init = ricoh_init; ricoh_set_zv(socket);
return 0; return 0;
} }
......
...@@ -136,6 +136,16 @@ ...@@ -136,6 +136,16 @@
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
/*
* Texas Instruments CardBus controller overrides.
*/
#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 ti_intctl(struct yenta_socket *socket) static int ti_intctl(struct yenta_socket *socket)
{ {
u8 new, reg = exca_readb(socket, I365_INTCTL); u8 new, reg = exca_readb(socket, I365_INTCTL);
...@@ -207,9 +217,8 @@ static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff) ...@@ -207,9 +217,8 @@ static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff)
config_writeb(socket, TI1250_MULTIMEDIA_CTL, reg); config_writeb(socket, TI1250_MULTIMEDIA_CTL, reg);
} }
static void ti_set_zv(struct pcmcia_socket *sock) static void ti_set_zv(struct yenta_socket *socket)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
if(socket->dev->vendor == PCI_VENDOR_ID_TI) if(socket->dev->vendor == PCI_VENDOR_ID_TI)
{ {
switch(socket->dev->device) switch(socket->dev->device)
...@@ -218,21 +227,18 @@ static void ti_set_zv(struct pcmcia_socket *sock) ...@@ -218,21 +227,18 @@ static void ti_set_zv(struct pcmcia_socket *sock)
case PCI_DEVICE_ID_TI_1220: case PCI_DEVICE_ID_TI_1220:
case PCI_DEVICE_ID_TI_1221: case PCI_DEVICE_ID_TI_1221:
case PCI_DEVICE_ID_TI_1225: case PCI_DEVICE_ID_TI_1225:
sock->zoom_video = ti_zoom_video; socket->socket.zoom_video = ti_zoom_video;
break; break;
case PCI_DEVICE_ID_TI_1250: case PCI_DEVICE_ID_TI_1250:
case PCI_DEVICE_ID_TI_1251A: case PCI_DEVICE_ID_TI_1251A:
case PCI_DEVICE_ID_TI_1251B: case PCI_DEVICE_ID_TI_1251B:
case PCI_DEVICE_ID_TI_1450: case PCI_DEVICE_ID_TI_1450:
sock->zoom_video = ti1250_zoom_video; socket->socket.zoom_video = ti1250_zoom_video;
} }
} }
} }
static int ti_init(struct pcmcia_socket *sock) static int ti_init(struct yenta_socket *socket)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
ti_set_zv(sock);
ti_intctl(socket); ti_intctl(socket);
return 0; return 0;
} }
...@@ -258,6 +264,8 @@ static int ti_override(struct yenta_socket *socket) ...@@ -258,6 +264,8 @@ static int ti_override(struct yenta_socket *socket)
if (new != reg) if (new != reg)
exca_writeb(socket, I365_INTCTL, new); exca_writeb(socket, I365_INTCTL, new);
ti_set_zv(socket);
#if 0 #if 0
/* /*
* If ISA interrupts don't work, then fall back to routing card * If ISA interrupts don't work, then fall back to routing card
...@@ -285,23 +293,11 @@ static int ti_override(struct yenta_socket *socket) ...@@ -285,23 +293,11 @@ static int ti_override(struct yenta_socket *socket)
} }
#endif #endif
socket->socket.ops->init = ti_init;
return 0; return 0;
} }
#define ti_sysctl(socket) ((socket)->private[0]) static int ti113x_init(struct yenta_socket *socket)
#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_init(struct pcmcia_socket *sock)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
ti_set_zv(sock);
config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket));
config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket)); config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket));
config_writeb(socket, TI113X_DEVICE_CONTROL, ti_devctl(socket)); config_writeb(socket, TI113X_DEVICE_CONTROL, ti_devctl(socket));
...@@ -318,16 +314,13 @@ static int ti113x_override(struct yenta_socket *socket) ...@@ -318,16 +314,13 @@ static int ti113x_override(struct yenta_socket *socket)
ti_cardctl(socket) &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); ti_cardctl(socket) &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
if (socket->cb_irq) if (socket->cb_irq)
ti_cardctl(socket) |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; ti_cardctl(socket) |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
ti_override(socket); return ti_override(socket);
socket->socket.ops->init = ti113x_init;
return 0;
} }
static int ti1250_init(struct pcmcia_socket *sock) static int ti1250_init(struct yenta_socket *socket)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); ti113x_init(socket);
ti113x_init(sock);
ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX); ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX);
#if 0 #if 0
ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */ ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */
...@@ -348,9 +341,7 @@ static int ti1250_override(struct yenta_socket *socket) ...@@ -348,9 +341,7 @@ static int ti1250_override(struct yenta_socket *socket)
ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ); ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ);
if (socket->cb_irq) if (socket->cb_irq)
ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ; ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
ti113x_override(socket); return ti113x_override(socket);
socket->socket.ops->init = ti1250_init;
return 0;
} }
......
...@@ -576,30 +576,35 @@ static void yenta_config_init(struct yenta_socket *socket) ...@@ -576,30 +576,35 @@ static void yenta_config_init(struct yenta_socket *socket)
} }
/* Called at resume and initialization events */ /* Called at resume and initialization events */
static int yenta_init(struct pcmcia_socket *sock) static int yenta_sock_init(struct pcmcia_socket *sock)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_config_init(socket); yenta_config_init(socket);
yenta_clear_maps(socket); yenta_clear_maps(socket);
/* Re-enable interrupts */ if (socket->type && socket->type->sock_init)
socket->type->sock_init(socket);
/* Re-enable CSC interrupts */
cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK); cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
return 0; return 0;
} }
static int yenta_suspend(struct pcmcia_socket *sock) static int yenta_sock_suspend(struct pcmcia_socket *sock)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_set_socket(sock, &dead_socket); yenta_set_socket(sock, &dead_socket);
/* Disable interrupts */ /* Disable CSC interrupts */
cb_writel(socket, CB_SOCKET_MASK, 0x0); cb_writel(socket, CB_SOCKET_MASK, 0x0);
/* /*
* This does not work currently. The controller * This does not work currently. The controller
* loses too much information during D3 to come up * loses too much information during D3 to come up
* cleanly. We should probably fix yenta_init() * cleanly. We should probably fix yenta_sock_init()
* to update all the critical registers, notably * to update all the critical registers, notably
* the IO and MEM bridging region data.. That is * the IO and MEM bridging region data.. That is
* something that pci_set_power_state() should * something that pci_set_power_state() should
...@@ -758,8 +763,8 @@ static void yenta_close(struct pci_dev *dev) ...@@ -758,8 +763,8 @@ static void yenta_close(struct pci_dev *dev)
static struct pccard_operations yenta_socket_operations = { static struct pccard_operations yenta_socket_operations = {
.init = yenta_init, .init = yenta_sock_init,
.suspend = yenta_suspend, .suspend = yenta_sock_suspend,
.get_status = yenta_get_status, .get_status = yenta_get_status,
.get_socket = yenta_get_socket, .get_socket = yenta_get_socket,
.set_socket = yenta_set_socket, .set_socket = yenta_set_socket,
...@@ -787,18 +792,23 @@ enum { ...@@ -787,18 +792,23 @@ enum {
struct cardbus_type cardbus_type[] = { struct cardbus_type cardbus_type[] = {
[CARDBUS_TYPE_TI] = { [CARDBUS_TYPE_TI] = {
.override = ti_override, .override = ti_override,
.sock_init = ti_init,
}, },
[CARDBUS_TYPE_TI113X] = { [CARDBUS_TYPE_TI113X] = {
.override = ti113x_override, .override = ti113x_override,
.sock_init = ti113x_init,
}, },
[CARDBUS_TYPE_TI12XX] = { [CARDBUS_TYPE_TI12XX] = {
.override = ti12xx_override, .override = ti12xx_override,
.sock_init = ti113x_init,
}, },
[CARDBUS_TYPE_TI1250] = { [CARDBUS_TYPE_TI1250] = {
.override = ti1250_override, .override = ti1250_override,
.sock_init = ti1250_init,
}, },
[CARDBUS_TYPE_RICOH] = { [CARDBUS_TYPE_RICOH] = {
.override = ricoh_override, .override = ricoh_override,
.sock_init = ricoh_init,
}, },
}; };
......
...@@ -99,6 +99,7 @@ struct yenta_socket; ...@@ -99,6 +99,7 @@ struct yenta_socket;
struct cardbus_type { struct cardbus_type {
int (*override)(struct yenta_socket *); int (*override)(struct yenta_socket *);
int (*sock_init)(struct yenta_socket *);
}; };
struct yenta_socket { struct yenta_socket {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment