2011-07-15 02:47:35     TWI i2c read/ write problem from ISR handler function

Document created by Aaronwu Employee on Aug 27, 2013
Version 1Show Document
  • View in full screen mode

2011-07-15 02:47:35     TWI i2c read/ write problem from ISR handler function

Sakthivel Perumal (INDIA)

Message: 102416   

 

Hi,

 

            I am working with 2010R1 distribution and tool chain for BF527 custom board. The board is having ADP5587 keypaad/gpio expander chip and its INTR pin connected to the PortH 15 of BF527.. i have configured the PH15 of bf527 as gpio for input and interrupt configuration to Falling edge(default state of that pin is level high) using

 

request_irq(IRQ_PH15,(void *) adp5587_isr_handler,IRQF_TRIGGER_FALLING,"adp5587",NULL);

 

 

 

the adp5587 driver structure is,

 

static struct file_operations adp5587_gpio_exp_driver_fops = {

 

.owner = THIS_MODULE,

 

.read = adp5587_gpio_exp_read,

 

.write = adp5587_gpio_exp_write,

 

.ioctl = adp5587_gpio_exp_ioctl,

 

.open = adp5587_gpio_exp_open,

 

.release= adp5587_gpio_exp_close,

 

};

 

 

 

the I2c address for adp5587 is 68 >>1(read) and 69>>1 (write)..the adp5587 is configured for gpio and the corresponding configuration of pins and registers through twi i2c . the folowing code i have added for accessing i2c

 

struct i2c_client *i2c_adp_5587_gpio_exp_client;

 

static struct i2c_driver adp5587_gpio_driver;

 

struct  adp5587_gpio_exp{

 

                               struct i2c_client *client;

 

                                         };

 

int adp5587_gpio_exp_i2c_write(struct i2c_client *client, u8 reg, u8 value)

 

{

 

gpio_exp_dbg(KERN_ERR "adp5587_gpio_exp i2c write start \n");

 

 

 

return i2c_smbus_write_byte_data(client, reg, value);

 

}

 

int adp5587_gpio_exp_i2c_read(struct i2c_client *client, u8 reg)

 

{

 

gpio_exp_dbg(KERN_ERR "adp5587_gpio_exp i2c read start \n");

 

return i2c_smbus_read_byte_data(client, reg);

 

}

 

 

 

{

 

struct adp5587_gpio_exp *add_i2c;

 

struct device *dev = &client->dev;

 

 

 

gpio_exp_dbg(KERN_INFO "\n adp5587_gpio_exp I2C Probe function ");

 

if (!i2c_check_functionality(client->adapter,I2C_FUNC_SMBUS_BYTE_DATA))

 

{

 

dev_err(&client->dev, "SMBUS Byte Data not Supported\n");

 

return -EIO;

 

}

 

client->addr=I2C_ADP_5587 >> 1;

 

 

 

add_i2c = kzalloc(sizeof(struct adp5587_gpio_exp), GFP_KERNEL);

 

if (add_i2c == NULL)

 

{

 

dev_err(dev, "failed to allocate memory \n");

 

return -ENOMEM;

 

}

 

add_i2c->client = client;

 

gpio_exp_dbg(KERN_INFO "\n adp5587_gpio_exp I2C clent addr %d",client->addr);

 

i2c_adp_5587_gpio_exp_client = client;

 

i2c_set_clientdata(client, add_i2c);

 

 

 

dev_info(dev, "adp5587 gpio exp i2c client created\n");

 

return 0;

 

}

 

static int __devexit adp5587_gpio_exp_remove(struct i2c_client *client)

 

{

 

struct adp5587_gpio_exp *remove_i2c= i2c_get_clientdata(client);

 

i2c_set_clientdata(remove_i2c, NULL);

 

kfree(remove_i2c);

 

return 0;

 

}

 

static const struct i2c_device_id adp5587_gpio_id[] = {

 

{ADP5587_GPIO_DRV_NAME, 0},

 

{}

 

};

 

