1Driver Model 2============ 3 4This README contains high-level information about driver model, a unified 5way of declaring and accessing drivers in U-Boot. The original work was done 6by: 7 8 Marek Vasut <marex@denx.de> 9 Pavel Herrmann <morpheus.ibis@gmail.com> 10 Viktor Křivák <viktor.krivak@gmail.com> 11 Tomas Hlavacek <tmshlvck@gmail.com> 12 13This has been both simplified and extended into the current implementation 14by: 15 16 Simon Glass <sjg@chromium.org> 17 18 19Terminology 20----------- 21 22Uclass - a group of devices which operate in the same way. A uclass provides 23 a way of accessing invidual devices within the group, but always 24 using the same interface. For example a GPIO uclass provides 25 operations for get/set value. An I2C uclass may have 10 I2C ports, 26 4 with one driver, and 6 with another. 27 28Driver - some code which talks to a peripheral and presents a higher-level 29 interface to it. 30 31Device - an instance of a driver, tied to a particular port or peripheral. 32 33 34How to try it 35------------- 36 37Build U-Boot sandbox and run it: 38 39 make sandbox_config 40 make 41 ./u-boot 42 43 (type 'reset' to exit U-Boot) 44 45 46There is a uclass called 'demo'. This uclass handles 47saying hello, and reporting its status. There are two drivers in this 48uclass: 49 50 - simple: Just prints a message for hello, doesn't implement status 51 - shape: Prints shapes and reports number of characters printed as status 52 53The demo class is pretty simple, but not trivial. The intention is that it 54can be used for testing, so it will implement all driver model features and 55provide good code coverage of them. It does have multiple drivers, it 56handles parameter data and platdata (data which tells the driver how 57to operate on a particular platform) and it uses private driver data. 58 59To try it, see the example session below: 60 61=>demo hello 1 62Hello '@' from 07981110: red 4 63=>demo status 2 64Status: 0 65=>demo hello 2 66g 67r@ 68e@@ 69e@@@ 70n@@@@ 71g@@@@@ 72=>demo status 2 73Status: 21 74=>demo hello 4 ^ 75 y^^^ 76 e^^^^^ 77l^^^^^^^ 78l^^^^^^^ 79 o^^^^^ 80 w^^^ 81=>demo status 4 82Status: 36 83=> 84 85 86Running the tests 87----------------- 88 89The intent with driver model is that the core portion has 100% test coverage 90in sandbox, and every uclass has its own test. As a move towards this, tests 91are provided in test/dm. To run them, try: 92 93 ./test/dm/test-dm.sh 94 95You should see something like this: 96 97 <...U-Boot banner...> 98 Running 12 driver model tests 99 Test: dm_test_autobind 100 Test: dm_test_autoprobe 101 Test: dm_test_children 102 Test: dm_test_fdt 103 Test: dm_test_gpio 104 sandbox_gpio: sb_gpio_get_value: error: offset 4 not reserved 105 Test: dm_test_leak 106 Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c 107 Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c 108 Test: dm_test_lifecycle 109 Test: dm_test_operations 110 Test: dm_test_ordering 111 Test: dm_test_platdata 112 Test: dm_test_remove 113 Test: dm_test_uclass 114 Failures: 0 115 116(You can add '#define DEBUG' as suggested to check for memory leaks) 117 118 119What is going on? 120----------------- 121 122Let's start at the top. The demo command is in common/cmd_demo.c. It does 123the usual command procesing and then: 124 125 struct device *demo_dev; 126 127 ret = uclass_get_device(UCLASS_DEMO, devnum, &demo_dev); 128 129UCLASS_DEMO means the class of devices which implement 'demo'. Other 130classes might be MMC, or GPIO, hashing or serial. The idea is that the 131devices in the class all share a particular way of working. The class 132presents a unified view of all these devices to U-Boot. 133 134This function looks up a device for the demo uclass. Given a device 135number we can find the device because all devices have registered with 136the UCLASS_DEMO uclass. 137 138The device is automatically activated ready for use by uclass_get_device(). 139 140Now that we have the device we can do things like: 141 142 return demo_hello(demo_dev, ch); 143 144This function is in the demo uclass. It takes care of calling the 'hello' 145method of the relevant driver. Bearing in mind that there are two drivers, 146this particular device may use one or other of them. 147 148The code for demo_hello() is in drivers/demo/demo-uclass.c: 149 150int demo_hello(struct device *dev, int ch) 151{ 152 const struct demo_ops *ops = device_get_ops(dev); 153 154 if (!ops->hello) 155 return -ENOSYS; 156 157 return ops->hello(dev, ch); 158} 159 160As you can see it just calls the relevant driver method. One of these is 161in drivers/demo/demo-simple.c: 162 163static int simple_hello(struct device *dev, int ch) 164{ 165 const struct dm_demo_pdata *pdata = dev_get_platdata(dev); 166 167 printf("Hello from %08x: %s %d\n", map_to_sysmem(dev), 168 pdata->colour, pdata->sides); 169 170 return 0; 171} 172 173 174So that is a trip from top (command execution) to bottom (driver action) 175but it leaves a lot of topics to address. 176 177 178Declaring Drivers 179----------------- 180 181A driver declaration looks something like this (see 182drivers/demo/demo-shape.c): 183 184static const struct demo_ops shape_ops = { 185 .hello = shape_hello, 186 .status = shape_status, 187}; 188 189U_BOOT_DRIVER(demo_shape_drv) = { 190 .name = "demo_shape_drv", 191 .id = UCLASS_DEMO, 192 .ops = &shape_ops, 193 .priv_data_size = sizeof(struct shape_data), 194}; 195 196 197This driver has two methods (hello and status) and requires a bit of 198private data (accessible through dev_get_priv(dev) once the driver has 199been probed). It is a member of UCLASS_DEMO so will register itself 200there. 201 202In U_BOOT_DRIVER it is also possible to specify special methods for bind 203and unbind, and these are called at appropriate times. For many drivers 204it is hoped that only 'probe' and 'remove' will be needed. 205 206The U_BOOT_DRIVER macro creates a data structure accessible from C, 207so driver model can find the drivers that are available. 208 209The methods a device can provide are documented in the device.h header. 210Briefly, they are: 211 212 bind - make the driver model aware of a device (bind it to its driver) 213 unbind - make the driver model forget the device 214 ofdata_to_platdata - convert device tree data to platdata - see later 215 probe - make a device ready for use 216 remove - remove a device so it cannot be used until probed again 217 218The sequence to get a device to work is bind, ofdata_to_platdata (if using 219device tree) and probe. 220 221 222Platform Data 223------------- 224 225Where does the platform data come from? See demo-pdata.c which 226sets up a table of driver names and their associated platform data. 227The data can be interpreted by the drivers however they like - it is 228basically a communication scheme between the board-specific code and 229the generic drivers, which are intended to work on any board. 230 231Drivers can acceess their data via dev->info->platdata. Here is 232the declaration for the platform data, which would normally appear 233in the board file. 234 235 static const struct dm_demo_cdata red_square = { 236 .colour = "red", 237 .sides = 4. 238 }; 239 static const struct driver_info info[] = { 240 { 241 .name = "demo_shape_drv", 242 .platdata = &red_square, 243 }, 244 }; 245 246 demo1 = driver_bind(root, &info[0]); 247 248 249Device Tree 250----------- 251 252While platdata is useful, a more flexible way of providing device data is 253by using device tree. With device tree we replace the above code with the 254following device tree fragment: 255 256 red-square { 257 compatible = "demo-shape"; 258 colour = "red"; 259 sides = <4>; 260 }; 261 262 263The easiest way to make this work it to add a few members to the driver: 264 265 .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), 266 .ofdata_to_platdata = testfdt_ofdata_to_platdata, 267 .probe = testfdt_drv_probe, 268 269The 'auto_alloc' feature allowed space for the platdata to be allocated 270and zeroed before the driver's ofdata_to_platdata method is called. This 271method reads the information out of the device tree and puts it in 272dev->platdata. Then the probe method is called to set up the device. 273 274Note that both methods are optional. If you provide an ofdata_to_platdata 275method then it wlil be called first (after bind). If you provide a probe 276method it will be called next. 277 278If you don't want to have the platdata automatically allocated then you 279can leave out platdata_auto_alloc_size. In this case you can use malloc 280in your ofdata_to_platdata (or probe) method to allocate the required memory, 281and you should free it in the remove method. 282 283 284Declaring Uclasses 285------------------ 286 287The demo uclass is declared like this: 288 289U_BOOT_CLASS(demo) = { 290 .id = UCLASS_DEMO, 291}; 292 293It is also possible to specify special methods for probe, etc. The uclass 294numbering comes from include/dm/uclass.h. To add a new uclass, add to the 295end of the enum there, then declare your uclass as above. 296 297 298Data Structures 299--------------- 300 301Driver model uses a doubly-linked list as the basic data structure. Some 302nodes have several lists running through them. Creating a more efficient 303data structure might be worthwhile in some rare cases, once we understand 304what the bottlenecks are. 305 306 307Changes since v1 308---------------- 309 310For the record, this implementation uses a very similar approach to the 311original patches, but makes at least the following changes: 312 313- Tried to agressively remove boilerplate, so that for most drivers there 314is little or no 'driver model' code to write. 315- Moved some data from code into data structure - e.g. store a pointer to 316the driver operations structure in the driver, rather than passing it 317to the driver bind function. 318- Rename some structures to make them more similar to Linux (struct device 319instead of struct instance, struct platdata, etc.) 320- Change the name 'core' to 'uclass', meaning U-Boot class. It seems that 321this concept relates to a class of drivers (or a subsystem). We shouldn't 322use 'class' since it is a C++ reserved word, so U-Boot class (uclass) seems 323better than 'core'. 324- Remove 'struct driver_instance' and just use a single 'struct device'. 325This removes a level of indirection that doesn't seem necessary. 326- Built in device tree support, to avoid the need for platdata 327- Removed the concept of driver relocation, and just make it possible for 328the new driver (created after relocation) to access the old driver data. 329I feel that relocation is a very special case and will only apply to a few 330drivers, many of which can/will just re-init anyway. So the overhead of 331dealing with this might not be worth it. 332- Implemented a GPIO system, trying to keep it simple 333 334 335Things to punt for later 336------------------------ 337 338- SPL support - this will have to be present before many drivers can be 339converted, but it seems like we can add it once we are happy with the 340core implementation. 341- Pre-relocation support - similar story 342 343That is not to say that no thinking has gone into these - in fact there 344is quite a lot there. However, getting these right is non-trivial and 345there is a high cost associated with going down the wrong path. 346 347For SPL, it may be possible to fit in a simplified driver model with only 348bind and probe methods, to reduce size. 349 350For pre-relocation we can simply call the driver model init function. Then 351post relocation we throw that away and re-init driver model again. For drivers 352which require some sort of continuity between pre- and post-relocation 353devices, we can provide access to the pre-relocation device pointers. 354 355Uclasses are statically numbered at compile time. It would be possible to 356change this to dynamic numbering, but then we would require some sort of 357lookup service, perhaps searching by name. This is slightly less efficient 358so has been left out for now. One small advantage of dynamic numbering might 359be fewer merge conflicts in uclass-id.h. 360 361 362Simon Glass 363sjg@chromium.org 364April 2013 365Updated 7-May-13 366Updated 14-Jun-13 367Updated 18-Oct-13 368Updated 5-Nov-13 369