diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
new file mode 100644
index 0000000..02106d6--- /dev/null+++ b/doc/driver-model/README.txt@@ -0,0 +1,320 @@+Driver Model+============++This README contains high-level information about driver model, a unified+way of declaring and accessing drivers in U-Boot. The original work was done+by:++ Marek Vasut <marex@denx.de>+ Pavel Herrmann <morpheus.ibis@gmail.com>+ Viktor Křivák <viktor.krivak@gmail.com>+ Tomas Hlavacek <tmshlvck@gmail.com>++This has been both simplified and extended into the current implementation+by:++ Simon Glass <sjg@chromium.org>+++Terminology+-----------++Uclass - a group of device which operate in the same way. A uclass provides+ a way of accessing invidual devices within the group, but always+ using the same interface. For example a GPIO uclass provides+ operations for get/set value. An I2C uclass may have 10 I2C ports,+ 4 with one driver, and 6 with another.++Driver - some code which talks to a peripheral and presents a higher-level+ interface to it.++Device - an instance of a driver, tied to a particular port or peripheral.+++How to try it+-------------++Build U-Boot sandbox and run it:++ make sandbox_config+ make+ ./u-boot++ (type 'reset' to exit U-Boot)+++There is a uclass called 'demo'. This uclass handles+saying hello, and reporting its status. There are two drivers in this+uclass:++ - simple: Just prints a message for hello, doesn't implement status+ - shape: Prints shapes and reports number of characters printed as status++The demo class is pretty simple, but not trivial. The intention is that it+can be used for testing, so it will implement all driver model features and+provide 100% code coverage of them. It does have multiple drivers, it+handles parameter data and platform_data (data which tells the driver how+to operate on a particular platform) and it uses private driver data.++To try it, see the example session below:++=>demo hello 1+Hello '@' from 07981110: red 4+=>demo status 2+Status: 0+=>demo hello 2+g+r@+e@@+e@@@+n@@@@+g@@@@@+=>demo status 2+Status: 21+=>demo hello 4 ^+ y^^^+ e^^^^^+l^^^^^^^+l^^^^^^^+ o^^^^^+ w^^^+=>demo status 4+Status: 36+=>+++Running the tests+-----------------++The intent with driver model is that the core portion has 100% test coverage+in sandbox, and every uclass has its own test. As a move towards this, tests+are provided in test/dm. To run them, try:++ ./test/dm/test-dm.sh+++What is going on?+-----------------++Let's start at the top. The demo command is in common/cmd_demo.c. It does+the usual command procesing and then:++ struct device *demo_dev;++ ret = uclass_get_device(UCLASS_DEMO, &demo_dev);++UCLASS_DEMO means the class of devices which implement 'demo'. Other+classes might be MMC, or GPIO, hashing or serial. The idea is that the+devices in the class all share a particular way of working. The class+presents a unified view of all these devices to U-Boot.++This function looks up the device for the demo uclass. Given a device+number we can find the device because all devices have registered with+the UCLASS_DEMO uclass.++Having found the device, we activate it with:++ ret = driver_activate(demo_dev);++This is because all devices are inactive until used in U-Boot. The exact+mechanism of activating a driver will hopefully change. For example, i+may be possible to combine uclass_get_child() and driver_activate().++Now that we have the device we can do things like:++ return demo_hello(demo_dev, ch);++This function is in the demo uclass. It takes care of calling the 'hello'+method of the relevant driver. Bearing in mind that there are two drivers,+this particular device may use one or other of them.++The code for demo_hello() is in drivers/demo/demo-uclass.c:++int demo_hello(struct device *dev, int ch)+{+ const struct demo_ops *ops = device_get_ops(dev);++ if (!ops->hello)+ return -ENOSYS;++ return ops->hello(dev, ch);+}++As you can see it just calls the relevant driver method. One of these is+in drivers/demo/demo-simple.c:++static int simple_hello(struct device *dev, int ch)+{+ const struct dm_demo_pdata *pdata = dev->platform_data;++ printf("Hello from %08x: %s %d\n", map_to_sysmem(dev),+ pdata->colour, pdata->sides);++ return 0;+}+++So that is a trip from top to bottom but it leaves a lot of topics to+address.+++Declaring Drivers+-----------------++A driver declaration looks something like this (see+drivers/demo/demo-shape.c):++static const struct demo_ops simple_ops = {+ .hello = shape_hello,+ .status = shape_status,+};++U_BOOT_DRIVER(demo_shape_drv) = {+ .name = "demo_shape_drv",+ .id = UCLASS_DEMO,+ .ops = &simple_ops,+ .priv_data_size = sizeof(struct shape_data),+};+++This driver has two methods (hello and status) and requires a bit+of private data (accessible through dev->priv once the driver has+been probed). It is a member of UCLASS_DEMO so will register itself+there.++In U_BOOT_DRIVER it is also possible to specify special methods for probe,+and bind, and these are called at appropriate times. For many drivers+it is hoped that only 'probe' and 'remove' will be needed.++The U_BOOT_DRIVER macro creates a data structure accessible from C,+so driver model can find the drivers that are available.+++Platform Data+-------------++Where does the platform data come from? See demo-pdata.c which+sets up a table of driver names and their associated platform data.+The data can be interpreted by the drivers however they like - it is+basically a communication scheme between the board-specific code and+the generic drivers, which are intended to work on any board.++Drivers can acceess their data via dev->info->platform_data. Here is+the declaration for the platform data, which would normally appear+in the board file.++ static const struct dm_demo_cdata red_square = {+ .colour = "red",+ .sides = 4.+ };+ static const struct driver_info info[] = {+ {+ .name = "demo_shape_drv",+ .platform_data = &red_square,+ },+ };++ demo1 = driver_bind(root, &info[0]);+++Device Tree+-----------++While platform_data is useful, a more flexible way of providing device data is+by using device tree. With device tree we replace the above code with the+following device treefragment:++ red-square {+ compatible = "demo-shape";+ colour = "red";+ sides = <4>;+ };+++The easiest way to make this work it to add a platform_data_size member to+the driver:++ .platform_data_auto_alloc_size = sizeof(struct dm_test_pdata),++This will be allocated and zeroed before the driver's probe method is called.+The driver can then read the information out of the device tree and put it+in dev->priv, typically using a ..._parse_dt() function.+++Declaring Uclasses+------------------++The demo uclass is declared like this:++U_BOOT_CLASS(demo) = {+ .id = UCLASS_DEMO,+};++It is also possible to specify special methods for probe, etc. The uclass+numbering comes from include/dm/uclass.h. To add a new uclass, add to the+end of the enum there, then declare your uclass as above.+++Data Structures+---------------++Driver model uses a doubly-linked list as the basic data structure. Some+nodes have several lists running through them. Creating a more efficient+data structure might be worthwhile in some rare cases, once we understand+what the bottlenecks are.+++Changes since v1+----------------++For the record, this implementation uses a very similar approach to the+original patches, but makes at least the following changes:++- Tried to agressively remove boilerplate, so that for most drivers there+is little or no 'driver model' code to write.+- Moved some data from code into data structure - e.g. store a pointer to+the driver operations structure in the driver, rather than passing it+to the driver bind function.+- Rename some structures to make them more similar to Linux (struct device+instead of struct instance, struct platform_data, etc.)+- Change the name 'core' to 'uclass', meaning U-Boot class. It seems that+this concept relates to a class of drivers (or a subsystem). We shouldn't+use 'class' since it is a C++ reserved word, so U-Boot class (uclass) seems+better than 'core'.+- Remove 'struct driver_instance' and just use a single 'struct device'.+This removes a level of indirection that doesn't seem necessary.+- Built in device tree support, to avoid the need for platform_data+- Removed the concept of driver relocation, and just make it possible for+the new driver (created after relocation) to access the old driver data.+I feel that relocation is a very special case and will only apply to a few+drivers, many of which can/will just re-init anyway. So the overhead of+dealing with this might not be worth it.+- Implemented a GPIO system, trying to keep it simple+++Things to punt for later+------------------------++- SPL support - this will have to be present before many drivers can be+converted, but it seems like we can add it once we are happy with the+core implementation.+- Pre-relocation support - similar story++That is not to say that no thinking has gone into these - in fact there+is quite a lot there. However, getting these right is non-trivial and+there is a high cost associated with going down the wrong path.++For SPL, it may be possible to fit in a simplified driver model with only+bind and probe methods, to reduce size.++For pre-relocation we can simply call the driver model init function. Then+post relocation we throw that away and re-init driver model again. For drivers+which require some sort of continuity between pre- and post-relocation+devices, we can provide access to the pre-relocatoin device pointers.+++Simon Glass+sjg@chromium.org+April 2013+Updated 7-May-13+Updated 14-Jun-13