~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/driver-api/driver-model/design-patterns.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/driver-api/driver-model/design-patterns.rst (Version linux-6.12-rc7) and /Documentation/driver-api/driver-model/design-patterns.rst (Version linux-4.19.323)


  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.                
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php