diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-17 11:56:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-17 11:56:43 -0400 |
commit | 43f82216f0bd114599f4a221ae6924f3658a0c9a (patch) | |
tree | 89dbd85a0a1882ae38e6b61e360b365c018195fd | |
parent | 20f85957667ccc53183b5ffac22213d75e317408 (diff) | |
parent | b435fdcda126db42343b8055d04a0a27c229717b (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: fm801-gp - handle errors from pci_enable_device()
Input: gameport core - handle errors returned by device_bind_driver()
Input: serio core - handle errors returned by device_bind_driver()
Lockdep: fix compile error in drivers/input/serio/serio.c
Input: serio - add lockdep annotations
Lockdep: add lockdep_set_class_and_subclass() and lockdep_set_subclass()
Input: atkbd - supress "too many keys" error message
Input: i8042 - supress ACK/NAKs when blinking during panic
Input: add missing exports to fix modular build
-rw-r--r-- | drivers/char/random.c | 1 | ||||
-rw-r--r-- | drivers/input/gameport/fm801-gp.c | 22 | ||||
-rw-r--r-- | drivers/input/gameport/gameport.c | 18 | ||||
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 54 | ||||
-rw-r--r-- | drivers/input/serio/i8042.c | 13 | ||||
-rw-r--r-- | drivers/input/serio/libps2.c | 3 | ||||
-rw-r--r-- | drivers/input/serio/serio.c | 22 | ||||
-rw-r--r-- | include/linux/lockdep.h | 17 | ||||
-rw-r--r-- | include/linux/serio.h | 1 | ||||
-rw-r--r-- | kernel/lockdep.c | 10 | ||||
-rw-r--r-- | kernel/mutex-debug.c | 2 | ||||
-rw-r--r-- | lib/kobject.c | 1 | ||||
-rw-r--r-- | lib/rwsem-spinlock.c | 2 | ||||
-rw-r--r-- | lib/rwsem.c | 2 | ||||
-rw-r--r-- | lib/spinlock_debug.c | 4 | ||||
-rw-r--r-- | net/core/sock.c | 2 |
16 files changed, 132 insertions, 42 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 07f47a0208a7..eb6b13f4211a 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -645,6 +645,7 @@ void add_input_randomness(unsigned int type, unsigned int code, | |||
645 | add_timer_randomness(&input_timer_state, | 645 | add_timer_randomness(&input_timer_state, |
646 | (type << 4) ^ code ^ (code >> 4) ^ value); | 646 | (type << 4) ^ code ^ (code >> 4) ^ value); |
647 | } | 647 | } |
648 | EXPORT_SYMBOL_GPL(add_input_randomness); | ||
648 | 649 | ||
649 | void add_interrupt_randomness(int irq) | 650 | void add_interrupt_randomness(int irq) |
650 | { | 651 | { |
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 90de5afe03c2..1dec00e20dbc 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
@@ -82,17 +82,19 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device | |||
82 | { | 82 | { |
83 | struct fm801_gp *gp; | 83 | struct fm801_gp *gp; |
84 | struct gameport *port; | 84 | struct gameport *port; |
85 | int error; | ||
85 | 86 | ||
86 | gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL); | 87 | gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL); |
87 | port = gameport_allocate_port(); | 88 | port = gameport_allocate_port(); |
88 | if (!gp || !port) { | 89 | if (!gp || !port) { |
89 | printk(KERN_ERR "fm801-gp: Memory allocation failed\n"); | 90 | printk(KERN_ERR "fm801-gp: Memory allocation failed\n"); |
90 | kfree(gp); | 91 | error = -ENOMEM; |
91 | gameport_free_port(port); | 92 | goto err_out_free; |
92 | return -ENOMEM; | ||
93 | } | 93 | } |
94 | 94 | ||
95 | pci_enable_device(pci); | 95 | error = pci_enable_device(pci); |
96 | if (error) | ||
97 | goto err_out_free; | ||
96 | 98 | ||
97 | port->open = fm801_gp_open; | 99 | port->open = fm801_gp_open; |
98 | #ifdef HAVE_COOKED | 100 | #ifdef HAVE_COOKED |
@@ -108,9 +110,8 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device | |||
108 | if (!gp->res_port) { | 110 | if (!gp->res_port) { |
109 | printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", | 111 | printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", |
110 | port->io, port->io + 0x0f); | 112 | port->io, port->io + 0x0f); |
111 | gameport_free_port(port); | 113 | error = -EBUSY; |
112 | kfree(gp); | 114 | goto err_out_disable_dev; |
113 | return -EBUSY; | ||
114 | } | 115 | } |
115 | 116 | ||
116 | pci_set_drvdata(pci, gp); | 117 | pci_set_drvdata(pci, gp); |
@@ -119,6 +120,13 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device | |||
119 | gameport_register_port(port); | 120 | gameport_register_port(port); |
120 | 121 | ||
121 | return 0; | 122 | return 0; |
123 | |||
124 | err_out_disable_dev: | ||
125 | pci_disable_device(pci); | ||
126 | err_out_free: | ||
127 | gameport_free_port(port); | ||
128 | kfree(gp); | ||
129 | return error; | ||
122 | } | 130 | } |
123 | 131 | ||
124 | static void __devexit fm801_gp_remove(struct pci_dev *pci) | 132 | static void __devexit fm801_gp_remove(struct pci_dev *pci) |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 3f47ae55c6f3..a0af97efe6ac 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -191,6 +191,8 @@ static void gameport_run_poll_handler(unsigned long d) | |||
191 | 191 | ||
192 | static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) | 192 | static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) |
193 | { | 193 | { |
194 | int error; | ||
195 | |||
194 | down_write(&gameport_bus.subsys.rwsem); | 196 | down_write(&gameport_bus.subsys.rwsem); |
195 | 197 | ||
196 | gameport->dev.driver = &drv->driver; | 198 | gameport->dev.driver = &drv->driver; |
@@ -198,8 +200,20 @@ static void gameport_bind_driver(struct gameport *gameport, struct gameport_driv | |||
198 | gameport->dev.driver = NULL; | 200 | gameport->dev.driver = NULL; |
199 | goto out; | 201 | goto out; |
200 | } | 202 | } |
201 | device_bind_driver(&gameport->dev); | 203 | |
202 | out: | 204 | error = device_bind_driver(&gameport->dev); |
205 | if (error) { | ||
206 | printk(KERN_WARNING | ||
207 | "gameport: device_bind_driver() failed " | ||
208 | "for %s (%s) and %s, error: %d\n", | ||
209 | gameport->phys, gameport->name, | ||
210 | drv->description, error); | ||
211 | drv->disconnect(gameport); | ||
212 | gameport->dev.driver = NULL; | ||
213 | goto out; | ||
214 | } | ||
215 | |||
216 | out: | ||
203 | up_write(&gameport_bus.subsys.rwsem); | 217 | up_write(&gameport_bus.subsys.rwsem); |
204 | } | 218 | } |
205 | 219 | ||
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index b6ef9eaad1dc..cbb93669d1ce 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -221,6 +221,7 @@ struct atkbd { | |||
221 | unsigned long xl_bit; | 221 | unsigned long xl_bit; |
222 | unsigned int last; | 222 | unsigned int last; |
223 | unsigned long time; | 223 | unsigned long time; |
224 | unsigned long err_count; | ||
224 | 225 | ||
225 | struct work_struct event_work; | 226 | struct work_struct event_work; |
226 | struct mutex event_mutex; | 227 | struct mutex event_mutex; |
@@ -234,11 +235,13 @@ static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t | |||
234 | #define ATKBD_DEFINE_ATTR(_name) \ | 235 | #define ATKBD_DEFINE_ATTR(_name) \ |
235 | static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ | 236 | static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ |
236 | static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \ | 237 | static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \ |
237 | static ssize_t atkbd_do_show_##_name(struct device *d, struct device_attribute *attr, char *b) \ | 238 | static ssize_t atkbd_do_show_##_name(struct device *d, \ |
239 | struct device_attribute *attr, char *b) \ | ||
238 | { \ | 240 | { \ |
239 | return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ | 241 | return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ |
240 | } \ | 242 | } \ |
241 | static ssize_t atkbd_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s) \ | 243 | static ssize_t atkbd_do_set_##_name(struct device *d, \ |
244 | struct device_attribute *attr, const char *b, size_t s) \ | ||
242 | { \ | 245 | { \ |
243 | return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \ | 246 | return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \ |
244 | } \ | 247 | } \ |
@@ -251,6 +254,32 @@ ATKBD_DEFINE_ATTR(set); | |||
251 | ATKBD_DEFINE_ATTR(softrepeat); | 254 | ATKBD_DEFINE_ATTR(softrepeat); |
252 | ATKBD_DEFINE_ATTR(softraw); | 255 | ATKBD_DEFINE_ATTR(softraw); |
253 | 256 | ||
257 | #define ATKBD_DEFINE_RO_ATTR(_name) \ | ||
258 | static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ | ||
259 | static ssize_t atkbd_do_show_##_name(struct device *d, \ | ||
260 | struct device_attribute *attr, char *b) \ | ||
261 | { \ | ||
262 | return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ | ||
263 | } \ | ||
264 | static struct device_attribute atkbd_attr_##_name = \ | ||
265 | __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL); | ||
266 | |||
267 | ATKBD_DEFINE_RO_ATTR(err_count); | ||
268 | |||
269 | static struct attribute *atkbd_attributes[] = { | ||
270 | &atkbd_attr_extra.attr, | ||
271 | &atkbd_attr_scroll.attr, | ||
272 | &atkbd_attr_set.attr, | ||
273 | &atkbd_attr_softrepeat.attr, | ||
274 | &atkbd_attr_softraw.attr, | ||
275 | &atkbd_attr_err_count.attr, | ||
276 | NULL | ||
277 | }; | ||
278 | |||
279 | static struct attribute_group atkbd_attribute_group = { | ||
280 | .attrs = atkbd_attributes, | ||
281 | }; | ||
282 | |||
254 | static const unsigned int xl_table[] = { | 283 | static const unsigned int xl_table[] = { |
255 | ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, | 284 | ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, |
256 | ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, | 285 | ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, |
@@ -396,7 +425,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
396 | add_release_event = 1; | 425 | add_release_event = 1; |
397 | break; | 426 | break; |
398 | case ATKBD_RET_ERR: | 427 | case ATKBD_RET_ERR: |
428 | atkbd->err_count++; | ||
429 | #ifdef ATKBD_DEBUG | ||
399 | printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); | 430 | printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); |
431 | #endif | ||
400 | goto out; | 432 | goto out; |
401 | } | 433 | } |
402 | 434 | ||
@@ -786,12 +818,7 @@ static void atkbd_disconnect(struct serio *serio) | |||
786 | synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */ | 818 | synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */ |
787 | flush_scheduled_work(); | 819 | flush_scheduled_work(); |
788 | 820 | ||
789 | device_remove_file(&serio->dev, &atkbd_attr_extra); | 821 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); |
790 | device_remove_file(&serio->dev, &atkbd_attr_scroll); | ||
791 | device_remove_file(&serio->dev, &atkbd_attr_set); | ||
792 | device_remove_file(&serio->dev, &atkbd_attr_softrepeat); | ||
793 | device_remove_file(&serio->dev, &atkbd_attr_softraw); | ||
794 | |||
795 | input_unregister_device(atkbd->dev); | 822 | input_unregister_device(atkbd->dev); |
796 | serio_close(serio); | 823 | serio_close(serio); |
797 | serio_set_drvdata(serio, NULL); | 824 | serio_set_drvdata(serio, NULL); |
@@ -961,11 +988,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
961 | atkbd_set_keycode_table(atkbd); | 988 | atkbd_set_keycode_table(atkbd); |
962 | atkbd_set_device_attrs(atkbd); | 989 | atkbd_set_device_attrs(atkbd); |
963 | 990 | ||
964 | device_create_file(&serio->dev, &atkbd_attr_extra); | 991 | sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group); |
965 | device_create_file(&serio->dev, &atkbd_attr_scroll); | ||
966 | device_create_file(&serio->dev, &atkbd_attr_set); | ||
967 | device_create_file(&serio->dev, &atkbd_attr_softrepeat); | ||
968 | device_create_file(&serio->dev, &atkbd_attr_softraw); | ||
969 | 992 | ||
970 | atkbd_enable(atkbd); | 993 | atkbd_enable(atkbd); |
971 | 994 | ||
@@ -1259,6 +1282,11 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co | |||
1259 | return count; | 1282 | return count; |
1260 | } | 1283 | } |
1261 | 1284 | ||
1285 | static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) | ||
1286 | { | ||
1287 | return sprintf(buf, "%lu\n", atkbd->err_count); | ||
1288 | } | ||
1289 | |||
1262 | 1290 | ||
1263 | static int __init atkbd_init(void) | 1291 | static int __init atkbd_init(void) |
1264 | { | 1292 | { |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 09b06e605b50..7e3141f37e32 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -106,6 +106,7 @@ static unsigned char i8042_ctr; | |||
106 | static unsigned char i8042_mux_present; | 106 | static unsigned char i8042_mux_present; |
107 | static unsigned char i8042_kbd_irq_registered; | 107 | static unsigned char i8042_kbd_irq_registered; |
108 | static unsigned char i8042_aux_irq_registered; | 108 | static unsigned char i8042_aux_irq_registered; |
109 | static unsigned char i8042_suppress_kbd_ack; | ||
109 | static struct platform_device *i8042_platform_device; | 110 | static struct platform_device *i8042_platform_device; |
110 | 111 | ||
111 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); | 112 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); |
@@ -316,7 +317,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
316 | unsigned char str, data; | 317 | unsigned char str, data; |
317 | unsigned int dfl; | 318 | unsigned int dfl; |
318 | unsigned int port_no; | 319 | unsigned int port_no; |
319 | int ret; | 320 | int ret = 1; |
320 | 321 | ||
321 | spin_lock_irqsave(&i8042_lock, flags); | 322 | spin_lock_irqsave(&i8042_lock, flags); |
322 | str = i8042_read_status(); | 323 | str = i8042_read_status(); |
@@ -378,10 +379,16 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
378 | dfl & SERIO_PARITY ? ", bad parity" : "", | 379 | dfl & SERIO_PARITY ? ", bad parity" : "", |
379 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); | 380 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); |
380 | 381 | ||
382 | if (unlikely(i8042_suppress_kbd_ack)) | ||
383 | if (port_no == I8042_KBD_PORT_NO && | ||
384 | (data == 0xfa || data == 0xfe)) { | ||
385 | i8042_suppress_kbd_ack = 0; | ||
386 | goto out; | ||
387 | } | ||
388 | |||
381 | if (likely(port->exists)) | 389 | if (likely(port->exists)) |
382 | serio_interrupt(port->serio, data, dfl); | 390 | serio_interrupt(port->serio, data, dfl); |
383 | 391 | ||
384 | ret = 1; | ||
385 | out: | 392 | out: |
386 | return IRQ_RETVAL(ret); | 393 | return IRQ_RETVAL(ret); |
387 | } | 394 | } |
@@ -842,11 +849,13 @@ static long i8042_panic_blink(long count) | |||
842 | led ^= 0x01 | 0x04; | 849 | led ^= 0x01 | 0x04; |
843 | while (i8042_read_status() & I8042_STR_IBF) | 850 | while (i8042_read_status() & I8042_STR_IBF) |
844 | DELAY; | 851 | DELAY; |
852 | i8042_suppress_kbd_ack = 1; | ||
845 | i8042_write_data(0xed); /* set leds */ | 853 | i8042_write_data(0xed); /* set leds */ |
846 | DELAY; | 854 | DELAY; |
847 | while (i8042_read_status() & I8042_STR_IBF) | 855 | while (i8042_read_status() & I8042_STR_IBF) |
848 | DELAY; | 856 | DELAY; |
849 | DELAY; | 857 | DELAY; |
858 | i8042_suppress_kbd_ack = 1; | ||
850 | i8042_write_data(led); | 859 | i8042_write_data(led); |
851 | DELAY; | 860 | DELAY; |
852 | last_blink = count; | 861 | last_blink = count; |
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index dcb16b5cbec0..e5b1b60757bb 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -189,7 +189,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
189 | return -1; | 189 | return -1; |
190 | } | 190 | } |
191 | 191 | ||
192 | mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING); | 192 | mutex_lock(&ps2dev->cmd_mutex); |
193 | 193 | ||
194 | serio_pause_rx(ps2dev->serio); | 194 | serio_pause_rx(ps2dev->serio); |
195 | ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; | 195 | ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; |
@@ -296,6 +296,7 @@ EXPORT_SYMBOL(ps2_schedule_command); | |||
296 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio) | 296 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio) |
297 | { | 297 | { |
298 | mutex_init(&ps2dev->cmd_mutex); | 298 | mutex_init(&ps2dev->cmd_mutex); |
299 | lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth); | ||
299 | init_waitqueue_head(&ps2dev->wait); | 300 | init_waitqueue_head(&ps2dev->wait); |
300 | ps2dev->serio = serio; | 301 | ps2dev->serio = serio; |
301 | } | 302 | } |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 960fae3c3cea..211943f85cb6 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -118,6 +118,8 @@ static int serio_match_port(const struct serio_device_id *ids, struct serio *ser | |||
118 | 118 | ||
119 | static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) | 119 | static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) |
120 | { | 120 | { |
121 | int error; | ||
122 | |||
121 | down_write(&serio_bus.subsys.rwsem); | 123 | down_write(&serio_bus.subsys.rwsem); |
122 | 124 | ||
123 | if (serio_match_port(drv->id_table, serio)) { | 125 | if (serio_match_port(drv->id_table, serio)) { |
@@ -126,9 +128,19 @@ static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) | |||
126 | serio->dev.driver = NULL; | 128 | serio->dev.driver = NULL; |
127 | goto out; | 129 | goto out; |
128 | } | 130 | } |
129 | device_bind_driver(&serio->dev); | 131 | error = device_bind_driver(&serio->dev); |
132 | if (error) { | ||
133 | printk(KERN_WARNING | ||
134 | "serio: device_bind_driver() failed " | ||
135 | "for %s (%s) and %s, error: %d\n", | ||
136 | serio->phys, serio->name, | ||
137 | drv->description, error); | ||
138 | serio_disconnect_driver(serio); | ||
139 | serio->dev.driver = NULL; | ||
140 | goto out; | ||
141 | } | ||
130 | } | 142 | } |
131 | out: | 143 | out: |
132 | up_write(&serio_bus.subsys.rwsem); | 144 | up_write(&serio_bus.subsys.rwsem); |
133 | } | 145 | } |
134 | 146 | ||
@@ -538,8 +550,12 @@ static void serio_init_port(struct serio *serio) | |||
538 | "serio%ld", (long)atomic_inc_return(&serio_no) - 1); | 550 | "serio%ld", (long)atomic_inc_return(&serio_no) - 1); |
539 | serio->dev.bus = &serio_bus; | 551 | serio->dev.bus = &serio_bus; |
540 | serio->dev.release = serio_release_port; | 552 | serio->dev.release = serio_release_port; |
541 | if (serio->parent) | 553 | if (serio->parent) { |
542 | serio->dev.parent = &serio->parent->dev; | 554 | serio->dev.parent = &serio->parent->dev; |
555 | serio->depth = serio->parent->depth + 1; | ||
556 | } else | ||
557 | serio->depth = 0; | ||
558 | lockdep_set_subclass(&serio->lock, serio->depth); | ||
543 | } | 559 | } |
544 | 560 | ||
545 | /* | 561 | /* |
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 1314ca0f29be..819f08f1310d 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h | |||
@@ -202,7 +202,7 @@ extern int lockdep_internal(void); | |||
202 | */ | 202 | */ |
203 | 203 | ||
204 | extern void lockdep_init_map(struct lockdep_map *lock, const char *name, | 204 | extern void lockdep_init_map(struct lockdep_map *lock, const char *name, |
205 | struct lock_class_key *key); | 205 | struct lock_class_key *key, int subclass); |
206 | 206 | ||
207 | /* | 207 | /* |
208 | * Reinitialize a lock key - for cases where there is special locking or | 208 | * Reinitialize a lock key - for cases where there is special locking or |
@@ -211,9 +211,14 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name, | |||
211 | * or they are too narrow (they suffer from a false class-split): | 211 | * or they are too narrow (they suffer from a false class-split): |
212 | */ | 212 | */ |
213 | #define lockdep_set_class(lock, key) \ | 213 | #define lockdep_set_class(lock, key) \ |
214 | lockdep_init_map(&(lock)->dep_map, #key, key) | 214 | lockdep_init_map(&(lock)->dep_map, #key, key, 0) |
215 | #define lockdep_set_class_and_name(lock, key, name) \ | 215 | #define lockdep_set_class_and_name(lock, key, name) \ |
216 | lockdep_init_map(&(lock)->dep_map, name, key) | 216 | lockdep_init_map(&(lock)->dep_map, name, key, 0) |
217 | #define lockdep_set_class_and_subclass(lock, key, sub) \ | ||
218 | lockdep_init_map(&(lock)->dep_map, #key, key, sub) | ||
219 | #define lockdep_set_subclass(lock, sub) \ | ||
220 | lockdep_init_map(&(lock)->dep_map, #lock, \ | ||
221 | (lock)->dep_map.key, sub) | ||
217 | 222 | ||
218 | /* | 223 | /* |
219 | * Acquire a lock. | 224 | * Acquire a lock. |
@@ -257,10 +262,14 @@ static inline int lockdep_internal(void) | |||
257 | # define lock_release(l, n, i) do { } while (0) | 262 | # define lock_release(l, n, i) do { } while (0) |
258 | # define lockdep_init() do { } while (0) | 263 | # define lockdep_init() do { } while (0) |
259 | # define lockdep_info() do { } while (0) | 264 | # define lockdep_info() do { } while (0) |
260 | # define lockdep_init_map(lock, name, key) do { (void)(key); } while (0) | 265 | # define lockdep_init_map(lock, name, key, sub) do { (void)(key); } while (0) |
261 | # define lockdep_set_class(lock, key) do { (void)(key); } while (0) | 266 | # define lockdep_set_class(lock, key) do { (void)(key); } while (0) |
262 | # define lockdep_set_class_and_name(lock, key, name) \ | 267 | # define lockdep_set_class_and_name(lock, key, name) \ |
263 | do { (void)(key); } while (0) | 268 | do { (void)(key); } while (0) |
269 | #define lockdep_set_class_and_subclass(lock, key, sub) \ | ||
270 | do { (void)(key); } while (0) | ||
271 | #define lockdep_set_subclass(lock, sub) do { } while (0) | ||
272 | |||
264 | # define INIT_LOCKDEP | 273 | # define INIT_LOCKDEP |
265 | # define lockdep_reset() do { debug_locks = 1; } while (0) | 274 | # define lockdep_reset() do { debug_locks = 1; } while (0) |
266 | # define lockdep_free_key_range(start, size) do { } while (0) | 275 | # define lockdep_free_key_range(start, size) do { } while (0) |
diff --git a/include/linux/serio.h b/include/linux/serio.h index 3a697cc6ecae..b99c5ca9708d 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h | |||
@@ -41,6 +41,7 @@ struct serio { | |||
41 | void (*stop)(struct serio *); | 41 | void (*stop)(struct serio *); |
42 | 42 | ||
43 | struct serio *parent, *child; | 43 | struct serio *parent, *child; |
44 | unsigned int depth; /* level of nesting in serio hierarchy */ | ||
44 | 45 | ||
45 | struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */ | 46 | struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */ |
46 | struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */ | 47 | struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */ |
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index d1a3b2cfe4a9..b739be2a6dc9 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -1176,7 +1176,7 @@ look_up_lock_class(struct lockdep_map *lock, unsigned int subclass) | |||
1176 | * itself, so actual lookup of the hash should be once per lock object. | 1176 | * itself, so actual lookup of the hash should be once per lock object. |
1177 | */ | 1177 | */ |
1178 | static inline struct lock_class * | 1178 | static inline struct lock_class * |
1179 | register_lock_class(struct lockdep_map *lock, unsigned int subclass) | 1179 | register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) |
1180 | { | 1180 | { |
1181 | struct lockdep_subclass_key *key; | 1181 | struct lockdep_subclass_key *key; |
1182 | struct list_head *hash_head; | 1182 | struct list_head *hash_head; |
@@ -1248,7 +1248,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass) | |||
1248 | out_unlock_set: | 1248 | out_unlock_set: |
1249 | __raw_spin_unlock(&hash_lock); | 1249 | __raw_spin_unlock(&hash_lock); |
1250 | 1250 | ||
1251 | if (!subclass) | 1251 | if (!subclass || force) |
1252 | lock->class_cache = class; | 1252 | lock->class_cache = class; |
1253 | 1253 | ||
1254 | DEBUG_LOCKS_WARN_ON(class->subclass != subclass); | 1254 | DEBUG_LOCKS_WARN_ON(class->subclass != subclass); |
@@ -1936,7 +1936,7 @@ void trace_softirqs_off(unsigned long ip) | |||
1936 | * Initialize a lock instance's lock-class mapping info: | 1936 | * Initialize a lock instance's lock-class mapping info: |
1937 | */ | 1937 | */ |
1938 | void lockdep_init_map(struct lockdep_map *lock, const char *name, | 1938 | void lockdep_init_map(struct lockdep_map *lock, const char *name, |
1939 | struct lock_class_key *key) | 1939 | struct lock_class_key *key, int subclass) |
1940 | { | 1940 | { |
1941 | if (unlikely(!debug_locks)) | 1941 | if (unlikely(!debug_locks)) |
1942 | return; | 1942 | return; |
@@ -1956,6 +1956,8 @@ void lockdep_init_map(struct lockdep_map *lock, const char *name, | |||
1956 | lock->name = name; | 1956 | lock->name = name; |
1957 | lock->key = key; | 1957 | lock->key = key; |
1958 | lock->class_cache = NULL; | 1958 | lock->class_cache = NULL; |
1959 | if (subclass) | ||
1960 | register_lock_class(lock, subclass, 1); | ||
1959 | } | 1961 | } |
1960 | 1962 | ||
1961 | EXPORT_SYMBOL_GPL(lockdep_init_map); | 1963 | EXPORT_SYMBOL_GPL(lockdep_init_map); |
@@ -1994,7 +1996,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, | |||
1994 | * Not cached yet or subclass? | 1996 | * Not cached yet or subclass? |
1995 | */ | 1997 | */ |
1996 | if (unlikely(!class)) { | 1998 | if (unlikely(!class)) { |
1997 | class = register_lock_class(lock, subclass); | 1999 | class = register_lock_class(lock, subclass, 0); |
1998 | if (!class) | 2000 | if (!class) |
1999 | return 0; | 2001 | return 0; |
2000 | } | 2002 | } |
diff --git a/kernel/mutex-debug.c b/kernel/mutex-debug.c index e3203c654dda..18651641a7b5 100644 --- a/kernel/mutex-debug.c +++ b/kernel/mutex-debug.c | |||
@@ -91,7 +91,7 @@ void debug_mutex_init(struct mutex *lock, const char *name, | |||
91 | * Make sure we are not reinitializing a held lock: | 91 | * Make sure we are not reinitializing a held lock: |
92 | */ | 92 | */ |
93 | debug_check_no_locks_freed((void *)lock, sizeof(*lock)); | 93 | debug_check_no_locks_freed((void *)lock, sizeof(*lock)); |
94 | lockdep_init_map(&lock->dep_map, name, key); | 94 | lockdep_init_map(&lock->dep_map, name, key, 0); |
95 | #endif | 95 | #endif |
96 | lock->owner = NULL; | 96 | lock->owner = NULL; |
97 | lock->magic = lock; | 97 | lock->magic = lock; |
diff --git a/lib/kobject.c b/lib/kobject.c index 1699eb9161f3..7dd5c0e9d996 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -119,6 +119,7 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) | |||
119 | 119 | ||
120 | return path; | 120 | return path; |
121 | } | 121 | } |
122 | EXPORT_SYMBOL_GPL(kobject_get_path); | ||
122 | 123 | ||
123 | /** | 124 | /** |
124 | * kobject_init - initialize object. | 125 | * kobject_init - initialize object. |
diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c index db4fed74b940..c4cfd6c0342f 100644 --- a/lib/rwsem-spinlock.c +++ b/lib/rwsem-spinlock.c | |||
@@ -28,7 +28,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name, | |||
28 | * Make sure we are not reinitializing a held semaphore: | 28 | * Make sure we are not reinitializing a held semaphore: |
29 | */ | 29 | */ |
30 | debug_check_no_locks_freed((void *)sem, sizeof(*sem)); | 30 | debug_check_no_locks_freed((void *)sem, sizeof(*sem)); |
31 | lockdep_init_map(&sem->dep_map, name, key); | 31 | lockdep_init_map(&sem->dep_map, name, key, 0); |
32 | #endif | 32 | #endif |
33 | sem->activity = 0; | 33 | sem->activity = 0; |
34 | spin_lock_init(&sem->wait_lock); | 34 | spin_lock_init(&sem->wait_lock); |
diff --git a/lib/rwsem.c b/lib/rwsem.c index 901d0e7da892..cdb4e3d05607 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c | |||
@@ -19,7 +19,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name, | |||
19 | * Make sure we are not reinitializing a held semaphore: | 19 | * Make sure we are not reinitializing a held semaphore: |
20 | */ | 20 | */ |
21 | debug_check_no_locks_freed((void *)sem, sizeof(*sem)); | 21 | debug_check_no_locks_freed((void *)sem, sizeof(*sem)); |
22 | lockdep_init_map(&sem->dep_map, name, key); | 22 | lockdep_init_map(&sem->dep_map, name, key, 0); |
23 | #endif | 23 | #endif |
24 | sem->count = RWSEM_UNLOCKED_VALUE; | 24 | sem->count = RWSEM_UNLOCKED_VALUE; |
25 | spin_lock_init(&sem->wait_lock); | 25 | spin_lock_init(&sem->wait_lock); |
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index dafaf1de2491..b6c4f898197c 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c | |||
@@ -20,7 +20,7 @@ void __spin_lock_init(spinlock_t *lock, const char *name, | |||
20 | * Make sure we are not reinitializing a held lock: | 20 | * Make sure we are not reinitializing a held lock: |
21 | */ | 21 | */ |
22 | debug_check_no_locks_freed((void *)lock, sizeof(*lock)); | 22 | debug_check_no_locks_freed((void *)lock, sizeof(*lock)); |
23 | lockdep_init_map(&lock->dep_map, name, key); | 23 | lockdep_init_map(&lock->dep_map, name, key, 0); |
24 | #endif | 24 | #endif |
25 | lock->raw_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; | 25 | lock->raw_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; |
26 | lock->magic = SPINLOCK_MAGIC; | 26 | lock->magic = SPINLOCK_MAGIC; |
@@ -38,7 +38,7 @@ void __rwlock_init(rwlock_t *lock, const char *name, | |||
38 | * Make sure we are not reinitializing a held lock: | 38 | * Make sure we are not reinitializing a held lock: |
39 | */ | 39 | */ |
40 | debug_check_no_locks_freed((void *)lock, sizeof(*lock)); | 40 | debug_check_no_locks_freed((void *)lock, sizeof(*lock)); |
41 | lockdep_init_map(&lock->dep_map, name, key); | 41 | lockdep_init_map(&lock->dep_map, name, key, 0); |
42 | #endif | 42 | #endif |
43 | lock->raw_lock = (raw_rwlock_t) __RAW_RW_LOCK_UNLOCKED; | 43 | lock->raw_lock = (raw_rwlock_t) __RAW_RW_LOCK_UNLOCKED; |
44 | lock->magic = RWLOCK_MAGIC; | 44 | lock->magic = RWLOCK_MAGIC; |
diff --git a/net/core/sock.c b/net/core/sock.c index b77e155cbe6c..d472db4776c3 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -823,7 +823,7 @@ static void inline sock_lock_init(struct sock *sk) | |||
823 | af_family_slock_key_strings[sk->sk_family]); | 823 | af_family_slock_key_strings[sk->sk_family]); |
824 | lockdep_init_map(&sk->sk_lock.dep_map, | 824 | lockdep_init_map(&sk->sk_lock.dep_map, |
825 | af_family_key_strings[sk->sk_family], | 825 | af_family_key_strings[sk->sk_family], |
826 | af_family_keys + sk->sk_family); | 826 | af_family_keys + sk->sk_family, 0); |
827 | } | 827 | } |
828 | 828 | ||
829 | /** | 829 | /** |