MODULE_DEVICE_TABLE(i2c, adp5587_gpio_id);

 

static struct i2c_driver adp5587_gpio_driver = {

 

.driver = {

 

.name = ADP5587_GPIO_DRV_NAME,

 

},

 

.probe = adp5587_gpio_exp_probe,

 

.remove = __devexit_p(adp5587_gpio_exp_remove),

 

.id_table = adp5587_gpio_id,

 

};

 

/* ADP 5587 GPIO Expander i2c driver */

 

static struct class *adp_5587_gpio_exp_class;

 

static int __init adp_5587_gpio_exp_module_init(void)

 

{

 

int ret, err = 0;

 

ret = register_chrdev(...........................);

 

if (ret < 0) {

 

}

 

/* udev support */

 

adp_5587_gpio_exp_class = class_create(.............................);

 

}

 

device_create(.................);

 

i2c_add_driver(&adp5587_gpio_driver);

 

gpio_exp_dbg("\n %s register major %d\n",ADP5587_GPIO_DRV_NAME,adp_5587_gpio_exp_major);

 

return 0;

 

}

 

module_init(adp_5587_gpio_exp_module_init);

 

static void adp_5587_gpio_exp_module_exit(void)

 

{

 

i2c_del_driver(&adp5587_gpio_driver);

 

device_destroy(..........));

 

class_destroy(...................);

 

unregister_chrdev(......................);

 

}

 

module_exit(adp_5587_gpio_exp_module_exit);

static int adp5587_gpio_exp_probe(struct i2c_client *client,const struct i2c_device_id *id)

 

I have created a stand alone application named MYWORK to access the driver ....  By using the  driver read()  function i will receive the soure for the interrupt..   the configuration of adp5587 is working fine.. when ever the interuupt received from adp5587 i want to read the interrupt pin then write 1 to clear the interrupt status register .. i am receiving ISR but when ever i try to read the adp5587 reg through i2c hardware trace is comming continuously.....  i have attached the response from the driver in attachment.. i am eagerly waiting for the solution for this ....

 

thanks & regards,

 

Sakthi.

 

adp5587_driver_output.txt

QuoteReplyEditDelete

 

 

2011-07-15 03:25:06     TWI i2c read/ write problem from ISR handler function

Michael Hennerich (GERMANY)

Message: 102429    I wonder why you are trying to a write a driver on your own?

If you are interested in ADP5587 GPIO and Interrupt capabilities use

this one:

 

  wiki.analog.com/resources/tools-software/linux-drivers/gpio/adp5588-gpio

 

In case you also like to have keypad functionality use this one:

 

  wiki.analog.com/resources/tools-software/linux-drivers/input-keyboard/adp5588

 

 

Regarding your problem here:

You are not allowed to call sleeping functions such as I2C transfers

from the hard IRQ handler.

 

-Michael

QuoteReplyEditDelete

 

 

2011-07-15 04:27:34     Re: TWI i2c read/ write problem from ISR handler function

Sakthivel Perumal (INDIA)

Message: 102431   

 

thank u .. also i am expecting ur valuble reply from ur experience..

 

i have a plan to use that existing driver.. But i can't have any clear idea from that one abt one thing.. that is i have used the adp5587  18 pin gpio's... The INTR  of adp5587 pin is connected  to the  port H 15 of BF 527 .. How can i get the adp5587 gpio pin which is caused the interrupt whenever receving interrupt in bf 527 port H 15 ISR?  or we need to requst irq for  all the adp5587   pins like our bf527 gpio pins?  if  it,s cleared i will use the existing driver only..

 

due to this, i plan to do separate driver like when ever receving ISR  from bf527 port H 15  we can get the interrupt status by reading the interrupt status registers of adp5587 and clear by writing 1.. But it also leads to the issue.. the out response i got shown below... wheather this one is possible or not?

 

adp5587_gpio_exp configuration:

adp5587_gpio_exp i2c write  start

adp5587_gpio_exp i2c read  start

u8WriteData = 0x0 u8ReadData = 0x0

adp5587_gpio_exp i2c write  start

adp5587_gpio_exp i2c read  start

u8WriteData = 0x2 u8ReadData = 0x2

adp5587_gpio_exp i2c write  start

adp5587_gpio_exp i2c read  start

u8WriteData = 0xff u8ReadData = 0xff

adp5587_gpio_exp i2c write  start

adp5587_gpio_exp i2c read  start

u8WriteData = 0x2 u8ReadData = 0x2

adp5587_gpio_exp i2c write  start

adp5587_gpio_exp i2c read  start

u8WriteData = 0x35 u8ReadData = 0x35

adp5587_gpio_exp i2c write  start

adp5587_gpio_exp i2c read  start

u8WriteData = 0x2 u8ReadData = 0x2

adp5587_gpio_exp i2c write  start

adp5587_gpio_exp i2c read  start

i2c i2c-0: smbus transfer timeout

adp 5587 gpio exp configuration eror 6

 

Gpio expander device opened succesfully

 

gpio_exp thread run

gpio_exp thread task id

 

adp5587 gpio exp intrrupt ISR

adp5587_gpio_exp i2c read  start

BUG: scheduling while atomic: MYWORK/266/0x04010000

Modules linked in:

 

ADSP-BF527-0.2 600(MHz CCLK) 120(MHz SCLK) (mpu off)

Linux version 2.6.34.7-ADI-2010R1 (nw_sb4@linux-m2nd) (gcc version 4.3.5 (ADI-20

10R1-RC4) ) #423 Fri Jul 15 10:38:14 IST 2011

 

SEQUENCER STATUS:               Not tainted

SEQSTAT: 00000000  IPEND: 0810  IMASK: 0000  SYSCFG: 0006

  Global Interrupts Disabled (IPEND[4])

  Peripheral interrupts masked off

  Kernel interrupts masked off

  EXCAUSE   : 0x0

  interrupts disabled

  physical IVG11 asserted : <0xffa00ee8> { _evt_evt11 + 0x0 }

  logical irq   6 mapped  : <0xffa0039c> { _bfin_coretmr_interrupt + 0x0 }

  logical irq  27 mapped  : <0x000d97c8> { _bfin_twi_interrupt_entry + 0x0 }

  logical irq  31 mapped  : <0x000b9dac> { _bfin_serial_dma_rx_int + 0x0 }

  logical irq  32 mapped  : <0x000b9b20> { _bfin_serial_dma_tx_int + 0x0 }

  logical irq  35 mapped  : <0x000d42a4> { _bfin_mac_interrupt + 0x0 }

  logical irq 118 mapped  : <0x000e0b9c> { _ADP5587_GPIO_EXP_ISR_Handler + 0x0 }

RETE: <0x00000000> /* Maybe null pointer? */

RETN: <0x049b4000> /* kernel dynamic memory */

RETX: <0x04d0e90a> [ /lib/libc.so.0 + 0xe90a ]

RETS: <0x049ba58a> [ /MYWORK + 0x258a ]

PC  : <0x049ba59a> [ /MYWORK + 0x259a ]

PROCESSOR STATE:

R0 : 00000001    R1 : 00000001    R2 : 00000000    R3 : 00000000

R4 : 00000001    R5 : 049fff80    R6 : 049fff60    R7 : 049fffa2

P0 : 04c0894c    P1 : 049d7718    P2 : 04c03708    P3 : 04c01448

P4 : 04c0e468    P5 : 049c0260    FP : 049ffe84    SP : 049b3f24

LB0: 04d1d8c1    LT0: 04d1d8be    LC0: 00000000

LB1: 04d1db2d    LT1: 04d1dae2    LC1: 00000000

B0 : 00000137    L0 : 00000000    M0 : fffffffc    I0 : 00000000

B1 : 000000c0    L1 : 00000000    M1 : 00000001    I1 : 00000001

