failing i2c driver on mpc8xx - interruptible_sleep_on()
Seb James
seb at peak.uklinux.net
Wed Jun 18 23:15:59 EST 2003
Hello all,
I'm attempting to write a driver to communicate on the i2c bus with a
single clock chip. The mpc8xx is the master device and the clock chip
is the slave. Very simple. The clock chip is a ds1307 from Dallas
Semiconductor. Linux kernel version is 2.4.4, modified by Denx Software
Engineering.
I'm using functions in i2c-core.c and i2c-algo-8xx.c. To write a message
(pointed to by msg) to the i2c bus, I call:
i2c_transfer(ds1307_client->adapter, msg, 1);
which is to be found in i2c-core.c and does the following:
I2C_LOCK(adap);
ret = adap->algo->master_xfer(adap,msgs,num);
I2C_UNLOCK(adap);
This locks the i2c adapter (which is a conceptual entity) and then calls
master_xfer(), which is a pointer to cpm_xfer(), which you can find in
i2c-algo-8xx.c. cpm_xfer() sorts some variables and such like and then calls:
cpm_iic_write(), from i2c-algo-8xx.c
This function contains a line:
interruptible_sleep_on(&iic_wait);
Which is causing my mpc8xx to hang (no serial console response, no telnet
access).
cpm_iic_read(), also has an interruptible_sleep_on() call which hangs my
target in the same way.
Does anyone know why this might be? interruptible_sleep_on() is in sched.c
and looks like:
void interruptible_sleep_on(wait_queue_head_t *q)
{
SLEEP_ON_VAR
// SEB: Makes the task an interuptible task, so another task can preempt it
current->state = TASK_INTERRUPTIBLE;
SLEEP_ON_HEAD
schedule();
SLEEP_ON_TAIL
}
where
SLEEP_ON_VAR
SLEEP_ON_HEAD
SLEEP_ON_TAIL
expand to:
#define SLEEP_ON_VAR \
unsigned long flags; \
wait_queue_t wait; \
init_waitqueue_entry(&wait, current);
#define SLEEP_ON_HEAD \
wq_write_lock_irqsave(&q->lock,flags); \
__add_wait_queue(q, &wait); \
wq_write_unlock(&q->lock);
#define SLEEP_ON_TAIL \
wq_write_lock_irq(&q->lock); \
__remove_wait_queue(q, &wait); \
wq_write_unlock_irqrestore(&q->lock,flags);
I am stepping through the code using a bdm debugger and gdb. The debugger
just waits when I try to step into interriptible_sleep_on().
Any help that anyone could offer such as suggestions on how to work out
what this problem is about will be gratefully received.
thanks,
Seb James.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list