Commit 47150372 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-pcmcia

into home.osdl.org:/home/torvalds/v2.5/linux
parents 22e370f9 5a26baff
...@@ -293,6 +293,7 @@ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, ...@@ -293,6 +293,7 @@ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
#endif #endif
ret = read_cis_mem(s, attr, addr, len, ptr); ret = read_cis_mem(s, attr, addr, len, ptr);
if (ret == 0) {
/* Copy data into the cache */ /* Copy data into the cache */
cis = kmalloc(sizeof(struct cis_cache_entry) + len, GFP_KERNEL); cis = kmalloc(sizeof(struct cis_cache_entry) + len, GFP_KERNEL);
if (cis) { if (cis) {
...@@ -302,6 +303,7 @@ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, ...@@ -302,6 +303,7 @@ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
memcpy(cis->cache, ptr, len); memcpy(cis->cache, ptr, len);
list_add(&cis->node, &s->cis_cache); list_add(&cis->node, &s->cis_cache);
} }
}
} }
static void static void
......
...@@ -142,59 +142,61 @@ static void ricoh_zoom_video(struct pcmcia_socket *sock, int onoff) ...@@ -142,59 +142,61 @@ 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 void ricoh_save_state(struct yenta_socket *socket)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); rl_misc(socket) = config_readw(socket, RL5C4XX_MISC);
yenta_init(sock); rl_ctl(socket) = config_readw(socket, RL5C4XX_16BIT_CTL);
ricoh_set_zv(sock); rl_io(socket) = config_readw(socket, RL5C4XX_16BIT_IO_0);
rl_mem(socket) = config_readw(socket, RL5C4XX_16BIT_MEM_0);
rl_config(socket) = config_readw(socket, RL5C4XX_CONFIG);
}
static void ricoh_restore_state(struct yenta_socket *socket)
{
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));
config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket)); config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket));
config_writew(socket, RL5C4XX_CONFIG, rl_config(socket)); config_writew(socket, RL5C4XX_CONFIG, rl_config(socket));
return 0;
} }
/* /*
* Magic Ricoh initialization code.. Save state at * Magic Ricoh initialization code..
* beginning, re-initialize it after suspend.
*/ */
static int ricoh_override(struct yenta_socket *socket) static int ricoh_override(struct yenta_socket *socket)
{ {
rl_misc(socket) = config_readw(socket, RL5C4XX_MISC); u16 config, ctl;
rl_ctl(socket) = config_readw(socket, RL5C4XX_16BIT_CTL);
rl_io(socket) = config_readw(socket, RL5C4XX_16BIT_IO_0); config = config_readw(socket, RL5C4XX_CONFIG);
rl_mem(socket) = config_readw(socket, RL5C4XX_16BIT_MEM_0);
rl_config(socket) = config_readw(socket, RL5C4XX_CONFIG);
/* Set the default timings, don't trust the original values */ /* Set the default timings, don't trust the original values */
rl_ctl(socket) = RL5C4XX_16CTL_IO_TIMING | RL5C4XX_16CTL_MEM_TIMING; ctl = RL5C4XX_16CTL_IO_TIMING | RL5C4XX_16CTL_MEM_TIMING;
if(socket->dev->device < PCI_DEVICE_ID_RICOH_RL5C475) { if(socket->dev->device < PCI_DEVICE_ID_RICOH_RL5C475) {
rl_ctl(socket) |= RL5C46X_16CTL_LEVEL_1 | RL5C46X_16CTL_LEVEL_2; ctl |= RL5C46X_16CTL_LEVEL_1 | RL5C46X_16CTL_LEVEL_2;
} else { } else {
rl_config(socket) |= RL5C4XX_CONFIG_PREFETCH; config |= RL5C4XX_CONFIG_PREFETCH;
} }
socket->socket.ops->init = ricoh_init; config_writew(socket, RL5C4XX_16BIT_CTL, ctl);
config_writew(socket, RL5C4XX_CONFIG, config);
ricoh_set_zv(socket);
return 0; return 0;
} }
......
...@@ -136,16 +136,34 @@ ...@@ -136,16 +136,34 @@
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
static int ti_intctl(struct yenta_socket *socket) /*
* 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])
/*
* These are the TI specific power management handlers.
*/
static void ti_save_state(struct yenta_socket *socket)
{ {
u8 new, reg = exca_readb(socket, I365_INTCTL); ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL);
ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX);
ti_cardctl(socket) = config_readb(socket, TI113X_CARD_CONTROL);
ti_devctl(socket) = config_readb(socket, TI113X_DEVICE_CONTROL);
ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC);
}
new = reg & ~I365_INTR_ENA; static void ti_restore_state(struct yenta_socket *socket)
if (socket->cb_irq) {
new |= I365_INTR_ENA; config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket));
if (new != reg) config_writel(socket, TI122X_IRQMUX, ti_irqmux(socket));
exca_writeb(socket, I365_INTCTL, new); config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket));
return 0; config_writeb(socket, TI113X_DEVICE_CONTROL, ti_devctl(socket));
config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket));
} }
/* /*
...@@ -185,8 +203,8 @@ static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff) ...@@ -185,8 +203,8 @@ static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff)
ti_zoom_video(sock, onoff); ti_zoom_video(sock, onoff);
reg = config_readb(socket, 0x84); reg = config_readb(socket, TI1250_MULTIMEDIA_CTL);
reg |= (1<<7); /* ZV bus enable */ reg |= TI1250_MMC_ZVOUTEN; /* ZV bus enable */
if(PCI_FUNC(socket->dev->devfn)==1) if(PCI_FUNC(socket->dev->devfn)==1)
shift = 1; shift = 1;
...@@ -204,12 +222,11 @@ static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff) ...@@ -204,12 +222,11 @@ static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff)
reg &= ~(1<<shift); /* Socket zoon video off */ reg &= ~(1<<shift); /* Socket zoon video off */
} }
config_writeb(socket, 0x84, 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,24 +235,16 @@ static void ti_set_zv(struct pcmcia_socket *sock) ...@@ -218,24 +235,16 @@ 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)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
ti_set_zv(sock);
ti_intctl(socket);
return 0;
}
/* /*
...@@ -250,6 +259,18 @@ static int ti_init(struct pcmcia_socket *sock) ...@@ -250,6 +259,18 @@ static int ti_init(struct pcmcia_socket *sock)
* This makes us correctly get PCI CSC interrupt * This makes us correctly get PCI CSC interrupt
* events. * events.
*/ */
static int ti_init(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_override(struct yenta_socket *socket) static int ti_override(struct yenta_socket *socket)
{ {
u8 new, reg = exca_readb(socket, I365_INTCTL); u8 new, reg = exca_readb(socket, I365_INTCTL);
...@@ -258,6 +279,8 @@ static int ti_override(struct yenta_socket *socket) ...@@ -258,6 +279,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,83 +308,85 @@ static int ti_override(struct yenta_socket *socket) ...@@ -285,83 +308,85 @@ static int ti_override(struct yenta_socket *socket)
} }
#endif #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)
{
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));
ti_intctl(socket);
return 0; return 0;
} }
static int ti113x_override(struct yenta_socket *socket) static int ti113x_override(struct yenta_socket *socket)
{ {
ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL); u8 cardctl;
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); cardctl = config_readb(socket, TI113X_CARD_CONTROL);
cardctl &= ~(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; cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
ti_override(socket); config_writeb(socket, TI113X_CARD_CONTROL, cardctl);
socket->socket.ops->init = ti113x_init;
return 0; return ti_override(socket);
} }
static int ti1250_init(struct pcmcia_socket *sock) static int ti12xx_override(struct yenta_socket *socket)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); u32 val;
ti113x_init(sock);
ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX);
#if 0
ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */
if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE))
ti_irqmux(socket) |= 0x20; /* route INTB */
#endif
config_writel(socket, TI122X_IRQMUX, ti_irqmux(socket)); /* make sure that memory burst is active */
val = config_readl(socket, TI113X_SYSTEM_CONTROL);
if (!(val & TI122X_SCR_MRBURSTUP)) {
printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n");
val |= TI122X_SCR_MRBURSTUP;
config_writel(socket, TI113X_SYSTEM_CONTROL, val);
}
config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket)); /*
return 0; * Yenta expects controllers to use CSCINT to route
* CSC interrupts to PCI rather than INTVAL.
*/
val = config_readb(socket, TI1250_DIAGNOSTIC);
printk(KERN_INFO "Yenta: Using %s to route CSC interrupts to PCI\n",
(val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n",
(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
return ti_override(socket);
} }
static int ti1250_override(struct yenta_socket *socket) static int ti1250_override(struct yenta_socket *socket)
{ {
ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC); u8 old, diag;
ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ); old = config_readb(socket, TI1250_DIAGNOSTIC);
diag = old & ~(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; diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
ti113x_override(socket);
socket->socket.ops->init = ti1250_init;
return 0;
}
if (diag != old) {
printk(KERN_INFO "Yenta: adjusting diagnostic: %02x -> %02x\n",
old, diag);
config_writeb(socket, TI1250_DIAGNOSTIC, diag);
}
static int ti12xx_override(struct yenta_socket *socket) #if 0
{ /*
/* make sure that memory burst is active */ * This is highly machine specific, and we should NOT touch
ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL); * this register - we have no knowledge how the hardware
ti_sysctl(socket) |= TI122X_SCR_MRBURSTUP; * is actually wired.
config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); *
* If we're going to do this, we should probably look into
* using the subsystem IDs.
*
* On ThinkPad 380XD, this changes MFUNC0 from the ISA IRQ3
* output (which it is) to IRQ2. We also change MFUNC1
* from ISA IRQ4 to IRQ6.
*/
irqmux = config_readl(socket, TI122X_IRQMUX);
irqmux = (irqmux & ~0x0f) | 0x02; /* route INTA */
if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE))
irqmux = (irqmux & ~0xf0) | 0x20; /* route INTB */
config_writel(socket, TI122X_IRQMUX, irqmux);
#endif
return ti113x_override(socket); return ti12xx_override(socket);
} }
#endif /* CONFIG_CARDBUS */ #endif /* CONFIG_CARDBUS */
......
...@@ -31,20 +31,7 @@ ...@@ -31,20 +31,7 @@
#ifndef _LINUX_TOPIC_H #ifndef _LINUX_TOPIC_H
#define _LINUX_TOPIC_H #define _LINUX_TOPIC_H
#ifndef PCI_VENDOR_ID_TOSHIBA /* Register definitions for Toshiba ToPIC95/97/100 controllers */
#define PCI_VENDOR_ID_TOSHIBA 0x1179
#endif
#ifndef PCI_DEVICE_ID_TOSHIBA_TOPIC95_A
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_A 0x0603
#endif
#ifndef PCI_DEVICE_ID_TOSHIBA_TOPIC95_B
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_B 0x060a
#endif
#ifndef PCI_DEVICE_ID_TOSHIBA_TOPIC97
#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f
#endif
/* Register definitions for Toshiba ToPIC95 controllers */
#define TOPIC_SOCKET_CONTROL 0x0090 /* 32 bit */ #define TOPIC_SOCKET_CONTROL 0x0090 /* 32 bit */
#define TOPIC_SCR_IRQSEL 0x00000001 #define TOPIC_SCR_IRQSEL 0x00000001
...@@ -93,4 +80,61 @@ ...@@ -93,4 +80,61 @@
#define TOPIC97_RCR_CAUDIO_OFF 0x00000002 #define TOPIC97_RCR_CAUDIO_OFF 0x00000002
#define TOPIC_RCR_CAUDIO_INVERT 0x00000001 #define TOPIC_RCR_CAUDIO_INVERT 0x00000001
#define TOPIC97_MISC1 0x00ad /* 8bit */
#define TOPIC97_MISC1_CLOCKRUN_ENABLE 0x80
#define TOPIC97_MISC1_CLOCKRUN_MODE 0x40
#define TOPIC97_MISC1_DETECT_REQ_ENA 0x10
#define TOPIC97_MISC1_SCK_CLEAR_DIS 0x04
#define TOPIC97_MISC1_R2_LOW_ENABLE 0x10
#define TOPIC97_MISC2 0x00ae /* 8 bit */
#define TOPIC97_MISC2_SPWRCLK_MASK 0x70
#define TOPIC97_MISC2_SPWRMOD 0x08
#define TOPIC97_MISC2_SPWR_ENABLE 0x04
#define TOPIC97_MISC2_ZV_MODE 0x02
#define TOPIC97_MISC2_ZV_ENABLE 0x01
#define TOPIC97_ZOOM_VIDEO_CONTROL 0x009c /* 8 bit */
#define TOPIC97_ZV_CONTROL_ENABLE 0x01
#define TOPIC97_AUDIO_VIDEO_SWITCH 0x003c /* 8 bit */
#define TOPIC97_AVS_AUDIO_CONTROL 0x02
#define TOPIC97_AVS_VIDEO_CONTROL 0x01
static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
u8 reg_zv, reg;
reg_zv = config_readb(socket, TOPIC97_ZOOM_VIDEO_CONTROL);
if (onoff) {
reg_zv |= TOPIC97_ZV_CONTROL_ENABLE;
config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
reg = config_readb(socket, TOPIC97_MISC2);
reg |= TOPIC97_MISC2_ZV_ENABLE;
config_writeb(socket, TOPIC97_MISC2, reg);
/* not sure this is needed, doc is unclear */
#if 0
reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
reg |= TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL;
config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
#endif
}
else {
reg_zv &= ~TOPIC97_ZV_CONTROL_ENABLE;
config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
}
}
static int topic97_override(struct yenta_socket *socket)
{
/* ToPIC97/100 support ZV */
socket->socket.zoom_video = topic97_zoom_video;
return 0;
}
#endif /* _LINUX_TOPIC_H */ #endif /* _LINUX_TOPIC_H */
...@@ -443,73 +443,6 @@ static void yenta_interrupt_wrapper(unsigned long data) ...@@ -443,73 +443,6 @@ static void yenta_interrupt_wrapper(unsigned long data)
add_timer(&socket->poll_timer); add_timer(&socket->poll_timer);
} }
/*
* Only probe "regular" interrupts, don't
* touch dangerous spots like the mouse irq,
* because there are mice that apparently
* get really confused if they get fondled
* too intimately.
*
* Default to 11, 10, 9, 7, 6, 5, 4, 3.
*/
static u32 isa_interrupts = 0x0ef8;
static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
{
int i;
unsigned long val;
u16 bridge_ctrl;
u32 mask;
/* Set up ISA irq routing to probe the ISA irqs.. */
bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
if (!(bridge_ctrl & CB_BRIDGE_INTR)) {
bridge_ctrl |= CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
}
/*
* Probe for usable interrupts using the force
* register to generate bogus card status events.
*/
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
exca_writeb(socket, I365_CSCINT, 0);
val = probe_irq_on() & isa_irq_mask;
for (i = 1; i < 16; i++) {
if (!((val >> i) & 1))
continue;
exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG | (i << 4));
cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
udelay(100);
cb_writel(socket, CB_SOCKET_EVENT, -1);
}
cb_writel(socket, CB_SOCKET_MASK, 0);
exca_writeb(socket, I365_CSCINT, 0);
mask = probe_irq_mask(val) & 0xffff;
bridge_ctrl &= ~CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
return mask;
}
/*
* Set static data that doesn't need re-initializing..
*/
static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
{
socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
socket->socket.map_size = 0x1000;
socket->socket.pci_irq = socket->cb_irq;
socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
socket->socket.cb_dev = socket->dev;
printk("Yenta IRQ list %04x, PCI irq%d\n", socket->socket.irq_mask, socket->cb_irq);
}
static void yenta_clear_maps(struct yenta_socket *socket) static void yenta_clear_maps(struct yenta_socket *socket)
{ {
int i; int i;
...@@ -528,42 +461,13 @@ static void yenta_clear_maps(struct yenta_socket *socket) ...@@ -528,42 +461,13 @@ static void yenta_clear_maps(struct yenta_socket *socket)
} }
} }
/* /* Called at resume and initialization events */
* Initialize the standard cardbus registers static int yenta_sock_init(struct pcmcia_socket *sock)
*/
static void yenta_config_init(struct yenta_socket *socket)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
u16 bridge; u16 bridge;
struct pci_dev *dev = socket->dev;
pci_set_power_state(socket->dev, 0);
config_writel(socket, CB_LEGACY_MODE_BASE, 0);
config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
config_writew(socket, PCI_COMMAND,
PCI_COMMAND_IO |
PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER |
PCI_COMMAND_WAIT);
/* MAGIC NUMBERS! Fixme */
config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
config_writeb(socket, PCI_LATENCY_TIMER, 168);
config_writel(socket, PCI_PRIMARY_BUS,
(176 << 24) | /* sec. latency timer */
(dev->subordinate->subordinate << 16) | /* subordinate bus */
(dev->subordinate->secondary << 8) | /* secondary bus */
dev->subordinate->primary); /* primary bus */
/* bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR;
* Set up the bridging state:
* - enable write posting.
* - memory window 0 prefetchable, window 1 non-prefetchable
* - PCI interrupts enabled if a PCI interrupt exists..
*/
bridge = config_readw(socket, CB_BRIDGE_CONTROL);
bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN;
if (!socket->cb_irq) if (!socket->cb_irq)
bridge |= CB_BRIDGE_INTR; bridge |= CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge); config_writew(socket, CB_BRIDGE_CONTROL, bridge);
...@@ -573,41 +477,27 @@ static void yenta_config_init(struct yenta_socket *socket) ...@@ -573,41 +477,27 @@ static void yenta_config_init(struct yenta_socket *socket)
/* Redo card voltage interrogation */ /* Redo card voltage interrogation */
cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST); cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
}
/* Called at resume and initialization events */
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); 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
* loses too much information during D3 to come up
* cleanly. We should probably fix yenta_init()
* to update all the critical registers, notably
* the IO and MEM bridging region data.. That is
* something that pci_set_power_state() should
* probably know about bridges anyway.
*
pci_set_power_state(socket->dev, 3);
*/
return 0; return 0;
} }
...@@ -758,8 +648,8 @@ static void yenta_close(struct pci_dev *dev) ...@@ -758,8 +648,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,
...@@ -770,51 +660,164 @@ static struct pccard_operations yenta_socket_operations = { ...@@ -770,51 +660,164 @@ static struct pccard_operations yenta_socket_operations = {
#include "ti113x.h" #include "ti113x.h"
#include "ricoh.h" #include "ricoh.h"
#include "topic.h"
enum {
CARDBUS_TYPE_DEFAULT = -1,
CARDBUS_TYPE_TI,
CARDBUS_TYPE_TI113X,
CARDBUS_TYPE_TI12XX,
CARDBUS_TYPE_TI1250,
CARDBUS_TYPE_RICOH,
CARDBUS_TYPE_TOPIC97
};
/* /*
* Different cardbus controllers have slightly different * Different cardbus controllers have slightly different
* initialization sequences etc details. List them here.. * initialization sequences etc details. List them here..
*/ */
#define PD(x,y) PCI_VENDOR_ID_##x, PCI_DEVICE_ID_##x##_##y struct cardbus_type cardbus_type[] = {
struct cardbus_override_struct { [CARDBUS_TYPE_TI] = {
unsigned short vendor; .override = ti_override,
unsigned short device; .save_state = ti_save_state,
int (*override) (struct yenta_socket *socket); .restore_state = ti_restore_state,
} cardbus_override[] = { .sock_init = ti_init,
{ PD(TI,1031), &ti_override }, },
[CARDBUS_TYPE_TI113X] = {
/* TBD: Check if these TI variants can use more .override = ti113x_override,
* advanced overrides instead */ .save_state = ti_save_state,
{ PD(TI,1210), &ti_override }, .restore_state = ti_restore_state,
{ PD(TI,1211), &ti_override }, .sock_init = ti_init,
{ PD(TI,1251A), &ti_override }, },
{ PD(TI,1251B), &ti_override }, [CARDBUS_TYPE_TI12XX] = {
{ PD(TI,1420), &ti_override }, .override = ti12xx_override,
{ PD(TI,1450), &ti_override }, .save_state = ti_save_state,
{ PD(TI,4410), &ti_override }, .restore_state = ti_restore_state,
{ PD(TI,4451), &ti_override }, .sock_init = ti_init,
},
{ PD(TI,1130), &ti113x_override }, [CARDBUS_TYPE_TI1250] = {
{ PD(TI,1131), &ti113x_override }, .override = ti1250_override,
.save_state = ti_save_state,
{ PD(TI,1220), &ti12xx_override }, .restore_state = ti_restore_state,
{ PD(TI,1221), &ti12xx_override }, .sock_init = ti_init,
{ PD(TI,1225), &ti12xx_override }, },
{ PD(TI,1520), &ti12xx_override }, [CARDBUS_TYPE_RICOH] = {
.override = ricoh_override,
{ PD(TI,1250), &ti1250_override }, .save_state = ricoh_save_state,
{ PD(TI,1410), &ti1250_override }, .restore_state = ricoh_restore_state,
},
{ PD(RICOH,RL5C465), &ricoh_override }, [CARDBUS_TYPE_TOPIC97] = {
{ PD(RICOH,RL5C466), &ricoh_override }, .override = topic97_override,
{ PD(RICOH,RL5C475), &ricoh_override }, },
{ PD(RICOH,RL5C476), &ricoh_override },
{ PD(RICOH,RL5C478), &ricoh_override },
{ }, /* all zeroes */
}; };
/*
* Only probe "regular" interrupts, don't
* touch dangerous spots like the mouse irq,
* because there are mice that apparently
* get really confused if they get fondled
* too intimately.
*
* Default to 11, 10, 9, 7, 6, 5, 4, 3.
*/
static u32 isa_interrupts = 0x0ef8;
static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
{
int i;
unsigned long val;
u16 bridge_ctrl;
u32 mask;
/* Set up ISA irq routing to probe the ISA irqs.. */
bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
if (!(bridge_ctrl & CB_BRIDGE_INTR)) {
bridge_ctrl |= CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
}
/*
* Probe for usable interrupts using the force
* register to generate bogus card status events.
*/
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
exca_writeb(socket, I365_CSCINT, 0);
val = probe_irq_on() & isa_irq_mask;
for (i = 1; i < 16; i++) {
if (!((val >> i) & 1))
continue;
exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG | (i << 4));
cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
udelay(100);
cb_writel(socket, CB_SOCKET_EVENT, -1);
}
cb_writel(socket, CB_SOCKET_MASK, 0);
exca_writeb(socket, I365_CSCINT, 0);
mask = probe_irq_mask(val) & 0xffff;
bridge_ctrl &= ~CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
return mask;
}
/*
* Set static data that doesn't need re-initializing..
*/
static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
{
socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
socket->socket.map_size = 0x1000;
socket->socket.pci_irq = socket->cb_irq;
socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
socket->socket.cb_dev = socket->dev;
printk(KERN_INFO "Yenta: ISA IRQ list %04x, PCI irq%d\n",
socket->socket.irq_mask, socket->cb_irq);
}
/*
* Initialize the standard cardbus registers
*/
static void yenta_config_init(struct yenta_socket *socket)
{
u16 bridge;
struct pci_dev *dev = socket->dev;
pci_set_power_state(socket->dev, 0);
config_writel(socket, CB_LEGACY_MODE_BASE, 0);
config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
config_writew(socket, PCI_COMMAND,
PCI_COMMAND_IO |
PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER |
PCI_COMMAND_WAIT);
/* MAGIC NUMBERS! Fixme */
config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
config_writeb(socket, PCI_LATENCY_TIMER, 168);
config_writel(socket, PCI_PRIMARY_BUS,
(176 << 24) | /* sec. latency timer */
(dev->subordinate->subordinate << 16) | /* subordinate bus */
(dev->subordinate->secondary << 8) | /* secondary bus */
dev->subordinate->primary); /* primary bus */
/*
* Set up the bridging state:
* - enable write posting.
* - memory window 0 prefetchable, window 1 non-prefetchable
* - PCI interrupts enabled if a PCI interrupt exists..
*/
bridge = config_readw(socket, CB_BRIDGE_CONTROL);
bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN | CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge);
}
/* /*
* Initialize a cardbus controller. Make sure we have a usable * Initialize a cardbus controller. Make sure we have a usable
* interrupt, and that we can map the cardbus area. Fill in the * interrupt, and that we can map the cardbus area. Fill in the
...@@ -823,7 +826,6 @@ struct cardbus_override_struct { ...@@ -823,7 +826,6 @@ struct cardbus_override_struct {
static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id) static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id)
{ {
struct yenta_socket *socket; struct yenta_socket *socket;
struct cardbus_override_struct *d;
int ret; int ret;
socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL); socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
...@@ -887,15 +889,14 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i ...@@ -887,15 +889,14 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
socket->cb_irq = dev->irq; socket->cb_irq = dev->irq;
/* Do we have special options for the device? */ /* Do we have special options for the device? */
d = cardbus_override; if (id->driver_data != CARDBUS_TYPE_DEFAULT &&
while (d->override) { id->driver_data < ARRAY_SIZE(cardbus_type)) {
if ((dev->vendor == d->vendor) && (dev->device == d->device)) { socket->type = &cardbus_type[id->driver_data];
ret = d->override(socket);
ret = socket->type->override(socket);
if (ret < 0) if (ret < 0)
goto unmap; goto unmap;
} }
d++;
}
/* We must finish initialization here */ /* We must finish initialization here */
...@@ -933,25 +934,97 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i ...@@ -933,25 +934,97 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
static int yenta_dev_suspend (struct pci_dev *dev, u32 state) static int yenta_dev_suspend (struct pci_dev *dev, u32 state)
{ {
return pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE); struct yenta_socket *socket = pci_get_drvdata(dev);
int ret;
ret = pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE);
if (socket) {
if (socket->type && socket->type->save_state)
socket->type->save_state(socket);
/* FIXME: pci_save_state needs to have a better interface */
pci_save_state(dev, socket->saved_state);
pci_read_config_dword(dev, 16*4, &socket->saved_state[16]);
pci_read_config_dword(dev, 17*4, &socket->saved_state[17]);
pci_set_power_state(dev, 3);
}
return ret;
} }
static int yenta_dev_resume (struct pci_dev *dev) static int yenta_dev_resume (struct pci_dev *dev)
{ {
struct yenta_socket *socket = pci_get_drvdata(dev);
if (socket) {
pci_set_power_state(dev, 0);
/* FIXME: pci_restore_state needs to have a better interface */
pci_restore_state(dev, socket->saved_state);
pci_write_config_dword(dev, 16*4, socket->saved_state[16]);
pci_write_config_dword(dev, 17*4, socket->saved_state[17]);
if (socket->type && socket->type->restore_state)
socket->type->restore_state(socket);
}
return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE); return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
} }
static struct pci_device_id yenta_table [] = { { #define CB_ID(vend,dev,type) \
.class = PCI_CLASS_BRIDGE_CARDBUS << 8, { \
.class_mask = ~0, .vendor = vend, \
.device = dev, \
.subvendor = PCI_ANY_ID, \
.subdevice = PCI_ANY_ID, \
.class = PCI_CLASS_BRIDGE_CARDBUS << 8, \
.class_mask = ~0, \
.driver_data = CARDBUS_TYPE_##type, \
}
.vendor = PCI_ANY_ID, static struct pci_device_id yenta_table [] = {
.device = PCI_ANY_ID, CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1031, TI),
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, /*
}, { /* all zeroes */ } * TBD: Check if these TI variants can use more
* advanced overrides instead. (I can't get the
* data sheets for these devices. --rmk)
*/
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1251B, TI),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1131, TI113X),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1211, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1220, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1221, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1225, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1251A, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1450, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4410, TI12XX),
// CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4450, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4451, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH),
CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97),
CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97),
/* match any cardbus bridge */
CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
{ /* all zeroes */ }
}; };
MODULE_DEVICE_TABLE(pci, yenta_table); MODULE_DEVICE_TABLE(pci, yenta_table);
......
...@@ -95,6 +95,15 @@ ...@@ -95,6 +95,15 @@
*/ */
#define CB_MEM_PAGE(map) (0x40 + (map)) #define CB_MEM_PAGE(map) (0x40 + (map))
struct yenta_socket;
struct cardbus_type {
int (*override)(struct yenta_socket *);
void (*save_state)(struct yenta_socket *);
void (*restore_state)(struct yenta_socket *);
int (*sock_init)(struct yenta_socket *);
};
struct yenta_socket { struct yenta_socket {
struct pci_dev *dev; struct pci_dev *dev;
int cb_irq, io_irq; int cb_irq, io_irq;
...@@ -102,9 +111,13 @@ struct yenta_socket { ...@@ -102,9 +111,13 @@ struct yenta_socket {
struct timer_list poll_timer; struct timer_list poll_timer;
struct pcmcia_socket socket; struct pcmcia_socket socket;
struct cardbus_type *type;
/* A few words of private data for special stuff of overrides... */ /* A few words of private data for special stuff of overrides... */
unsigned int private[8]; unsigned int private[8];
/* PCI saved state */
u32 saved_state[18];
}; };
......
...@@ -1345,7 +1345,10 @@ ...@@ -1345,7 +1345,10 @@
#define PCI_VENDOR_ID_TOSHIBA 0x1179 #define PCI_VENDOR_ID_TOSHIBA 0x1179
#define PCI_DEVICE_ID_TOSHIBA_601 0x0601 #define PCI_DEVICE_ID_TOSHIBA_601 0x0601
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a #define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_A 0x0603
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_B 0x060a
#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f #define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f
#define PCI_DEVICE_ID_TOSHIBA_TOPIC100 0x0617
#define PCI_VENDOR_ID_TOSHIBA_2 0x102f #define PCI_VENDOR_ID_TOSHIBA_2 0x102f
#define PCI_DEVICE_ID_TOSHIBA_TX3927 0x000a #define PCI_DEVICE_ID_TOSHIBA_TX3927 0x000a
......
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