Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932918Ab2KEUkw (ORCPT ); Mon, 5 Nov 2012 15:40:52 -0500 Received: from mail-pb0-f46.google.com ([209.85.160.46]:52515 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753893Ab2KEUkv (ORCPT ); Mon, 5 Nov 2012 15:40:51 -0500 MIME-Version: 1.0 From: Grant Likely Date: Mon, 5 Nov 2012 20:40:30 +0000 X-Google-Sender-Auth: QVCIpyoeq7fQh-8KcnkMRESHz98 Message-ID: Subject: [RFC] Device Tree Overlays Proposal (Was Re: capebus moving omap_devices to mach-omap2) To: Pantelis Antoniou , Rob Herring , Deepak Saxena , Benjamin Herrenschmidt , Scott Wood , Tony Lindgren Cc: Russ Dill , Felipe Balbi , Benoit Cousson , linux-kernel , Koen Kooi , Matt Porter , linux-omap@vger.kernel.org, Kevin Hilman , Paul Walmsley , devicetree-discuss@lists.ozlabs.org Content-Type: text/plain; charset=ISO-8859-1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 12800 Lines: 289 Hey folks, As promised, here is my early draft to try and capture what device tree overlays need to do and how to get there. Comments and suggestions greatly appreciated. Device Tree Overlay Feature Purpose ======= Sometimes it is not convenient to describe an entire system with a single FDT. For example, processor modules that are plugged into one or more modules (a la the BeagleBone), or systems with an FPGA peripheral that is programmed after the system is booted. For these cases it is proposed to implement an overlay feature for the so that the initial device tree data can be modified by userspace at runtime by loading additional overlay FDTs that amend the original data. User Stories ============ Note - These are potential use cases, but just because it is listed here doesn't mean it is important. I just want to thoroughly think through the implications before making design decisions. Jane is building custom BeagleBone expansion boards called 'capes'. She can boot the system with a stock BeagleBoard device tree, but additional data is needed before a cape can be used. She could replace the FDT file used by U-Boot with one that contains the extra data, but she uses the same Linux system image regardless of the cape, and it is inconvenient to have to select a different device tree at boot time depending on the cape. Jane solves this problem by storing an FDT overlay for each cape in the root filesystem. When the kernel detects that a cape is installed it reads the cape's eeprom to identify it and uses request_firmware() to obtain the appropriate overlay. Userspace passes the overlay to the kernel in the normal way. If the cape doesn't have an eeprom, then the kernel will still use firmware_request(), but userspace needs to already know which cape is installed. Nigel is building a real-time video processing system around a MIPS SoC and a Virtex FPGA. Video data is streamed through the FPGA for post processing operations like motion tracking or compression. The FPGA is configured via the SPI bus, and is also connected to GPIO lines and the memory mapped peripheral bus. Nigel has designed several FPGA configurations for different video processing tasks. The user will choose which configuration to load which can even be reprogrammed at runtime to switch tasks. Each FPGA has a different interface to the processor, so the kernel needs additional data before it can use each device. Nigel is passing that data to the kernel using an FDT overlay. When Linux loads a new FPGA configuration, it uses request_firmare() to obtain the overlay for that FPGA. When the FPGA gets reprogrammed, the kernel throws away the previous overlay data and uses request_firmware() to get the overlay for the new design. Mandy has a Raspberry Pi which she has wired by hand up to sensors and motor controllers in her prototype autonomous robot project. She is doing self-hosted driver development on the Raspberry Pi itself. However, she needs a method to tell the kernel about the attached devices. By installing dtc on the Pi, Mandy compiles the overlay for her prototype hardware. However, she doesn't have a copy of the Pi's original FDT source, so instead she uses the dtc 'fs' input format to compile the overlay file against the live DT data in /proc. Amit is writing kernel drivers for Jane's BeagleBone capes, but he finds loading new DT files into the root filesystem inconvenient. Instead, he includes the FDT overlay file in the initramfs that is built and linked in at kernel compile time so that the kernel can find and load overlays automatically. Joanne has purchased one of Jane's capes and packaged it into a rugged case for data logging. As far as Joanne is concerned, the BeagleBone and cape together are a single unit and she'd prefer a single monolithic FDT instead of using an FDT overlay. Option A: Using dtc, she uses the BeagleBone and cape .dts source files to generate a single .dtb for the entire system which is loaded by U-Boot. -or- Option B: Joanne uses a tool to merge the BeagleBone and cape .dtb files (instead of .dts files), -or- Option C: U-Boot loads both the base and overlay FDT files, merges them, and passes the resolved tree to the kernel. .... Summary points: - Create an FDT overlay data format and usage model - SHALL reliable resolve or validate of phandles between base and overlay trees - SHOULD reliably handle changes between different underlying overlays (ie. what happens to existing .dtb overly files if the structure of the dtb it is layered over changes. If not possible, then SHALL detect when the base tree doesn't match and refuse to apply the overlay. - dts syntax needs to be extended for overlay .dtb files - DTC tool needs to be modified to support overlay .dtb generation - Overlays SHOULD be able to be applied either by firmware or the kernel - libfdt SHALL be extended to parse and apply overlays - Linux SHALL be extended to parse and apply overlays from userspace - Linux SHALL be extended to notify drivers of changes to device tree - Linux MAY use request_firmware() to load overlays via sysfs - (mechanism for triggering overlay load TBD) - Linux MAY support removal of overlays (harder, but some use-cases want this) - Linux MAY be extended to remove devices associated with removed overlays Technical details to resolve: - How does an overlay get attached to the correct base tree nodes? - How are phandles fixed up and/or verified? - What is the model for overlays? - Can an overlay modify existing properties? - Can an overlay add new properties to existing nodes? - Can an overlay delete existing nodes/properties? - Does FDT need a schema? - Schema should be tightly associated with binding documentation. Verifying schema at runtime should be simple. Runtime checking is harder, but could be used as part of phandle fixup. - Similarly, does FDT need data typing? Other than reading the binding there is no mechanism to determine if a single cell is a phandle, an integer (possibly enum), a flags field, or part of a string. - Data typing would require additional per-property data; probably by adding companion properties containing the data typing. ie. an optional '.reg,format' property could contain the format of the 'reg' property. (The naming scheme for the new property can be debated, it just needs to be something that won't conflict with regular names). - Data type data could be used as part of phandle fixups. - How do bus drivers get notified when FDT data changes? - node addition/removal - property changes on existing nodes - A notifier chain may work here, or maybe a generic "firmware data changed" device driver callback. I could see this being generically useful for other driver data like ACPI Project plan ============ 1) Create syntax for overlays ----------------------------- DTC already uses an overlay model internally which is often used in conjunction with .dtsi files. It should be a natural extension to generate FDT overlay files from the existing syntax (maybe minor modifications) Doing this will require a method to differentiate between overlay and include directives. Maybe they aren't really different at all and it will depend on dtc options to determine whether or not to produce an overlay. Suggestions are welcome here. 2) Create a data format for overlays ------------------------------------ The overlay data format could be a direct extension from the existing dtb data format. One option is to construct the overlay tree by creating empty nodes for each node that it either adds children to or references the phandle of in the base tree. Empty nodes could even be tagged as a prereq by adding a '.readonly' property to those nodes. When an overlay parser encounters those nodes, it would know that it needs to already exist in the tree. There is a problem though with phandles. If the phandle values in the base tree don't match the ones in the overlay, then the overlay won't be able to correctly reference base nodes. At a minimum, the parser must verify that the phandles match before applying the overlay. Ideally, phandles in the overlay should be fixed up at application time, but this isn't easy. It would probably require first adding property data type information to the device tree. It may be sufficient to solve it by making the phandle values less volatile. Right now dtc generates phandles linearly. Generated phandles could be overridden with explicit phandle properties, but it isn't a fantastic solution. Perhaps generating the phandle from a hash of the node name would be sufficient. Example: an overlay source file might look something like this: /include/ "base-file.dts" /* 'include' may not be the best syntax here */ &i2c0 { /* i2c0 resolved by label */ touchpad@10 { compatible = "acme,touchpad"; reg = <0x10>; interrupt-parent = <&intc>; interrupts = <100>; }; }; And the generated overlay dtb may look like this: / { .readonly; interrupt-controller@0x10005000 { .readonly; phandle = <0x1234>; }; peripheral-bus { .readonly; i2c@20001000 { touchpad@10 { compatible = "acme,touchpad"; reg = <0x10>; interrupt-parent = <0x1234>; interrupts = <100>; }; }; }; }; Which is obviously missing a bunch of information for the rest of the system, but contains enough data to ensure that the path to the touchpad node is valid and that the phandle has not changed. This handles many of the use cases, but it assumes that an overlay is board specific. If it ever is required to support multiple base boards with a single overlay file then there is a problem. The .dtb overlays generated in this manor cannot handle different phandles or nodes that are in a different place. On the other hand, the overlay source files should have no problem being compiled for multiple targets. 3) Modify DTC and libfdt to process overlays -------------------------------------------- Direct follow on from above. This will require DTC to be modified to generate the overlay output format and new test cases to verify it works. In the process libfdt will get modified to add overlay support which will immediately be available to U-Boot and other bootloaders. 4) Teach Linux to request FDT overlays -------------------------------------- Add request_firmware() hook for adding overlays. If the platform supports detecting the attached expansion board, then this may manipulate the filename for a specific file. The kernel will graft the overlay into the existing live tree Workitems: Document device tree node lifecycle Add tests to enforce device tree node lifecycle Add interface to firmware_request() an FDT overlay Add support to merge overlay FDT nodes into base tree Add support to track FDT changes per-overlay Add runtime fixups of overlay phandles - Without this overlay phandles must exactly match the base tree Add support to remove an overlay (question: is this important?) 5) Teach Linux driver model to respond to device tree changes ------------------------------------------------------------- There are several parts to this. The most obvious are adding hooks for platform_device, i2c_device and spi_device creation. In all three cases, the users should already be providing enough information to support dynamic addition (and possibly removal) of dt nodes. of_platform_populate() is called for platform devices, of_register_spi_devices() for spi and of_i2c_register_devices(). Right now all three functions register all the child devices and then immediately return. However, if they could set up a notifier for node addition, then it would be easy to trigger additional device creation when new nodes are added. Other busses would be similar, but i2c, spi and platform are the most common use cases currently. Workitems: Modify of_platform_populate() to get new node notifications Modify of_register_spi_devices to get new node notifications Modify of_register_i2c_devices to get new node notifications 6) Other work ------------- The device node user space interface could use some work. Here are some random work items that are peripherally related to the overlay feature. Other Workitems: Define FDT schema syntax Add FDT schema support to FDT (basically lint-style testing) Investigate runtime schema validation Make device_nodes first-class kobjects and remove the procfs interface - it can be emulated with a symlink Add symlinks from devices to devicetree nodes in sysfs -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/