Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drivers/input/serio/hp_sdc.c: fix crash when removing hp_sdc module

On parisc machines, which don't have HIL, removing the hp_sdc module
panics the kernel. Fix this by returning early in hp_sdc_exit() if no HP
SDC controller was found.

Add functionality to probe for the hp_sdc_mlc kernel module (which takes
care of the upper layer HIL functionality on parisc) after two seconds.
This is needed to get all the other HIL drivers (keyboard / mouse/ ..)
drivers automatically loaded by udev later as well.

Signed-off-by: Helge Deller <deller@gmx.de>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Frans Pop <elendil@planet.nl>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Grant Grundler <grundler@parisc-linux.org>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Helge Deller and committed by
Linus Torvalds
aa0b8f36 e638c139

+23 -1
+23 -1
drivers/input/serio/hp_sdc.c
··· 819 819 MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl); 820 820 821 821 static int __init hp_sdc_init_hppa(struct parisc_device *d); 822 + static struct delayed_work moduleloader_work; 822 823 823 824 static struct parisc_driver hp_sdc_driver = { 824 825 .name = "hp_sdc", ··· 931 930 932 931 #if defined(__hppa__) 933 932 933 + static void request_module_delayed(struct work_struct *work) 934 + { 935 + request_module("hp_sdc_mlc"); 936 + } 937 + 934 938 static int __init hp_sdc_init_hppa(struct parisc_device *d) 935 939 { 940 + int ret; 941 + 936 942 if (!d) 937 943 return 1; 938 944 if (hp_sdc.dev != NULL) ··· 952 944 hp_sdc.data_io = d->hpa.start + 0x800; 953 945 hp_sdc.status_io = d->hpa.start + 0x801; 954 946 955 - return hp_sdc_init(); 947 + INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); 948 + 949 + ret = hp_sdc_init(); 950 + /* after sucessfull initialization give SDC some time to settle 951 + * and then load the hp_sdc_mlc upper layer driver */ 952 + if (!ret) 953 + schedule_delayed_work(&moduleloader_work, 954 + msecs_to_jiffies(2000)); 955 + 956 + return ret; 956 957 } 957 958 958 959 #endif /* __hppa__ */ 959 960 960 961 static void hp_sdc_exit(void) 961 962 { 963 + /* do nothing if we don't have a SDC */ 964 + if (!hp_sdc.dev) 965 + return; 966 + 962 967 write_lock_irq(&hp_sdc.lock); 963 968 964 969 /* Turn off all maskable "sub-function" irq's. */ ··· 990 969 tasklet_kill(&hp_sdc.task); 991 970 992 971 #if defined(__hppa__) 972 + cancel_delayed_work_sync(&moduleloader_work); 993 973 if (unregister_parisc_driver(&hp_sdc_driver)) 994 974 printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); 995 975 #endif