Hello, thank you very much for your answer. Am 25. Januar 2010 20:31 schrieb Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>: > On Mon, Jan 25, 2010 at 06:16:08PM +0100, Julian Fuchs wrote: (...) > Did you try with IRQF_NODELAY on vanilla and without it in rt? I tried it with IRQF_NODELAY in rt and without IRQF_NODELAY on vanilla (vanilla won't compile with IRQF_NODELAY AFAIR). > Are you sure the irq fires in rt? It fires in the normal kernel (i.e. the hardware is working). How can I determine whether the interrupt fires in rt? > Does your interrupt appear in /proc/interrupts? Yes, it appears there (and the name of the module is listed correctly in the same line). On vanilla, the counter in /proc/interrupts increases, on rt, it doesn't. It seems that the interrupt just doesn't fire... is there any kind of "magic" I can do on rt to "enable" the interrupt? It seems disabled :-( > What platform are you working on? I'm working on a Intel Celeron 1,8 GHz board (x86) with Ubuntu Linux 9.10 as a distro. > Do you can send the code of a minimal example? Sure. Below you find the code of a minimal example for a rs232 interface. If you have any suggestions for a smaller example, please tell me and will create it (I just don't know how to create the interrupt otherwise). Thanks a lot for your help, Julian ----- #include <linux/module.h> #include <linux/kernel.h> #include <linux/mm.h> #include <asm/uaccess.h> #include <linux/sched.h> #include <linux/ioport.h> #include <asm/io.h> #include <linux/proc_fs.h> #include <linux/inet.h> #include <linux/net.h> #include <net/tcp.h> #include <net/ip.h> #include <net/protocol.h> /* --- DEFITIONS AND SETTINGS --- */ // Module information MODULE_AUTHOR("Somebody"); MODULE_DESCRIPTION("some serial interface driver"); MODULE_LICENSE("GPL"); #define MODULE_IDENT "foobar" #define VERSION_STRING "foobar v0.1\n" // Configurable parameters int base_port = 0xcf00; const int port_range = 8; int irq = 16; int irq_counter = 0; module_param(base_port, int, 0644); MODULE_PARM_DESC(base_port, "The base port address of the serial interface"); module_param(irq, int, 0644); MODULE_PARM_DESC(irq, "IRQ of the serial interface"); // Serial port communication // registers #define IER 1 // interrupt enable register #define FCR 2 // FIFO control register (write) / Interrupt Identification Register (read) #define LCR 3 // line control register // serial port settings #define PARITY_NO 0x0 #define STOPBIT_1 0 #define CS_8 0x3 #define MAX_BAUDRATE 921600 #define DIVISOR_ACCESS 0x80 // interrupt identification and enabling #define IER_DATA_AVAILABLE 0x1 #define IER_LS_CHANGE 0x4 // Global control variables int stage = 0; /* --- SERIAL PORT CONFIGURATION INTERFACE --- */ void set_serial_options(void); void set_serial_options(void) { unsigned int divisor; unsigned char parity, stopbit, cs, status; stopbit = STOPBIT_1; parity = PARITY_NO; cs = CS_8; status = parity | stopbit | cs | DIVISOR_ACCESS; outb(status, base_port+LCR); divisor = 24; outb(divisor & 0x00ff, base_port); outb(divisor & 0xff00, base_port+1); // reset divisor access bit outb(status &~ DIVISOR_ACCESS, base_port+LCR); } irqreturn_t interrupt_handler(int myirq, void *dev_id) { unsigned char iir_byte, bitmask; iir_byte = inb(base_port + FCR); bitmask = 1; if ( (iir_byte & bitmask) == 1) { // interrupt is not for this module return IRQ_NONE; } // interrupt is for this module unsigned char data_byte; data_byte = inb(base_port); irq_counter++; return IRQ_HANDLED; } void cleanup_module(void) { // I/O ports reserved if (stage >= 2) { release_region(base_port, port_range); printk(KERN_INFO "%s: releasing I/O ports\n", MODULE_IDENT); } // IRQ reserved if (stage >= 1) { // because of shared irq, &stage is given, otherwise NULL will do, too free_irq(irq, &stage); // disable interrupts from the card outb(0, base_port + IER); printk(KERN_INFO "%s: freeing irq %i\n", MODULE_IDENT, irq); } printk(KERN_INFO "%s: module unloaded\n", MODULE_IDENT); printk(KERN_ERR "%d irq_counter\n", irq_counter); } /* Setup all operations - called by kernel when module is loaded */ int init_module(void) { int err = 0; printk(KERN_INFO VERSION_STRING); // Stage 1. Request IRQ using shared interrupts // dev_id can't be NULL since the kernel needs to label the different ISRs // stage is just as a pointer to our address space, any other address will do, too. if ((err = request_irq(irq, interrupt_handler, IRQF_SHARED | IRQF_DISABLED | IRQF_NODELAY, MODULE_IDENT, &stage)) < 0) return err; stage++; // Stage 2. Request access to I/O ports if ((err = check_region(base_port, port_range)) < 0) { cleanup_module(); return err; } request_region(base_port, port_range, MODULE_IDENT); stage++; printk(KERN_INFO "Using serial port at %x, IRQ %i\n", base_port, irq); // Configure serial port set_serial_options(); // disable FIFO outb(0, base_port+FCR); // enable interrupts if data available or break signal received outb(IER_DATA_AVAILABLE | IER_LS_CHANGE, base_port+IER); printk(KERN_ERR "INIT MODULE DONE!\n"); return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html