diff options
author | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2019-06-18 17:53:27 -0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-06-21 15:47:26 +0200 |
commit | 4489f161b739f01ab60a58784f6ef7de9d7a1352 (patch) | |
tree | eac4bc84b8e7c5c4e2ba0b87fdec9dd66ce3b62e /Documentation/driver-model/design-patterns.txt | |
parent | 58cb346c7188f04bafa2a089ab0b093f5642572c (diff) | |
download | linux-next-4489f161b739f01ab60a58784f6ef7de9d7a1352.tar.gz |
docs: driver-model: convert docs to ReST and rename to *.rst
Convert the various documents at the driver-model, preparing
them to be part of the driver-api book.
The conversion is actually:
- add blank lines and identation in order to identify paragraphs;
- fix tables markups;
- add some lists markups;
- mark literal blocks;
- adjust title markups.
At its new index.rst, let's add a :orphan: while this is not linked to
the main index.rst file, in order to avoid build warnings.
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> # ice
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'Documentation/driver-model/design-patterns.txt')
-rw-r--r-- | Documentation/driver-model/design-patterns.txt | 116 |
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. |