Commit 47baacef authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.5

into home.osdl.org:/home/torvalds/v2.5/linux
parents 2708bcf5 2af67469
......@@ -465,10 +465,17 @@ t2_init_arch(void)
*(vulp)T2_HAE_1 = 0; mb(); /* Sparse MEM HAE */
*(vulp)T2_HAE_2 = 0; mb(); /* Sparse I/O HAE */
*(vulp)T2_HAE_3 = 0; mb(); /* Config Space HAE */
#if 0
/* !!! DO NOT EVER TOUCH THIS !!! */
*(vulp)T2_HAE_4 = 0; mb(); /* Dense MEM HAE */
#endif
/*
* We also now zero out HAE_4, the dense memory HAE, so that
* we need not account for its "offset" when accessing dense
* memory resources which we allocated in our normal way. This
* HAE would need to stay untouched were we to keep the SRM
* resource settings.
*
* Thus we can now run standard X servers on SABLE/LYNX. :-)
*/
*(vulp)T2_HAE_4 = 0; mb();
}
void
......
......@@ -270,7 +270,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct thread_info *childti = p->thread_info;
struct pt_regs * childregs;
struct switch_stack * childstack, *stack;
unsigned long stack_offset;
unsigned long stack_offset, settls;
stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
if (!(regs->ps & 8))
......@@ -279,6 +279,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
(stack_offset + PAGE_SIZE + (long) childti);
*childregs = *regs;
settls = regs->r20;
childregs->r0 = 0;
childregs->r19 = 0;
childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */
......@@ -292,14 +293,16 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childti->pcb.flags = 1; /* set FEN, clear everything else */
/* Set a new TLS for the child thread? Peek back into the
syscall arguments that we saved on syscall entry. */
syscall arguments that we saved on syscall entry. Oops,
except we'd have clobbered it with the parent/child set
of r20. Read the saved copy. */
/* Note: if CLONE_SETTLS is not set, then we must inherit the
value from the parent, which will have been set by the block
copy in dup_task_struct. This is non-intuitive, but is
required for proper operation in the case of a threaded
application calling fork. */
if (clone_flags & CLONE_SETTLS)
childti->pcb.unique = regs->r20;
childti->pcb.unique = settls;
return 0;
}
......
......@@ -231,18 +231,6 @@ static const lookup_t service_table[] = {
======================================================================*/
static int register_callback(struct pcmcia_socket *s, void (*handler)(void *, unsigned int), void * info)
{
int error;
if (handler && !try_module_get(s->ss_entry->owner))
return -ENODEV;
error = s->ss_entry->register_callback(s, handler, info);
if (!handler)
module_put(s->ss_entry->owner);
return error;
}
static int get_socket_status(struct pcmcia_socket *s, int *val)
{
return s->ss_entry->get_status(s, val);
......@@ -363,6 +351,7 @@ static int pcmcia_add_socket(struct class_device *class_dev)
wait_for_completion(&socket->thread_done);
BUG_ON(!socket->thread);
pcmcia_parse_events(socket, SS_DETECT);
return 0;
}
......@@ -723,6 +712,9 @@ static int socket_insert(struct pcmcia_socket *skt)
{
int ret;
if (!try_module_get(skt->owner))
return CS_NO_CARD;
ret = socket_setup(skt, setup_delay);
if (ret == CS_SUCCESS) {
#ifdef CONFIG_CARDBUS
......@@ -733,8 +725,10 @@ static int socket_insert(struct pcmcia_socket *skt)
#endif
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
skt->socket.flags &= ~SS_DEBOUNCED;
} else
} else {
socket_shutdown(skt);
module_put(skt->owner);
}
return ret;
}
......@@ -778,14 +772,55 @@ static int socket_resume(struct pcmcia_socket *skt)
send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
}
skt->socket.flags &= ~SS_DEBOUNCED;
} else
} else {
unsigned int old_state = skt->state;
socket_shutdown(skt);
if (old_state & SOCKET_PRESENT)
module_put(skt->owner);
}
skt->state &= ~SOCKET_SUSPEND;
return CS_SUCCESS;
}
static void socket_remove(struct pcmcia_socket *skt)
{
socket_shutdown(skt);
module_put(skt->owner);
}
/*
* Process a socket card detect status change.
*
* If we don't have a card already present, delay the detect event for
* about 20ms (to be on the safe side) before reading the socket status.
*
* Some i82365-based systems send multiple SS_DETECT events during card
* insertion, and the "card present" status bit seems to bounce. This
* will probably be true with GPIO-based card detection systems after
* the product has aged.
*/
static void socket_detect_change(struct pcmcia_socket *skt)
{
if (!(skt->state & SOCKET_SUSPEND)) {
int status;
if (!(skt->state & SOCKET_PRESENT)) {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(cs_to_timeout(2));
}
get_socket_status(skt, &status);
if ((skt->state & SOCKET_PRESENT) &&
!(status & SS_DETECT))
socket_remove(skt);
if (!(skt->state & SOCKET_PRESENT) &&
(status & SS_DETECT))
socket_insert(skt);
}
}
static int pccardd(void *__skt)
{
struct pcmcia_socket *skt = __skt;
......@@ -809,17 +844,8 @@ static int pccardd(void *__skt)
if (events) {
down(&skt->skt_sem);
if (events & SS_DETECT && !(skt->state & SOCKET_SUSPEND)) {
int status;
get_socket_status(skt, &status);
if ((skt->state & SOCKET_PRESENT) &&
!(status & SS_DETECT))
socket_shutdown(skt);
if (!(skt->state & SOCKET_PRESENT) &&
(status & SS_DETECT))
socket_insert(skt);
}
if (events & SS_DETECT)
socket_detect_change(skt);
if (events & SS_BATDEAD)
send_event(skt, CS_EVENT_BATTERY_DEAD, CS_EVENT_PRI_LOW);
if (events & SS_BATWARN)
......@@ -839,21 +865,17 @@ static int pccardd(void *__skt)
}
remove_wait_queue(&skt->thread_wait, &wait);
socket_shutdown(skt);
complete_and_exit(&skt->thread_done, 0);
}
static void parse_events(void *info, u_int events)
void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
{
struct pcmcia_socket *s = info;
spin_lock(&s->thread_lock);
s->thread_events |= events;
spin_unlock(&s->thread_lock);
wake_up(&s->thread_wait);
} /* parse_events */
} /* pcmcia_parse_events */
/*======================================================================
......@@ -1114,9 +1136,6 @@ int pcmcia_deregister_client(client_handle_t handle)
handle->event_handler = NULL;
}
if (--s->real_clients == 0)
register_callback(s, NULL, NULL);
return CS_SUCCESS;
} /* deregister_client */
......@@ -1531,11 +1550,6 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
if (client == NULL)
return CS_OUT_OF_RESOURCE;
if (++s->real_clients == 1) {
register_callback(s, &parse_events, s);
parse_events(s, SS_DETECT);
}
*handle = client;
client->state &= ~CLIENT_UNBOUND;
client->Socket = s;
......@@ -2213,7 +2227,7 @@ int pcmcia_eject_card(client_handle_t handle, client_req_t *req)
if (ret != 0)
break;
socket_shutdown(skt);
socket_remove(skt);
ret = CS_SUCCESS;
} while (0);
up(&skt->skt_sem);
......@@ -2504,6 +2518,7 @@ EXPORT_SYMBOL(pcmcia_write_memory);
EXPORT_SYMBOL(dead_socket);
EXPORT_SYMBOL(CardServices);
EXPORT_SYMBOL(MTDHelperEntry);
EXPORT_SYMBOL(pcmcia_parse_events);
struct class pcmcia_socket_class = {
.name = "pcmcia_socket",
......
......@@ -64,10 +64,8 @@ static struct pci_driver i82092aa_pci_drv = {
/* the pccard structure and its functions */
static struct pccard_operations i82092aa_operations = {
.owner = THIS_MODULE,
.init = i82092aa_init,
.suspend = i82092aa_suspend,
.register_callback = i82092aa_register_callback,
.get_status = i82092aa_get_status,
.get_socket = i82092aa_get_socket,
.set_socket = i82092aa_set_socket,
......@@ -85,12 +83,6 @@ struct socket_info {
3 = operational card */
int io_base; /* base io address of the socket */
unsigned int pending_events; /* Pending events on this interface */
void (*handler)(void *info, u_int events);
/* callback to the driver of the card */
void *info; /* to be passed to the handler */
struct pcmcia_socket socket;
struct pci_dev *dev; /* The PCI device for the socket */
};
......@@ -142,6 +134,7 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
sockets[i].socket.map_size = 0x1000;
sockets[i].socket.irq_mask = 0;
sockets[i].socket.pci_irq = dev->irq;
sockets[i].socket.owner = THIS_MODULE;
sockets[i].number = i;
......@@ -324,23 +317,6 @@ static int to_cycles(int ns)
/* Interrupt handler functionality */
static void i82092aa_bh(void *dummy)
{
unsigned int events;
int i;
for (i=0; i < socket_count; i++) {
events = xchg(&(sockets[i].pending_events),0);
printk("events = %x \n",events);
if (sockets[i].handler)
sockets[i].handler(sockets[i].info, events);
}
}
static DECLARE_WORK(i82092aa_task, i82092aa_bh, NULL);
static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs)
{
int i;
......@@ -367,8 +343,7 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs)
csc = indirect_read(i,I365_CSC); /* card status change register */
if ((csc==0) || /* no events on this socket */
(sockets[i].handler==NULL)) /* no way to handle events */
if (csc==0) /* no events on this socket */
continue;
handled = 1;
events = 0;
......@@ -389,8 +364,7 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs)
}
if (events) {
sockets[i].pending_events |= events;
schedule_work(&i82092aa_task);
pcmcia_parse_events(&sockets[i].socket, events);
}
active |= events;
}
......@@ -475,16 +449,6 @@ static int i82092aa_suspend(struct pcmcia_socket *sock)
return retval;
}
static int i82092aa_register_callback(struct pcmcia_socket *socket, void (*handler)(void *, unsigned int), void * info)
{
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
enter("i82092aa_register_callback");
sockets[sock].handler = handler;
sockets[sock].info = info;
leave("i82092aa_register_callback");
return 0;
} /* i82092aa_register_callback */
static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)
{
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
......
......@@ -35,7 +35,6 @@ static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_ma
static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem);
static int i82092aa_init(struct pcmcia_socket *socket);
static int i82092aa_suspend(struct pcmcia_socket *socket);
static int i82092aa_register_callback(struct pcmcia_socket *socket, void (*handler)(void *, unsigned int), void * info);
#endif
......@@ -164,8 +164,6 @@ struct i82365_socket {
ioaddr_t ioaddr;
u_short psock;
u_char cs_irq, intr;
void (*handler)(void *info, u_int events);
void *info;
union {
cirrus_state_t cirrus;
vg46x_state_t vg46x;
......@@ -863,35 +861,6 @@ static void __init isa_probe(void)
/*====================================================================*/
static u_int pending_events[8];
static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
static void pcic_bh(void *dummy)
{
u_int events;
int i;
for (i=0; i < sockets; i++) {
spin_lock_irq(&pending_event_lock);
events = pending_events[i];
pending_events[i] = 0;
spin_unlock_irq(&pending_event_lock);
/*
SS_DETECT events need a small delay here. The reason for this is that
the "is there a card" electronics need time to see the card after the
"we have a card coming in" electronics have seen it.
*/
if (events & SS_DETECT)
mdelay(4);
if (socket[i].handler)
socket[i].handler(socket[i].info, events);
}
}
static DECLARE_WORK(pcic_task, pcic_bh, NULL);
static unsigned long last_detect_jiffies;
static irqreturn_t pcic_interrupt(int irq, void *dev,
struct pt_regs *regs)
{
......@@ -911,26 +880,12 @@ static irqreturn_t pcic_interrupt(int irq, void *dev,
handled = 1;
ISA_LOCK(i, flags);
csc = i365_get(i, I365_CSC);
if ((csc == 0) || (!socket[i].handler) ||
(i365_get(i, I365_IDENT) & 0x70)) {
if ((csc == 0) || (i365_get(i, I365_IDENT) & 0x70)) {
ISA_UNLOCK(i, flags);
continue;
}
events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
/* Several sockets will send multiple "new card detected"
events in rapid succession. However, the rest of the pcmcia expects
only one such event. We just ignore these events by having a
timeout */
if (events) {
if ((jiffies - last_detect_jiffies)<(HZ/20))
events = 0;
last_detect_jiffies = jiffies;
}
if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
else {
......@@ -941,12 +896,9 @@ static irqreturn_t pcic_interrupt(int irq, void *dev,
ISA_UNLOCK(i, flags);
DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events);
if (events) {
spin_lock(&pending_event_lock);
pending_events[i] |= events;
spin_unlock(&pending_event_lock);
schedule_work(&pcic_task);
}
if (events)
pcmcia_parse_events(&socket[i].socket, events);
active |= events;
}
if (!active) break;
......@@ -968,16 +920,6 @@ static void pcic_interrupt_wrapper(u_long data)
/*====================================================================*/
static int pcic_register_callback(struct pcmcia_socket *s, void (*handler)(void *, unsigned int), void * info)
{
unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
socket[sock].handler = handler;
socket[sock].info = info;
return 0;
} /* pcic_register_callback */
/*====================================================================*/
static int i365_get_status(u_short sock, u_int *value)
{
u_int status;
......@@ -1400,10 +1342,8 @@ static int pcic_suspend(struct pcmcia_socket *sock)
}
static struct pccard_operations pcic_operations = {
.owner = THIS_MODULE,
.init = pcic_init,
.suspend = pcic_suspend,
.register_callback = pcic_register_callback,
.get_status = pcic_get_status,
.get_socket = pcic_get_socket,
.set_socket = pcic_set_socket,
......@@ -1464,6 +1404,7 @@ static int __init init_i82365(void)
for (i = 0; i < sockets; i++) {
socket[i].socket.dev.dev = &i82365_device.dev;
socket[i].socket.ss_entry = &pcic_operations;
socket[i].socket.owner = THIS_MODULE;
socket[i].number = i;
ret = pcmcia_register_socket(&socket[i].socket);
if (ret && i--) {
......
......@@ -38,15 +38,13 @@
#include <linux/init.h>
#include <linux/config.h>
#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/notifier.h>
#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/io.h>
......@@ -263,29 +261,27 @@ static int sa1100_pcmcia_suspend(struct pcmcia_socket *sock)
return ret;
}
static spinlock_t status_lock = SPIN_LOCK_UNLOCKED;
/* sa1100_pcmcia_task_handler()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Processes serviceable socket events using the "eventd" thread context.
*
* Event processing (specifically, the invocation of the Card Services event
* callback) occurs in this thread rather than in the actual interrupt
* handler due to the use of scheduling operations in the PCMCIA core.
/* sa1100_check_status()
* ^^^^^^^^^^^^^^^^^^^^^
*/
static void sa1100_pcmcia_task_handler(void *data)
static void sa1100_check_status(struct sa1100_pcmcia_socket *skt)
{
struct sa1100_pcmcia_socket *skt = data;
unsigned int events;
DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
do {
unsigned int status;
unsigned long flags;
status = sa1100_pcmcia_skt_state(skt);
spin_lock_irqsave(&status_lock, flags);
events = (status ^ skt->status) & skt->cs_state.csc_mask;
skt->status = status;
spin_unlock_irqrestore(&status_lock, flags);
DEBUG(2, "events: %s%s%s%s%s%s\n",
events == 0 ? "<NONE>" : "",
......@@ -295,8 +291,8 @@ static void sa1100_pcmcia_task_handler(void *data)
events & SS_BATWARN ? "BATWARN " : "",
events & SS_STSCHG ? "STSCHG " : "");
if (events && skt->handler != NULL)
skt->handler(skt->handler_info, events);
if (events)
pcmcia_parse_events(&skt->socket, events);
} while (events);
}
......@@ -311,7 +307,7 @@ static void sa1100_pcmcia_poll_event(unsigned long dummy)
mod_timer(&skt->poll_timer, jiffies + SA1100_PCMCIA_POLL_PERIOD);
schedule_work(&skt->work);
sa1100_check_status(skt);
}
......@@ -330,44 +326,11 @@ static irqreturn_t sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *r
DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
schedule_work(&skt->work);
sa1100_check_status(skt);
return IRQ_HANDLED;
}
/* sa1100_pcmcia_register_callback()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the register_callback() operation for the in-kernel
* PCMCIA service (formerly SS_RegisterCallback in Card Services). If
* the function pointer `handler' is not NULL, remember the callback
* location in the state for `sock', and increment the usage counter
* for the driver module. (The callback is invoked from the interrupt
* service routine, sa1100_pcmcia_interrupt(), to notify Card Services
* of interesting events.) Otherwise, clear the callback pointer in the
* socket state and decrement the module usage count.
*
* Returns: 0
*/
static int
sa1100_pcmcia_register_callback(struct pcmcia_socket *sock,
void (*handler)(void *, unsigned int),
void *info)
{
struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
if (handler) {
if (!try_module_get(skt->ops->owner))
return -ENODEV;
skt->handler_info = info;
skt->handler = handler;
} else {
skt->handler = NULL;
module_put(skt->ops->owner);
}
return 0;
}
/* sa1100_pcmcia_get_status()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -655,10 +618,8 @@ static CLASS_DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
static struct pccard_operations sa11xx_pcmcia_operations = {
.owner = THIS_MODULE,
.init = sa1100_pcmcia_sock_init,
.suspend = sa1100_pcmcia_suspend,
.register_callback = sa1100_pcmcia_register_callback,
.get_status = sa1100_pcmcia_get_status,
.get_socket = sa1100_pcmcia_get_socket,
.set_socket = sa1100_pcmcia_set_socket,
......@@ -765,10 +726,9 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
memset(skt, 0, sizeof(*skt));
skt->socket.ss_entry = &sa11xx_pcmcia_operations;
skt->socket.owner = ops->owner;
skt->socket.dev.dev = dev;
INIT_WORK(&skt->work, sa1100_pcmcia_task_handler, skt);
init_timer(&skt->poll_timer);
skt->poll_timer.function = sa1100_pcmcia_poll_event;
skt->poll_timer.data = (unsigned long)skt;
......
......@@ -59,8 +59,6 @@ struct sa1100_pcmcia_socket {
unsigned int status;
socket_state_t cs_state;
void (*handler)(void *, unsigned int);
void *handler_info;
unsigned short spd_io[MAX_IO_WIN];
unsigned short spd_mem[MAX_WIN];
......@@ -75,7 +73,6 @@ struct sa1100_pcmcia_socket {
unsigned int irq_state;
struct timer_list poll_timer;
struct work_struct work;
};
struct pcmcia_low_level {
......
......@@ -116,8 +116,6 @@ static struct pccard_operations tcic_operations;
struct tcic_socket {
u_short psock;
void (*handler)(void *info, u_int events);
void *info;
u_char last_sstat;
u_char id;
struct pcmcia_socket socket;
......@@ -433,10 +431,9 @@ static int __init init_tcic(void)
for (i = 0; i < sock; i++) {
if ((i == ignore) || is_active(i)) continue;
socket_table[sockets].psock = i;
socket_table[sockets].handler = NULL;
socket_table[sockets].info = NULL;
socket_table[sockets].id = get_tcic_id();
socket_table[sockets].socket.owner = THIS_MODULE;
/* only 16-bit cards, memory windows must be size-aligned */
/* No PCI or CardBus support */
socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
......@@ -558,26 +555,6 @@ static void __exit exit_tcic(void)
/*====================================================================*/
static u_int pending_events[2];
static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
static void tcic_bh(void *dummy)
{
u_int events;
int i;
for (i=0; i < sockets; i++) {
spin_lock_irq(&pending_event_lock);
events = pending_events[i];
pending_events[i] = 0;
spin_unlock_irq(&pending_event_lock);
if (socket_table[i].handler)
socket_table[i].handler(socket_table[i].info, events);
}
}
static DECLARE_WORK(tcic_task, tcic_bh, NULL);
static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
{
int i, quick = 0;
......@@ -605,7 +582,7 @@ static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
quick = 1;
}
if ((latch == 0) || (socket_table[psock].handler == NULL))
if (latch == 0)
continue;
events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
......@@ -617,10 +594,7 @@ static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
}
if (events) {
spin_lock(&pending_event_lock);
pending_events[i] |= events;
spin_unlock(&pending_event_lock);
schedule_work(&tcic_task);
pcmcia_parse_events(&socket_table[i].socket, events);
}
}
......@@ -645,16 +619,6 @@ static void tcic_timer(u_long data)
/*====================================================================*/
static int tcic_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
{
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
socket_table[psock].handler = handler;
socket_table[psock].info = info;
return 0;
} /* tcic_register_callback */
/*====================================================================*/
static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
{
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
......@@ -915,10 +879,8 @@ static int tcic_suspend(struct pcmcia_socket *sock)
}
static struct pccard_operations tcic_operations = {
.owner = THIS_MODULE,
.init = tcic_init,
.suspend = tcic_suspend,
.register_callback = tcic_register_callback,
.get_status = tcic_get_status,
.get_socket = tcic_get_socket,
.set_socket = tcic_set_socket,
......
......@@ -250,7 +250,6 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
if (state->flags & SS_DEBOUNCED) {
/* The insertion debounce period has ended. Clear any pending insertion events */
socket->events &= ~SS_DETECT;
state->flags &= ~SS_DEBOUNCED; /* SS_DEBOUNCED is oneshot */
}
yenta_set_power(socket, state);
......@@ -420,19 +419,6 @@ static unsigned int yenta_events(struct yenta_socket *socket)
}
static void yenta_bh(void *data)
{
struct yenta_socket *socket = data;
unsigned int events;
spin_lock_irq(&socket->event_lock);
events = socket->events;
socket->events = 0;
spin_unlock_irq(&socket->event_lock);
if (socket->handler)
socket->handler(socket->info, events);
}
static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned int events;
......@@ -440,10 +426,7 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
events = yenta_events(socket);
if (events) {
spin_lock(&socket->event_lock);
socket->events |= events;
spin_unlock(&socket->event_lock);
schedule_work(&socket->tq_task);
pcmcia_parse_events(&socket->socket, events);
return IRQ_HANDLED;
}
return IRQ_NONE;
......@@ -771,21 +754,9 @@ static void yenta_close(struct pci_dev *dev)
}
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,
.get_status = yenta_get_status,
.get_socket = yenta_get_socket,
.set_socket = yenta_set_socket,
......@@ -860,11 +831,11 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
socket->socket.ss_entry = &yenta_socket_operations;
socket->socket.dev.dev = &dev->dev;
socket->socket.driver_data = socket;
socket->socket.owner = THIS_MODULE;
/* prepare struct yenta_socket */
socket->dev = dev;
pci_set_drvdata(dev, socket);
spin_lock_init(&socket->event_lock);
/*
* Do some basic sanity checking..
......@@ -907,8 +878,6 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
/* We must finish initialization here */
INIT_WORK(&socket->tq_task, yenta_bh, socket);
if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, SA_SHIRQ, socket->dev->dev.name, socket)) {
/* No IRQ or request_irq failed. Poll */
socket->cb_irq = 0; /* But zero is a valid IRQ number. */
......
......@@ -99,11 +99,6 @@ struct yenta_socket {
struct pci_dev *dev;
int cb_irq, io_irq;
void *base;
void (*handler)(void *, unsigned int);
void *info;
spinlock_t event_lock;
unsigned int events;
struct work_struct tq_task;
struct timer_list poll_timer;
struct pcmcia_socket socket;
......
......@@ -119,7 +119,6 @@ typedef struct cb_bridge_map {
struct pcmcia_socket;
struct pccard_operations {
struct module *owner;
int (*init)(struct pcmcia_socket *sock);
int (*suspend)(struct pcmcia_socket *sock);
int (*register_callback)(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info);
......@@ -169,6 +168,7 @@ struct config_t;
struct region_t;
struct pcmcia_socket {
struct module *owner;
spinlock_t lock;
struct pccard_operations * ss_entry;
socket_state_t socket;
......@@ -235,6 +235,7 @@ struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr);
extern void pcmcia_parse_events(struct pcmcia_socket *socket, unsigned int events);
extern int pcmcia_register_socket(struct pcmcia_socket *socket);
extern void pcmcia_unregister_socket(struct pcmcia_socket *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