1 ============================= 2 Device Driver Design Patterns 3 ============================= 4 5 This document describes a few common design pa 6 It is likely that subsystem maintainers will a 7 conform to these design patterns. 8 9 1. State Container 10 2. container_of() 11 12 13 1. State Container 14 ~~~~~~~~~~~~~~~~~~ 15 16 While the kernel contains a few device drivers 17 only be probed() once on a certain system (sin 18 that the device the driver binds to will appea 19 means that the probe() function and all callba 20 21 The most common way to achieve this is to use 22 pattern. It usually has this form:: 23 24 struct foo { 25 spinlock_t lock; /* Example member */ 26 (...) 27 }; 28 29 static int foo_probe(...) 30 { 31 struct foo *foo; 32 33 foo = devm_kzalloc(dev, sizeof(*foo), GF 34 if (!foo) 35 return -ENOMEM; 36 spin_lock_init(&foo->lock); 37 (...) 38 } 39 40 This will create an instance of struct foo in 41 called. This is our state container for this i 42 Of course it is then necessary to always pass 43 state around to all functions that need access 44 45 For example, if the driver is registering an i 46 pass around a pointer to struct foo like this: 47 48 static irqreturn_t foo_handler(int irq, void 49 { 50 struct foo *foo = arg; 51 (...) 52 } 53 54 static int foo_probe(...) 55 { 56 struct foo *foo; 57 58 (...) 59 ret = request_irq(irq, foo_handler, 0, " 60 } 61 62 This way you always get a pointer back to the 63 your interrupt handler. 64 65 66 2. container_of() 67 ~~~~~~~~~~~~~~~~~ 68 69 Continuing on the above example we add an offl 70 71 struct foo { 72 spinlock_t lock; 73 struct workqueue_struct *wq; 74 struct work_struct offload; 75 (...) 76 }; 77 78 static void foo_work(struct work_struct *wor 79 { 80 struct foo *foo = container_of(work, str 81 82 (...) 83 } 84 85 static irqreturn_t foo_handler(int irq, void 86 { 87 struct foo *foo = arg; 88 89 queue_work(foo->wq, &foo->offload); 90 (...) 91 } 92 93 static int foo_probe(...) 94 { 95 struct foo *foo; 96 97 foo->wq = create_singlethread_workqueue( 98 INIT_WORK(&foo->offload, foo_work); 99 (...) 100 } 101 102 The design pattern is the same for an hrtimer 103 return a single argument which is a pointer to 104 callback. 105 106 container_of() is a macro defined in <linux/ke 107 108 What container_of() does is to obtain a pointe 109 a pointer to a member by a simple subtraction 110 standard C, which allows something similar to 111 Notice that the contained member must not be a 112 for this to work. 113 114 We can see here that we avoid having global po 115 instance this way, while still keeping the num 116 work function to a single pointer.
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.