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)
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)
{
switch(socket->dev->device)
{
/* There may be more .. */
case PCI_DEVICE_ID_RICOH_RL5C478:
sock->zoom_video = ricoh_zoom_video;
socket->socket.zoom_video = ricoh_zoom_video;
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_16BIT_CTL, rl_ctl(socket));
config_writew(socket, RL5C4XX_16BIT_IO_0, rl_io(socket));
......@@ -194,7 +189,7 @@ static int ricoh_override(struct yenta_socket *socket)
rl_config(socket) |= RL5C4XX_CONFIG_PREFETCH;
}
socket->socket.ops->init = ricoh_init;
ricoh_set_zv(socket);
return 0;
}
......
......@@ -136,6 +136,16 @@
#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)
{
u8 new, reg = exca_readb(socket, I365_INTCTL);
......@@ -207,9 +217,8 @@ static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff)
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)
{
switch(socket->dev->device)
......@@ -218,21 +227,18 @@ static void ti_set_zv(struct pcmcia_socket *sock)
case PCI_DEVICE_ID_TI_1220:
case PCI_DEVICE_ID_TI_1221:
case PCI_DEVICE_ID_TI_1225:
sock->zoom_video = ti_zoom_video;
socket->socket.zoom_video = ti_zoom_video;
break;
case PCI_DEVICE_ID_TI_1250:
case PCI_DEVICE_ID_TI_1251A:
case PCI_DEVICE_ID_TI_1251B:
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);
return 0;
}
......@@ -258,6 +264,8 @@ static int ti_override(struct yenta_socket *socket)
if (new != reg)
exca_writeb(socket, I365_INTCTL, new);
ti_set_zv(socket);
#if 0
/*
* If ISA interrupts don't work, then fall back to routing card
......@@ -285,23 +293,11 @@ static int ti_override(struct yenta_socket *socket)
}
#endif
socket->socket.ops->init = ti_init;
return 0;
}
#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_init(struct pcmcia_socket *sock)
static int ti113x_init(struct yenta_socket *socket)
{
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_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket));
config_writeb(socket, TI113X_DEVICE_CONTROL, ti_devctl(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);
if (socket->cb_irq)
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;
return ti_override(socket);
}
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(sock);
ti113x_init(socket);
ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX);
#if 0
ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */
......@@ -348,9 +341,7 @@ static int ti1250_override(struct yenta_socket *socket)
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;
return ti113x_override(socket);
}
......
......@@ -576,30 +576,35 @@ static void yenta_config_init(struct yenta_socket *socket)
}
/* 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);
yenta_config_init(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);
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);
yenta_set_socket(sock, &dead_socket);
/* Disable interrupts */
/* Disable CSC interrupts */
cb_writel(socket, CB_SOCKET_MASK, 0x0);
/*
* This does not work currently. The controller
* 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
* the IO and MEM bridging region data.. That is
* something that pci_set_power_state() should
......@@ -758,8 +763,8 @@ static void yenta_close(struct pci_dev *dev)
static struct pccard_operations yenta_socket_operations = {
.init = yenta_init,
.suspend = yenta_suspend,
.init = yenta_sock_init,
.suspend = yenta_sock_suspend,
.get_status = yenta_get_status,
.get_socket = yenta_get_socket,
.set_socket = yenta_set_socket,
......@@ -787,18 +792,23 @@ enum {
struct cardbus_type cardbus_type[] = {
[CARDBUS_TYPE_TI] = {
.override = ti_override,
.sock_init = ti_init,
},
[CARDBUS_TYPE_TI113X] = {
.override = ti113x_override,
.sock_init = ti113x_init,
},
[CARDBUS_TYPE_TI12XX] = {
.override = ti12xx_override,
.sock_init = ti113x_init,
},
[CARDBUS_TYPE_TI1250] = {
.override = ti1250_override,
.sock_init = ti1250_init,
},
[CARDBUS_TYPE_RICOH] = {
.override = ricoh_override,
.sock_init = ricoh_init,
},
};
......
......@@ -99,6 +99,7 @@ struct yenta_socket;
struct cardbus_type {
int (*override)(struct yenta_socket *);
int (*sock_init)(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