There's really no good reason not to just grab the desired IRQ at driver init time, instead of every time the lirc device node is accessed. This also improves the speed and reliability with which a serial transmitter can operate, as back-to-back transmission attempts (i.e., channel change to a multi-digit channel) don't have to spend time acquiring and then releasing the IRQ for every digit, sometimes multiple times, if lircd has been told to use the min_repeat parameter.
Showing the changes to drivers/staging/lirc/lirc_serial.c (1 of 1 file). Show all
Unified · Split
| @@ -838,7 +838,23 @@ static int hardware_init_port(void) · 837 unmodified lines | ||
| 838 | 838 | |
| 839 | 839 | static int init_port(void) |
| 840 | 840 | { |
| 841 | − int i, nlow, nhigh; | |
| 841 | + int i, nlow, nhigh, result; | |
| 842 | + | |
| 843 | + result = request_irq(irq, irq_handler, | |
| 844 | + IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0), | |
| 845 | + LIRC_DRIVER_NAME, (void *)&hardware); | |
| 846 | + | |
| 847 | + switch (result) { | |
| 848 | + case -EBUSY: | |
| 849 | + printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); | |
| 850 | + return -EBUSY; | |
| 851 | + case -EINVAL: | |
| 852 | + printk(KERN_ERR LIRC_DRIVER_NAME | |
| 853 | + ": Bad irq number or handler\n"); | |
| 854 | + return -EINVAL; | |
| 855 | + default: | |
| 856 | + break; | |
| 857 | + }; | |
| 842 | 858 | |
| 843 | 859 | /* Reserve io region. */ |
| 844 | 860 | /* |
| @@ -893,34 +909,17 @@ static int init_port(void) · 48 unmodified lines | ||
| 893 | 909 | printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active " |
| 894 | 910 | "%s receiver\n", sense ? "low" : "high"); |
| 895 | 911 | |
| 912 | + dprintk("Interrupt %d, port %04x obtained\n", irq, io); | |
| 896 | 913 | return 0; |
| 897 | 914 | } |
| 898 | 915 | |
| 899 | 916 | static int set_use_inc(void *data) |
| 900 | 917 | { |
| 901 | − int result; | |
| 902 | 918 | unsigned long flags; |
| 903 | 919 | |
| 904 | 920 | /* initialize timestamp */ |
| 905 | 921 | do_gettimeofday(&lasttv); |
| 906 | 922 | |
| 907 | − result = request_irq(irq, irq_handler, | |
| 908 | − IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0), | |
| 909 | − LIRC_DRIVER_NAME, (void *)&hardware); | |
| 910 | − | |
| 911 | − switch (result) { | |
| 912 | − case -EBUSY: | |
| 913 | − printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); | |
| 914 | − return -EBUSY; | |
| 915 | − case -EINVAL: | |
| 916 | − printk(KERN_ERR LIRC_DRIVER_NAME | |
| 917 | − ": Bad irq number or handler\n"); | |
| 918 | − return -EINVAL; | |
| 919 | − default: | |
| 920 | − dprintk("Interrupt %d, port %04x obtained\n", irq, io); | |
| 921 | − break; | |
| 922 | − } | |
| 923 | − | |
| 924 | 923 | spin_lock_irqsave(&hardware[type].lock, flags); |
| 925 | 924 | |
| 926 | 925 | /* Set DLAB 0. */ |
| @@ -945,10 +944,6 @@ static void set_use_dec(void *data) · 18 unmodified lines | ||
| 945 | 944 | soutp(UART_IER, sinp(UART_IER) & |
| 946 | 945 | (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); |
| 947 | 946 | spin_unlock_irqrestore(&hardware[type].lock, flags); |
| 948 | − | |
| 949 | − free_irq(irq, (void *)&hardware); | |
| 950 | − | |
| 951 | − dprintk("freed IRQ %d\n", irq); | |
| 952 | 947 | } |
| 953 | 948 | |
| 954 | 949 | static ssize_t lirc_write(struct file *file, const char *buf, |
| @@ -1256,6 +1251,9 @@ exit_serial_exit: · 301 unmodified lines | ||
| 1256 | 1251 | static void __exit lirc_serial_exit_module(void) |
| 1257 | 1252 | { |
| 1258 | 1253 | lirc_serial_exit(); |
| 1254 | + | |
| 1255 | + free_irq(irq, (void *)&hardware); | |
| 1256 | + | |
| 1259 | 1257 | if (iommap != 0) |
| 1260 | 1258 | release_mem_region(iommap, 8 << ioshift); |
| 1261 | 1259 | else |