On Tue, 25 Mar 2008 19:55:59 +0900
Paul Mundt <[EMAIL PROTECTED]> wrote:

> This is V3 of the SuperH Mobile I2C Controller Driver. A simple Master
> only driver for the I2C block included in processors such as sh7343,
> sh7722 and sh7723. Tested on a sh7722 MigoR using a rs5c372b rtc.
> 
> +#include <asm/io.h>

please use checkpatch.

> +static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
> +                         int op, unsigned char data)
> +{
> +     unsigned char ret = 0;
> +
> +     dev_dbg(pd->dev, "op %d, data in 0x%02x\n", op, data);
> +
> +     spin_lock_irq(&pd->lock);
> +
> +     switch (op) {
> +     case OP_START:
> +             iowrite8(0x94, ICCR(pd));
> +             break;
> +     case OP_TX_ONLY:
> +             iowrite8(data, ICDR(pd));
> +             break;
> +     case OP_TX_STOP:
> +             iowrite8(data, ICDR(pd));
> +             iowrite8(0x90, ICCR(pd));
> +             iowrite8(ICIC_ALE | ICIC_TACKE, ICIC(pd));
> +             break;
> +     case OP_TX_TO_RX:
> +             iowrite8(data, ICDR(pd));
> +             iowrite8(0x81, ICCR(pd));
> +             break;
> +     case OP_RX_ONLY:
> +             ret = ioread8(ICDR(pd));
> +             break;
> +     case OP_RX_STOP:
> +             ret = ioread8(ICDR(pd));
> +             iowrite8(0xc0, ICCR(pd));
> +             break;
> +     }
> +
> +     spin_unlock_irq(&pd->lock);
> +
> +     dev_dbg(pd->dev, "op %d, data out 0x%02x\n", op, ret);
> +     return ret;
> +}

I'd be a bit concerned about reenabling interrupts...

> +static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
> +{
> +     struct platform_device *dev = dev_id;
> +     struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
> +     struct i2c_msg *msg = pd->msg;
> +     unsigned char data, sr;
> +     int wakeup = 0;
> +
> +     sr = ioread8(ICSR(pd));
> +     pd->sr |= sr;
> +
> +     dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
> +            (msg->flags & I2C_M_RD) ? "read" : "write",
> +            pd->pos, msg->len);
> +
> +     if (sr & (ICSR_AL | ICSR_TACK)) {
> +             iowrite8(0, ICIC(pd)); /* disable interrupts */
> +             wakeup = 1;
> +             goto do_wakeup;
> +     }
> +
> +     if (pd->pos == msg->len) {
> +             i2c_op(pd, OP_RX_ONLY, 0);

from the interrupt handler...

> +static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
> +{
> +     struct resource *res;
> +     int ret = -ENXIO;
> +     int q, m;
> +     int k = 0;
> +     int n = 0;
> +
> +     while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) {
> +             for (n = res->start; hook && n <= res->end; n++) {
> +                     if (request_irq(n, sh_mobile_i2c_isr, 0,
> +                                     dev->dev.bus_id, dev))

even though it isn't using IRQF_DISABLED here,


: int request_irq(unsigned int irq, irq_handler_t handler,
:               unsigned long irqflags, const char *devname, void *dev_id)
: {
:       struct irqaction *action;
:       int retval;
: 
: #ifdef CONFIG_LOCKDEP
:       /*
:        * Lockdep wants atomic interrupt handlers:
:        */
:       irqflags |= IRQF_DISABLED;
: #endif

it will do so if lockdep is supported.

_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c

Reply via email to