]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
firewire: core: expose kernel API to schedule work item to process isochronous context
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 8 Sep 2024 04:05:48 +0000 (13:05 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 8 Sep 2024 04:05:48 +0000 (13:05 +0900)
In packet-per-buffer mode for isochronous context of 1394 OHCI, software
can schedule hardIRQ to the buffer in which the content of isochronous
packet is processed. The actual behaviour is different between isochronous
receive (IR) and transmit (IT) contexts in respect to isochronous cycle in
which the hardIRQ occurs.

In IR context, the hardIRQ occurs when the buffer is filled actually by
the content of received packet. If there are any isochronous cycles in
which the packet transmission is skipped, it is postponed to generate
the hardIRQ in respect to the isochronous cycle. In IT context, software
can schedule the content of packet every isochronous cycle including
skipping, therefore the hardIRQ occurs in the isochronous cycle to which
the software scheduled.

ALSA firewire stack uses the packet-per-buffer mode for both IR/IT
contexts. To process time stamp per packet (or per sample in some cases)
steadily for media clock recovery against unexpected transmission skips,
it uses an IT context to operate all of isochronous contexts by calls of
fw_iso_context_flush_completions() in the bottom-half of hardIRQ for the
IT context.

Although it looks well to handle all of isochronous contexts in a single
bottom-half context, it relatively takes longer time. In the future code
integration (not yet), it is possible to apply parallelism method to
process these context. In the case, it is useful to allow unit drivers to
schedule work items to process these isochronous contexts.

As a preparation, this commit exposes
fw_iso_context_schedule_flush_completions() as a kernel API available by
unit drivers. It is renamed from fw_iso_context_queue_work() since it is
a counter part of fw_iso_context_flush_completions().

Link: https://lore.kernel.org/r/20240908040549.75304-2-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Documentation/driver-api/firewire.rst
drivers/firewire/core.h
drivers/firewire/ohci.c
include/linux/firewire.h

index d3cfa73cbb2b47e624961f3e15aadb6528dfec37..28a32410f7d23ccf0e2348fb2a4481765f34d571 100644 (file)
@@ -43,6 +43,8 @@ Firewire core transaction interfaces
 Firewire Isochronous I/O interfaces
 ===================================
 
+.. kernel-doc:: include/linux/firewire.h
+   :functions: fw_iso_context_schedule_flush_completions
 .. kernel-doc:: drivers/firewire/core-iso.c
    :export:
 
index 2874f316156a63a8eb1eeba8bb88e69fec820b2d..0ae2c84ecafedb8eb7ecc54ed5edf268a445270e 100644 (file)
@@ -164,11 +164,6 @@ static inline void fw_iso_context_init_work(struct fw_iso_context *ctx, work_fun
        INIT_WORK(&ctx->work, func);
 }
 
-static inline void fw_iso_context_queue_work(struct fw_iso_context *ctx)
-{
-       queue_work(ctx->card->isoc_wq, &ctx->work);
-}
-
 
 /* -topology */
 
index d0b1fccc450f2151395eb267357e588abcbfa8e5..3a911cfb5ff31a4bd1a31cf984d061b6def53f5b 100644 (file)
@@ -2283,7 +2283,7 @@ static irqreturn_t irq_handler(int irq, void *data)
 
                while (iso_event) {
                        i = ffs(iso_event) - 1;
-                       fw_iso_context_queue_work(&ohci->ir_context_list[i].base);
+                       fw_iso_context_schedule_flush_completions(&ohci->ir_context_list[i].base);
                        iso_event &= ~(1 << i);
                }
        }
@@ -2294,7 +2294,7 @@ static irqreturn_t irq_handler(int irq, void *data)
 
                while (iso_event) {
                        i = ffs(iso_event) - 1;
-                       fw_iso_context_queue_work(&ohci->it_context_list[i].base);
+                       fw_iso_context_schedule_flush_completions(&ohci->it_context_list[i].base);
                        iso_event &= ~(1 << i);
                }
        }
index 72f497b6173914d1e6a362b9fc5f6fe0b670751b..f815d12deda0315ff045f1bc58d6ef24f3bad587 100644 (file)
@@ -531,6 +531,23 @@ int fw_iso_context_queue(struct fw_iso_context *ctx,
                         unsigned long payload);
 void fw_iso_context_queue_flush(struct fw_iso_context *ctx);
 int fw_iso_context_flush_completions(struct fw_iso_context *ctx);
+
+/**
+ * fw_iso_context_schedule_flush_completions() - schedule work item to process isochronous context.
+ * @ctx: the isochronous context
+ *
+ * Schedule a work item on workqueue to process the isochronous context. The registered callback
+ * function is called in the worker if some packets have been already transferred since the last
+ * time. If it is required to process the context in the current context,
+ * fw_iso_context_flush_completions() is available instead.
+ *
+ * Context: Any context.
+ */
+static inline void fw_iso_context_schedule_flush_completions(struct fw_iso_context *ctx)
+{
+       queue_work(ctx->card->isoc_wq, &ctx->work);
+}
+
 int fw_iso_context_start(struct fw_iso_context *ctx,
                         int cycle, int sync, int tags);
 int fw_iso_context_stop(struct fw_iso_context *ctx);