B2 : 7ffff000    L2 : 00000000    M2 : 00001802    I2 : 00000003

B3 : 00000000    L3 : 00000000    M3 : 0000005b    I3 : 00000006

A0.w: 00000000   A0.x: 00000000   A1.w: 00000000   A1.x: 00000000

USP : 049ffdec  ASTAT: 02003044

 

BUG: scheduling while atomic: MYWORK/266/0x00010000

Modules linked in:

 

ADSP-BF527-0.2 600(MHz CCLK) 120(MHz SCLK) (mpu off)

Linux version 2.6.34.7-ADI-2010R1 (nw_sb4@linux-m2nd) (gcc version 4.3.5 (ADI-20

10R1-RC4) ) #423 Fri Jul 15 10:38:14 IST 2011

 

SEQUENCER STATUS:               Not tainted

SEQSTAT: 00000000  IPEND: 0810  IMASK: 0000  SYSCFG: 0006

  Global Interrupts Disabled (IPEND[4])

  Peripheral interrupts masked off

  Kernel interrupts masked off

  EXCAUSE   : 0x0

  interrupts disabled

  physical IVG11 asserted : <0xffa00ee8> { _evt_evt11 + 0x0 }

  logical irq   6 mapped  : <0xffa0039c> { _bfin_coretmr_interrupt + 0x0 }

  logical irq  27 mapped  : <0x000d97c8> { _bfin_twi_interrupt_entry + 0x0 }

  logical irq  31 mapped  : <0x000b9dac> { _bfin_serial_dma_rx_int + 0x0 }

  logical irq  32 mapped  : <0x000b9b20> { _bfin_serial_dma_tx_int + 0x0 }

  logical irq  35 mapped  : <0x000d42a4> { _bfin_mac_interrupt + 0x0 }

  logical irq 118 mapped  : <0x000e0b9c> { _ADP5587_GPIO_EXP_ISR_Handler + 0x0 }

RETE: <0x00000000> /* Maybe null pointer? */

RETN: <0x049b4000> /* kernel dynamic memory */

RETX: <0x04d0e90a> [ /lib/libc.so.0 + 0xe90a ]

RETS: <0x049ba58a> [ /MYWORK + 0x258a ]

PC  : <0x049ba59a> [ /MYWORK + 0x259a ]

PROCESSOR STATE:

R0 : 00000001    R1 : 00000001    R2 : 00000000    R3 : 00000000

R4 : 00000001    R5 : 049fff80    R6 : 049fff60    R7 : 049fffa2

P0 : 04c0894c    P1 : 049d7718    P2 : 04c03708    P3 : 04c01448

P4 : 04c0e468    P5 : 049c0260    FP : 049ffe84    SP : 049b3f24

LB0: 04d1d8c1    LT0: 04d1d8be    LC0: 00000000

LB1: 04d1db2d    LT1: 04d1dae2    LC1: 00000000

B0 : 00000137    L0 : 00000000    M0 : fffffffc    I0 : 00000000

B1 : 000000c0    L1 : 00000000    M1 : 00000001    I1 : 00000001

B2 : 7ffff000    L2 : 00000000    M2 : 00001802    I2 : 00000003

B3 : 00000000    L3 : 00000000    M3 : 0000005b    I3 : 00000006

A0.w: 00000000   A0.x: 00000000   A1.w: 00000000   A1.x: 00000000

USP : 049ffdec  ASTAT: 02003044

 

BUG: scheduling while atomic: MYWORK/266/0x00010000

Modules linked in:

 

ADSP-BF527-0.2 600(MHz CCLK) 120(MHz SCLK) (mpu off)

Linux version 2.6.34.7-ADI-2010R1 (nw_sb4@linux-m2nd) (gcc version 4.3.5 (ADI-20

10R1-RC4) ) #423 Fri Jul 15 10:38:14 IST 2011

 

SEQUENCER STATUS:               Not tainted

