 Felly mae, Mark Rutland. Mae'n gwybod i'r ffordd o'r ffordd o'r newid yn ymddiadau newydd. Felly mae'n ddweud o'r gweithio gyd, ac mae'n gwybod i'n ffordd i'n ddysgu'r ddysgastau o'r ffordd i'n ddod i'r gweithio. Ddysgastau yw gydig i ddigon ychydig, But it evidently has managed to inspire quite a few of you to come along, so that ploy has worked. So these are the things I want to talk about. Why we moved two divisory in the first place, so what was wrong with all of FALs. What we actually mean by divisory, what it actually is how it differs. ond we've converted so far what's gone wrong, how we can fix what's gone wrong, and how we can prevent more things from going wrong in the future. So, if you think back to 2010, early 2011, we had a couple of problems. The way that we developed board support with board files, platform code in the kernel, and the fact that everyone was developing their own kernel, we weren't unifying all the effort to produce a single image that would work everywhere, was just leading to more and more problems over time. So, all this board support in the kernel meant that, with the variation that we have, it wasn't feasible to maintain all of that in the kernel. We have so much configurability. You have an SoC, that SoC gets put into a different device, and you happen to wire up a GPIO line differently or a clock ever so subtly differently, and you need to upgrade the kernel. You need to change all the kernels. So, if you're trying to do a rolling release or any kind of thing like that, it just doesn't work, because every minor change requires a huge change of your entire stack. And because we're all working independently on kernels that would just boot on one platform, you couldn't test it. Guy from platform A decides to rework his controller logic, makes a change to the core, looks all right, build tests for him, breaks everyone else's platform, but we only discover that after hitting next or after hitting mainline, in some cases, because not everyone tests. So, we wanted to fix this with a single image. We want to get less of this bizarre configuration happening through board files, get it more dynamic, and just move it out of the kernel so that, for the rolling release type scenarios, you describe your hardware once it continues to work, you don't need to care. So, we move to device tree, and this is all the marketing stuff about device tree. It's a standard. Great. And it's extended by some other standards. Great. It's used on a load of architectures. A few of these it wasn't used on when we moved to it, but it is now. And it's used by other OSs. It's handled by bootloaders that already exist. They can modify the DT, they can parse it, they can do things with it that it's useful. And also, for virtualisation, we can generate it, which is much nicer than having a board file. You can describe the exact virtual platform you want. You don't need to implement some sort of probable bus like PCI and emulate all of that. You can just have simple memory map devices, but you can still dynamically create a platform hand up to the kernel, and it should just work. So, here's the less marketing description of device tree. So, it's a tree data structure, as the name would imply. It's essentially a set of key value. So, each node in the tree has a set of key value pairs, and that value may actually be a list of values in the general case. So, I'll get on to that in a moment. But it is just a data structure. All those standards that have been developed over the years are describing how to describe things in the tree. They're describing the binary format of the tree. But in general, it's conventions rather than rigid rules. We can, if we really want to, encode the entire kernel in the device tree when there's the flattened image tree that's used by U-boot and a couple of hours. And that's still device tree, but it's not what we would use in the kernel. So, each device gets described with a thing? This is a question I should have asked earlier. How many of you have used device tree? Raise your hand. How many of us have not used device tree? OK, well, the next couple of slides are for you guys. So, as device tree is just a data structure, you obviously, to describe a device in it, you need a format for that device. And that's known as the binding. That's just how you describe its merrimap regions, its interrupts, and so on. I'll get on to that in a moment. And that's typically implemented by the vendor of the device or the first person to actually implement some driver using it. There is no central authority as it stands at the moment for device tree. So, everyone who I showed before using device tree might have subtly different conventions, subtly different support. For those of you unfamiliar with device tree, each device has a document like this associated with it where you describe some properties of the device. You'll say, I've got this device. It's the Dev 2000 from vendor, and these aren't particularly good names of things that we realise now. And we've got two variants of it, one that's backwards compatible, the older one in the programming model. So, perhaps it shares the same memory mapped interface. Perhaps it has more interrupts or something like that. So, each binding is matched by the compatible string, which is a list of strings which enable you to fall back, so, in the case of the V2 devices which are backwards compatible, you can say, I've got a V2 device, but by the way, it's also a V1 device if you know how to handle V1 devices. We describe some other properties, so the reg is just a convention for where you put your memory map registers or if you're not memory mapped, this could be your I2C address or so on. It's basically your location on the bus. And interrupts are another standardish property because, obviously, pretty much everyone knows what an interrupt is and will probably want to describe it. So, we end up, for each device, writing something like this, which maps pretty well onto the binding document. We have a few conventions here like these hash properties, which are properties which define how to parse the DT itself. So, they tell you, address cells and size cells tell you how big this reg entry is, and a cell is an unsigned big-endian 32-bit integer. And as you can see, we've described a few things that we had in that binding. We've also got this other property that's a more standardish property that tells us what our interrupt controller is and the interrupt controller is itself described in DT. Find so far. So, the reason I have this slide at all is that the device tray is novel to many of us in the arms space and, essentially, if we haven't worked on Spark or PowerPC in the past, we might not really have even seen it before. And most of us don't really know the history, the idioms, all the kind of things that's just assumed that we know because you're working in that area. And for those of us who actually want to learn more about it or want to write our device drivers, write our bindings, write our firmware to touch this, we have a problem in that all of the old documentation has disappeared because everyone who's familiar with it doesn't need it. So, why do we need to bother keeping it around? And as it's developed over a number of years and people who aren't familiar with it have worked on it, we've got inconsistencies that have crept up and appeared everywhere and all the binding documents that we have are vague, they don't really say the format of properties, they just tell you, oh, it's this standard property that's not defined anywhere. And for an example of this, these are a number of ways I discovered that we refer to interrupts in the kernel source tree bindings. The last one is objectively wrong. The others are just vague. But if you're trying to do this from scratch and you don't know what you're doing, which one of these do you write in your binding? It's no wonder that we've got a mess in my hand with this inconsistency growing. But for those of you unfamiliar, there is still documentation online. ePAPR exists, it's the one we normally point out. That's the Embedded Power Architecture Platform Requirements. That defines most of the conventions we use today even on the ARM port. Obviously, the Linux documentation source is still available. And from talks over the last couple of days in the ARM mini-summit, we are working to improve this documentation. So I've been working on a mailing list to try and push for more standard conventions. And we are writing more documentation, but that's going to be a while. One of the better things that should be coming soon will be schemers. Schemers will, instead of that plain text document I showed you, actually define the format of each property, how to puzzle, you should be able to write validators based on that. So we'll hopefully be able to more accurately describe what the contract is defined by the binding. We have the Device Tree mailing list, which has changed a couple of months ago, which may explain why a few of you have got pretty confused. But if you need a place to look to see what the current way of doing things is, the Device Tree mailing list, or hash device tree on FreeNode are best places to start at the moment. So we're all used to board files, because that's where we came from. And board files have a useful property in that updates are atomic. If you change the data structure that a driver uses, you can update all of the providers of the data structure in one commit, and everything happily works. That's a very useful property. Board files also describe what Linux needs. If we've got a very complicated device, we can just say you have this single register here, it's four bytes, and you've got this interrupt, and that's all you really need to know to programme this device, because if we need to fix that, we can just update everything atomically later. And who needs to document board files? Who bothers to document every single IO resource mem and IO resource IRQ that they've put into their driver? And so looking at the slide I showed you a few moments ago, the conversion looks pretty simple. We've got the platform device name, that's what we match on for a device. We've got some IO resources, and we've got standard conventions for describing them. So conversion looks deceptively simple. But, as I mentioned earlier, that useful property of atomic updates to board files to the drivers and all the data providers doesn't really apply to DT. So when we get this conversion step wrong, we create ourselves a lot of pain. And even better, when we try and fix things up as this pseudo-email shows, I've dropped the line at the bottom. So I get several of these emails a week where we say we've noticed a problem in the binding, we've listed a sign a bit to general, let's fix it up. So we fix up the driver and we fix up the DTs in the kernel and we fix up the binding document. But people already have DTBs, the compiled device tree blobs, loaded into their firmware. Everyone who's bored was booting before this commit and now suddenly breaks. Because we're not considering device tree as an ABI as we need to. And we really have to. There are products now shipping using device tree. Users expect it to work because it worked yesterday. Why doesn't it not work today? And logically, the hardware hasn't changed. So why does the device tree needs to change? We don't see the future. We don't see that we've described this wrong. And so I've not fought out the next line. So when we create the binding for the first time, there will be bits that we miss. And if we happen to have, say, two U-arts that look pretty much the same, we give them the same compatible string, we give them the same binding, it looks all fine. And then we discover later down the line that if we vote some part of a register on one of them, our regulator blows up. And we need to fix that. And the only way we can fix that is by changing the binding. And then everyone's existing platform suddenly stopped booting. And no one's happy with that. So what we need to move more towards is designing bindings such that they can be extended without breaking the possibility of support for an existing binding. So if you happen to have to add a new interrupt to your binding, all those old boards that only have one interrupt should continue to work. And we can obviously still extend bindings at that point and we can introduce new bindings. But the one thing that we really, really, really need to do is maintain backwards compatibility. And that leaves a big maintenance burden in that we have to maintain that backwards compatibility in our platform code and our driver code, which is our new platform code, gets bigger and bigger for maintaining all these bizarre edge cases that no one's used for five or so years. So we need to have a staged deprecation mechanism. We'll make a mistake, we'll have a binding and we need to say that's supported for five years. And after that, no, you need to update your bootloader. And that will align with most people's, yes? So I'll assume that your binding is in the mainline and your product is just through the mainline criminal in the arm world that is more the exception than the rule. So how much leverage do I have as an evil vendor to say, I ship my device to you with these bindings so these bindings need to go into the kernel and then we can work on proper bindings. That argument is going to come up. So, yeah. There was discussion at the Omni summit about stable and unstable bindings. And the idea with this would be that... Can I get back to this in a few slides of time? Sure. So I'm just going to jump a bit. As an example, we have made mistakes in the past with our bindings. So, hopefully Rob won't be too angry about me showing this one. The prime cell bindings, which apply to the set of prime cell devices from ARM such as the PL1810, which is an MMC controller. There are PLO11, which is a serial controller and so on. They have some wonderful wording which says that in the clocks property we provide the APBP clock first. But if you happen to look in all of the DT files in the kernel you'll notice that the APBP clock is second. And so these DTs do boot. That's the only reason they're in the kernel already. But if we want to make it possible to actually write up these correctly in the future we need to change something. Either those DTs need to change because they're wrong or the kernel needs to change because it's wrong. And in this case we can fix things up because we've got the wonderful clock names property telling us which clock is which to disambiguate those cases. And as we're going to make mistakes we need to design for future correction. So as I showed a moment ago with the clock names property we avoided ambiguity. We could tell which clock was which. So we can grab the correct one and if we don't have that property we can assume the old binding. So we have a level of compatibility we can provide that. And we need to carry that precision over to other elements that we describe in the DT. So that entry that I showed with interrupts we have an interrupt names property for reg. We have reg names. And for other properties we can define mechanisms for disambiguating which specific GPIO you're describing and so on. And this is a related but not quite the same issue in that the platform data defines what Linux wants. So I said that we describe that case of here's the one register you really care about for poking. So designing your device tree binding the board support package is not the place to start because that device consists of more than a single register and if we want to change Linux to be able to deal with more of that device you need more of that device described initially. And that's not too hard. So in the general case we have a large register bank instead of describing a portion of it describe all of it. You can work you already know what the offset within that will be and if you don't then we need a more complex binding but that applies to a very small subset of bindings for the very very configurable hardware. If you describe one clock describe all of them and provide them or at least provide a mechanism for describing which clocks you're providing and this applies to our resources and so on. And just consider what is going to change in that IP in the future because the only people who are likely to know that are the vendors designing these bindings and we're not omnisian. We can't consider what you know internally is going to change and if you know things are going to change and you need to extend things and you know that there's going to be a problematic area describe them in the binding provide some sort of mechanism for forward compatibility as well because that way you can change the DT and still boot your own your old kernel. So I think this ties in slightly more to your question. So there are two ways we could have converted platforms when we moved to the industry. One is to start with the board files and tear them down, move stuff into the DT and then deprecate board files. The other is to build up from the bottom and describe everything from the start and because we like things to continue working we went for the former option but it does mean that we know DT changes are going to be required in the future and that things are going to continue breaking until we're finished and so essentially in your evil vendor case we need to acknowledge in advance that those bindings are unstable and not necessarily going to be supported for the long term but as long as we design the bindings for extensibility for changing they may not be that different from the final bindings and they may in fact be the final bindings. We have common conventions everywhere in the kernel that we can follow but for new platforms we really need to start from the bottom and we really need to start with the clocks, the regulators that feed in to all those devices because otherwise we're feeding in side channel data as we do with our current board files and we know things are going to break and it's pointless for most of the platforms we've converted to device trees so far half the stuff is still in board files and they're not really converted to device tree we know that those bindings are going to break but we do have a good option for new platforms Mark, are you in there? Mark there at the back, waving his hand The ARM64 KVM maintainer among a few other elements implemented an empty platform for ARM Linux known as MacVert and the nice thing about MacVert is that there is no platform data associated with it there are no assumptions built into it if your platform is able to boot by just describing your devices and just being compatible with MacVert so at the top level of your DT you have this Linux dummy-vert thing Linux will happily probe that boot your platform but you have no side channel data at all because you don't have the clocks coming in from some arbitrary board file so if you can boot with this it's probably going to work in the future because if it doesn't, it's a regression that we need to fix elsewhere rather than being limited to your one tree for your one SOC with some arbitrary file that no one else knows how to read Could you explain the loophole? Your side channel I believe so I'm not sure on BoardGeneric.C but the idea would be that this is your external BoardGeneric.C where you describe all your devices and you don't need BoardGeneric.C because you can describe your devices externally I know but I know that a certain silicon fender probably drives for a DT-only platform and it turns out that in the little town in India they had a honking made board file instead of doing it in their board file they moved to BoardGeneric because that gets broke for the device tree case so they achieved and it was really hard to detect and I wonder if Dummy Fert has safeguards for BoardGeneric to get squashed At present I can't answer that however BoardGeneric.C is that in the mainline? Yes Sorry could you speak up? So there's an interesting point there on what compatible actually means because in general if you read any device tree documentation people define this compatible string as meaning the particular variant of the hardware that you're on really that compatible string is defining a particular description format that you're compatible with This description format if it has nothing is compatible with Linux Dummy Fert If you were to modify for instance a serial driver binding because you realise that you made it completely wrong and it's impossible to fix up you can create a new binding a new compatible string for that and that's perfectly valid because there's a sense of Linux into the DT here in that you're mentioning oh by the way Linux you know how to treat me like this but pretty much everything in device tree is convention rather than rigid rules so that's not necessarily a bad thing and if your platform is already compatible with Linux Dummy Fert add Linux Dummy Fert get rid of your board file now another OS can happily ignore that or it can happily pick it up Does that sound reasonable? That would be my final slide So I'll make a bit for it and I'll get back to that if that's okay So there is obviously the big elephant in the room as it's been described with binding review and it's been referred to as drinking from the fire there's quite a few times now there aren't that many of us doing binding review and it pretty much ends up being only the device tree maintainers and possibly a couple of device maintainers who really know what they're doing but because we're trying to convert pretty much every platform in the architecture to device tree everyone is writing a binding and trying to push it now and obviously that's a bottleneck and we're being hit by lots of trivial issues because of the aforementioned unfamiliarity and documentation issues that we have and we don't know everything about every platform I am not an MTD expert so solely being the only review on an MTD device binding doesn't work and we need help from maintainers in that regard for at least does this describe does this binding describe the hardware or a subset thereof does it really describe the need or what the hardware is but it is getting better in this regard in that DTE is becoming more familiar and we have common patterns for most of the tricky things that we're dealing with at the moment so for GPIO interrupts I obviously had interrupts but for GPIO clocks, pin control we now have standard conventions that it is a lot easier to fit to but it's still a bit of a pain because there are still novel devices that we have no idea to describe coming up and we're being we don't have the time to necessarily review them thoroughly because of how many trivial issues we'll get coming through that really must be fixed not defining the type of a property treating it completely differently in the code from binding so the obvious fixes for that are actually following what's already there for most of the bindings that have gone through in the last few months the bindings themselves are of an objectively higher quality than the bindings that have gone in over the few months before that and from there on in there are bindings of very high quality and very low quality and it varies from device to device but we do need help so anyone who would like to help with device to review please raise your hand now just the one and so the aforementioned mechanism for defining a binding defining it as being deprecated and so on leads to a split of stable and unstable bindings where a binding which has been in for a very long time and hasn't changed is essentially de facto stable and for the evil evil board vendor and so on yes, you can define a binding and it should make it into mainline there are some minimum hygiene levels that it needs to reach but it might not be the one that we support long term and we're leaving that to maintainers in general because maintainers are getting more used to device tree and we have those common patterns if you meet those common patterns and you're not too different you will get in just just make sure that the binding makes sense if you think it does, if the maintainer thinks it does it should go in and if we have to fix it up later we will with some stage level support for deprecating the old crafty unhappy binding and so a last couple of points we're not sharing FreeBSD have been at the same time developing device tree support for ARM and for some things had it before us as a trivial example here is the generic interrupt controller binding in Linux and FreeBSD other than this one string they're pretty much compatible if we pick up the FreeBSD binding and if they pick up ours we suddenly have compatibility and this doesn't necessarily go through all the devices that iRivers have but we really do need to cooperate with other device tree users we need to pick up bindings we need to help by designing bindings that others can pick up and the way to do that is obviously describing the hardware not the portions of it that we need such that everyone can pick out the specific portions of it that they want and we can't pretend we're in charge we have to pick up all the people's bindings eventually as with anything in this area de facto standards are the only standards that really apply and if you want even more fun people are doing ACPI right now that was a scary grunt and the major issues we've had with DT are that we're unfamiliar and we don't know how to describe the hardware and those same issues that we're going to apply to ACPI the format in particular is not the problem we are the problem and we need to not make the same set of mistakes or we've got a combinatorial explosion in the amount of problems we're going to have we'll have drivers that support ACPI and DT and we don't want ACPI support modifications breaking DT and vice versa so a few things we can do on that front are the board files are tall when using ACPI if possible I'm not that familiar with ACPI there are others far more familiar who can probably tell me if that's reasonable at all there are some gaps there was a presentation on that ok that's the one I should have attended and the things I mentioned before describing the hardware designing for compatibility from the start and cooperating with other OS communities there are going to be other people using ACPI and if you want to help this is what you need to do so basic things describing the hardware in abstract not the portions that we want today just so we can pick out the portions we want it gives us greater flexibility in the long term and it's more likely that you're binding work in the future and extending that a bit really think about what's going to happen in future you do know how things are going to change at least in abstract and you can predict some subset of the problems that we will encounter and if we fix them now if you discover that the GPIO binding for example can't describe your hardware we can extend it now and that compatibility can be there a lot earlier and we can deprecate the old forms a lot earlier and that means lower support burden overall in the long term working with others if you're writing a binding in an area if you're writing a serial driver please talk with other people writing serial drivers please try and get some sort of uniformity there that's not that difficult and be proactive which I guess is the first two points just repeated over and over again if we fix something today we're going to have less problems later and if you know something is broken raise it we can fix it now and we don't have to support it and all the workarounds for it we're not on this yet there will be cases where a binding will be completely unworkable in the long term where a description of something just either a description doesn't describe the hardware or describes it in a way that's very difficult to extend you're assuming a perfection you're assuming a perfection I'm not we will never get perfection agreed there is a higher barrier to entry in this regard in terms of thinking ahead you're setting up a perfect solution that will never happen so I'm not asking you to design a perfect binding from the outset I'm asking you to consider what things are likely to change and attempt to plan for them but we're not on this yet we will need to have findings introduced in future that won't be compatible with old kernels we will have to support findings we don't like we will have to have some platform code around to support that that's inevitable but we can minimise that pain you have to keep the binding stable so that updated kernels will work with the old bindings but that's never the case I have never seen a case where someone updates a kernel and doesn't update the flat device to you I can't that's about all my systems because I might want to produce more kernels but you can make sure that this works in your special case and your data cannot get data between you there's no guarantee you're always going to be testing on that system we can't hear you now my big problem is that we've run automated testing we have a problem with rewriting kernels on our systems where we don't want to be going booting a kernel and then having to rewrite the device tree because we're moving between different kernel versions for different testing scenarios but most of the cases that I've worked in was you update the kernel you update the device tree as well because most of the changes in the kernel also include changes in the drivers fixes maybe you need to add some properties I'd like to comment on the mobile phone case so we're shipping a million devices and every single one we're shipping a million devices and every single one of them has the device tree appended to the kernel so there is no backwards compatibility problem the device tree is not coming from the firmware so so far this is not buying me anything but headaches right so that's my so the device tree has ABI there is no ABI correct me if I'm wrong but at least in my market there is no ABI because it's not disassociated from the kernel sorry I'll leave it in your hands Mark thank you so I'll deliver my classical line we have KVM it's not something futuristic it exists KVM builds a device tree for the guest it's sold on in user space as such it is an ABI okay so is there some way that you can get what you want and I can get what I want which is not a stable ABI so there are shades of grey here and the obvious shade is that there are different periods of compatibility that different players are going to want in the mobile phone case where we care about compatibility from release to release as long as that specific kernel and that specific DT work fine there will be other users who want a longer term compatibility right so my request would be for those of us who have the DT bound to the kernel can we have a grace period where we don't have to go through this rigorous look there's nothing stopping you from putting a device tree into the question I think you need to care now if you don't start now when do you start when is your flag day it's not great the problem with having an unstable binding is that it actively prevents a mainline because you've got other developers who want to use that board, you want to use some deaf board if you're completely changing the binding every week their board stops working they can't implement half the support they want to you're expecting things out of device tree that we were never getting out of board files it's an advantage over board files but you wouldn't expect to take a board file from one kernel version and drop it into another kernel version and have it work no there is a difference here so you shouldn't hold device tree to a huge standard just a slightly higher standard let it improve things but don't make it an impossible goal and so the deprecation I mentioned earlier with the arbitrary figure of five years does not have to be five years this depends on your concern if you're raising an SOC up from scratch then obviously there aren't going to be users of it out there whose platforms are going to break so to say I can have the device tree binding fixed before it even reelsilting out there so I'm so I think there's a confusion here as to what stability means so that stability may just mean that your patch that changes the binding has for a single cycle an RC some support for the old thing that just does a PR and says by the way please shift over to this other mechanism for describing this and then that gets dropped later but that's different from just suddenly changing repeatedly every single patch that goes in breaking every single time and that's obviously different to maintaining the stability for a five year period so there are different periods of stability that we need to aim for and in general we want to aim for the longest term of stability possible but that's not going to be attainable on every single case and just because you need a new description tomorrow doesn't mean that you can't have the current description alongside it we can have different compatible strings and so on and at some point we will drop the old ones because they're no longer used and if it's no longer used right from the outset we drop it almost immediately so how do you view deprotation moving forward you talked about finding schemas in order to help for automation checking and verification would you also want to make deprotation part of that check yes so then how would you expect that mechanism to work and how would we get to that so schemas would be a key point onto that in terms of having a consistent definition of here is the set of properties here is the layout I expect of sub nodes and what not on that if it is a single property change that's an attribute of that property that oh we no longer support the vendor specific always on at boot property and there are two halves that will have to have something in the schema and something in the kernel for that point when we maintain support for that old property or we've introduced some new property that deprecates the old one there would be some change of the code to either produce a warning or we can introduce a more formal mechanism a sort of taint saying this is using a deprecated DT binding we can at least produce a warning to the user out of that and we would define roughly when we expect to deprecate it assuming that no users are complaining along the standard lines of how we deprecate how we deprecate system calls and so on it would seem likely as these changes come in and the bindings are moving to a different repo that you could have a different branch a different folder that has the legacy deprecated ones and maybe flags in the device tree compiler so that you know that you're choosing ones that are either not stable not marked as stable yet or maybe are deprecated yeah that is part of the plan with the schemers to define what we consider stable or unstable and to have their mechanism for warning you at the moment because of the way the bindings are written as plain text documents we don't have the correct mechanism for getting that data to the tool so at the moment it is rather ad hoc but we are already moving in that direction on the kernel side with printing warnings for deprecated properties and actually maintaining support for a short term can we make a rule that when the driver is or the board is converted from the board file to the device tree and the device tree version does not even boot in the main line that we don't have to care about stability of the bindings if there are no users there is no stability problem okay because we got the review comments in this thing like the board wasn't even in a state where it would boot and we were already getting review comments like hey you can't do this, this is supposed to be ABI please don't do that so there is a general issue in that as I said earlier we're not on this so we don't know about every single platform every single driver, every single we don't know A how that driver works entirely and we don't know what the set of users for that what the set of users for the particular device tree bindings are and there is a hygiene there is a hygiene case here as well even if we think there are no users providing a simple short term stability change where we keep the old property around printer warning for one RC cycle is good enough so I don't have a good answer for that at present but this is something to continue discussions on so we've got one minute left so so so what is the scope of a device tree you say describe hardware where do you stop can we put in all the pin marks information for a chip do we describe the amount of data lines going out to an external controller do we put in key codes default trigger for LEDs and things like that there is a scope for system configuration and system description and system description is subtly different from Linux specific definitions saying what key is and happening to use the same key code as Linux has internally is not the same as saying probe this specific Linux driver and set this specific variable to this value internally in such a way that we can't change things so could you pass the mic what is the point of device tree is to make undiscoverable hardware discoverable and if you look at PCI what do you get in terms of discoverability vendor and product ID and so forth I'd just like to add as well there's really no excuse if your device boots from flash your boot load is in flash there's no excuse not to have your device tree separate from your kernel there's no excuse it's not a good one however they're not mainline there's no breaking of compatibility Linux didn't boot your Linux did it's not mainline no one said to mainline they should but no one knows mainline does not work on like hardware I get my driver into hardware a year pass and the truck is over I have no colleague that drives into mainline anyway so don't test the amount of time it takes thank you very much