Documentation/driver-api/driver-model/design-patterns.rst

Source file repositories/reference/linux-study-clean/Documentation/driver-api/driver-model/design-patterns.rst

File Facts

System
Linux kernel
Corpus path
Documentation/driver-api/driver-model/design-patterns.rst
Extension
.rst
Size
3205 bytes
Lines
117
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct foo {
      spinlock_t lock; /* Example member */
      (...)
  };

  static int foo_probe(...)
  {
      struct foo *foo;

      foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL);
      if (!foo)
          return -ENOMEM;
      spin_lock_init(&foo->lock);
      (...)
  }

This will create an instance of struct foo in memory every time probe() is
called. This is our state container for this instance of the device driver.
Of course it is then necessary to always pass this instance of the
state around to all functions that need access to the state and its members.

For example, if the driver is registering an interrupt handler, you would
pass around a pointer to struct foo like this::

  static irqreturn_t foo_handler(int irq, void *arg)
  {
      struct foo *foo = arg;
      (...)
  }

  static int foo_probe(...)
  {
      struct foo *foo;

      (...)
      ret = request_irq(irq, foo_handler, 0, "foo", foo);
  }

This way you always get a pointer back to the correct instance of foo in
your interrupt handler.


2. container_of()
~~~~~~~~~~~~~~~~~

Continuing on the above example we add an offloaded work::

  struct foo {
      spinlock_t lock;
      struct workqueue_struct *wq;
      struct work_struct offload;
      (...)
  };

  static void foo_work(struct work_struct *work)
  {
      struct foo *foo = container_of(work, struct foo, offload);

      (...)
  }

  static irqreturn_t foo_handler(int irq, void *arg)
  {
      struct foo *foo = arg;

      queue_work(foo->wq, &foo->offload);
      (...)
  }

  static int foo_probe(...)

Annotation

Implementation Notes