Date: | 2011-07-06 23:26:18 (12 years 8 months ago) |
---|---|
Author: | Werner Almesberger |
Commit: | edb55e1d9917f35ce2ec30afa47ede66fb06273b |
Message: | atusb: converted interrupt delivery to use tasklets Tasklets are a lot cleaner than the atomic operations and weird logic we had before. And the result should also be more correct ;-) Signed-off-by: Werner Almesberger <werner@almesberger.net> |
Files: |
drivers/spi/atusb.c (7 diffs) |
Change Details
drivers/spi/atusb.c | ||
---|---|---|
19 | 19 | #include <linux/module.h> |
20 | 20 | #include <linux/platform_device.h> |
21 | 21 | #include <linux/interrupt.h> |
22 | #include <linux/atomic.h> | |
23 | 22 | #include <linux/usb.h> |
24 | 23 | #include <linux/spi/spi.h> |
25 | 24 | #include <linux/spi/at86rf230.h> |
... | ... | |
47 | 46 | int slave_irq; |
48 | 47 | struct urb *irq_urb; |
49 | 48 | uint8_t irq_buf; /* scratch space */ |
50 | atomic_t pending; /* pending interrupts */ | |
51 | atomic_t masked; /* masking levels */ | |
49 | struct tasklet_struct task; /* interrupt delivery tasklet */ | |
52 | 50 | struct at86rf230_platform_data platform_data; |
53 | 51 | /* copy platform_data so that we can adapt .reset_data */ |
54 | 52 | struct spi_device *spi; |
... | ... | |
357 | 355 | /* ----- Interrupt handling ------------------------------------------------ */ |
358 | 356 | |
359 | 357 | |
360 | static void atusb_do_irq(struct atusb_local *atusb); | |
361 | ||
362 | static void atusb_irq_enable(struct atusb_local *atusb) | |
358 | static void atusb_tasklet(unsigned long data) | |
363 | 359 | { |
364 | printk(KERN_INFO "atusb_irq_enable\n"); | |
365 | if (atomic_dec_return(&atusb->masked)) | |
366 | return; | |
367 | if (!atomic_add_unless(&atusb->pending, -1, 0)) | |
368 | return; | |
369 | /* @@@ probably racy around here. | |
370 | need to think this through some more - wa */ | |
371 | atusb_do_irq(atusb); | |
372 | } | |
360 | struct atusb_local *atusb = (void *) data; | |
373 | 361 | |
374 | static void atusb_do_irq(struct atusb_local *atusb) | |
375 | { | |
376 | printk(KERN_INFO "atusb_do_irq\n"); | |
377 | if (atomic_inc_return(&atusb->masked) == 1) | |
378 | generic_handle_irq(atusb->slave_irq); | |
379 | else | |
380 | atomic_set(&atusb->pending, 1); | |
381 | printk(KERN_INFO "atusb_do_irq out\n"); | |
382 | atusb_irq_enable(atusb); | |
362 | generic_handle_irq(atusb->slave_irq); | |
383 | 363 | } |
384 | 364 | |
385 | 365 | static void atusb_irq(struct urb *urb) |
... | ... | |
389 | 369 | printk(KERN_INFO "atusb_irq (%d)\n", urb->status); |
390 | 370 | usb_free_urb(urb); |
391 | 371 | atusb->irq_urb = NULL; |
392 | atusb_do_irq(atusb); | |
372 | tasklet_schedule(&atusb->task); | |
393 | 373 | } |
394 | 374 | |
395 | 375 | static int atusb_arm_interrupt(struct atusb_local *atusb) |
... | ... | |
436 | 416 | struct atusb_local *atusb = irq_data_get_irq_chip_data(data); |
437 | 417 | |
438 | 418 | printk(KERN_INFO "atusb_irq_mask\n"); |
439 | atomic_inc(&atusb->masked); | |
419 | tasklet_disable_nosync(&atusb->task); | |
440 | 420 | } |
441 | 421 | |
442 | 422 | static void atusb_irq_unmask(struct irq_data *data) |
... | ... | |
444 | 424 | struct atusb_local *atusb = irq_data_get_irq_chip_data(data); |
445 | 425 | |
446 | 426 | printk(KERN_INFO "atusb_irq_unmask\n"); |
447 | atusb_irq_enable(atusb); | |
427 | tasklet_enable(&atusb->task); | |
448 | 428 | } |
449 | 429 | |
450 | 430 | static struct irq_chip atusb_irq_chip = { |
... | ... | |
607 | 587 | board_info.platform_data = &atusb->platform_data; |
608 | 588 | board_info.irq = atusb->slave_irq; |
609 | 589 | |
610 | atomic_set(&atusb->masked, 0); | |
611 | atomic_set(&atusb->pending, 0); | |
590 | tasklet_init(&atusb->task, atusb_tasklet, (unsigned long) atusb); | |
612 | 591 | atusb_arm_interrupt(atusb); |
613 | 592 | |
614 | 593 | atusb->spi = spi_new_device(master, &board_info); |
Branches:
ben-wpan
ben-wpan-stefan
5396a9238205f20f811ea57898980d3ca82df0b6
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9