1*4882a593Smuzhiyun============================= 2*4882a593SmuzhiyunDevice Driver Design Patterns 3*4882a593Smuzhiyun============================= 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunThis document describes a few common design patterns found in device drivers. 6*4882a593SmuzhiyunIt is likely that subsystem maintainers will ask driver developers to 7*4882a593Smuzhiyunconform to these design patterns. 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun1. State Container 10*4882a593Smuzhiyun2. container_of() 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun1. State Container 14*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~ 15*4882a593Smuzhiyun 16*4882a593SmuzhiyunWhile the kernel contains a few device drivers that assume that they will 17*4882a593Smuzhiyunonly be probed() once on a certain system (singletons), it is custom to assume 18*4882a593Smuzhiyunthat the device the driver binds to will appear in several instances. This 19*4882a593Smuzhiyunmeans that the probe() function and all callbacks need to be reentrant. 20*4882a593Smuzhiyun 21*4882a593SmuzhiyunThe most common way to achieve this is to use the state container design 22*4882a593Smuzhiyunpattern. It usually has this form:: 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun struct foo { 25*4882a593Smuzhiyun spinlock_t lock; /* Example member */ 26*4882a593Smuzhiyun (...) 27*4882a593Smuzhiyun }; 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun static int foo_probe(...) 30*4882a593Smuzhiyun { 31*4882a593Smuzhiyun struct foo *foo; 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL); 34*4882a593Smuzhiyun if (!foo) 35*4882a593Smuzhiyun return -ENOMEM; 36*4882a593Smuzhiyun spin_lock_init(&foo->lock); 37*4882a593Smuzhiyun (...) 38*4882a593Smuzhiyun } 39*4882a593Smuzhiyun 40*4882a593SmuzhiyunThis will create an instance of struct foo in memory every time probe() is 41*4882a593Smuzhiyuncalled. This is our state container for this instance of the device driver. 42*4882a593SmuzhiyunOf course it is then necessary to always pass this instance of the 43*4882a593Smuzhiyunstate around to all functions that need access to the state and its members. 44*4882a593Smuzhiyun 45*4882a593SmuzhiyunFor example, if the driver is registering an interrupt handler, you would 46*4882a593Smuzhiyunpass around a pointer to struct foo like this:: 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun static irqreturn_t foo_handler(int irq, void *arg) 49*4882a593Smuzhiyun { 50*4882a593Smuzhiyun struct foo *foo = arg; 51*4882a593Smuzhiyun (...) 52*4882a593Smuzhiyun } 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun static int foo_probe(...) 55*4882a593Smuzhiyun { 56*4882a593Smuzhiyun struct foo *foo; 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun (...) 59*4882a593Smuzhiyun ret = request_irq(irq, foo_handler, 0, "foo", foo); 60*4882a593Smuzhiyun } 61*4882a593Smuzhiyun 62*4882a593SmuzhiyunThis way you always get a pointer back to the correct instance of foo in 63*4882a593Smuzhiyunyour interrupt handler. 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun2. container_of() 67*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~ 68*4882a593Smuzhiyun 69*4882a593SmuzhiyunContinuing on the above example we add an offloaded work:: 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun struct foo { 72*4882a593Smuzhiyun spinlock_t lock; 73*4882a593Smuzhiyun struct workqueue_struct *wq; 74*4882a593Smuzhiyun struct work_struct offload; 75*4882a593Smuzhiyun (...) 76*4882a593Smuzhiyun }; 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun static void foo_work(struct work_struct *work) 79*4882a593Smuzhiyun { 80*4882a593Smuzhiyun struct foo *foo = container_of(work, struct foo, offload); 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun (...) 83*4882a593Smuzhiyun } 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun static irqreturn_t foo_handler(int irq, void *arg) 86*4882a593Smuzhiyun { 87*4882a593Smuzhiyun struct foo *foo = arg; 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun queue_work(foo->wq, &foo->offload); 90*4882a593Smuzhiyun (...) 91*4882a593Smuzhiyun } 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun static int foo_probe(...) 94*4882a593Smuzhiyun { 95*4882a593Smuzhiyun struct foo *foo; 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun foo->wq = create_singlethread_workqueue("foo-wq"); 98*4882a593Smuzhiyun INIT_WORK(&foo->offload, foo_work); 99*4882a593Smuzhiyun (...) 100*4882a593Smuzhiyun } 101*4882a593Smuzhiyun 102*4882a593SmuzhiyunThe design pattern is the same for an hrtimer or something similar that will 103*4882a593Smuzhiyunreturn a single argument which is a pointer to a struct member in the 104*4882a593Smuzhiyuncallback. 105*4882a593Smuzhiyun 106*4882a593Smuzhiyuncontainer_of() is a macro defined in <linux/kernel.h> 107*4882a593Smuzhiyun 108*4882a593SmuzhiyunWhat container_of() does is to obtain a pointer to the containing struct from 109*4882a593Smuzhiyuna pointer to a member by a simple subtraction using the offsetof() macro from 110*4882a593Smuzhiyunstandard C, which allows something similar to object oriented behaviours. 111*4882a593SmuzhiyunNotice that the contained member must not be a pointer, but an actual member 112*4882a593Smuzhiyunfor this to work. 113*4882a593Smuzhiyun 114*4882a593SmuzhiyunWe can see here that we avoid having global pointers to our struct foo * 115*4882a593Smuzhiyuninstance this way, while still keeping the number of parameters passed to the 116*4882a593Smuzhiyunwork function to a single pointer. 117