How to use mpc8xxx_gpio.c device driver

Ravi Gupta dceravigupta at gmail.com
Wed Aug 18 22:45:02 EST 2010


Hi,

Thanks for all your replies. Now I want to enable interrupts on some GPIO
pins(GPIO pins number 224, 225, 226, 227, 228 and 229 i.e gpiochip224's pins
0 to 5). I configured these pins as input(GPIOF_IN) during gpio request. I
am able to request gpio pins successfully.

#define GPIO_CHIP0_BASE    192
#define GPIO_CHIP0_COUNT   32

#define GPIO_CHIP1_BASE    224
#define GPIO_CHIP1_COUNT   32

#define GPIO(chip, pin) (GPIO_CHIP##chip##_BASE + (pin))

/* Initial GPIO pins setting. */
static struct gpio gpio_pins[] = {
  { GPIO(1,  0), GPIOF_IN,            "Chip 1, Pin 0"  },
  { GPIO(1,  1), GPIOF_IN,            "Chip 1, Pin 1"  },
  { GPIO(1,  2), GPIOF_IN,            "Chip 1, Pin 2"  },
  { GPIO(1,  3), GPIOF_IN,            "Chip 1, Pin 3"  },
  { GPIO(1,  4), GPIOF_IN,            "Chip 1, Pin 4"  },
  { GPIO(1,  5), GPIOF_IN,            "Chip 1, Pin 5"  },
};

static __init int gpio_module_init(void)
{
  int err;
  dev_t devno = 0;

  printk(KERN_INFO "GPIO Driver Version 0.1\n");

  /* resuest the gpio pin */
  err = gpio_request_array(gpio_pins, ARRAY_SIZE(gpio_pins));
  if (err) {
      printk(KERN_WARNING "gpio: unable to request gpio pins\n");
      return -EBUSY;
  }

  /* register interrupts handlers */
  err = gpio_request_irq_array(gpio_irq_pins, ARRAY_SIZE(gpio_irq_pins));
  if (err) {
      printk(KERN_WARNING "gpio: unable to register interrupt handler.\n");
      goto interrupt_fail;
  }
.
.
.
}

Now in order to enable interrupts I have to set the bits corresponding to
these pins in gpiochp Interrupt Mask Register.

My first question is that is there any gpio API call available for doing
this? OR I have to manually memory map the gpio IMR register and set bit
manually? For the time being I have manually set the IMR bit(using memory
map).

Second, in order to register an interrupt handler on a gpio pin, I need a
IRQ number, so how am I going to get that number? From the
Documentation/gpio.txt, it looks to me that gpio_to_irq() function should
give me the irq number, but when I tried to use it, it gives me an error.

#define GPIO_CHIP0_BASE    192
#define GPIO_CHIP0_COUNT   32

#define GPIO_CHIP1_BASE    224
#define GPIO_CHIP1_COUNT   32

#define GPIO(chip, pin) (GPIO_CHIP##chip##_BASE + (pin))

static struct gpio_irq gpio_irq_pins[] = {
  { GPIO(1, 0), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
  { GPIO(1, 1), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
  { GPIO(1, 2), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
  { GPIO(1, 3), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
  { GPIO(1, 4), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
  { GPIO(1, 5), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
};

int gpio_request_irq_array(struct gpio_irq *array, size_t num)
{
  int i, err, irq;

  for (i = 0; i < num; i++, array++) {
    /* get the irq number corresponding to the gpio pin */
    irq = gpio_to_irq(array->gpio);
    if (irq < 0) {
      printk(KERN_ERR "gpio: Trying to get irq number for GPIO%d\n",
array->gpio);
      err = -EINVAL;
      goto err_free;
    }
    printd("gpio: irq number for GPIO%d = %d(i=%d)\n", array->gpio, irq, i);


    /* set the irq type for the gpio pin */
    err = set_irq_type(irq, array->type);
    if (err)
      goto err_free;

    /* register irq handler */
    err = request_irq(irq, gpio_irq_handler, IRQF_SHARED, "GPIO Driver",
NULL);
    if (err) {
      printk(KERN_ERR "gpio: can't get assigned irq for GPIO%d\n",
array->gpio);
      goto err_free;
    }
  }
  return 0;

err_free:
  while (i--)
    free_irq(gpio_to_irq((--array)->gpio), NULL);
  return err;
}

Given above is my driver code, I have implemented a function named
"gpio_request_irq_array" which works in same manner as that of
"gpio_request_array". I am calling in the init function, see the init code
given initially. Now when I load it on my MPC837xERDB board, it gives the
following errors.

[ 1812.776420] GPIO Driver Version 0.1
[ 1812.779985] gpio: Trying to get irq number for GPIO224
[ 1812.785126] gpio: unable to register interrupt handler.
insmod: error inserting './gpio.ko': -1 Invalid parameters

Thanks in advance
Ravi Gupta
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20100818/e473b34e/attachment.html>


More information about the Linuxppc-dev mailing list