[PATCH 1/5] capemgr: Beaglebone DT overlay based cape manager
Pantelis Antoniou
panto at antoniou-consulting.com
Wed Jan 9 20:56:59 EST 2013
Hi Linus,
On Jan 9, 2013, at 10:29 AM, Linus Walleij wrote:
> On Wed, Jan 9, 2013 at 9:11 AM, Lee Jones <lee.jones at linaro.org> wrote:
>> On Tue, 08 Jan 2013, Arnd Bergmann wrote:
>>
>>> On Tuesday 08 January 2013, Pantelis Antoniou wrote:
>>>> On Jan 8, 2013, at 2:12 PM, Arnd Bergmann wrote:
>>>>
>>>>> On Tuesday 08 January 2013, Lee Jones wrote:
>>>>>>> If there is not, there is no way to automatically load the overlays; you can always
>>>>>>> use the kernel command line, or have the a user space application to request the loading
>>>>>>> of a specific board's overlay.
>>>>>>
>>>>>> Unfortunately, there is no way to probe the UIBs. :(
>>>>>
>>>>> I thought that some of the newer UIBs had it, just not the old ones.
>>>>> As Pantelis says, we could at least detect the ones that have an EEPROM
>>>>> on them, and use a command line option or device tree attribute for the others.
>>>>>
>>>>> Arnd
>>>>
>>>> So I gather the new ones have an eeprom?
>>>
>>> I don't remember the details unfortunately. Lee should be the one who can find out.
>>> IIRC there was at least a single integeger number on them.
>>
>> Not as far as I can remember. There was (is?) a crude method of
>> identifying UIBs, but attempting to obtain certain I2C lines and
>> testing which ones were accessible. However, if there is an issue
>> with I2C, the wrong UIB was 'probed'.
>
> Right, so the UIBs had different GPIO expanders on some I2C addresses,
> so we attempt to communicate with the expander to see if it's board type A,
> and if it doesn't respond it's deemed to be board type B.
>
> This is the code:
> arch/arm/mach-ux500/board-mop500-uib.c
>
> /*
> * Detect the UIB attached based on the presence or absence of i2c devices.
> */
> int __init mop500_uib_init(void)
> {
> struct uib *uib = mop500_uib;
> struct i2c_adapter *i2c0;
> int ret;
>
> if (!cpu_is_u8500_family())
> return -ENODEV;
>
> if (uib) {
> __mop500_uib_init(uib, "from uib= boot argument");
> return 0;
> }
>
> i2c0 = i2c_get_adapter(0);
> if (!i2c0) {
> __mop500_uib_init(&mop500_uibs[STUIB],
> "fallback, could not get i2c0");
> return -ENODEV;
> }
>
> /* U8500-UIB has the TC35893 at 0x44 on I2C0, the ST-UIB doesn't. */
> ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0,
> I2C_SMBUS_QUICK, NULL);
> i2c_put_adapter(i2c0);
>
> if (ret == 0)
> uib = &mop500_uibs[U8500UIB];
> else
> uib = &mop500_uibs[STUIB];
>
> __mop500_uib_init(uib, "detected");
>
> return 0;
> }
>
> Not elegant but better than e.g. passing a kernel command line option.
>
> As you say it has the downside of detecting the wrong UIB if there is
> some (other) problem with the I2C block. But in that case the system is
> likely borked anyway so I wonder if it matters...
>
> Even with the device tree approach we'd be into trouble if say, the UIB
> was unplugged (which is perfectly possible). The device tree cannot
> detect that.
>
> The larger question is how to handle, at runtime, hardware that may
> or may not be present, in a device tree world.
>
> Compare this other case: the Integrator has pluggable daughterboards,
> (called LMs, logic modules) and in that case we have specific registers
> to detect them, and register the daughter board on this specific bus
> that Russell came up with in arch/arm/mach-integrator/lm.c,
> the actual board detection is in arch/arm/mach-integrator/integrator_ap.c:
>
> static void __init ap_init(void)
> {
> unsigned long sc_dec;
> int i;
>
> platform_device_register(&cfi_flash_device);
>
> sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
> for (i = 0; i < 4; i++) {
> struct lm_device *lmdev;
>
> if ((sc_dec & (16 << i)) == 0)
> continue;
>
> lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
> if (!lmdev)
> continue;
>
> lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
> lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
> lmdev->resource.flags = IORESOURCE_MEM;
> lmdev->irq = IRQ_AP_EXPINT0 + i;
> lmdev->id = i;
>
> lm_device_register(lmdev);
> }
>
> integrator_init(false);
> }
>
> In this case I think the autodetect is so nice that device tree probing
> is mostly pointless. If it wasn't for the fact that we get a
> cross-depenency to defined interrupts and clocks and whatever that
> are coming from the device tree. Which is where DT shows its
> all-or-nothing face.
>
> So to get an elegant DT probing in this case I *guess* the right thing
> to do is to dynamically add nodes to the device tree from the board
> code, or have all alternatives inside the DT marked "disable" and then
> mark them as "okay" from the board code by modifying the DT at
> runtime.
>
> Ideas welcome.
>
Your problems are not all that different than the ones we have with the
beaglebone. Your UIBs seem to be exactly like beaglebone capes without
a reliable probing mechanism, which the LMs seem to have a register where a
bit is turn on for each board present.
Let me try to make a list about the kind of boards the DT overlay stuff
might be applicable, and the different probe methods.
Beaglebone: I2C EEPROM read (standard format)
Beagleboard: I2C EEPROM read (standard format - sometimes)
Pandaboard N/A (not quite sure there)
ux500: I2C probe of device at known address
integrator: Memory read of system config register
pengutronix: N/A (maybe some kind of known device probe would work)
I've also heard in passing of some boards that just have an area in NAND
where a list of plugged in boards is stored. It can be simplified by
having the bootloader pass a command line argument.
Other than the different probe method (and possible future hot-plug capability)
I don't see anything different.
What do you think?
Regards
-- Pantelis
> Yours,
> Linus Walleij
More information about the devicetree-discuss
mailing list