summaryrefslogtreecommitdiff
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2024-09-09 23:00:17 +0900
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>2024-09-09 23:00:17 +0900
commite97fb38fa1404abef72bac7de2c5bf2bbab4d93b (patch)
tree9471d2dbdf0b4fe564f250effb59c1f949e33138 /drivers/firewire/ohci.c
parent7b713929bbd80a400ceb90f398bffe58e5cc8fc8 (diff)
firewire: core: move workqueue handler from 1394 OHCI driver to core function
In current implementation, the work item for isochronous context executes the same procedure of fw_iso_context_flush_completions() internally. There is a space to refactor the implementation. This commit calls fw_iso_context_flush_completions() in the work item. It obsoletes fw_iso_context_init_work(). It also obsoletes a pair of disable_work_sync() and enable_work() since the usage of test_and_set_bit_lock() mediates concurrent call already. Link: https://lore.kernel.org/r/20240909140018.65289-2-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r--drivers/firewire/ohci.c45
1 files changed, 2 insertions, 43 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 3a911cfb5ff3..02ff0363d3ad 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1182,47 +1182,6 @@ static void context_tasklet(unsigned long data)
}
}
-static void ohci_isoc_context_work(struct work_struct *work)
-{
- struct fw_iso_context *base = container_of(work, struct fw_iso_context, work);
- struct iso_context *isoc_ctx = container_of(base, struct iso_context, base);
- struct context *ctx = &isoc_ctx->context;
- struct descriptor *d, *last;
- u32 address;
- int z;
- struct descriptor_buffer *desc;
-
- desc = list_entry(ctx->buffer_list.next, struct descriptor_buffer, list);
- last = ctx->last;
- while (last->branch_address != 0) {
- struct descriptor_buffer *old_desc = desc;
-
- address = le32_to_cpu(last->branch_address);
- z = address & 0xf;
- address &= ~0xf;
- ctx->current_bus = address;
-
- // If the branch address points to a buffer outside of the current buffer, advance
- // to the next buffer.
- if (address < desc->buffer_bus || address >= desc->buffer_bus + desc->used)
- desc = list_entry(desc->list.next, struct descriptor_buffer, list);
- d = desc->buffer + (address - desc->buffer_bus) / sizeof(*d);
- last = find_branch_descriptor(d, z);
-
- if (!ctx->callback(ctx, d, last))
- break;
-
- if (old_desc != desc) {
- // If we've advanced to the next buffer, move the previous buffer to the
- // free list.
- old_desc->used = 0;
- guard(spinlock_irqsave)(&ctx->ohci->lock);
- list_move_tail(&old_desc->list, &ctx->buffer_list);
- }
- ctx->last = last;
- }
-}
-
/*
* Allocate a new buffer and add it to the list of free buffers for this
* context. Must be called with ohci->lock held.
@@ -3169,7 +3128,6 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
ret = context_init(&ctx->context, ohci, regs, callback);
if (ret < 0)
goto out_with_header;
- fw_iso_context_init_work(&ctx->base, ohci_isoc_context_work);
if (type == FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
set_multichannel_mask(ohci, 0);
@@ -3624,7 +3582,8 @@ static int ohci_flush_iso_completions(struct fw_iso_context *base)
int ret = 0;
if (!test_and_set_bit_lock(0, &ctx->flushing_completions)) {
- ohci_isoc_context_work(&base->work);
+ // Note that tasklet softIRQ is not used to process isochronous context anymore.
+ context_tasklet((unsigned long)&ctx->context);
switch (base->type) {
case FW_ISO_CONTEXT_TRANSMIT: