diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2012-04-09 15:40:33 -0400 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2012-04-17 16:27:37 -0400 |
| commit | 8a8c47364eef8595e05b5bf53352aa6f16784356 (patch) | |
| tree | 6e033f3c8698111e0ad662907978409fc418cb2e /drivers/firewire/ohci.c | |
| parent | d713dfa708e14352cfb71342cf985d08fe14be95 (diff) | |
firewire: ohci: omit spinlock IRQ flags where possible
bus_reset_work() is only called from workqueue thread context.
ohci_set_config_rom() and ohci_allocate_iso_context() perform GFP_KERNEL
memory allocations, therefore they must be called with interrupts
enabled.
Hence these functions may disable and enable local IRQs without having
to track IRQ state.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/ohci.c')
| -rw-r--r-- | drivers/firewire/ohci.c | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index b66112da2a61..c1af05e834b6 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
| @@ -1823,7 +1823,6 @@ static void bus_reset_work(struct work_struct *work) | |||
| 1823 | container_of(work, struct fw_ohci, bus_reset_work); | 1823 | container_of(work, struct fw_ohci, bus_reset_work); |
| 1824 | int self_id_count, generation, new_generation, i, j; | 1824 | int self_id_count, generation, new_generation, i, j; |
| 1825 | u32 reg; | 1825 | u32 reg; |
| 1826 | unsigned long flags; | ||
| 1827 | void *free_rom = NULL; | 1826 | void *free_rom = NULL; |
| 1828 | dma_addr_t free_rom_bus = 0; | 1827 | dma_addr_t free_rom_bus = 0; |
| 1829 | bool is_new_root; | 1828 | bool is_new_root; |
| @@ -1930,13 +1929,13 @@ static void bus_reset_work(struct work_struct *work) | |||
| 1930 | } | 1929 | } |
| 1931 | 1930 | ||
| 1932 | /* FIXME: Document how the locking works. */ | 1931 | /* FIXME: Document how the locking works. */ |
| 1933 | spin_lock_irqsave(&ohci->lock, flags); | 1932 | spin_lock_irq(&ohci->lock); |
| 1934 | 1933 | ||
| 1935 | ohci->generation = -1; /* prevent AT packet queueing */ | 1934 | ohci->generation = -1; /* prevent AT packet queueing */ |
| 1936 | context_stop(&ohci->at_request_ctx); | 1935 | context_stop(&ohci->at_request_ctx); |
| 1937 | context_stop(&ohci->at_response_ctx); | 1936 | context_stop(&ohci->at_response_ctx); |
| 1938 | 1937 | ||
| 1939 | spin_unlock_irqrestore(&ohci->lock, flags); | 1938 | spin_unlock_irq(&ohci->lock); |
| 1940 | 1939 | ||
| 1941 | /* | 1940 | /* |
| 1942 | * Per OHCI 1.2 draft, clause 7.2.3.3, hardware may leave unsent | 1941 | * Per OHCI 1.2 draft, clause 7.2.3.3, hardware may leave unsent |
| @@ -1946,7 +1945,7 @@ static void bus_reset_work(struct work_struct *work) | |||
| 1946 | at_context_flush(&ohci->at_request_ctx); | 1945 | at_context_flush(&ohci->at_request_ctx); |
| 1947 | at_context_flush(&ohci->at_response_ctx); | 1946 | at_context_flush(&ohci->at_response_ctx); |
| 1948 | 1947 | ||
| 1949 | spin_lock_irqsave(&ohci->lock, flags); | 1948 | spin_lock_irq(&ohci->lock); |
| 1950 | 1949 | ||
| 1951 | ohci->generation = generation; | 1950 | ohci->generation = generation; |
| 1952 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); | 1951 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); |
| @@ -1990,7 +1989,7 @@ static void bus_reset_work(struct work_struct *work) | |||
| 1990 | reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0); | 1989 | reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0); |
| 1991 | #endif | 1990 | #endif |
| 1992 | 1991 | ||
| 1993 | spin_unlock_irqrestore(&ohci->lock, flags); | 1992 | spin_unlock_irq(&ohci->lock); |
| 1994 | 1993 | ||
| 1995 | if (free_rom) | 1994 | if (free_rom) |
| 1996 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | 1995 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, |
| @@ -2402,7 +2401,6 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
| 2402 | const __be32 *config_rom, size_t length) | 2401 | const __be32 *config_rom, size_t length) |
| 2403 | { | 2402 | { |
| 2404 | struct fw_ohci *ohci; | 2403 | struct fw_ohci *ohci; |
| 2405 | unsigned long flags; | ||
| 2406 | __be32 *next_config_rom; | 2404 | __be32 *next_config_rom; |
| 2407 | dma_addr_t uninitialized_var(next_config_rom_bus); | 2405 | dma_addr_t uninitialized_var(next_config_rom_bus); |
| 2408 | 2406 | ||
| @@ -2441,7 +2439,7 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
| 2441 | if (next_config_rom == NULL) | 2439 | if (next_config_rom == NULL) |
| 2442 | return -ENOMEM; | 2440 | return -ENOMEM; |
| 2443 | 2441 | ||
| 2444 | spin_lock_irqsave(&ohci->lock, flags); | 2442 | spin_lock_irq(&ohci->lock); |
| 2445 | 2443 | ||
| 2446 | /* | 2444 | /* |
| 2447 | * If there is not an already pending config_rom update, | 2445 | * If there is not an already pending config_rom update, |
| @@ -2467,7 +2465,7 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
| 2467 | 2465 | ||
| 2468 | reg_write(ohci, OHCI1394_ConfigROMmap, ohci->next_config_rom_bus); | 2466 | reg_write(ohci, OHCI1394_ConfigROMmap, ohci->next_config_rom_bus); |
| 2469 | 2467 | ||
| 2470 | spin_unlock_irqrestore(&ohci->lock, flags); | 2468 | spin_unlock_irq(&ohci->lock); |
| 2471 | 2469 | ||
| 2472 | /* If we didn't use the DMA allocation, delete it. */ | 2470 | /* If we didn't use the DMA allocation, delete it. */ |
| 2473 | if (next_config_rom != NULL) | 2471 | if (next_config_rom != NULL) |
| @@ -2891,10 +2889,9 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, | |||
| 2891 | descriptor_callback_t uninitialized_var(callback); | 2889 | descriptor_callback_t uninitialized_var(callback); |
| 2892 | u64 *uninitialized_var(channels); | 2890 | u64 *uninitialized_var(channels); |
| 2893 | u32 *uninitialized_var(mask), uninitialized_var(regs); | 2891 | u32 *uninitialized_var(mask), uninitialized_var(regs); |
| 2894 | unsigned long flags; | ||
| 2895 | int index, ret = -EBUSY; | 2892 | int index, ret = -EBUSY; |
| 2896 | 2893 | ||
| 2897 | spin_lock_irqsave(&ohci->lock, flags); | 2894 | spin_lock_irq(&ohci->lock); |
| 2898 | 2895 | ||
| 2899 | switch (type) { | 2896 | switch (type) { |
| 2900 | case FW_ISO_CONTEXT_TRANSMIT: | 2897 | case FW_ISO_CONTEXT_TRANSMIT: |
| @@ -2938,7 +2935,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, | |||
| 2938 | ret = -ENOSYS; | 2935 | ret = -ENOSYS; |
| 2939 | } | 2936 | } |
| 2940 | 2937 | ||
| 2941 | spin_unlock_irqrestore(&ohci->lock, flags); | 2938 | spin_unlock_irq(&ohci->lock); |
| 2942 | 2939 | ||
| 2943 | if (index < 0) | 2940 | if (index < 0) |
| 2944 | return ERR_PTR(ret); | 2941 | return ERR_PTR(ret); |
| @@ -2964,7 +2961,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, | |||
| 2964 | out_with_header: | 2961 | out_with_header: |
| 2965 | free_page((unsigned long)ctx->header); | 2962 | free_page((unsigned long)ctx->header); |
| 2966 | out: | 2963 | out: |
| 2967 | spin_lock_irqsave(&ohci->lock, flags); | 2964 | spin_lock_irq(&ohci->lock); |
| 2968 | 2965 | ||
| 2969 | switch (type) { | 2966 | switch (type) { |
| 2970 | case FW_ISO_CONTEXT_RECEIVE: | 2967 | case FW_ISO_CONTEXT_RECEIVE: |
| @@ -2977,7 +2974,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, | |||
| 2977 | } | 2974 | } |
| 2978 | *mask |= 1 << index; | 2975 | *mask |= 1 << index; |
| 2979 | 2976 | ||
| 2980 | spin_unlock_irqrestore(&ohci->lock, flags); | 2977 | spin_unlock_irq(&ohci->lock); |
| 2981 | 2978 | ||
| 2982 | return ERR_PTR(ret); | 2979 | return ERR_PTR(ret); |
| 2983 | } | 2980 | } |
