diff --git a/Documentation/devicetree/bindings/README b/Documentation/devicetree/bindings/README new file mode 100644 index 000000000..b818ee824 --- /dev/null +++ b/Documentation/devicetree/bindings/README @@ -0,0 +1,6 @@ + +barebox uses the same devicetree bindings as the kernel. For +the bindings derived from the kernel look in the kernel sources +for reference. + +barebox specific bindings are documented here. diff --git a/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt b/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt new file mode 100644 index 000000000..ed3efcc31 --- /dev/null +++ b/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt @@ -0,0 +1,20 @@ +Freescale i.MX IIM (Ic Identification Module) + +Required properties: + +- compatible: fsl,imx-iim +- reg: physical register base and size + +Optional properties: + +- barebox,provide-mac-address: Provide MAC addresses for ethernet devices. This + can be multiple entries in the form <&phandle bankno fuseofs> to specify a MAC + address to a ethernet device. + +Example: + +iim: iim@83f98000 { + compatible = "fsl,imx51-iim", "fsl,imx-iim"; + reg = <0x83f98000 0x4000>; + barebox,provide-mac-address = <&fec 1 9>; +}; diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c index bb806d78f..956811cc6 100644 --- a/arch/arm/mach-imx/iim.c +++ b/arch/arm/mach-imx/iim.c @@ -223,6 +223,54 @@ static int imx_iim_add_bank(struct device_d *dev, void __iomem *base, int num) return devfs_create(cdev); } +#if IS_ENABLED(CONFIG_OFDEVICE) + +/* + * a single MAC address reference has the form + * <&phandle iim-bank-no offset>, so three cells + */ +#define MAC_ADDRESS_PROPLEN (3 * sizeof(__be32)) + +static void imx_iim_init_dt(struct device_d *dev) +{ + char mac[6]; + const __be32 *prop; + struct device_node *node = dev->device_node; + int len, ret; + + if (!node) + return; + + prop = of_get_property(node, "barebox,provide-mac-address", &len); + if (!prop) + return; + + while (len >= MAC_ADDRESS_PROPLEN) { + struct device_node *rnode; + uint32_t phandle, bank, offset; + + phandle = be32_to_cpup(prop++); + + rnode = of_find_node_by_phandle(phandle); + bank = be32_to_cpup(prop++); + offset = be32_to_cpup(prop++); + + ret = imx_iim_read(bank, offset, mac, 6); + if (ret == 6) { + of_eth_register_ethaddr(rnode, mac); + } else { + dev_err(dev, "cannot read: %s\n", strerror(-ret)); + } + + len -= MAC_ADDRESS_PROPLEN; + } +} +#else +static inline void imx_iim_init_dt(struct device_d *dev) +{ +} +#endif + static int imx_iim_probe(struct device_d *dev) { int i; @@ -234,6 +282,7 @@ static int imx_iim_probe(struct device_d *dev) imx_iim_add_bank(dev, base, i); } + imx_iim_init_dt(dev); if (IS_ENABLED(CONFIG_IMX_IIM_FUSE_BLOW)) dev_add_param_bool(dev, "permanent_write_enable", @@ -245,9 +294,18 @@ static int imx_iim_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id imx_iim_dt_ids[] = { + { + .compatible = "fsl,imx-iim", + }, { + /* sentinel */ + } +}; + static struct driver_d imx_iim_driver = { .name = DRIVERNAME, .probe = imx_iim_probe, + .of_compatible = DRV_OF_COMPAT(imx_iim_dt_ids), }; static int imx_iim_init(void)