RFC: Mezzanine handling for 96boards
Subsystems (5)
cover RFC: Mezzanine handling for 96boards
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96
You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
TODO:
- Proper device tree bindings for the connector, for now look at the example.
- Discuss whether to actually do this or just take it all and flush it down the drain because the community doesn't like it. I'm not one of those especially infatuated with my own code, I always stay by the old programming project management mantra to calculate to make one version and throw it away as stepping stone to a good final design.
- Placement: putting this in drivers/bus is just an example. drivers/platform/96boards-mezzanines is fine too, maybe better?
- I am especially curious about input from Andy and Mika from the Intel/ACPI camp on what they have seen for non-discoverable plug-in boards. Does this problem even exist in the Intel world, or not...
Background:
- These boards connect on a custom connector on this family of boards. The relationship is many-to-many with the connector as nexus. The electronic standard for the connector is specified:
https://github.com/96boards/documentation/blob/master/Specifications/96Boards-CE-Specification.pdf
Example mezzanines:
https://www.96boards.org/documentation/mezzanine/
- These boards have siblings on other platforms, the problem scope is similar with BeagleBone "capes":
https://beagleboard.org/capes
Raspberry Pi expansion boards:
https://www.abelectronics.co.uk/products/18/raspberry-pi-expansion-boards
Intel Edison, Galileo, Joule also have expansion boards.
Idea: add a driver for the connector itself and tie it in to the device tree with a compatible string. Since the boards are non-discoverable two mechanisms are provided to discover them:
- Add a very simple device tree node with just a compatible string for the board in the node. This will be simple to add from e.g. a boot loader or as an overlay from userspace.
board {
compatible = "96boards,secure96";
};- Echo 1 > boardname into a sysfs file to populate the board and echo 0 > boardname to depopulate it. This makes it easy to even switch out expansion boards at runtime, if allowed by the electronics.
Quoted 2 lines
cd
/sys/devices/platform/connector
echo 1 > secure96
lscon connector: called mezzanine_store on secure96 lscon connector: populate secure96
at24 1-0050: 2048 byte 24c128 EEPROM, writable, 128 bytes/write atmel-ecc 1-0060: configuration zone is unlocked tpm_tis_spi spi0.0: 2.0 TPM (device-id 0x1B, rev-id 16) (...)
What this patch set does not do:
- It does not use device tree or ACPI DSDT or any other hardware decription language to model the contents of the board per se. Instead the boards buses are populated directly with platform devices.
Predictable complaints about this design:
Q: This is not device tree overlays. Why is it not device
tree overlays?
A1: Right tool for the job, overlays are complex and the
plan to get it in place seems to be spanning years, this is a few devices on simple busses and it works today. Using this approach I can already work on shaping up drivers for the mezzanine board devices as proved by:
https://marc.info/?l=linux-crypto-vger&m=152820660120590&w=2
https://marc.info/?l=linux-crypto-vger&m=152820662820595&w=2
(...)
I can work on drivers for the chips on the Secure96 mezzanine board. It's just an example of what the mezzanine community can do.
Now they are hacking around in userspace instead of doing/reusing kernel drivers for their stuff:
https://github.com/jbech-linaro/secure96
This way we can bring developers for these components into the kernel community instead of telling them to wait for some big infrastructure that comes later before they can contribute their stuff.
A2: Overlays does not solve the problem if the system runs
ACPI, and what about if the same connector[s] appear on a server board, servers use ACPI. Also notice that Intel have development boards with non-discoverable expansion boards as well. They just will not use device tree.
A3: Overlays is Big Upfront Design.
https://en.wikipedia.org/wiki/Big_Design_Up_Front
This way of designing things is associated with the (pejorative term) "waterfall model" which is out of fashion as a way of doing development. I think I am not the only one slightly annoyed by the fact that device tree overlays is now starting to look like a very big very upfront design. It's just not possible to get something up and running in small iterative steps with device tree overlays. Instead huge efforts are required and it involves major possible showstoppers and uncertain outcome as indicated by Frank's TODO:
https://elinux.org/Frank's_Evolving_Overlay_Thoughts
This appears also in our work process documents:
Documentation/process/4.Coding.rst
"experience has shown that excessive or premature
abstraction can be just as harmful as premature optimization. Abstraction should be used to the level required and no further."
So for that reason, or other predictable statements such as "you're reinventing board files", I'd like to have an open discussion on how to actually support these boards with the mainline kernel and work on device drivers common with other systems now, and not in 2020 when they are already obsolete.
Yeah it is a bit controversial, but what we are doing right now for non-discoverable expansion boards isn't working in my opinion, so I have to throw something out there, and this is it.
Linus Walleij (5):
RFC: gpio: Add API to explicitly name a consumer
RFC: eeprom: at24: Allow passing gpiodesc from pdata
RFC: spi: Make of_find_spi_device_by_node() available
RFC: bus: 96boards Low-Speed Connector
RFC: ARM64: dts: Add Low-Speed Connector to ZCU100
.../boot/dts/xilinx/zynqmp-zcu100-revC.dts | 27 +- .../96boards-ls-connector.c | 307 ++++++++++++++++++ .../96boards-mezzanines/96boards-mezzanines.h | 46 +++ .../96boards-mezzanines/96boards-secure96.c | 249 ++++++++++++++ drivers/bus/96boards-mezzanines/Kconfig | 36 ++ drivers/bus/96boards-mezzanines/Makefile | 6 + drivers/bus/Kconfig | 2 + drivers/bus/Makefile | 4 +- drivers/gpio/gpiolib.c | 13 + drivers/misc/eeprom/at24.c | 6 +- drivers/spi/spi.c | 33 +- include/linux/gpio/consumer.h | 7 + include/linux/platform_data/at24.h | 2 + include/linux/spi/spi.h | 4 + 14 files changed, 723 insertions(+), 19 deletions(-) create mode 100644 drivers/bus/96boards-mezzanines/96boards-ls-connector.c create mode 100644 drivers/bus/96boards-mezzanines/96boards-mezzanines.h create mode 100644 drivers/bus/96boards-mezzanines/96boards-secure96.c create mode 100644 drivers/bus/96boards-mezzanines/Kconfig create mode 100644 drivers/bus/96boards-mezzanines/Makefile
Signature · 1 line
2.17.0
PATCH 1/5 RFC: gpio: Add API to explicitly name a consumer
The GPIO (descriptor) API registers a "label" naming what is currently using the GPIO line. Typically this is taken from things like the device tree node, so "reset-gpios" will result in he line being labeled "reset".
The technical effect is pretty much zero: the use is for debug and introspection, such as "lsgpio" and debugfs files.
However sometimes the user want this cuddly feeling of listing all GPIO lines and seeing exactly what they are for and it gives a very fulfilling sense of control. Especially in the cases when the device tree node doesn't provide a good name, or anonymous GPIO lines assigned just to "gpios" in the device tree because the usage is implicit.
For these cases it may be nice to be able to label the line directly and explicitly.
--- drivers/gpio/gpiolib.c | 13 +++++++++++++ include/linux/gpio/consumer.h | 7 +++++++ 2 files changed, 20 insertions(+)
drivers/gpio/gpiolib.c +13 -0
@@ -3193,6 +3193,19 @@ int gpiod_cansleep(const struct gpio_desc *desc) }EXPORT_SYMBOL_GPL (gpiod_cansleep); +/** +* gpiod_set_consumer_name() - set the consumer name for the descriptor +* @desc: gpio to set the consumer name on +* @name: the new consumer name +*/ +void gpiod_set_consumer_name (struct gpio_desc *desc,const char *name) +{ +VALIDATE_DESC_VOID (desc); +/* Just overwrite whatever the previous name was */ + desc->label = name; +} +EXPORT_SYMBOL_GPL (gpiod_set_consumer_name); +/** * gpiod_to_irq() - return the IRQ corresponding to a GPIO * @desc: gpio whose IRQ will be returned (already requested)
include/linux/gpio/consumer.h +7 -0
@@ -145,6 +145,7 @@ int gpiod_is_active_low(const struct gpio_desc *desc);int gpiod_cansleep (const struct gpio_desc *desc);int gpiod_to_irq (const struct gpio_desc *desc); +void gpiod_set_consumer_name (struct gpio_desc *desc,const char *name);/* Convert between the old gpio_ and new gpiod_ interfaces */ struct gpio_desc *gpio_to_desc (unsigned gpio);
@@ -467,6 +468,12 @@ static inline int gpiod_to_irq(const struct gpio_desc *desc)return -EINVAL ; } +static inline void gpiod_set_consumer_name (struct gpio_desc *desc,const char *name) +{ +/* GPIO can never have been requested */ +WARN_ON (1 ); +} +static inline struct gpio_desc *gpio_to_desc (unsigned gpio) {return ERR_PTR (-EINVAL );
Signature · 1 line
2.17.0
PATCH 2/5 RFC: eeprom: at24: Allow passing gpiodesc from pdata
In reply to Linus WalleijThis makes it possible to pass an initialized GPIO descriptor to the driver through platform data.
This is useful when we are dealing with EEPROMs on expansion boards where the GPIO has to be looked up indirectly using a connector abstraction (several systems using the same connector) so the machine descriptor tables cannot be used to associate the descriptor with the device and we then want to pass this descriptor on to the EEPROM driver this way instead.
--- drivers/misc/eeprom/at24.c | 6 +++++- include/linux/platform_data/at24.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-)
drivers/misc/eeprom/at24.c +5 -1
@@ -662,7 +662,11 @@ static int at24_probe(struct i2c_client *client) at24->client[0 ].client = client; at24->client[0 ].regmap = regmap; - at24->wp_gpio =devm_gpiod_get_optional (dev,"wp" ,GPIOD_OUT_HIGH ); +if (pdata.wp_gpiod) + at24->wp_gpio = pdata.wp_gpiod; +else + at24->wp_gpio = +devm_gpiod_get_optional (dev,"wp" ,GPIOD_OUT_HIGH );if (IS_ERR (at24->wp_gpio))return PTR_ERR (at24->wp_gpio);
include/linux/platform_data/at24.h +2 -0
@@ -11,6 +11,7 @@#include <linux/types.h> #include <linux/nvmem-consumer.h> #include <linux/bitops.h> +#include <linux/gpio/consumer.h> /** * struct at24_platform_data - data to set up at24 (generic eeprom) driver
@@ -55,6 +56,7 @@ struct at24_platform_data {void (*setup)(struct nvmem_device *nvmem,void *context);void *context; + struct gpio_desc *wp_gpiod; };#endif /* _LINUX_AT24_H */
Signature · 1 line
2.17.0
PATCH 2/5 RFC: eeprom: at24: Allow passing gpiodesc from pdata
Quoted 10 lines · Linus Walleij
This makes it possible to pass an initialized GPIO descriptor to the driver through platform data.
This is useful when we are dealing with EEPROMs on expansion boards where the GPIO has to be looked up indirectly using a connector abstraction (several systems using the same connector) so the machine descriptor tables cannot be used to associate the descriptor with the device and we then want to pass this descriptor on to the EEPROM driver this way instead.
How this descriptor is supposed to be created?
Whenever we probe the device we might add properties to it (consider how MFD does instansiate them), I guess same way GPIO lookup tables work. No?
P.S. I really would like to hear a _strong_ argument why it can't be done using other means like built-in device properties or GPIO lookup tables (which on my opinion have to work in the similar way at run time).
Signature · 2 lines
With Best Regards, Andy Shevchenko
PATCH 3/5 RFC: spi: Make of_find_spi_device_by_node() available
In reply to Linus WalleijThis externalizes and exports the symbol of_find_spi_device_by_node() from the SPI core akin to how of_find_i2c_adapter_by_node() is already available. As we will need this also for non-dynamic OF setups, we move it under a CONFIG_OF check.
--- drivers/spi/spi.c | 33 ++++++++++++++++++--------------- include/linux/spi/spi.h | 4 ++++ 2 files changed, 22 insertions(+), 15 deletions(-)
drivers/spi/spi.c +18 -15
@@ -3314,27 +3314,14 @@ EXPORT_SYMBOL_GPL(spi_write_then_read);/*-------------------------------------------------------------------------*/ -#if IS_ENABLED (CONFIG_OF_DYNAMIC ) -static int __spi_of_device_match (struct device *dev,void *data) -{ -return dev->of_node == data; -} - -/* must call put_device() when done with returned spi_device device */ -static struct spi_device *of_find_spi_device_by_node (struct device_node *node) -{ -struct device *dev =bus_find_device (&spi_bus_type,NULL , node, - __spi_of_device_match); -return dev ?to_spi_device (dev) :NULL ; -} - +#if IS_ENABLED (CONFIG_OF )static int __spi_of_controller_match (struct device *dev,const void *data) {return dev->of_node == data; }/* the spi controllers are not using spi_bus, so we find it with another way */ -static struct spi_controller *of_find_spi_controller_by_node (struct device_node *node) +struct spi_controller *of_find_spi_controller_by_node (struct device_node *node) {struct device *dev;
@@ -3349,6 +3336,22 @@ static struct spi_controller *of_find_spi_controller_by_node(struct device_node/* reference got in class_find_device */ return container_of(dev, struct spi_controller, dev); } +EXPORT_SYMBOL_GPL (of_find_spi_controller_by_node); +#endif + +#if IS_ENABLED (CONFIG_OF_DYNAMIC ) +static int __spi_of_device_match (struct device *dev,void *data) +{ +return dev->of_node == data; +} + +/* must call put_device() when done with returned spi_device device */ +static struct spi_device *of_find_spi_device_by_node (struct device_node *node) +{ +struct device *dev =bus_find_device (&spi_bus_type,NULL , node, + __spi_of_device_match); +return dev ?to_spi_device (dev) :NULL ; +}static int of_spi_notify (struct notifier_block *nb,unsigned long action,void *arg)
include/linux/spi/spi.h +4 -0
@@ -639,6 +639,10 @@ extern int devm_spi_register_controller(struct device *dev, struct spi_controller *ctlr);extern void spi_unregister_controller (struct spi_controller *ctlr); +#if IS_ENABLED (CONFIG_OF ) +struct spi_controller *of_find_spi_controller_by_node (struct device_node *node); +#endif +extern struct spi_controller *spi_busnum_to_master (u16 busnum);/*
Signature · 1 line
2.17.0
PATCH 4/5 RFC: bus: 96boards Low-Speed Connector
In reply to Linus WalleijThis illustrates my idea for using a small connector driver to plug in "mezzanine boards" on the 96boards low-speed connector.
These "mezzanine boards" are no different than "capes", "logic modules", etc. This thing, a non-discoverable connector where a user can plug in a few peripherals has been reinvented a few times.
As a proof-of-concept we add the Secure96, a quite minimal mezzanine board.
Users can register their boards in a simple way. Either just add their compatible-string in the device tree:
board {
compatible = "96boards,secure96";
};And if they can't even change three lines in their device tree, or if they at runtime decide to plug in some board and test it, they can use sysfs, as exemplified by plugging in the secure96 security board at runtime:
Quoted 2 lines
cd
/sys/devices/platform/connector
echo 1 > secure96
[ 61.014629] lscon connector: called mezzanine_store on secure96 [ 61.020530] lscon connector: populate secure96 [ 61.027081] at24 1-0050: 2048 byte 24c128 EEPROM, writable, 128 bytes/write [ 61.053569] atmel-ecc 1-0060: configuration zone is unlocked [ 61.502535] tpm_tis_spi spi0.0: 2.0 TPM (device-id 0x1B, rev-id 16)
(...)
The plug-in board can be removed from sysfs and added back again multiple times like this with the devices being runtime added and removed by two writes to sysfs.
Quoted 3 lines
echo 0 > secure96
echo 1 > secure96
echo 0 > secure96
(...)
I certainly see some scalability problems with this particular code for example, but the fact is: it pretty much works. The devices need hooks in I2C and SPI, and need to be able to accept initialized GPIO descriptors passed in as platform data.
Any discussions related to the concept compared to doing device tree overlays/fragments etc: please discuss in patch 0 (the cover letter).
--- .../96boards-ls-connector.c | 307 ++++++++++++++++++ .../96boards-mezzanines/96boards-mezzanines.h | 46 +++ .../96boards-mezzanines/96boards-secure96.c | 249 ++++++++++++++ drivers/bus/96boards-mezzanines/Kconfig | 36 ++ drivers/bus/96boards-mezzanines/Makefile | 6 + drivers/bus/Kconfig | 2 + drivers/bus/Makefile | 4 +- 7 files changed, 649 insertions(+), 1 deletion(-) create mode 100644 drivers/bus/96boards-mezzanines/96boards-ls-connector.c create mode 100644 drivers/bus/96boards-mezzanines/96boards-mezzanines.h create mode 100644 drivers/bus/96boards-mezzanines/96boards-secure96.c create mode 100644 drivers/bus/96boards-mezzanines/Kconfig create mode 100644 drivers/bus/96boards-mezzanines/Makefile
drivers/bus/96boards-mezzanines/96boards-ls-connector.c new file +307 -0
@@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* 96boards Low-speed Connector driver +* (C) 2018 Linus Walleij <[email protected]> +*/ + +#include <linux/init.h> +#include <linux/sysfs.h> +#include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/i2c.h> +#include <linux/spi/spi.h> +#include "96boards-mezzanines.h" + +/** +* struct mezzanine - daughter boards (mezzanines) data +* Having dynamic data here means that we can only plug ONE board +* of each type. Stacking two different boards is fine. This +* should be fixed using a linked list of mezzanines if we +* go for this solution. +*/ +struct mezzanine { +const char *compatible; +const char *sysfs_name; +struct dev_ext_attribute ext_attr; +void * (*populate) (struct lscon *ls); +void (*depopulate) (void *data); +void *data; +}; + +static struct mezzanine mezzanines[] = { +#if IS_ENABLED(96BOARDS_SECURE96) + { + .compatible ="96boards,secure96" , + .sysfs_name ="secure96" , + .populate = secure96_populate, + .depopulate = secure96_depopulate, + }, +#endif +/* Add any other mezzanines here */ +}; + +struct gpio_desc *mezzanine_ls_get_gpiod (struct lscon *ls, +enum mezzanine_ls_gpio pin, +const char *consumer_name, +enum gpiod_flags flags) +{ +struct gpio_desc *retdesc; + +/* +* TODO: get all the LS GPIOs as an array on probe() then +* the consumers can skip error handling of IS_ERR() descriptors +* and this need only set the consumer name. +*/ + retdesc =devm_gpiod_get_index (ls->dev,NULL , pin, flags); +if (!IS_ERR (retdesc) && consumer_name) +gpiod_set_consumer_name (retdesc, consumer_name); + +return retdesc; +} +EXPORT_SYMBOL_GPL (mezzanine_ls_get_gpiod); + +/* +* Mezzanine boards will call this to orderly remove their claimed +* gpio descriptors, since we acquired them all with devm_gpiod_get() +* they will eventually be released once this connector device +* disappears if the board do not release them in order. +*/ +void mezzanine_ls_put_gpiod (struct lscon *ls,struct gpio_desc *gpiod) +{ +devm_gpiod_put (ls->dev, gpiod); +} +EXPORT_SYMBOL_GPL (mezzanine_ls_put_gpiod); + +static ssize_t mezzanine_show (struct device *dev, +struct device_attribute *attr, +char *buf) +{ +struct lscon *ls =dev_get_drvdata (dev); +struct dev_ext_attribute *d =container_of (attr, + struct dev_ext_attribute, + attr); +struct mezzanine *mez = d->var; + +dev_info (ls->dev,"called %s on %s\n" , __func__, mez->sysfs_name); +return 0 ; +} + +static ssize_t mezzanine_store (struct device *dev, +struct device_attribute *attr, +const char *buf,size_t count) +{ +struct lscon *ls =dev_get_drvdata (dev); +struct dev_ext_attribute *d =container_of (attr, + struct dev_ext_attribute, + attr); +struct mezzanine *mez = d->var; +unsigned long state; +int ret; + +dev_info (ls->dev,"called %s on %s\n" , __func__, mez->sysfs_name); + + ret =kstrtoul (buf,0 , &state); +if (ret) +return ret; + +if (state ==1 ) { +void *data; + +/* Already populated */ +if (mez->data) +return count; + + data = mez->populate (ls); +if (IS_ERR (data)) +return PTR_ERR (data); + mez->data = data; +return count; + } + +if (state ==0 ) { +/* Not populated so nothing to do here */ +if (!mez->data) +return count; + mez->depopulate (mez->data); + mez->data =NULL ; +return count; + } + +return -EINVAL ; +} + +/** +* This adds one sysfs file per mezzanine board that we support, so they +* can be probed and added from userspace. +*/ +static int lscon_add_sysfs_mezzanines (struct lscon *ls) +{ +struct mezzanine *mez; +struct dev_ext_attribute *ext_attr; +int ret; +int i; + +for (i =0 ; i <ARRAY_SIZE (mezzanines); i++) { + mez = &mezzanines[i]; + ext_attr = &mez->ext_attr; + + ext_attr->var = mez; + ext_attr->attr.attr.name = mez->sysfs_name; + ext_attr->attr.attr.mode =VERIFY_OCTAL_PERMISSIONS (0644 ); + ext_attr->attr.show = mezzanine_show; + ext_attr->attr.store = mezzanine_store; + ret =device_create_file (ls->dev, &ext_attr->attr); +if (ret) +dev_err (ls->dev,"unable to create sysfs entries\n" ); + + } + +return 0 ; +} + +static int lscon_probe_of_mezzanine (struct lscon *ls,struct device_node *np) +{ +struct mezzanine *mez; +void *data; +int i; + +for (i =0 ; i <ARRAY_SIZE (mezzanines); i++) { + mez = &mezzanines[i]; +if (of_device_is_compatible (np, mez->compatible)) { +dev_info (ls->dev,"found %s\n" , mez->compatible); + data = mez->populate (ls); +if (IS_ERR (data)) +return PTR_ERR (data); + mez->data = data; +return 0 ; + } + } + +return 0 ; +} + +static int lscon_probe (struct platform_device *pdev) +{ +struct device *dev = &pdev->dev; +struct device_node *np = dev->of_node; +struct device_node *child; +struct spi_controller *spi; +struct mezzanine *mez; +struct lscon *ls; +int ret; +int i; + + ls =devm_kzalloc (dev,sizeof (*ls),GFP_KERNEL ); +if (!ls) +return -ENOMEM ; + ls->dev = dev; + +/* Bridge I2C busses */ + child =of_parse_phandle (np,"i2c0" ,0 ); +if (!child) { +dev_err (dev,"no i2c0 phandle\n" ); +return -ENODEV ; + } + ls->i2c0 =of_get_i2c_adapter_by_node (child); +if (!ls->i2c0) { +dev_err (dev,"no i2c0 adapter, deferring\n" ); +return -EPROBE_DEFER ; + } + + child =of_parse_phandle (np,"i2c1" ,0 ); +if (!child) { +dev_err (dev,"no i2c1 phandle\n" ); + ret = -ENODEV ; + goto out_put_i2c0; + } + ls->i2c1 =of_get_i2c_adapter_by_node (child); +if (!ls->i2c1) { +dev_err (dev,"no i2c0 adapter, deferring\n" ); + ret = -EPROBE_DEFER ; + goto out_put_i2c0; + } + +/* Bride SPI bus */ + child =of_parse_phandle (np,"spi" ,0 ); +if (!child) { +dev_err (dev,"no spi phandle\n" ); + ret = -ENODEV ; + goto out_put_i2c1; + } + spi =of_find_spi_controller_by_node (child); +if (!spi) { +dev_err (dev,"no spi controller, deferring\n" ); + ret = -EPROBE_DEFER ; + goto out_put_i2c1; + } + ls->spi =spi_controller_get (spi); +if (!ls->spi) { +dev_err (dev,"no spi reference\n" ); + ret = -ENODEV ; + goto out_put_i2c1; + } + +platform_set_drvdata (pdev, ls); + +/* Get the mezzanine boards, stacking possible */ +for_each_available_child_of_node (np, child) +lscon_probe_of_mezzanine (ls, child); + + ret =lscon_add_sysfs_mezzanines (ls); +if (ret) + goto out_remove_mezzanines; + +return 0 ; + +out_remove_mezzanines: +/* Depopulate any populated boards */ +for (i =0 ; i <ARRAY_SIZE (mezzanines); i++) { + mez = &mezzanines[i]; +if (mez->data) + mez->depopulate (mez->data); + mez->data =NULL ; + } +out_put_i2c1: +i2c_put_adapter (ls->i2c1); +out_put_i2c0: +i2c_put_adapter (ls->i2c0); +return ret; +} + +static int lscon_remove (struct platform_device *pdev) +{ +struct lscon *ls =platform_get_drvdata (pdev); +struct mezzanine *mez; +int i; + +/* Depopulate any populated boards */ +for (i =0 ; i <ARRAY_SIZE (mezzanines); i++) { + mez = &mezzanines[i]; +if (mez->data) + mez->depopulate (mez->data); + mez->data =NULL ; + } + +spi_controller_put (ls->spi); +i2c_put_adapter (ls->i2c1); +i2c_put_adapter (ls->i2c0); + +return 0 ; +} + +static const struct of_device_id lscon_of_match[] = { + { + .compatible ="96boards,low-speed-connector" , + }, +}; + +static struct platform_driver lscon_driver = { + .driver = { + .name ="lscon" , + .of_match_table =of_match_ptr (lscon_of_match), + }, + .probe = lscon_probe, + .remove = lscon_remove, +}; +builtin_platform_driver (lscon_driver);
drivers/bus/96boards-mezzanines/96boards-mezzanines.h new file +46 -0
46 lines not on this page · raw message
drivers/bus/96boards-mezzanines/96boards-secure96.c new file +249 -0
249 lines not on this page · raw message
drivers/bus/96boards-mezzanines/Kconfig new file +36 -0
@@ -0,0 +1,36 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# 96boards mezzanine connectors and drivers + +menuconfig 96BOARDS_MEZZANINES + bool "96boards mezzanine boards" + +if 96BOARDS_MEZZANINES + +config 96BOARDS_LS_CONNECTOR + bool "96boards low speed connector driver" + depends on OF + depends on I2C + depends on SPI_MASTER + depends on GPIOLIB + help + Driver for the 96boards low speed connector + +config 96BOARDS_SECURE96 + bool "96boards Secure96 board driver" + depends on 96BOARDS_LS_CONNECTOR + select NEW_LEDS + select LEDS_CLASS + select LEDS_GPIO + select EEPROM_AT24 + select CRYPTO_HW + select CRYPTO_DEV_ATMEL_ECC + select HW_RANDOM + select TCG_TPM + select HW_RANDOM_TPM + select TCG_TIS + select TCG_TIS_SPI + help + Driver for the 96boards Secure96 mezzanine + +endif
drivers/bus/96boards-mezzanines/Makefile new file +6 -0
@@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the 96boards mezzanines +# +obj-$(CONFIG_96BOARDS_LS_CONNECTOR) += 96boards-ls-connector.o +obj-$(CONFIG_96BOARDS_SECURE96) += 96boards-secure96.o
drivers/bus/Kconfig +2 -0
@@ -173,4 +173,6 @@ config DA8XX_MSTPRI source "drivers/bus/fsl-mc/Kconfig" +source "drivers/bus/96boards-mezzanines/Kconfig" + endmenu
drivers/bus/Makefile +3 -1
@@ -29,5 +29,7 @@ obj-$(CONFIG_TI_SYSC) += ti-sysc.o obj-$(CONFIG_TS_NBUS) += ts-nbus.o obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o - obj-$(CONFIG_DA8XX_MSTPRI) += da8xx-mstpri.o + +# 96boards mezzanines +obj-$(CONFIG_96BOARDS_MEZZANINES) += 96boards-mezzanines/
Signature · 1 line
2.17.0
PATCH 4/5 RFC: bus: 96boards Low-Speed Connector
Quoted 32 lines · Linus Walleij
This illustrates my idea for using a small connector driver to plug in "mezzanine boards" on the 96boards low-speed connector.
These "mezzanine boards" are no different than "capes", "logic modules", etc. This thing, a non-discoverable connector where a user can plug in a few peripherals has been reinvented a few times.
As a proof-of-concept we add the Secure96, a quite minimal mezzanine board.
Users can register their boards in a simple way. Either just add their compatible-string in the device tree:
board { compatible = "96boards,secure96"; };And if they can't even change three lines in their device tree, or if they at runtime decide to plug in some board and test it, they can use sysfs, as exemplified by plugging in the secure96 security board at runtime:
Quoted 2 lines
cd
/sys/devices/platform/connector
echo 1 > secure96[ 61.014629] lscon connector: called mezzanine_store on secure96 [ 61.020530] lscon connector: populate secure96 [ 61.027081] at24 1-0050: 2048 byte 24c128 EEPROM, writable, 128 bytes/write [ 61.053569] atmel-ecc 1-0060: configuration zone is unlocked [ 61.502535] tpm_tis_spi spi0.0: 2.0 TPM (device-id 0x1B, rev-id 16)(...)
Quoted 8 lines
The plug-in board can be removed from sysfs and added back again multiple times like this with the devices being runtime added and removed by two writes to sysfs.
Quoted 3 lines
echo 0 > secure96
echo 1 > secure96
echo 0 > secure96(...)
Having a sysfs interface is useful (I certainly love being able to use sysfs to manage ad-hoc I2C chains).
However it feels like the current blurring between connector device and mezzanine device is shining through in this interface if only because the look and feel is very different to instantiating an I2C device from user-space.
Daniel.
PATCH 5/5 RFC: ARM64: dts: Add Low-Speed Connector to ZCU100
In reply to Linus WalleijThis adds the low-speed connector to the ZCU100 rev C device tree (also known as the Ultra96 board).
This is a proof-of-concept only, showing how it is possible to populate a Secure96 board using the other patches in the series.
If you comment out or delete the board {} node, you can populate/depopulate the board from sysfs instead.
--- .../boot/dts/xilinx/zynqmp-zcu100-revC.dts | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +25 -2
@@ -110,6 +110,28 @@ compatible = "mmc-pwrseq-simple"; reset-gpios = <&gpio 7 GPIO_ACTIVE_LOW>; /* WIFI_EN */ }; + + lscon: connector { + compatible = "96boards,low-speed-connector"; + i2c0 = <&i2csw_0>; + i2c1 = <&i2csw_1>; + spi = <&spi0>; + gpios = <&gpio 36 GPIO_ACTIVE_HIGH>, /* GPIO-A */ + <&gpio 37 GPIO_ACTIVE_HIGH>, /* GPIO-B */ + <&gpio 39 GPIO_ACTIVE_HIGH>, /* GPIO-C */ + <&gpio 40 GPIO_ACTIVE_HIGH>, /* GPIO-D */ + <&gpio 44 GPIO_ACTIVE_HIGH>, /* GPIO-E */ + <&gpio 45 GPIO_ACTIVE_HIGH>, /* GPIO-F */ + <&gpio 78 GPIO_ACTIVE_HIGH>, /* GPIO-G */ + <&gpio 79 GPIO_ACTIVE_HIGH>, /* GPIO-H */ + <&gpio 80 GPIO_ACTIVE_HIGH>, /* GPIO-I */ + <&gpio 81 GPIO_ACTIVE_HIGH>, /* GPIO-J */ + <&gpio 82 GPIO_ACTIVE_HIGH>, /* GPIO-K */ + <&gpio 83 GPIO_ACTIVE_HIGH>; /* GPIO-L */ + board { + compatible = "96boards,secure96"; + }; + }; }; &dcc {
@@ -134,8 +156,9 @@ "USB1_DIR", "USB1_DATA2", "USB1_NXT", "USB1_DATA0", "USB1_DATA1", "USB1_STP", "USB1_DATA3", "USB1_DATA4", "USB1_DATA5", "USB1_DATA6", "USB_DATA7", "WLAN_IRQ", "PMIC_IRQ", /* MIO end and EMIO start */ - "", "", - "", "", "", "", "", "", "", "", "", "", + "GPIO-G", "GPIO-H", + "GPIO-I", "GPIO-J", "GPIO-K", "GPIO-L", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
Signature · 1 line
2.17.0
PATCH 5/5 RFC: ARM64: dts: Add Low-Speed Connector to ZCU100
+David G
Quoted 20 lines · Linus Walleij
This adds the low-speed connector to the ZCU100 rev C device tree (also known as the Ultra96 board).
This is a proof-of-concept only, showing how it is possible to populate a Secure96 board using the other patches in the series.
If you comment out or delete the board {} node, you can populate/depopulate the board from sysfs instead.
Signed-off-by Linus Walleij <[email protected]>--- .../boot/dts/xilinx/zynqmp-zcu100-revC.dts | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-)arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +0
-0
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts line 118
Quoted 9 lines
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +6
-0@@ -110,6 +110,28 @@ compatible = "mmc-pwrseq-simple"; reset-gpios = <&gpio 7 GPIO_ACTIVE_LOW>; /* WIFI_EN */ }; + + lscon: connector { + compatible = "96boards,low-speed-connector"; + i2c0 = <&i2csw_0>; + i2c1 = <&i2csw_1>; + spi = <&spi0>;
David had suggested having an aliases node here for mapping things like SPI and I2C. That actually seems like a good use for aliases compared to the usual abuse to make Linux provide fixed numbering.
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts line 119
Quoted 1 line
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +1
-0+ gpios = <&gpio 36 GPIO_ACTIVE_HIGH>, /* GPIO-A */
Why aren't you using gpio-map? This is what it was defined for.
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts line 132
Quoted 13 lines
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +13
-0+ <&gpio 37 GPIO_ACTIVE_HIGH>, /* GPIO-B */ + <&gpio 39 GPIO_ACTIVE_HIGH>, /* GPIO-C */ + <&gpio 40 GPIO_ACTIVE_HIGH>, /* GPIO-D */ + <&gpio 44 GPIO_ACTIVE_HIGH>, /* GPIO-E */ + <&gpio 45 GPIO_ACTIVE_HIGH>, /* GPIO-F */ + <&gpio 78 GPIO_ACTIVE_HIGH>, /* GPIO-G */ + <&gpio 79 GPIO_ACTIVE_HIGH>, /* GPIO-H */ + <&gpio 80 GPIO_ACTIVE_HIGH>, /* GPIO-I */ + <&gpio 81 GPIO_ACTIVE_HIGH>, /* GPIO-J */ + <&gpio 82 GPIO_ACTIVE_HIGH>, /* GPIO-K */ + <&gpio 83 GPIO_ACTIVE_HIGH>; /* GPIO-L */ + board { + compatible = "96boards,secure96";
I'm all for putting things in the kernel/drivers for things we can't nail down bindings for, but it really seems like you are punting all the problems. Plus if we fully define how to handle the different bindings, we'll likely end up with something different and incompatible with what you have here.
Rob
PATCH 5/5 RFC: ARM64: dts: Add Low-Speed Connector to ZCU100
In reply to Linus WalleijQuoted 31 lines · Linus Walleij
This adds the low-speed connector to the ZCU100 rev C device tree (also known as the Ultra96 board).
This is a proof-of-concept only, showing how it is possible to populate a Secure96 board using the other patches in the series.
If you comment out or delete the board {} node, you can populate/depopulate the board from sysfs instead.
Signed-off-by Linus Walleij <[email protected]>--- .../boot/dts/xilinx/zynqmp-zcu100-revC.dts | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-)arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +8
-0@@ -110,6 +110,28 @@ compatible = "mmc-pwrseq-simple"; reset-gpios = <&gpio 7 GPIO_ACTIVE_LOW>; /* WIFI_EN */ }; + + lscon: connector { + compatible = "96boards,low-speed-connector"; + i2c0 = <&i2csw_0>; + i2c1 = <&i2csw_1>; + spi = <&spi0>; + gpios = <&gpio 36 GPIO_ACTIVE_HIGH>, /* GPIO-A */ + <&gpio 37 GPIO_ACTIVE_HIGH>, /* GPIO-B */
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts line 130
Quoted 10 lines
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +10
-0+ <&gpio 39 GPIO_ACTIVE_HIGH>, /* GPIO-C */ + <&gpio 40 GPIO_ACTIVE_HIGH>, /* GPIO-D */ + <&gpio 44 GPIO_ACTIVE_HIGH>, /* GPIO-E */ + <&gpio 45 GPIO_ACTIVE_HIGH>, /* GPIO-F */ + <&gpio 78 GPIO_ACTIVE_HIGH>, /* GPIO-G */ + <&gpio 79 GPIO_ACTIVE_HIGH>, /* GPIO-H */ + <&gpio 80 GPIO_ACTIVE_HIGH>, /* GPIO-I */ + <&gpio 81 GPIO_ACTIVE_HIGH>, /* GPIO-J */ + <&gpio 82 GPIO_ACTIVE_HIGH>, /* GPIO-K */ + <&gpio 83 GPIO_ACTIVE_HIGH>; /* GPIO-L */
This connector has also 2 uarts which you should have here too.
Thanks,
Michal
Quoted 20 lines
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +7
-2+ board { + compatible = "96boards,secure96"; + }; + }; }; &dcc {@@ -134,8 +156,9 @@ "USB1_DIR", "USB1_DATA2", "USB1_NXT", "USB1_DATA0", "USB1_DATA1", "USB1_STP", "USB1_DATA3", "USB1_DATA4", "USB1_DATA5", "USB1_DATA6", "USB_DATA7", "WLAN_IRQ", "PMIC_IRQ", /* MIO end and EMIO start */ - "", "", - "", "", "", "", "", "", "", "", "", "", + "GPIO-G", "GPIO-H", + "GPIO-I", "GPIO-J", "GPIO-K", "GPIO-L", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
Arnd Bergmann
maintainercover RFC: Mezzanine handling for 96boards
In reply to Linus WalleijQuoted 9 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
Quoted 6 lines
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
Hi Linus,
Thanks for your work on solving this long-standing problem. I've just read through your patches briefly and have a few thoughts:
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
- I don't like the idea of having the bus driver contain a list of possible add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a proper bus_type, to allow drivers to register against it as loadable modules, and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures etc, which could all be described as mezzanines. One open question is how we structure the commonality between the various connectors, but we can defer that until we have more than one or two of them.
Arnd
cover RFC: Mezzanine handling for 96boards
Quoted 35 lines · Arnd Bergmann
Quoted 9 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
Quoted 6 lines
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
Hi Linus,
Thanks for your work on solving this long-standing problem. I've just read through your patches briefly and have a few thoughts:
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
- I don't like the idea of having the bus driver contain a list of possible add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a proper
bus_type, to allow drivers to register against it as loadable modules, and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.
Quoted 9 lines
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures etc, which could all be described as mezzanines. One open question is how we structure the commonality between the various connectors, but we can defer that until we have more than one or two of them.
Hello all,
We should also consider firmware use of the mezzanines. For instance, the Secure96 has a RNG which UEFI may want to use so the early boot code can access is for KASLR. It also has a TPM, which should not be reset/reinitialized/etc by the OS if we want to make meaningful use of it.
Also, given that we can (and do) already describe topologies involving mezzanines by ignoring the connector altogether (which is not entirely unreasonable given the fact that we [as Linaro/96boards] dropped the ball on this one and did not mandate discoverability for mezzanines). So ideally, DTs can be expressed such that older kernels can still use those peripherals.
Arnd Bergmann
maintainercover RFC: Mezzanine handling for 96boards
Quoted 9 lines · Ard Biesheuvel
Quoted 1 line · Arnd Bergmann
On Mon, Jun 18, 2018 at 9:45 AM, Linus Walleij <[email protected]> wrote:
Also, given that we can (and do) already describe topologies involving mezzanines by ignoring the connector altogether (which is not entirely unreasonable given the fact that we [as Linaro/96boards] dropped the ball on this one and did not mandate discoverability for mezzanines). So ideally, DTs can be expressed such that older kernels can still use those peripherals.
Not sure. Modeling the connector as a device with its own driver does seem like a significant advantage, which to me weighs more than backward compatibility with old kernels. We can clearly always describe the devices behind the connector individually and ignore the connector on old kernels and we should still allow running DT files that work with the old kernels on new kernels, but I don't see running new DT files on old kernels as essential in this case. Many platforms don't actually care about that case at all today (but some do of course).
Arnd
cover RFC: Mezzanine handling for 96boards
Quoted 12 lines · Arnd Bergmann
Quoted 9 lines · Ard Biesheuvel
Quoted 1 line · Arnd Bergmann
On Mon, Jun 18, 2018 at 9:45 AM, Linus Walleij <[email protected]> wrote:
Also, given that we can (and do) already describe topologies involving mezzanines by ignoring the connector altogether (which is not entirely unreasonable given the fact that we [as Linaro/96boards] dropped the ball on this one and did not mandate discoverability for mezzanines). So ideally, DTs can be expressed such that older kernels can still use those peripherals.
Quoted 8 lines
Not sure. Modeling the connector as a device with its own driver does seem like a significant advantage, which to me weighs more than backward compatibility with old kernels. We can clearly always describe the devices behind the connector individually and ignore the connector on old kernels and we should still allow running DT files that work with the old kernels on new kernels, but I don't see running new DT files on old kernels as essential in this case. Many platforms don't actually care about that case at all today (but some do of course).
Linus choose Ultra96 board which is showing that "standard" 96boards connector doesn't need to be standard in all cases.
If you look at board schematics that you will see that loaded bitstream/configuration is making these connector compatible with 96boards spec.
Almost the whole HS connector is connected to programmable logic and low speed connector is pretty much flexible too.
Also resource/power saving case should be considered.
I will take uart mezzanine as an example which requires only 6 uart pins and one gpio. In Ultra96 that means that doesn't make sense to waste your fpga resources for something what you don't need. (Truth is that for low speed it is just about wires but with High speed connector MIPI is in PL part which consume a logic).
And both connectors should also be handled together because some mezzanine cards require both of them.
Thanks,
Michal
Quoted 57 lines · Ard Biesheuvel
Quoted 1 line · Arnd Bergmann
On Mon, Jun 18, 2018 at 9:45 AM, Linus Walleij <[email protected]>
Quoted 11 lines · wrote:
Quoted 11 lines
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96
Quoted 10 lines
Quoted 4 lines
You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
Hi Linus,
Thanks for your work on solving this long-standing problem. I've just read through your patches briefly and have a few thoughts:
Quoted 7 lines
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
- I don't like the idea of having the bus driver contain a list of
possible
Quoted 6 lines
add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a proper
bus_type, to allow drivers to register against it as loadable modules, and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.Quoted 9 lines
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures etc, which could all be described as mezzanines. One open question is how we structure the commonality between the various connectors, but we can defer that until we have more than one or two of them.
Hello all,
We should also consider firmware use of the mezzanines. For instance, the Secure96 has a RNG which UEFI may want to use so the early boot code can access is for KASLR. It also has a TPM, which should not be reset/reinitialized/etc by the OS if we want to make meaningful use of it.
Quoted 5 lines
Also, given that we can (and do) already describe topologies involving mezzanines by ignoring the connector altogether (which is not entirely unreasonable given the fact that we [as Linaro/96boards] dropped the ball on this one and did not mandate discoverability for mezzanines).
The design guideline has been reviewed by many inside/outside linaro through the [email protected] and 96b-spec-sig < [email protected]> published as recommended/strongly recommended item from day one. 'dropping the ball' is a strong conclusion.
https://www.96boards.org/documentation/mezzanine/
Quoted 7 lines
So ideally, DTs can be expressed such that older kernels can still use those peripherals.
_______________________________________________
Dev mailing list
[email protected]
https://lists.96boards.org/mailman/listinfo/dev
cover RFC: Mezzanine handling for 96boards
Quoted 67 lines · Yang Zhang
Quoted 58 lines · Ard Biesheuvel
Quoted 38 lines · Arnd Bergmann
Quoted 9 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
Quoted 7 lines
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96
You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
Hi Linus,
Thanks for your work on solving this long-standing problem. I've just read through your patches briefly and have a few thoughts:
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
- I don't like the idea of having the bus driver contain a list of possible
add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a properbus_type, to allow drivers to register against it as loadable modules, and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.Quoted 9 lines
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures etc, which could all be described as mezzanines. One open question is how we structure the commonality between the various connectors, but we can defer that until we have more than one or two of them.
Hello all,
We should also consider firmware use of the mezzanines. For instance, the Secure96 has a RNG which UEFI may want to use so the early boot code can access is for KASLR. It also has a TPM, which should not be reset/reinitialized/etc by the OS if we want to make meaningful use of it.
Quoted 4 lines
Also, given that we can (and do) already describe topologies involving mezzanines by ignoring the connector altogether (which is not entirely unreasonable given the fact that we [as Linaro/96boards] dropped the ball on this one and did not mandate discoverability for mezzanines).
Quoted 5 lines
The design guideline has been reviewed by many inside/outside linaro through the mezzanine at lists.96boards.org and 96b-spec-sig <[email protected]> published as recommended/strongly recommended item from day one. 'dropping the ball' is a strong conclusion.
Apologies for using a term that you seem to take issue with. Are you saying the spec currently recommends it?
Yes.
Under Configuration data section
Quoted 83 lines · Ard Biesheuvel
Quoted 3 lines · Yang Zhang
On 18 June 2018 at 14:22, Ard Biesheuvel <[email protected]>
Quoted 9 lines · wrote:
Quoted 9 lines · Arnd Bergmann
Quoted 7 lines
Quoted 5 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
The code can be obtained from here:
linux-integrator.git/log/?h=ultra96
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 4 lines
You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
Hi Linus,
Thanks for your work on solving this long-standing problem. I've just read through your patches briefly and have a few thoughts:
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
- I don't like the idea of having the bus driver contain a list of possible
add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a properbus_type, to allow drivers to register against it as loadablemodules,
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures
etc,
Quoted 14 lines
Quoted 14 lines
Quoted 5 lines
which could all be described as mezzanines. One open question is how we structure the commonality between the various connectors, but we can defer that until we have more than one or two of them.
Hello all,
We should also consider firmware use of the mezzanines. For instance, the Secure96 has a RNG which UEFI may want to use so the early boot code can access is for KASLR. It also has a TPM, which should not be reset/reinitialized/etc by the OS if we want to make meaningful use of it.
Quoted 7 lines
Quoted 4 lines
Also, given that we can (and do) already describe topologies involving mezzanines by ignoring the connector altogether (which is not entirely unreasonable given the fact that we [as Linaro/96boards] dropped the ball on this one and did not mandate discoverability for mezzanines).
The design guideline has been reviewed by many inside/outside linaro
through
Quoted 2 lines
the [email protected] and 96b-spec-sig <[email protected]> published as recommended/strongly
recommended
Quoted 2 lines
item from day one. 'dropping the ball' is a strong conclusion.
Apologies for using a term that you seem to take issue with. Are you saying the spec currently recommends it?
cover RFC: Mezzanine handling for 96boards
Quoted 6 lines · Yang Zhang
Yes.
Under Configuration data section
OK, fair enough. Do any such mezzanines exist yet? Should we offer more guidance on how exactly this discovery should be implemented?
Quoted 86 lines · Ard Biesheuvel
Quoted 83 lines · Yang Zhang
Quoted 71 lines
Quoted 61 lines · Ard Biesheuvel
Quoted 40 lines · Arnd Bergmann
Quoted 9 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
Quoted 8 lines
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96
You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
Hi Linus,
Thanks for your work on solving this long-standing problem. I've just read through your patches briefly and have a few thoughts:
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
- I don't like the idea of having the bus driver contain a list of possible
add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a properbus_type, to allow drivers to register against it as loadable
modules,
and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.Quoted 10 lines
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures
etc,
which could all be described as mezzanines. One open question is how we structure the commonality between the various connectors, but we can defer that until we have more than one or two of them.Hello all,
We should also consider firmware use of the mezzanines. For instance, the Secure96 has a RNG which UEFI may want to use so the early boot code can access is for KASLR. It also has a TPM, which should not be reset/reinitialized/etc by the OS if we want to make meaningful use of it.
Quoted 4 lines
Also, given that we can (and do) already describe topologies involving mezzanines by ignoring the connector altogether (which is not entirely unreasonable given the fact that we [as Linaro/96boards] dropped the ball on this one and did not mandate discoverability for mezzanines).
Quoted 7 lines
The design guideline has been reviewed by many inside/outside linaro through
the mezzanine at lists.96boards.org and 96b-spec-sig <[email protected]> published as recommended/strongly recommended
item from day one. 'dropping the ball' is a strong conclusion.Apologies for using a term that you seem to take issue with. Are you saying the spec currently recommends it?
Quoted 13 lines · Ard Biesheuvel
Quoted 3 lines · Yang Zhang
Yes.
mezzanine/files/mezzanine-design-guidelines.pdf
Quoted 3 lines
Under Configuration data section
OK, fair enough. Do any such mezzanines exist yet? Should we offer more guidance on how exactly this discovery should be implemented?
I can't be sure, could look into it - I know there were couple of from Arrow and ST were supporting this.
Yes, more details guidance of "How to" is always welcome :-).
Quoted 97 lines
Quoted 1 line
On 19 June 2018 at 16:25, Ard Biesheuvel <[email protected]>
Quoted 15 lines · wrote:
Quoted 15 lines · Yang Zhang
Quoted 13 lines
Quoted 9 lines · Ard Biesheuvel
Quoted 7 lines · Arnd Bergmann
Quoted 5 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
The code can be obtained from here:
linux-integrator.git/log/?h=ultra96
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 4 lines
You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
Hi Linus,
Thanks for your work on solving this long-standing problem. I've
just
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
read through your patches briefly and have a few thoughts:
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
- I don't like the idea of having the bus driver contain a list of possible
add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a properbus_type, to allow drivers to register against it as loadable
modules,
and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something
related
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures
etc,
which could all be described as mezzanines. One open question is how we structure the commonality between the various connectors, but we can defer that until we have more than one or two of them.Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Hello all,
We should also consider firmware use of the mezzanines. For instance, the Secure96 has a RNG which UEFI may want to use so the early boot code can access is for KASLR. It also has a TPM, which should not be reset/reinitialized/etc by the OS if we want to make meaningful use
of
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
it.
Also, given that we can (and do) already describe topologies
involving
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
mezzanines by ignoring the connector altogether (which is not
entirely
Quoted 19 lines
Quoted 14 lines
Quoted 11 lines
Quoted 2 lines
unreasonable given the fact that we [as Linaro/96boards] dropped the ball on this one and did not mandate discoverability for mezzanines).
The design guideline has been reviewed by many inside/outside linaro through
the [email protected] and 96b-spec-sig <[email protected]> published as recommended/strongly recommended
item from day one. 'dropping the ball' is a strong conclusion.Apologies for using a term that you seem to take issue with. Are you saying the spec currently recommends it?
cover RFC: Mezzanine handling for 96boards
Quoted 11 lines · Yang Zhang
Quoted 9 lines · Ard Biesheuvel
Quoted 3 lines · Yang Zhang
Yes.
mezzanine/files/mezzanine-design-guidelines.pdf
Quoted 3 lines
Under Configuration data section
Quoted 8 lines
Quoted 4 lines
OK, fair enough. Do any such mezzanines exist yet? Should we offer more guidance on how exactly this discovery should be implemented?
I can't be sure, could look into it - I know there were couple of from Arrow and ST were supporting this.
Yes, more details guidance of "How to" is always welcome :-).
Unfortunately this is not saying i2c address and also how to handle stacked solution.
I have told to Linus what Xilinx is using for FMC connector present on the most of xilinx development boards.
These on board FMC eeproms contain information in FRU format. Also there incomplete support fmc support in the kernel in drivers/fmc which was added by Alessandro Rubini in 2013.
At least these eeprom could reuse FRU data format.
Thanks,
Michal
cover RFC: Mezzanine handling for 96boards
Quoted 7 lines · Michal Simek
I have told to Linus what Xilinx is using for FMC connector present on the most of xilinx development boards.
These on board FMC eeproms contain information in FRU format. Also there incomplete support fmc support in the kernel indrivers/fmcwhich was added by Alessandro Rubini in 2013.At least these eeprom could reuse FRU data format.
The FRU is a very tasteful design IMO and since it is a discoverable (plug and play!) bus I think we should have a clean FRU bus driver along Alessandro's suggestion to support them and spawn devices much like I do, as long as there is interest and some person who spends time writing the bus driver for it.
Yours,
Linus Walleij
cover RFC: Mezzanine handling for 96boards
In reply to Ard BiesheuvelQuoted 5 lines · Ard Biesheuvel
We should also consider firmware use of the mezzanines. For instance, the Secure96 has a RNG which UEFI may want to use so the early boot code can access is for KASLR. It also has a TPM, which should not be reset/reinitialized/etc by the OS if we want to make meaningful use of it.
This problem: sharing or dedicating a piece of hardware to UEFI or the TrustZone secure world is a generic problem not related to mezzanines or plug-in boards specifically.
c.f.arch/arm64/boot/dts/arm/juno-motherboard.dtsi:
flash at 0,00000000 {
/* 2 * 32MiB NOR Flash memory mounted on CS0 */
compatible = "arm,vexpress-flash", "cfi-flash";
linux,part-probe = "afs";
reg = <0 0x00000000 0x04000000>;
bank-width = <4>;
/*
* Unfortunately, accessing the flash disturbs
* the CPU idle states (suspend) and CPU
* hotplug of the platform. For this reason,
* flash hardware access is disabled by default.
*/
status = "disabled";
};What we need for this is something like
status = "secure-world-exclusive";
status = "UEFI-exclusive";
Or something like the same when using device tree.
If people probe this from sysfs (as in my example) they are obviously not novice users and they know what they are doing. For a simple user experience, I suspect device tree is what we want to use to populate defaults.
Quoted 2 lines
So ideally, DTs can be expressed such that older kernels can still use those peripherals.
That kind of expressions are possible already, such as putting the TPM DT node inside a SoC-specific I2C bus node. The boot loader can do that for example.
Then they can't also probe the same board from userspace, obviously. No matter whether they use the idea I present here or device tree overlays or anything else.
Yours,
Linus Walleij
cover RFC: Mezzanine handling for 96boards
Quoted 31 lines · Linus Walleij
Quoted 5 lines · Ard Biesheuvel
We should also consider firmware use of the mezzanines. For instance, the Secure96 has a RNG which UEFI may want to use so the early boot code can access is for KASLR. It also has a TPM, which should not be reset/reinitialized/etc by the OS if we want to make meaningful use of it.
This problem: sharing or dedicating a piece of hardware to UEFI or the TrustZone secure world is a generic problem not related to mezzanines or plug-in boards specifically.
c.f.
arch/arm64/boot/dts/arm/juno-motherboard.dtsi:flash at 0,00000000 { /* 2 * 32MiB NOR Flash memory mounted on CS0 */ compatible = "arm,vexpress-flash", "cfi-flash"; linux,part-probe = "afs"; reg = <0 0x00000000 0x04000000>; bank-width = <4>; /* * Unfortunately, accessing the flash disturbs * the CPU idle states (suspend) and CPU * hotplug of the platform. For this reason, * flash hardware access is disabled by default. */ status = "disabled"; };
Quoted 7 lines
What we need for this is something like
status = "secure-world-exclusive";
status = "UEFI-exclusive";Or something like the same when using device tree.
I agree that this is *also* a problem. But it is not what I was talking about.
My example is about peripherals that firmware and OS should both drive natively, and in the TPM case, the OS should be mindful of the fact that the measured state should be preserved. Also, it means that we may be duplicating functionality between the OS and firmware [as usual] so it might make sense to come up with something that takes both use cases into account.
Quoted 8 lines
If people probe this from sysfs (as in my example) they are obviously not novice users and they know what they are doing. For a simple user experience, I suspect device tree is what we want to use to populate defaults.
Quoted 2 lines
So ideally, DTs can be expressed such that older kernels can still use those peripherals.
Quoted 8 lines
That kind of expressions are possible already, such as putting the TPM DT node inside a SoC-specific I2C bus node. The boot loader can do that for example.
Then they can't also probe the same board from userspace, obviously. No matter whether they use the idea I present here or device tree overlays or anything else.
OK.
cover RFC: Mezzanine handling for 96boards
Quoted 13 lines · Ard Biesheuvel
Quoted 12 lines · Linus Walleij
Quoted 5 lines · Ard Biesheuvel
We should also consider firmware use of the mezzanines. For instance, the Secure96 has a RNG which UEFI may want to use so the early boot code can access is for KASLR. It also has a TPM, which should not be reset/reinitialized/etc by the OS if we want to make meaningful use of it.
This problem: sharing or dedicating a piece of hardware to UEFI or the TrustZone secure world is a generic problem not related to mezzanines or plug-in boards specifically.
(...)
Quoted 5 lines
I agree that this is *also* a problem. But it is not what I was talking about.
My example is about peripherals that firmware and OS should both drive natively, and in the TPM case, the OS should be mindful of the fact that the measured state should be preserved.
Ah I see.
In that case this is something the TPM driver should be doing I guess? I mean it is a "firmware plus OS TPM driver"-specific problem.
I guess that would be hard to duct-tape on if the peripheral is context-unaware and easy to do if the designer of the peripheral HW took multiple call-context into account. Whether TPM does this I don't know...
Quoted 4 lines
Also, it means that we
may be duplicating functionality between the OS and firmware [as usual] so it might make sense to come up with something that takes both use cases into account.
What we are doing now with Atmel's ECC chip is even worse:
duplicating functionality between OS and userspace. So I'm trying to solve that first.
Yours,
Linus Walleij
cover RFC: Mezzanine handling for 96boards
In reply to Arnd BergmannQuoted 5 lines · Arnd Bergmann
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
This is my point of view as well.
Quoted 6 lines
- I don't like the idea of having the bus driver contain a list of possible add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a proper
bus_type, to allow drivers to register against it as loadable modules, and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.
OK I think I can do that. It will take some thinking and I would guess I should also move it to drivers/platform/*
My idea here would be to have a connector bus that some random add-on (such as a 96board mezzanine) would probe to, so we make it generic for any connector plug.
Quoted 5 lines
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures etc, which could all be described as mezzanines.
Michal also brings up the (discoverable!) FMC connectors Xilinx are using. So the idea would be to create something generic to help probe and populate them all whether partly discoverable or not.
Quoted 4 lines
One open question
is how we structure the commonality between the various connectors, but we can defer that until we have more than one or two of them.
I can clean up the namespace at least so it gets clear where to add them. I will try to be more generic in the next iteration.
Yours,
Linus Walleij
Arnd Bergmann
maintainercover RFC: Mezzanine handling for 96boards
Quoted 17 lines · Linus Walleij
Quoted 5 lines · Arnd Bergmann
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
This is my point of view as well.
Quoted 6 lines
- I don't like the idea of having the bus driver contain a list of possible add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a proper
bus_type, to allow drivers to register against it as loadable modules, and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.
Quoted 2 lines
OK I think I can do that. It will take some thinking and I would guess I should also move it to
drivers/platform/*
I'd probably leave it in drivers/bus/, though this might be one of the rare cases that drivers/platform makes sense for as well.
Quoted 3 lines
My idea here would be to have a connector bus that some random add-on (such as a 96board mezzanine) would probe to, so we make it generic for any connector plug.
The question here is whether we want one 'struct bus_type' instance shared by all connector types, or one for each type. I was actually leaning towards the latter here.
Quoted 9 lines
Quoted 5 lines
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures etc, which could all be described as mezzanines.
Michal also brings up the (discoverable!) FMC connectors Xilinx are using. So the idea would be to create something generic to help probe and populate them all whether partly discoverable or not.
If a bus is fully discoverable, I think it's better to use a separate bus_type that does not use DT based probing for its children. However, many buses (even USB and PCI) turn out to be only mostly discoverable, so we end up having to come up with a way to represent child devices in DT as well.
Arnd
Mark Brown
maintainercover RFC: Mezzanine handling for 96boards
In reply to Linus WalleijQuoted 11 lines · Linus Walleij
Quoted 5 lines · Arnd Bergmann
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures etc, which could all be described as mezzanines.
Michal also brings up the (discoverable!) FMC connectors Xilinx are using. So the idea would be to create something generic to help probe and populate them all whether partly discoverable or not.
There's also the plug in modules in the Wolfson Cragganmore, there's
enumeration support for that in mainline.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180626/61df6737/attachment.sig>
Quoted 19 lines · Arnd Bergmann
Quoted 9 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
Quoted 6 lines
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
Hi Linus,
Quoted 8 lines
Thanks for your work on solving this long-standing problem. I've just read through your patches briefly and have a few thoughts:
- I really like the idea of having C code deal with the mezzanine connector itself, acting as an intermediate to tie a number of boards to a number of add-on cards, this seems much simpler than trying to do everything with overlays or one of the other more generic mechanisms.
Certainly we need at least some code to trigger probing devices under a connector. I suspect some connectors can be handled generically and some will need connector specific drivers.
Quoted 6 lines
- I don't like the idea of having the bus driver contain a list of possible add-ons, this seems to go against our usual driver model. What I think we want instead is to make the connector itself a proper
bus_type, to allow drivers to register against it as loadable modules, and devices (maybe limited to one device) being created as probed from DT or some other method as you describe.
Why a bus versus just a platform device? The infrastructure is already there to instantiate platform devices and match to compatible strings and a platform driver can create child devices. So what would we gain from a new bus?
We have 2 cases to consider I think: discoverable and non-discoverable boards. But discoverable here only provides us what overlay to load and/or driver to enumerate.
Quoted 11 lines
- You export symbols in the mezzanine_* namespace, which I think is a bit too generic and should perhaps contain something related to 96boards in its name to make it less ambiguous. I suspect we would add a number of further connectors for hats, capes, lures etc, which could all be described as mezzanines. One open question is how we structure the commonality between the various connectors, but we can defer that until we have more than one or two of them.
Arnd
cover RFC: Mezzanine handling for 96boards
In reply to Linus WalleijQuoted 9 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
Quoted 6 lines
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
Like other commenters I'm rather like using C to solve this, and your comments Big Upfront Design are good backup in term of convincing me.
Quoted 12 lines
TODO:
- Proper device tree bindings for the connector, for now look at the example.
- Discuss whether to actually do this or just take it all and flush it down the drain because the community doesn't like it. I'm not one of those especially infatuated with my own code, I always stay by the old programming project management mantra to calculate to make one version and throw it away as stepping stone to a good final design.
Quoted 7 lines
- Placement: putting this in
drivers/busis just an example.drivers/platform/96boards-mezzaninesis fine too, maybe better?- I am especially curious about input from Andy and Mika from the Intel/ACPI camp on what they have seen for non-discoverable plug-in boards. Does this problem even exist in the Intel world, or not...
I'm also interested in the "what about ACPI" question?
Using C makes describing a board in ACPI fairly easy. AFAICT allocating IDs to a board rather than its included components is fairly natural for ACPI.
However I'm too ignorant to be able to figure out if the expansion connector itself could/should be described in the tables (e.g. if connector is a bus and the board is[1] a device, could the bus driver be instantiated in a reasonable way).
Daniel.
[1] ... or becomes a device, based on feedback in this thread ;-)
Mark Brown
maintainercover RFC: Mezzanine handling for 96boards
Quoted 7 lines · Daniel Thompson
Quoted 4 lines · Linus Walleij
- I am especially curious about input from Andy and Mika from the Intel/ACPI camp on what they have seen for non-discoverable plug-in boards. Does this problem even exist in the Intel world, or not...
Quoted 5 lines
I'm also interested in the "what about ACPI" question?
Using C makes describing a board in ACPI fairly easy. AFAICT allocating IDs to a board rather than its included components is fairly natural for ACPI.
Yes, they have this problem - they have plug in modules on for example the minnowboard and some of their other reference platforms. They have overlays working for ACPI, these have their own problems in that they don't appear to have the equivalent of DMI data (at least the patches people are sending indicates that they don't) which is unfortuate as the idiomatic thing for ACPI is as you say to key huge chunks of data of quirk tables based on the DMI information for their boards.
They don't to my knowledge have generic connectors or anything like
that, it's just patches to the base ACPI.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180619/fed9da48/attachment-0001.sig>
cover RFC: Mezzanine handling for 96boards
In reply to Linus WalleijQuoted 120 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
TODO:
- Proper device tree bindings for the connector, for now look at the example.
- Discuss whether to actually do this or just take it all and flush it down the drain because the community doesn't like it. I'm not one of those especially infatuated with my own code, I always stay by the old programming project management mantra to calculate to make one version and throw it away as stepping stone to a good final design.
- Placement: putting this in
drivers/busis just an example.drivers/platform/96boards-mezzaninesis fine too, maybe better?- I am especially curious about input from Andy and Mika from the Intel/ACPI camp on what they have seen for non-discoverable plug-in boards. Does this problem even exist in the Intel world, or not...
Background:
- These boards connect on a custom connector on this family of boards. The relationship is many-to-many with the connector as nexus. The electronic standard for the connector is specified:
https://github.com/96boards/documentation/blob/master/Specifications/96Boards-CE-Specification.pdf
Example mezzanines:
https://www.96boards.org/documentation/mezzanine/- These boards have siblings on other platforms, the problem scope is similar with BeagleBone "capes":
https://beagleboard.org/capes
Raspberry Pi expansion boards:
https://www.abelectronics.co.uk/products/18/raspberry-pi-expansion-boards
Intel Edison, Galileo, Joule also have expansion boards.Idea: add a driver for the connector itself and tie it in to the device tree with a compatible string. Since the boards are non-discoverable two mechanisms are provided to discover them:
- Add a very simple device tree node with just a compatible string for the board in the node. This will be simple to add from e.g. a boot loader or as an overlay from userspace.
board { compatible = "96boards,secure96"; };- Echo 1 > boardname into a sysfs file to populate the board and echo 0 > boardname to depopulate it. This makes it easy to even switch out expansion boards at runtime, if allowed by the electronics.
Quoted 2 lines
cd
/sys/devices/platform/connector
echo 1 > secure96lscon connector: called
mezzanine_storeon secure96 lscon connector: populate secure96
at24 1-0050: 2048 byte 24c128 EEPROM, writable, 128 bytes/write atmel-ecc 1-0060: configuration zone is unlockedtpm_tis_spispi0.0: 2.0 TPM (device-id0x1B, rev-id 16) (...)What this patch set does not do:
- It does not use device tree or ACPI DSDT or any other hardware decription language to model the contents of the board per se. Instead the boards buses are populated directly with platform devices.
Predictable complaints about this design:
Q: This is not device tree overlays. Why is it not device
tree overlays?A1: Right tool for the job, overlays are complex and the
plan to get it in place seems to be spanning years, this is a few devices on simple busses and it works today. Using this approach I can already work on shaping up drivers for the mezzanine board devices as proved by:
https://marc.info/?l=linux-crypto-vger&m=152820660120590&w=2
https://marc.info/?l=linux-crypto-vger&m=152820662820595&w=2
(...)I can work on drivers for the chips on the Secure96 mezzanine board. It's just an example of what the mezzanine community can do.
Now they are hacking around in userspace instead of doing/reusing kernel drivers for their stuff:
https://github.com/jbech-linaro/secure96This way we can bring developers for these components into the kernel community instead of telling them to wait for some big infrastructure that comes later before they can contribute their stuff.
A2: Overlays does not solve the problem if the system runs
ACPI, and what about if the same connector[s] appear on a server board, servers use ACPI. Also notice that Intel have development boards with non-discoverable expansion boards as well. They just will not use device tree.
Quoted 13 lines
A3: Overlays is Big Upfront Design.
https://en.wikipedia.org/wiki/Big_Design_Up_Front
This way of designing things is associated with the (pejorative term) "waterfall model" which is out of fashion as a way of doing development. I think I am not the only one slightly annoyed by the fact that device tree overlays is now starting to look like a very big very upfront design. It's just not possible to get something up and running in small iterative steps with device tree overlays. Instead huge efforts are required and it involves major possible showstoppers and uncertain outcome as indicated by Frank's TODO:
https://elinux.org/Frank's_Evolving_Overlay_Thoughts
I don't agree. This can be broken down into various smaller mostly independent problems. Overlay handling is mostly an orthogonal problem. The exception is that we need to ensure bindings allow a decoupling of upstream of the connector and downstream of the connector so the downstream part can be a reusable overlay. Defining anything while ignoring this known criteria would be a mistake.
The list is roughly like this:
- Connector node binding and probing infrastructure
- GPIO (already done w/ gpio-map binding)
- I2C
- SPI
- Pinmux
- clocks
- OF graph (displays, cameras, etc.)
- USB (re-use the USB connector binding for non-standard connectors)
- Userspace interface
We don't have to support every interface from the start. The bindings and corresponding kernel support can be designed 1-by-1 for the most part. Start with something simple like a GPIO LED on a mezzanine. Once the base is functionality is there, the other parts can be worked on incrementally. We can punt any overlay handling to the bootloader initially. That punts all the issues around overlays like designing a userspace interface, where overlays are located (filesystem, passed from bootloader, built into the kernel), when they are loaded, and how to specify which overlays to load. Most of Frank's list is related to these issues.
Rob
cover RFC: Mezzanine handling for 96boards
Quoted 165 lines · Rob Herring
Quoted 120 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
The RFC was done on the brand new Ultra96 board from Xilinx with a Secure96 mezzanine expansion board. The main part is in patch 4, the rest is enabling and examples.
The code can be obtained from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96You can for example probably augment the DTS file for any upstream-supported 96board and get the Secure96 going with it with minor efforts.
TODO:
- Proper device tree bindings for the connector, for now look at the example.
- Discuss whether to actually do this or just take it all and flush it down the drain because the community doesn't like it. I'm not one of those especially infatuated with my own code, I always stay by the old programming project management mantra to calculate to make one version and throw it away as stepping stone to a good final design.
- Placement: putting this in
drivers/busis just an example.drivers/platform/96boards-mezzaninesis fine too, maybe better?- I am especially curious about input from Andy and Mika from the Intel/ACPI camp on what they have seen for non-discoverable plug-in boards. Does this problem even exist in the Intel world, or not...
Background:
- These boards connect on a custom connector on this family of boards. The relationship is many-to-many with the connector as nexus. The electronic standard for the connector is specified:
https://github.com/96boards/documentation/blob/master/Specifications/96Boards-CE-Specification.pdf
Example mezzanines:
https://www.96boards.org/documentation/mezzanine/- These boards have siblings on other platforms, the problem scope is similar with BeagleBone "capes":
https://beagleboard.org/capes
Raspberry Pi expansion boards:
https://www.abelectronics.co.uk/products/18/raspberry-pi-expansion-boards
Intel Edison, Galileo, Joule also have expansion boards.Idea: add a driver for the connector itself and tie it in to the device tree with a compatible string. Since the boards are non-discoverable two mechanisms are provided to discover them:
- Add a very simple device tree node with just a compatible string for the board in the node. This will be simple to add from e.g. a boot loader or as an overlay from userspace.
board { compatible = "96boards,secure96"; };- Echo 1 > boardname into a sysfs file to populate the board and echo 0 > boardname to depopulate it. This makes it easy to even switch out expansion boards at runtime, if allowed by the electronics.
Quoted 2 lines
cd
/sys/devices/platform/connector
echo 1 > secure96lscon connector: called
mezzanine_storeon secure96 lscon connector: populate secure96
at24 1-0050: 2048 byte 24c128 EEPROM, writable, 128 bytes/write atmel-ecc 1-0060: configuration zone is unlockedtpm_tis_spispi0.0: 2.0 TPM (device-id0x1B, rev-id 16) (...)What this patch set does not do:
- It does not use device tree or ACPI DSDT or any other hardware decription language to model the contents of the board per se. Instead the boards buses are populated directly with platform devices.
Predictable complaints about this design:
Q: This is not device tree overlays. Why is it not device
tree overlays?A1: Right tool for the job, overlays are complex and the
plan to get it in place seems to be spanning years, this is a few devices on simple busses and it works today. Using this approach I can already work on shaping up drivers for the mezzanine board devices as proved by:
https://marc.info/?l=linux-crypto-vger&m=152820660120590&w=2
https://marc.info/?l=linux-crypto-vger&m=152820662820595&w=2
(...)I can work on drivers for the chips on the Secure96 mezzanine board. It's just an example of what the mezzanine community can do.
Now they are hacking around in userspace instead of doing/reusing kernel drivers for their stuff:
https://github.com/jbech-linaro/secure96This way we can bring developers for these components into the kernel community instead of telling them to wait for some big infrastructure that comes later before they can contribute their stuff.
A2: Overlays does not solve the problem if the system runs
ACPI, and what about if the same connector[s] appear on a server board, servers use ACPI. Also notice that Intel have development boards with non-discoverable expansion boards as well. They just will not use device tree.Quoted 13 lines
A3: Overlays is Big Upfront Design.
https://en.wikipedia.org/wiki/Big_Design_Up_Front
This way of designing things is associated with the (pejorative term) "waterfall model" which is out of fashion as a way of doing development. I think I am not the only one slightly annoyed by the fact that device tree overlays is now starting to look like a very big very upfront design. It's just not possible to get something up and running in small iterative steps with device tree overlays. Instead huge efforts are required and it involves major possible showstoppers and uncertain outcome as indicated by Frank's TODO:
https://elinux.org/Frank's_Evolving_Overlay_ThoughtsI don't agree. This can be broken down into various smaller mostly independent problems. Overlay handling is mostly an orthogonal problem. The exception is that we need to ensure bindings allow a decoupling of upstream of the connector and downstream of the connector so the downstream part can be a reusable overlay. Defining anything while ignoring this known criteria would be a mistake.
The list is roughly like this:
- Connector node binding and probing infrastructure
- GPIO (already done w/ gpio-map binding)
- I2C
- SPI
- Pinmux
- clocks
- OF graph (displays, cameras, etc.)
- USB (re-use the USB connector binding for non-standard connectors)
- Userspace interfaceWe don't have to support every interface from the start. The bindings and corresponding kernel support can be designed 1-by-1 for the most part. Start with something simple like a GPIO LED on a mezzanine. Once the base is functionality is there, the other parts can be worked on incrementally. We can punt any overlay handling to the bootloader initially. That punts all the issues around overlays like designing a userspace interface, where overlays are located (filesystem, passed from bootloader, built into the kernel), when they are loaded, and how to specify which overlays to load. Most of Frank's list is related to these issues.
Quoted 2 lines
Rob
Agreeing with Rob (despite my other reply asking why the current devicetree mechanisms can't be used) that we do have a desire to have the ability to create bindings for connectors - this has been discussed before.
-Frank
cover RFC: Mezzanine handling for 96boards
Quoted 2 lines · Frank Rowand
Agreeing with Rob (despite my other reply asking why the current devicetree mechanisms can't be used)
I think I answer also your comments in my reply to Rob, please check!
Quoted 3 lines
that we do have a desire to
have the ability to create bindings for connectors - this has been discussed before.
Let's create bindings for connectors.
But I have this caveat: let's create a binding for connectors that does not stipulate that its children must be populated using overlays, but could optionally be bound to driver that populate the children any way the OS want to do this.
Yours,
Linus Walleij
cover RFC: Mezzanine handling for 96boards
In reply to Rob HerringQuoted 3 lines · Rob Herring
Quoted 1 line · Linus Walleij
A3: Overlays is Big Upfront Design.
(...)
Quoted 6 lines
I don't agree. This can be broken down into various smaller mostly independent problems. Overlay handling is mostly an orthogonal problem. The exception is that we need to ensure bindings allow a decoupling of upstream of the connector and downstream of the connector so the downstream part can be a reusable overlay. Defining anything while ignoring this known criteria would be a mistake.
Hopefully we can make a connector binding that can be used in any way by the OS: either probe a board populating driver (such as in this patch set) or allow an overlay to be inserted (the aforementioned driver compiled out or inactive) further down the road. I would like to believe the board population problem is a both/and thing, not an either/or thing here.
Could be a simple as a compatible-string for the connector(s). We just keep it dirt simple.
Quoted 4 lines
The list is roughly like this:
- Connector node binding and probing infrastructure
- GPIO (already done w/ gpio-map binding)
I tested that actually, using the connector as nexus. It works fine. The problem I ran into was more practical
(see below).
Quoted 11 lines
- I2C
- SPI
- Pinmux
- clocks
- OF graph (displays, cameras, etc.)
- USB (re-use the USB connector binding for non-standard connectors)
- Userspace interfaceWe don't have to support every interface from the start. The bindings and corresponding kernel support can be designed 1-by-1 for the most part. Start with something simple like a GPIO LED on a mezzanine.
I have that working today, I just didn't go beyond that.
It's because of usability issues. (Described below.)
Quoted 4 lines
Once
the base is functionality is there, the other parts can be worked on incrementally. We can punt any overlay handling to the bootloader initially.
I didn't even do that. I just patched the DTS with a connector and booted it.
Quoted 1 line
From a user point of view whether having a
patched up DTS or a boot loader modifying the DTB at run-time does not really matter as these boards are non-discoverable anyway. The boot loader will now know if they are there or not. What should the user do? Should they send command line arguments to U-Boot to say that we have the secure96 board? Flash different boot loaders depending on what board(s) are connected? That is even more awkward (IMO) than just modifying and redeploying the DTB.
The bright side of this patch set is that the user boots and the kernel is aware of there being a connector and presents sysfs files to populate the boards.
User goes "hm OK I have a secure96":
cd /sys/bus/platform/devices/connector
echo 1 > secure96
And there it populates.
No special boot loaders. No special tools.
Quoted 5 lines
That punts all the issues around overlays like designing a userspace interface, where overlays are located (filesystem, passed from bootloader, built into the kernel), when they are loaded, and how to specify which overlays to load. Most of Frank's list is related to these issues.
And that is where the user (also me) stops short.
Now I want to plug this board. OK download device tree compiler, author a fragment, compile it, compile a special userspace for inserting it into the right node, flash filesystem with that new userpace tool, also do not forget the DTB fragment, parameterize that tool to load the fragment into the connector node. Maybe the user need to change stuff on the fly? Hm then they need a text editor and a DT compiler on the target too, OK things like that can be done.
Admittedly the above is more versatile. Probably awesome when you need to populate a device forest on an FPGA.
But is that even a realistic usecase? And what about the average plug-in board user? If they can do the population by compiling a kernel driver for their board and say it's there and populate it with a simple echo into a sysfs file they will be happy.
It doesn't exclude (IMHO if done right) the possibility for a more complex device tree fragment approach to
be substituted for this later, if it is better for the user. They just stop to compile in that kernel module for populating the board, or do not use the sysfs file.
IMO it is way better than "stop everything and fix fragments first". It's a stopgap thing, if overlays materialize later.
Yours,
Linus Walleij
Rob Herring
maintainercover RFC: Mezzanine handling for 96boards
Quoted 13 lines · Linus Walleij
Quoted 3 lines · Rob Herring
Quoted 1 line · Linus Walleij
A3: Overlays is Big Upfront Design.
(...)
Quoted 6 lines
I don't agree. This can be broken down into various smaller mostly independent problems. Overlay handling is mostly an orthogonal problem. The exception is that we need to ensure bindings allow a decoupling of upstream of the connector and downstream of the connector so the downstream part can be a reusable overlay. Defining anything while ignoring this known criteria would be a mistake.
Quoted 7 lines
Hopefully we can make a connector binding that can be used in any way by the OS: either probe a board populating driver (such as in this patch set) or allow an overlay to be inserted (the aforementioned driver compiled out or inactive) further down the road. I would like to believe the board population problem is a both/and thing, not an either/or thing here.
Certainly both can be supported. The base DT should be the same. I don't think populating via DT needs to be a further down the road thing. We're already further down the road...
Quoted 2 lines
Could be a simple as a compatible-string for the connector(s). We just keep it dirt simple.
Yes, that would be the most simple case. Not really any work to do there, so what's the point? Soon enough, we'll need to support all the things listed below and what we certainly don't need is each connector doing things their own way.
Quoted 25 lines
Quoted 4 lines
The list is roughly like this:
- Connector node binding and probing infrastructure
- GPIO (already done w/ gpio-map binding)I tested that actually, using the connector as nexus. It works fine. The problem I ran into was more practical
(see below).Quoted 11 lines
- I2C
- SPI
- Pinmux
- clocks
- OF graph (displays, cameras, etc.)
- USB (re-use the USB connector binding for non-standard connectors)
- Userspace interfaceWe don't have to support every interface from the start. The bindings and corresponding kernel support can be designed 1-by-1 for the most part. Start with something simple like a GPIO LED on a mezzanine.
I have that working today, I just didn't go beyond that.
It's because of usability issues. (Described below.)
Quoted 7 lines
Quoted 4 lines
Once
the base is functionality is there, the other parts can be worked on incrementally. We can punt any overlay handling to the bootloader initially.I didn't even do that. I just patched the DTS with a connector and booted it.
Yes, or just do that. In any case, don't blame overlays for avoiding more fully defining connector bindings.
Quoted 10 lines
From a user point of view whether having a patched up DTS or a boot loader modifying the DTB at run-time does not really matter as these boards are non-discoverable anyway. The boot loader will now know if they are there or not. What should the user do? Should they send command line arguments to U-Boot to say that we have the secure96 board? Flash different boot loaders depending on what board(s) are connected? That is even more awkward (IMO) than just modifying and redeploying the DTB.
Ideally, it would be as simple as editing a syslinux style menu text file or setting an EFI variable. But yes, we do need to define exactly how that is done. It's something on the todo list for EBBR, but not going to happen until after the 1st release.
Quoted 20 lines
The bright side of this patch set is that the user boots and the kernel is aware of there being a connector and presents sysfs files to populate the boards.
User goes "hm OK I have a secure96":
cd/sys/bus/platform/devices/connector
echo 1 > secure96And there it populates.
No special boot loaders. No special tools.
Quoted 5 lines
That punts all the issues around overlays like designing a userspace interface, where overlays are located (filesystem, passed from bootloader, built into the kernel), when they are loaded, and how to specify which overlays to load. Most of Frank's list is related to these issues.
And that is where the user (also me) stops short.
Quoted 9 lines
Now I want to plug this board. OK download device tree compiler, author a fragment, compile it, compile a special userspace for inserting it into the right node, flash filesystem with that new userpace tool, also do not forget the DTB fragment, parameterize that tool to load the fragment into the connector node. Maybe the user need to change stuff on the fly? Hm then they need a text editor and a DT compiler on the target too, OK things like that can be done.
With your series, they'd just have to edit and rebuild the kernel...
Quoted 9 lines
Admittedly the above is more versatile. Probably awesome when you need to populate a device forest on an FPGA.
But is that even a realistic usecase? And what about the average plug-in board user? If they can do the population by compiling a kernel driver for their board and say it's there and populate it with a simple echo into a sysfs file they will be happy.
Only a kernel developer would think compiling a kernel driver makes for a good usecase.
For users, I think all the board dtbs have to be on the filesystem and the user only has to set which ones to apply (when there is no eeprom to allow doing that automatically). That's essentially what you have on RPi today (though I've got issues with some of their overlays, but that's a whole other can of worms).
The other user usecase I think is custom or prototyping boards. For those cases, we probably do want some run-time interface which could be a kernel driver (as you have) or configfs overlay interface. But I'd start with the first usecase and worry about this one later.
Rob
cover RFC: Mezzanine handling for 96boards
+Pantelis
Quoted 137 lines · Rob Herring
Quoted 13 lines · Linus Walleij
Quoted 3 lines · Rob Herring
Quoted 1 line · Linus Walleij
A3: Overlays is Big Upfront Design.
(...)
Quoted 6 lines
I don't agree. This can be broken down into various smaller mostly independent problems. Overlay handling is mostly an orthogonal problem. The exception is that we need to ensure bindings allow a decoupling of upstream of the connector and downstream of the connector so the downstream part can be a reusable overlay. Defining anything while ignoring this known criteria would be a mistake.
Quoted 7 lines
Hopefully we can make a connector binding that can be used in any way by the OS: either probe a board populating driver (such as in this patch set) or allow an overlay to be inserted (the aforementioned driver compiled out or inactive) further down the road. I would like to believe the board population problem is a both/and thing, not an either/or thing here.
Certainly both can be supported. The base DT should be the same. I don't think populating via DT needs to be a further down the road thing. We're already further down the road...
Quoted 2 lines
Could be a simple as a compatible-string for the connector(s). We just keep it dirt simple.
Yes, that would be the most simple case. Not really any work to do there, so what's the point? Soon enough, we'll need to support all the things listed below and what we certainly don't need is each connector doing things their own way.
Quoted 25 lines
Quoted 4 lines
The list is roughly like this:
- Connector node binding and probing infrastructure
- GPIO (already done w/ gpio-map binding)I tested that actually, using the connector as nexus. It works fine. The problem I ran into was more practical
(see below).Quoted 11 lines
- I2C
- SPI
- Pinmux
- clocks
- OF graph (displays, cameras, etc.)
- USB (re-use the USB connector binding for non-standard connectors)
- Userspace interfaceWe don't have to support every interface from the start. The bindings and corresponding kernel support can be designed 1-by-1 for the most part. Start with something simple like a GPIO LED on a mezzanine.
I have that working today, I just didn't go beyond that.
It's because of usability issues. (Described below.)
Quoted 7 lines
Quoted 4 lines
Once
the base is functionality is there, the other parts can be worked on incrementally. We can punt any overlay handling to the bootloader initially.I didn't even do that. I just patched the DTS with a connector and booted it.
Yes, or just do that. In any case, don't blame overlays for avoiding more fully defining connector bindings.
Quoted 10 lines
From a user point of view whether having a patched up DTS or a boot loader modifying the DTB at run-time does not really matter as these boards are non-discoverable anyway. The boot loader will now know if they are there or not. What should the user do? Should they send command line arguments to U-Boot to say that we have the secure96 board? Flash different boot loaders depending on what board(s) are connected? That is even more awkward (IMO) than just modifying and redeploying the DTB.
Ideally, it would be as simple as editing a syslinux style menu text file or setting an EFI variable. But yes, we do need to define exactly how that is done. It's something on the todo list for EBBR, but not going to happen until after the 1st release.
Quoted 20 lines
The bright side of this patch set is that the user boots and the kernel is aware of there being a connector and presents sysfs files to populate the boards.
User goes "hm OK I have a secure96":
cd/sys/bus/platform/devices/connector
echo 1 > secure96And there it populates.
No special boot loaders. No special tools.
Quoted 5 lines
That punts all the issues around overlays like designing a userspace interface, where overlays are located (filesystem, passed from bootloader, built into the kernel), when they are loaded, and how to specify which overlays to load. Most of Frank's list is related to these issues.
And that is where the user (also me) stops short.
Quoted 9 lines
Now I want to plug this board. OK download device tree compiler, author a fragment, compile it, compile a special userspace for inserting it into the right node, flash filesystem with that new userpace tool, also do not forget the DTB fragment, parameterize that tool to load the fragment into the connector node. Maybe the user need to change stuff on the fly? Hm then they need a text editor and a DT compiler on the target too, OK things like that can be done.
With your series, they'd just have to edit and rebuild the kernel...
Quoted 9 lines
Admittedly the above is more versatile. Probably awesome when you need to populate a device forest on an FPGA.
But is that even a realistic usecase? And what about the average plug-in board user? If they can do the population by compiling a kernel driver for their board and say it's there and populate it with a simple echo into a sysfs file they will be happy.
Only a kernel developer would think compiling a kernel driver makes for a good usecase.
For users, I think all the board dtbs have to be on the filesystem and the user only has to set which ones to apply (when there is no eeprom to allow doing that automatically). That's essentially what you have on RPi today (though I've got issues with some of their overlays, but that's a whole other can of worms).
Quoted 4 lines
The other user usecase I think is custom or prototyping boards. For those cases, we probably do want some run-time interface which could be a kernel driver (as you have) or configfs overlay interface. But I'd start with the first usecase and worry about this one later.
Pantelis had (I believe still have) configs overlay interface already. At least we are keep having it in xilinx soc tree.
Thanks,
Michal
cover RFC: Mezzanine handling for 96boards
In reply to Linus WalleijQuoted 4 lines · Linus Walleij
This is a proposal for how to handle the non-discoverable 96boards plug-in expansion boards called "mezzanines" in the Linux kernel. It is a working RFC series meant for discussion at the moment.
< snip >
Quoted 11 lines
So for that reason, or other predictable statements such as "you're reinventing board files", I'd like to have an open discussion on how to actually support these boards with the mainline kernel and work on device drivers common with other systems now, and not in 2020 when they are already obsolete.
Yeah it is a bit controversial, but what we are doing right now for non-discoverable expansion boards isn't working in my opinion, so I have to throw something out there, and this is it.
< snip >
why can't a devicetree description of the devices on the mezzanine board be used?
I do understand the desire to describe interchangeable mezzanine boards separately from the base devicetree, such as in an overlay. Overlays can be applied today by U-boot before the Linux kernel is booted, so lack of being able to apply an overlay after Linux boot completes is not a blocker.
-Frank