aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/driver-model/design-patterns.txt
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/driver-model/design-patterns.txt')
-rw-r--r--Documentation/driver-model/design-patterns.txt116
1 files changed, 0 insertions, 116 deletions
diff --git a/Documentation/driver-model/design-patterns.txt b/Documentation/driver-model/design-patterns.txt
deleted file mode 100644
index ba7b2df64904..000000000000
--- a/Documentation/driver-model/design-patterns.txt
+++ /dev/null
@@ -1,116 +0,0 @@
-
-Device Driver Design Patterns
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This document describes a few common design patterns found in device drivers.
-It is likely that subsystem maintainers will ask driver developers to
-conform to these design patterns.
-
-1. State Container
-2. container_of()
-
-
-1. State Container
-~~~~~~~~~~~~~~~~~~
-
-While the kernel contains a few device drivers that assume that they will
-only be probed() once on a certain system (singletons), it is custom to assume
-that the device the driver binds to will appear in several instances. This
-means that the probe() function and all callbacks need to be reentrant.
-
-The most common way to achieve this is to use the state container design
-pattern. It usually has this form:
-
-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(...)
-{
- struct foo *foo;
-
- foo->wq = create_singlethread_workqueue("foo-wq");
- INIT_WORK(&foo->offload, foo_work);
- (...)
-}
-
-The design pattern is the same for an hrtimer or something similar that will
-return a single argument which is a pointer to a struct member in the
-callback.
-
-container_of() is a macro defined in <linux/kernel.h>
-
-What container_of() does is to obtain a pointer to the containing struct from
-a pointer to a member by a simple subtraction using the offsetof() macro from
-standard C, which allows something similar to object oriented behaviours.
-Notice that the contained member must not be a pointer, but an actual member
-for this to work.
-
-We can see here that we avoid having global pointers to our struct foo *
-instance this way, while still keeping the number of parameters passed to the
-work function to a single pointer.