SEQSTAT: 00000000  IPEND: 0810  IMASK: 0000  SYSCFG: 0006

  Global Interrupts Disabled (IPEND[4])

  Peripheral interrupts masked off

  Kernel interrupts masked off

  EXCAUSE   : 0x0

  interrupts disabled

  physical IVG11 asserted : <0xffa00ee8> { _evt_evt11 + 0x0 }

  logical irq   6 mapped  : <0xffa0039c> { _bfin_coretmr_interrupt + 0x0 }

  logical irq  27 mapped  : <0x000d97c8> { _bfin_twi_interrupt_entry + 0x0 }

  logical irq  31 mapped  : <0x000b9dac> { _bfin_serial_dma_rx_int + 0x0 }

  logical irq  32 mapped  : <0x000b9b20> { _bfin_serial_dma_tx_int + 0x0 }

  logical irq  35 mapped  : <0x000d42a4> { _bfin_mac_interrupt + 0x0 }

  logical irq 118 mapped  : <0x000e0b9c> { _ADP5587_GPIO_EXP_ISR_Handler + 0x0 }

RETE: <0x00000000> /* Maybe null pointer? */

RETN: <0x049b4000> /* kernel dynamic memory */

RETX: <0x04d0e90a> [ /lib/libc.so.0 + 0xe90a ]

RETS: <0x049ba58a> [ /MYWORK + 0x258a ]

PC  : <0x049ba59a> [ /MYWORK + 0x259a ]

PROCESSOR STATE:

R0 : 00000001    R1 : 00000001    R2 : 00000000    R3 : 00000000

R4 : 00000001    R5 : 049fff80    R6 : 049fff60    R7 : 049fffa2

P0 : 04c0894c    P1 : 049d7718    P2 : 04c03708    P3 : 04c01448

P4 : 04c0e468    P5 : 049c0260    FP : 049ffe84    SP : 049b3f24

LB0: 04d1d8c1    LT0: 04d1d8be    LC0: 00000000

LB1: 04d1db2d    LT1: 04d1dae2    LC1: 00000000

B0 : 00000137    L0 : 00000000    M0 : fffffffc    I0 : 00000000

B1 : 000000c0    L1 : 00000000    M1 : 00000001    I1 : 00000001

B2 : 7ffff000    L2 : 00000000    M2 : 00001802    I2 : 00000003

B3 : 00000000    L3 : 00000000    M3 : 0000005b    I3 : 00000006

A0.w: 00000000   A0.x: 00000000   A1.w: 00000000   A1.x: 00000000

USP : 049ffdec  ASTAT: 02003044

 

i2c i2c-0: smbus transfer timeout

 

adp5587 gpio exp intrrupt 0xffffffff

QuoteReplyEditDelete

 

 

2011-07-15 05:05:11     Re: TWI i2c read/ write problem from ISR handlerfunction

Michael Hennerich (GERMANY)

Message: 102434    As I said before - you can't call any I2C transactions from your hard

IRQ handler/ISR.

Either schedule a workqueue or use threaded interrupts.

 

Regarding the ADP5588/7-gpio driver.

 

Read this first:

  docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gpio-sysfs&s[]=gpio&s[]=poll

 

This driver provides up to 18 GPIOs which in return also can be

requested as interrupts.

If you don't need kernel level interrupt access you can also use poll()

in user space...

 

See note:

With recent kernels (2.6.33+) it is now possible to poll() on a GPIO

simply set “rising”, “falling” or “both” to /sys/class/gpio/gpioX/edge

then poll for POLLPRI on the relevant open+read fd.

 

-Michael

QuoteReplyEditDelete

 

 

2011-07-21 02:33:19     Re: TWI i2c read/ write problem from ISR handlerfunction

Sakthivel Perumal (INDIA)

Message: 102559   

 

Hi  Michael Hennerich,

 

thank very much ...  My driver is working fine by using " request_ threaded_ irq (....)"..  i tried to thank u on monday itself , due to log In problem its delayed.. thank u again..

QuoteReplyEditDelete

Attachments

    Outcomes