|  |  | 
|  | 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. |