Доброго времени суток, продолжая тему о драйверах для IP-CORE Microblaze, столкнулся со следующей проблемой:
Решил написать драйвер который обрабатывает внешние прерывание по нажатию на кнопку. Драйвер в системе регистрируется нормально, но обработчик прерывания никак не реагирует.
Код драйвера:
Код
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
static int irq;
static irqreturn_t test_irq_handler(int irq, void *dev_id)
{
printk(KERN_ALERT "all ok!\n");
return IRQ_HANDLED;
}
static int __init kruger_driver_init(void)
{
struct device_node *root_dn;
struct device_node *kruger_gpio;
struct resource resource;
int result;
unsigned int start_addr;
unsigned long *virt_addr;
printk(KERN_ALERT "Kruger driver init\n");
root_dn = of_find_node_by_path("/");
kruger_gpio = of_find_node_by_name(root_dn, "gpiob");
if (!kruger_gpio)
{
printk(KERN_ALERT "GPIO buttons not found in DTF\n");
return -ENODEV;
}
result = of_address_to_resource(kruger_gpio, 0, &resource);
if (result < 0)
{
printk(KERN_ALERT "GPIO buttons: error address to resource");
return -ENODEV;
}
printk(KERN_ALERT "GPIO buttons: reg. size=%d Bytes\n", (u32)resource.end-(u32)resource.start);
start_addr = (unsigned int)resource.start;
irq = of_irq_to_resource(kruger_gpio, 0, &resource);
if (irq == NO_IRQ)
{
printk(KERN_ALERT "GPIO buttons: of_irq_to_resource() failed\n");
of_node_put(kruger_gpio);
return -ENODEV;
}
printk(KERN_ALERT "GPIO buttons: irq=%d\n", irq);
virt_addr = of_iomap(kruger_gpio, 0);
printk(KERN_ALERT "GPIO buttons: at 0x%08X mapped to 0x%08X\n", start_addr, (u32)virt_addr);
result = request_irq(irq, &test_irq_handler, IRQF_TRIGGER_MASK, "Gpio Buttons", NULL);
if (result < 0)
{
printk(KERN_ALERT "GPIO buttons: error to request IRQ%d : %d\n", irq, result);
of_node_put(kruger_gpio);
return -ENODEV;
}
printk(KERN_ALERT "GPIO buttons module inserted successfully\n");
return 0;
}
static void __exit kruger_driver_exit(void)
{
printk(KERN_ALERT "Kruger driver exit\n");
}
module_init(kruger_driver_init);
module_exit(kruger_driver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kruger");
MODULE_DESCRIPTION("Gpio example driver");
Часть DTF-файла отвечающая за кнопки:
Код
Push_Buttons: gpiob@81400000 {
compatible = "xlnx,xps-gpio-2.00.a", "xlnx,xps-gpio-1.00.a";
interrupt-parent = <&xps_intc_0>;
interrupts = < 1 2 >;
reg = < 0x81400000 0x10000 >;
xlnx,all-inputs = <0x1>;
xlnx,all-inputs-2 = <0x0>;
xlnx,dout-default = <0x0>;
xlnx,dout-default-2 = <0x0>;
xlnx,family = "spartan3adsp";
xlnx,gpio-width = <0x4>;
xlnx,gpio2-width = <0x20>;
xlnx,interrupt-present = <0x1>;
xlnx,is-dual = <0x0>;
xlnx,tri-default = <0xffffffff>;
xlnx,tri-default-2 = <0xffffffff>;
};
Часть лога при инициализации драйвера:
Код
[ 7.635430] Kruger driver init
[ 7.637493] GPIO buttons: reg. size=65535 Bytes
[ 7.642095] GPIO buttons: irq=1
[ 7.645278] GPIO buttons: at 0x81400000 mapped to 0xC80A0000
[ 7.651114] GPIO buttons module inserted successfully
Вывод файла /proc/interrupt
Код
CPU0
1: 0 level Xilinx INTC Gpio Buttons
2: 546096 edge Xilinx INTC timer
4: 1193 edge Xilinx INTC uartlite
Кто-то пробовал "запускать" внешние прерывания по линухом? В чем может быть проблема?
ЗЫ: Задавал этот же вопрос на офф. сайте Xilinx в разделе Embedded Linux - молчат как партизаны