mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 00/13] prepare Protonic board code for mainline
@ 2020-08-05 10:16 Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 01/13] ARM: dts: imx6q-prti6q: fix PHY register Oleksij Rempel
                   ` (13 more replies)
  0 siblings, 14 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

changes v2:
- add power init support for KvG boards
- spell fixes
- do not print error on probe exit
- add of_console_get_by_alias() helper
- free requested gpio array
- exit fec init only in case of PROBE_DEFERED

This patch series is a preparation and actual Protonic board code.
Following changes was made in the main code:
- register DT root node as device to make it possible to loade board
  code as usual driver
- provide helpers to read ethernet mac from nvmem cell register in a
  devicetree.
- provide barebox-serial driver which should be a nvmem cell consumer
  and
  serial-number DT property provider.
- provide gpio helper to read gpio based board revision.

Oleksij Rempel (13):
  ARM: dts: imx6q-prti6q: fix PHY register
  ARM: dts: imx6: vicut1: fix network support
  of: base: register DT root as device
  ARM: embest-riotboard: port board file to the driver model
  net: port nvmem_get_mac_address() from linux kernel
  of: of_net: sync of_get_mac_address() with latest kernel version
  net: fec_imx: use of_get_mac_address() to get mac address out of DT
  of: of_device_get_match_compatible() helper
  gpiolib: add gpio_array_to_id helper to get ID out of GPIO array
  common: console_common: add of_console_get_by_alias() helper
  ARM: protonic-imx6: port Protonic specific board code
  of: add barebox-serial driver
  ARM: dts: imx6q-prti6q: add barebox,serial-number node

 arch/arm/boards/embest-riotboard/board.c |  18 +-
 arch/arm/boards/protonic-imx6/Makefile   |   1 +
 arch/arm/boards/protonic-imx6/board.c    | 860 +++++++++++++++++++++++
 arch/arm/dts/imx6q-prti6q.dts            |   4 +-
 arch/arm/dts/imx6q-vicut1.dts            |  18 +-
 arch/arm/dts/imx6qdl-prti6q.dtsi         |   6 +
 common/console_common.c                  |  18 +
 drivers/gpio/gpiolib.c                   |  31 +
 drivers/net/fec_imx.c                    |  14 +
 drivers/of/Makefile                      |   2 +-
 drivers/of/barebox_serial.c              | 113 +++
 drivers/of/base.c                        |   5 +
 drivers/of/device.c                      |  12 +
 drivers/of/of_net.c                      |  63 +-
 include/console.h                        |   1 +
 include/gpio.h                           |   5 +
 include/net.h                            |   4 +
 include/of_device.h                      |   6 +
 net/eth.c                                |  38 +
 19 files changed, 1197 insertions(+), 22 deletions(-)
 create mode 100644 arch/arm/boards/protonic-imx6/board.c
 create mode 100644 drivers/of/barebox_serial.c

-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 01/13] ARM: dts: imx6q-prti6q: fix PHY register
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 02/13] ARM: dts: imx6: vicut1: fix network support Oleksij Rempel
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 arch/arm/dts/imx6q-prti6q.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/dts/imx6q-prti6q.dts b/arch/arm/dts/imx6q-prti6q.dts
index f0469d5f62..76bb4d53d3 100644
--- a/arch/arm/dts/imx6q-prti6q.dts
+++ b/arch/arm/dts/imx6q-prti6q.dts
@@ -225,8 +225,8 @@
 		#size-cells = <0>;
 
 		/* Microchip KSZ9031RNX PHY */
-		rgmii_phy: ethernet-phy@0 {
-			reg = <0>;
+		rgmii_phy: ethernet-phy@4 {
+			reg = <4>;
 			interrupts-extended = <&gpio1 28 IRQ_TYPE_LEVEL_LOW>;
 			reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
 			reset-assert-us = <10000>;
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 02/13] ARM: dts: imx6: vicut1: fix network support
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 01/13] ARM: dts: imx6q-prti6q: fix PHY register Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 03/13] of: base: register DT root as device Oleksij Rempel
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Create the PHY node with properly configured phy-mode and reset lines.
In this case we will not need board specific PHY fixups.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 arch/arm/dts/imx6q-vicut1.dts | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/arm/dts/imx6q-vicut1.dts b/arch/arm/dts/imx6q-vicut1.dts
index 9f60ed1ac2..9747b3c62e 100644
--- a/arch/arm/dts/imx6q-vicut1.dts
+++ b/arch/arm/dts/imx6q-vicut1.dts
@@ -19,9 +19,23 @@
 &fec {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_enet>;
-	phy-mode = "rgmii";
-	/* phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; */
+	phy-mode = "rgmii-id";
+	phy-handle = <&rgmii_phy>;
 	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* Microchip KSZ9031RNX PHY */
+		rgmii_phy: ethernet-phy@4 {
+			reg = <4>;
+			interrupts-extended = <&gpio1 28 IRQ_TYPE_LEVEL_LOW>;
+			reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+			reset-assert-us = <10000>;
+			reset-deassert-us = <300>;
+		};
+	};
 };
 
 &iomuxc {
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 03/13] of: base: register DT root as device
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 01/13] ARM: dts: imx6q-prti6q: fix PHY register Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 02/13] ARM: dts: imx6: vicut1: fix network support Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 04/13] ARM: embest-riotboard: port board file to the driver model Oleksij Rempel
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

A usual board file contains at least one of_machine_is_compatible().
Some of the have a rather long list with complicated version logic.

To avoid own implementation for driver management, register the root node
of device tree as platform device. So, the main platform bus can attach
proper board driver. After this patch a typical board.c file can reuse
existing driver infrastructure.

After this patch, you will be able to see all registered board drivers
with drvinfo as fallow:
...
board-embest-riot
board-protonic-imx6
    machine.of
...

With devinfo, you'll be able to get some board specific information,
if this is implemented:
barebox@Protonic PRTI6Q board:/ devinfo machine.of
Driver: board-protonic-imx6
Bus: platform
Parameters:
  boardid: 0 (type: uint32)
  boardrev: 1 (type: uint32)

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/of/base.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 4c633bcd49..c48bf7a7fb 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2133,6 +2133,7 @@ static void of_probe_memory(void)
 int of_probe(void)
 {
 	struct device_node *firmware;
+	struct device_d *dev;
 
 	if(!root_node)
 		return -ENODEV;
@@ -2149,6 +2150,10 @@ int of_probe(void)
 	if (firmware)
 		of_platform_populate(firmware, NULL, NULL);
 
+	dev = of_platform_device_create(root_node, NULL);
+	if (dev)
+		dev_set_name(dev, "%s.of", "machine");
+
 	of_clk_init(root_node, NULL);
 	of_platform_populate(root_node, of_default_bus_match_table, NULL);
 
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 04/13] ARM: embest-riotboard: port board file to the driver model
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (2 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 03/13] of: base: register DT root as device Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 05/13] net: port nvmem_get_mac_address() from linux kernel Oleksij Rempel
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

This patch can be used as example for the new board-driver
functionality.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 arch/arm/boards/embest-riotboard/board.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boards/embest-riotboard/board.c b/arch/arm/boards/embest-riotboard/board.c
index 2e0cc9f0ab..746ecf0562 100644
--- a/arch/arm/boards/embest-riotboard/board.c
+++ b/arch/arm/boards/embest-riotboard/board.c
@@ -51,11 +51,8 @@ static int ar8035_phy_fixup(struct phy_device *dev)
 	return 0;
 }
 
-static int riotboard_device_init(void)
+static int riotboard_probe(struct device_d *dev)
 {
-	if (!of_machine_is_compatible("riot,imx6s-riotboard"))
-		return 0;
-
 	phy_register_fixup_for_uid(0x004dd072, 0xffffffef, ar8035_phy_fixup);
 
 	imx6_bbu_internal_mmc_register_handler("emmc", "/dev/mmc3.barebox",
@@ -65,4 +62,15 @@ static int riotboard_device_init(void)
 
 	return 0;
 }
-device_initcall(riotboard_device_init);
+
+static const struct of_device_id riotboard_of_match[] = {
+	{ .compatible = "riot,imx6s-riotboard" },
+	{},
+};
+
+static struct driver_d riotboard_driver = {
+	.name = "board-embest-riot",
+	.probe = riotboard_probe,
+	.of_compatible = DRV_OF_COMPAT(riotboard_of_match),
+};
+device_platform_driver(riotboard_driver);
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 05/13] net: port nvmem_get_mac_address() from linux kernel
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (3 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 04/13] ARM: embest-riotboard: port board file to the driver model Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 06/13] of: of_net: sync of_get_mac_address() with latest kernel version Oleksij Rempel
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Port nvmem help to read mac-address from nvmem cell linked to the
ethernet node. This function was ported from kernel 5.8-rc1.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 include/net.h |  4 ++++
 net/eth.c     | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/include/net.h b/include/net.h
index 54db8a179a..a5bfe9e7f8 100644
--- a/include/net.h
+++ b/include/net.h
@@ -97,9 +97,13 @@ static inline void of_eth_register_ethaddr(struct device_node *node,
 		const char *ethaddr)
 {
 }
+static inline int nvmem_get_mac_address(struct device_d *dev, void *addrbuf)
+{
+}
 #else
 void eth_register_ethaddr(int ethid, const char *ethaddr);
 void of_eth_register_ethaddr(struct device_node *node, const char *ethaddr);
+int nvmem_get_mac_address(struct device_d *dev, void *addrbuf);
 #endif
 /*
  *	Ethernet header
diff --git a/net/eth.c b/net/eth.c
index e3d0d06efe..b33ef5fe1f 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -29,6 +29,7 @@
 #include <globalvar.h>
 #include <environment.h>
 #include <linux/ctype.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/stat.h>
 
 static uint64_t last_link_check;
@@ -152,6 +153,43 @@ void of_eth_register_ethaddr(struct device_node *node, const char *ethaddr)
 	list_add_tail(&addr->list, &ethaddr_list);
 }
 
+/**
+ * Obtain the MAC address from an nvmem cell named 'mac-address' associated
+ * with given device.
+ *
+ * @dev:	Device with which the mac-address cell is associated.
+ * @addrbuf:	Buffer to which the MAC address will be copied on success.
+ *
+ * Returns 0 on success or a negative error number on failure.
+ */
+int nvmem_get_mac_address(struct device_d *dev, void *addrbuf)
+{
+	struct nvmem_cell *cell;
+	const void *mac;
+	size_t len;
+
+	cell = nvmem_cell_get(dev, "mac-address");
+	if (IS_ERR(cell))
+		return PTR_ERR(cell);
+
+	mac = nvmem_cell_read(cell, &len);
+	nvmem_cell_put(cell);
+
+	if (IS_ERR(mac))
+		return PTR_ERR(mac);
+
+	if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
+		kfree(mac);
+		return -EINVAL;
+	}
+
+	memcpy(addrbuf, mac, ETH_ALEN);
+	kfree(mac);
+
+	return 0;
+}
+EXPORT_SYMBOL(nvmem_get_mac_address);
+
 struct eth_device *eth_get_byname(const char *ethname)
 {
 	struct eth_device *edev;
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 06/13] of: of_net: sync of_get_mac_address() with latest kernel version
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (4 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 05/13] net: port nvmem_get_mac_address() from linux kernel Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 07/13] net: fec_imx: use of_get_mac_address() to get mac address out of DT Oleksij Rempel
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Sync of_get_mac_address() with kernel 5.8-rc1 do add nvmem cell support

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/of/of_net.c | 63 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 51 insertions(+), 12 deletions(-)

diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c
index cee4597195..946c4a4352 100644
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -67,12 +67,45 @@ int of_get_phy_mode(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_get_phy_mode);
 
+static const void *of_get_mac_addr(struct device_node *np, const char *name)
+{
+	struct property *pp = of_find_property(np, name, NULL);
+
+	if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value))
+		return pp->value;
+	return NULL;
+}
+
+static const void *of_get_mac_addr_nvmem(struct device_node *np)
+{
+	int ret;
+	const void *mac;
+	u8 nvmem_mac[ETH_ALEN];
+	struct device_d *dev = of_find_device_by_node(np);
+
+	if (!dev)
+		return ERR_PTR(-ENODEV);
+
+	ret = nvmem_get_mac_address(dev, &nvmem_mac);
+	if (ret) {
+		return ERR_PTR(ret);
+	}
+
+	mac = kmemdup(nvmem_mac, ETH_ALEN, GFP_KERNEL);
+	if (!mac)
+		return ERR_PTR(-ENOMEM);
+
+	return mac;
+}
+
 /**
  * Search the device tree for the best MAC address to use.  'mac-address' is
  * checked first, because that is supposed to contain to "most recent" MAC
  * address. If that isn't set, then 'local-mac-address' is checked next,
- * because that is the default address.  If that isn't set, then the obsolete
- * 'address' is checked, just in case we're using an old device tree.
+ * because that is the default address. If that isn't set, then the obsolete
+ * 'address' is checked, just in case we're using an old device tree. If any
+ * of the above isn't set, then try to get MAC address from nvmem cell named
+ * 'mac-address'.
  *
  * Note that the 'address' property is supposed to contain a virtual address of
  * the register set, but some DTS files have redefined that property to be the
@@ -84,19 +117,25 @@ EXPORT_SYMBOL_GPL(of_get_phy_mode);
  * addresses.  Some older U-Boots only initialized 'local-mac-address'.  In
  * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
  * but is all zeros.
+ *
+ * Return: Will be a valid pointer on success and ERR_PTR in case of error.
 */
 const void *of_get_mac_address(struct device_node *np)
 {
-	const void *p;
-	int len, i;
-	const char *str[] = { "mac-address", "local-mac-address", "address" };
-
-	for (i = 0; i < ARRAY_SIZE(str); i++) {
-		p = of_get_property(np, str[i], &len);
-		if (p && (len == 6) && is_valid_ether_addr(p))
-			return p;
-	}
+	const void *addr;
 
-	return NULL;
+	addr = of_get_mac_addr(np, "mac-address");
+	if (addr)
+		return addr;
+
+	addr = of_get_mac_addr(np, "local-mac-address");
+	if (addr)
+		return addr;
+
+	addr = of_get_mac_addr(np, "address");
+	if (addr)
+		return addr;
+
+	return of_get_mac_addr_nvmem(np);
 }
 EXPORT_SYMBOL(of_get_mac_address);
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 07/13] net: fec_imx: use of_get_mac_address() to get mac address out of DT
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (5 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 06/13] of: of_net: sync of_get_mac_address() with latest kernel version Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 08/13] of: of_device_get_match_compatible() helper Oleksij Rempel
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

A mac address can be provided by the DT over nvmem cell. Start to use
of_get_mac_address() since it will be able to read nvmem cell for us.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/net/fec_imx.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 0c2d600d12..65dbb1d9c0 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -628,6 +628,7 @@ static void fec_free_receive_packets(struct fec_priv *fec, int count, int size)
 static int fec_probe_dt(struct device_d *dev, struct fec_priv *fec)
 {
 	struct device_node *mdiobus;
+	const char *mac_addr;
 	int ret;
 
 	ret = of_get_phy_mode(dev->device_node);
@@ -640,6 +641,19 @@ static int fec_probe_dt(struct device_d *dev, struct fec_priv *fec)
 	if (mdiobus)
 		fec->miibus.dev.device_node = mdiobus;
 
+	mac_addr = of_get_mac_address(dev->device_node);
+	if (IS_ERR(mac_addr)) {
+		if (PTR_ERR(mac_addr) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		else
+			dev_err(fec->dev, "Failed on of_get_mac_address: %li\n",
+				PTR_ERR(mac_addr));
+	} else {
+		of_eth_register_ethaddr(dev->device_node, mac_addr);
+
+		kfree(mac_addr);
+	}
+
 	return 0;
 }
 #else
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 08/13] of: of_device_get_match_compatible() helper
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (6 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 07/13] net: fec_imx: use of_get_mac_address() to get mac address out of DT Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 09/13] gpiolib: add gpio_array_to_id helper to get ID out of GPIO array Oleksij Rempel
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Some times we need to know, against which compatible did the driver
was registered. So, instead of coding it in the driver, add generic
helper for all drivers.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/of/device.c | 12 ++++++++++++
 include/of_device.h |  6 ++++++
 2 files changed, 18 insertions(+)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 67a67bd565..b3f522e1fa 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -31,3 +31,15 @@ const void *of_device_get_match_data(const struct device_d *dev)
 	return match->data;
 }
 EXPORT_SYMBOL(of_device_get_match_data);
+
+const char *of_device_get_match_compatible(const struct device_d *dev)
+{
+	const struct of_device_id *match;
+
+	match = of_match_device(dev->driver->of_compatible, dev);
+	if (!match)
+		return NULL;
+
+	return match->compatible;
+}
+EXPORT_SYMBOL(of_device_get_match_compatible);
diff --git a/include/of_device.h b/include/of_device.h
index 244f5fcbbb..cef6d5b5cc 100644
--- a/include/of_device.h
+++ b/include/of_device.h
@@ -22,6 +22,7 @@ static inline int of_driver_match_device(struct device_d *dev,
 }
 
 extern const void *of_device_get_match_data(const struct device_d *dev);
+extern const char *of_device_get_match_compatible(const struct device_d *dev);
 
 #else /* CONFIG_OFTREE */
 
@@ -36,6 +37,11 @@ static inline const void *of_device_get_match_data(const struct device_d *dev)
 	return NULL;
 }
 
+static inline const char *of_device_get_match_compatible(const struct device_d *dev)
+{
+	return NULL;
+}
+
 static inline const struct of_device_id *__of_match_device(
 		const struct of_device_id *matches, const struct device_d *dev)
 {
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 09/13] gpiolib: add gpio_array_to_id helper to get ID out of GPIO array
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (7 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 08/13] of: of_device_get_match_compatible() helper Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 10/13] common: console_common: add of_console_get_by_alias() helper Oleksij Rempel
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Some boards provide a board version and/or ID coded by pull-up/down
resistors connected to the gpio pins (or pins which can be multiplexed
at some point as gpio). In this case every one implements own gpio id
reader function.

To avoid it, provide the common helper function to extract a value out
of provided gpio array.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/gpio/gpiolib.c | 31 +++++++++++++++++++++++++++++++
 include/gpio.h         |  5 +++++
 2 files changed, 36 insertions(+)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 27674af54c..556b82fea3 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -381,6 +381,37 @@ void gpio_free_array(const struct gpio *array, size_t num)
 }
 EXPORT_SYMBOL_GPL(gpio_free_array);
 
+int gpio_array_to_id(const struct gpio *array, size_t num, u32 *val)
+{
+	u32 id = 0;
+	int ret, i;
+
+	if (num > 32)
+		return -EOVERFLOW;
+
+	ret = gpio_request_array(array, num);
+	if (ret)
+		return ret;
+
+	/* Wait until logic level will be stable */
+	udelay(5);
+	for (i = 0; i < num; i++) {
+		ret = gpio_is_active(array[i].gpio);
+		if (ret < 0)
+			goto free_array;
+
+		id |= ret << i;
+	}
+
+	*val = id;
+	ret = 0;
+
+free_array:
+	gpio_free_array(array, num);
+	return ret;
+}
+EXPORT_SYMBOL(gpio_array_to_id);
+
 static int gpiochip_find_base(int start, int ngpio)
 {
 	int i;
diff --git a/include/gpio.h b/include/gpio.h
index 98c5b93ba2..81beb47309 100644
--- a/include/gpio.h
+++ b/include/gpio.h
@@ -145,6 +145,10 @@ static inline void gpio_free_array(const struct gpio *array, size_t num)
 	/* GPIO can never have been requested */
 	WARN_ON(1);
 }
+static inline int gpio_array_to_id(const struct gpio *array, size_t num, u32 *val)
+{
+	return -EINVAL;
+}
 #else
 int gpio_request(unsigned gpio, const char *label);
 int gpio_find_by_name(const char *name);
@@ -153,6 +157,7 @@ void gpio_free(unsigned gpio);
 int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
 int gpio_request_array(const struct gpio *array, size_t num);
 void gpio_free_array(const struct gpio *array, size_t num);
+int gpio_array_to_id(const struct gpio *array, size_t num, u32 *val);
 #endif
 
 struct gpio_chip;
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 10/13] common: console_common: add of_console_get_by_alias() helper
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (8 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 09/13] gpiolib: add gpio_array_to_id helper to get ID out of GPIO array Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 11/13] ARM: protonic-imx6: port Protonic specific board code Oleksij Rempel
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Add helper function to get console device by devicetree alias

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 common/console_common.c | 18 ++++++++++++++++++
 include/console.h       |  1 +
 2 files changed, 19 insertions(+)

diff --git a/common/console_common.c b/common/console_common.c
index a174c2deed..8cd57e623d 100644
--- a/common/console_common.c
+++ b/common/console_common.c
@@ -23,6 +23,7 @@
 #include <environment.h>
 #include <globalvar.h>
 #include <magicvar.h>
+#include <of.h>
 #include <password.h>
 #include <clock.h>
 #include <malloc.h>
@@ -323,6 +324,23 @@ struct console_device *console_get_first_active(void)
 }
 EXPORT_SYMBOL(console_get_first_active);
 
+struct console_device *of_console_get_by_alias(const char *alias)
+{
+	struct device_node *node;
+	struct device_d *dev;
+
+	node = of_find_node_by_alias(NULL, alias);
+	if (!node)
+		return NULL;
+
+	dev = of_find_device_by_node(node);
+	if (!dev)
+		return NULL;
+
+	return console_get_by_dev(dev);
+}
+EXPORT_SYMBOL(of_console_get_by_alias);
+
 #endif /* !CONFIG_CONSOLE_NONE */
 
 int dprintf(int file, const char *fmt, ...)
diff --git a/include/console.h b/include/console.h
index 5b5c037026..a71d0da42e 100644
--- a/include/console.h
+++ b/include/console.h
@@ -87,6 +87,7 @@ int console_unregister(struct console_device *cdev);
 
 struct console_device *console_get_by_dev(struct device_d *dev);
 struct console_device *console_get_by_name(const char *name);
+struct console_device *of_console_get_by_alias(const char *alias);
 
 extern struct list_head console_list;
 #define for_each_console(console) list_for_each_entry(console, &console_list, list)
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 11/13] ARM: protonic-imx6: port Protonic specific board code
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (9 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 10/13] common: console_common: add of_console_get_by_alias() helper Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-05 10:16 ` [PATCH v2 12/13] of: add barebox-serial driver Oleksij Rempel
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 arch/arm/boards/protonic-imx6/Makefile |   1 +
 arch/arm/boards/protonic-imx6/board.c  | 860 +++++++++++++++++++++++++
 2 files changed, 861 insertions(+)
 create mode 100644 arch/arm/boards/protonic-imx6/board.c

diff --git a/arch/arm/boards/protonic-imx6/Makefile b/arch/arm/boards/protonic-imx6/Makefile
index b08c4a93ca..01c7a259e9 100644
--- a/arch/arm/boards/protonic-imx6/Makefile
+++ b/arch/arm/boards/protonic-imx6/Makefile
@@ -1 +1,2 @@
+obj-y += board.o
 lwl-y += lowlevel.o
diff --git a/arch/arm/boards/protonic-imx6/board.c b/arch/arm/boards/protonic-imx6/board.c
new file mode 100644
index 0000000000..6def2174a8
--- /dev/null
+++ b/arch/arm/boards/protonic-imx6/board.c
@@ -0,0 +1,860 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: 2012 Steffen Trumtrar, Pengutronix
+// SPDX-FileCopyrightText: 2014 Protonic Holland
+// SPDX-FileCopyrightText: 2020 Oleksij Rempel, Pengutronix
+
+#include <bbu.h>
+#include <common.h>
+#include <gpio.h>
+#include <mach/bbu.h>
+#include <mach/imx6.h>
+#include <of_device.h>
+
+#define GPIO_HW_REV_ID  {\
+	{IMX_GPIO_NR(2, 8), GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, "rev_id0"}, \
+	{IMX_GPIO_NR(2, 9), GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, "rev_id1"}, \
+	{IMX_GPIO_NR(2, 10), GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, "rev_id2"} \
+}
+
+#define GPIO_HW_TYPE_ID  {\
+	{IMX_GPIO_NR(2, 11), GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, "hw_id0"}, \
+	{IMX_GPIO_NR(2, 12), GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, "hw_id1"}, \
+	{IMX_GPIO_NR(2, 13), GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, "hw_id2"}, \
+	{IMX_GPIO_NR(2, 14), GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, "hw_id3"}, \
+	{IMX_GPIO_NR(2, 15), GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, "hw_id4"} \
+}
+
+enum {
+	HW_TYPE_PRTI6Q = 0,
+	HW_TYPE_PRTWD2 = 1,
+	HW_TYPE_ALTI6S = 2,
+	HW_TYPE_VICUT1 = 4,
+	HW_TYPE_ALTI6P = 6,
+	HW_TYPE_PRTMVT = 8,
+	HW_TYPE_PRTI6G = 10,
+	HW_TYPE_PRTRVT = 12,
+	HW_TYPE_VICUT2 = 16,
+	HW_TYPE_PLYM2M = 20,
+	HW_TYPE_PRTVT7 = 22,
+	HW_TYPE_LANMCU = 23,
+	HW_TYPE_PLYBAS = 24,
+	HW_TYPE_VICTGO = 28,
+};
+
+enum prt_imx6_kvg_pw_mode {
+	PW_MODE_KVG_WITH_YACO = 0,
+	PW_MODE_KVG_NEW = 1,
+	PW_MODE_KUBOTA = 2,
+};
+
+/* board specific flags */
+#define PRT_IMX6_BOOTSRC_EMMC		BIT(1)
+#define PRT_IMX6_BOOTSRC_SPI_NOR	BIT(0)
+
+struct prt_imx6_priv;
+struct prt_machine_data {
+	unsigned int hw_id;
+	unsigned int hw_rev;
+	unsigned int i2c_addr;
+	unsigned int i2c_adapter;
+	unsigned int flags;
+	int (*init)(struct prt_imx6_priv *priv);
+};
+
+struct prt_imx6_priv {
+	struct device_d *dev;
+	const struct prt_machine_data *dcfg;
+	unsigned int hw_id;
+	unsigned int hw_rev;
+};
+
+struct prt_imx6_kvg_yaco {
+	char serial[ARRAY_SIZE("serialxx")];
+};
+
+#define GPIO_DIP1_FB   IMX_GPIO_NR(4, 18)
+#define GPIO_FORCE_ON1 IMX_GPIO_NR(2, 30)
+#define GPIO_ON1_CTRL  IMX_GPIO_NR(4, 21)
+#define GPIO_ON2_CTRL  IMX_GPIO_NR(4, 22)
+
+static const struct gpio prt_imx6_kvg_gpios[] = {
+	{
+		.gpio = GPIO_DIP1_FB,
+		.flags = GPIOF_IN,
+		.label = "DIP1_FB",
+	},
+	{
+		.gpio = GPIO_FORCE_ON1,
+		.flags = GPIOF_OUT_INIT_HIGH,
+		.label = "FORCE_ON1",
+	},
+	{
+		.gpio = GPIO_ON1_CTRL,
+		.flags = GPIOF_IN,
+		.label = "ON1_CTRL",
+	},
+	{
+		.gpio = GPIO_ON2_CTRL,
+		.flags = GPIOF_IN,
+		.label = "ON2_CTRL",
+	},
+};
+
+static struct device_d *prt_imx6_func_add(struct prt_imx6_priv *priv,
+					  const char *name, void *data,
+					  size_t size)
+{
+	struct device_d *dev;
+	int ret;
+
+	dev = device_alloc(name, DEVICE_ID_DYNAMIC);
+	dev->parent = priv->dev;
+	device_add_data(dev, data, size);
+
+	ret = platform_device_register(dev);
+	if (ret)
+		return NULL;
+
+	return dev;
+}
+
+/* Functions which should be done later: */
+/* KvG YaCO power init sequence depends on console which is probed later */
+static int prt_imx6_yaco_set_kvg_power_mode(struct device_d *dev)
+{
+	static const char command[] = "{\"command\":\"mode\",\"value\":\"kvg\",\"on2\":true}";
+	struct prt_imx6_kvg_yaco *yaco = dev->platform_data;
+	struct console_device *yccon;
+	int ret;
+
+	yccon = of_console_get_by_alias(yaco->serial);
+	if (!yccon) {
+		dev_dbg(dev, "Cant find the %s node, try later\n", yaco->serial);
+		return -EPROBE_DEFER;
+	}
+
+	ret = console_set_baudrate(yccon, 115200);
+	if (ret)
+		goto exit_yaco_set_kvg_power_mode;
+
+	yccon->puts(yccon, command, sizeof(command));
+
+	dev_info(dev, "Send YaCO power init sequence to the %s\n", yaco->serial);
+	return 0;
+
+exit_yaco_set_kvg_power_mode:
+	dev_err(dev, "Failed to set YaCO pw mode: %i", ret);
+
+	return ret;
+}
+
+static struct platform_device_id prt_imx6_init_ids[] = {
+	{ .name = "kvg_yaco_pwinit" },
+	{ /* sentinel */ },
+};
+
+static struct driver_d prt_imx6_init_driver = {
+	.probe = prt_imx6_yaco_set_kvg_power_mode,
+	.name = "pwinit_drv",
+	.id_table = prt_imx6_init_ids,
+};
+device_platform_driver(prt_imx6_init_driver);
+
+static int prt_imx6_nvmem_link_serial(struct prt_imx6_priv *priv,
+				      struct device_node *root,
+				      struct device_node *nvmem_node)
+{
+	struct device_node *ser_node;
+	phandle nvmem_handle;
+	int ret;
+
+	/* Ignore non-barebox DTs */
+	if (root != of_get_root_node())
+		return 0;
+
+	ser_node = of_find_compatible_node(root, NULL, "barebox,serial-number");
+	if (!ser_node) {
+		dev_err(priv->dev, "Cant find the serial node\n");
+		return -ENODEV;
+	}
+
+	nvmem_handle = of_node_create_phandle(nvmem_node);
+
+	ret = of_property_write_u32(ser_node, "nvmem-cells", nvmem_handle);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int prt_imx6_nvmem_link_fec(struct prt_imx6_priv *priv,
+				   struct device_node *root,
+				   struct device_node *nvmem_node)
+{
+	struct device_node *fec_node;
+	phandle nvmem_handle;
+	int ret;
+
+	fec_node = of_find_node_by_alias(root, "ethernet0");
+	if (!fec_node) {
+		dev_err(priv->dev, "Cant find the fec node\n");
+		return -ENODEV;
+	}
+
+	nvmem_handle = of_node_create_phandle(nvmem_node);
+
+	ret = of_property_write_u32(fec_node, "nvmem-cells", nvmem_handle);
+	if (ret)
+		return ret;
+
+	ret = of_property_write_string(fec_node, "nvmem-cell-names",
+				       "mac-address");
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static struct device_node *
+prt_imx6_create_nvmem_cells(struct prt_imx6_priv *priv,
+			    struct device_node *nvmem_node,
+			    const char *node_name, size_t offset, size_t size)
+{
+	struct device_node *nvcell_node;
+	int na, ns, len = 0;
+	int ret;
+	u8 *tmp;
+
+	nvcell_node = of_create_node(nvmem_node, node_name);
+	if (!nvcell_node) {
+		dev_err(priv->dev, "Failed to create %s cell\n", node_name);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	na = of_n_addr_cells(nvcell_node);
+	ns = of_n_size_cells(nvcell_node);
+	tmp = xzalloc((na + ns) * 4);
+
+	of_write_number(tmp + len, offset, na);
+	len += na * 4;
+	of_write_number(tmp + len, size, ns);
+	len += ns * 4;
+
+	ret = of_set_property(nvcell_node, "reg", tmp, len, 1);
+	kfree(tmp);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return nvcell_node;
+}
+
+static int prt_imx6_rfid_fixup(struct prt_imx6_priv *priv,
+			       struct device_node *root)
+{
+	const struct prt_machine_data *dcfg = priv->dcfg;
+	struct device_node *node, *i2c_node, *tmp_node;
+	char *eeprom_node_name, *alias;
+	int na, ns, len = 0;
+	int ret;
+	u8 *tmp;
+
+	alias = basprintf("i2c%d", dcfg->i2c_adapter);
+	if (!alias) {
+		ret = -ENOMEM;
+		goto exit_error;
+	}
+
+	i2c_node = of_find_node_by_alias(root, alias);
+	if (!i2c_node) {
+		dev_err(priv->dev, "Unsupported i2c adapter\n");
+		ret = -ENODEV;
+		goto free_alias;
+	}
+
+	eeprom_node_name = basprintf("/eeprom@%x", dcfg->i2c_addr);
+	if (!eeprom_node_name) {
+		ret = -ENOMEM;
+		goto free_alias;
+	}
+
+	node = of_create_node(i2c_node, eeprom_node_name);
+	if (!node) {
+		dev_err(priv->dev, "Failed to create node %s\n",
+			eeprom_node_name);
+		ret = -ENOMEM;
+		goto free_eeprom;
+	}
+
+	ret = of_property_write_string(node, "compatible", "atmel,24c256");
+	if (ret)
+		goto free_eeprom;
+
+	na = of_n_addr_cells(node);
+	ns = of_n_size_cells(node);
+	tmp = xzalloc((na + ns) * 4);
+
+	of_write_number(tmp + len, dcfg->i2c_addr, na);
+	len += na * 4;
+	of_write_number(tmp + len, 0, ns);
+	len += ns * 4;
+
+	ret = of_set_property(node, "reg", tmp, len, 1);
+	kfree(tmp);
+	if (ret)
+		goto free_eeprom;
+
+	ret = of_property_write_u32(node, "#size-cells", 1);
+	if (ret)
+		goto free_eeprom;
+
+	ret = of_property_write_u32(node, "#address-cells", 1);
+	if (ret)
+		goto free_eeprom;
+
+	tmp_node = prt_imx6_create_nvmem_cells(priv, node, "/mac-address@0",
+					       0x6000, 6);
+	if (IS_ERR(tmp_node)) {
+		ret = PTR_ERR(tmp_node);
+		goto free_eeprom;
+	}
+
+	ret = prt_imx6_nvmem_link_fec(priv, root, tmp_node);
+	if (ret)
+		goto free_eeprom;
+
+	tmp_node = prt_imx6_create_nvmem_cells(priv, node, "/serial@6",
+					       0x6006, 10);
+	if (IS_ERR(tmp_node)) {
+		ret = PTR_ERR(tmp_node);
+		goto free_eeprom;
+	}
+
+	ret = prt_imx6_nvmem_link_serial(priv, root, tmp_node);
+	if (ret)
+		goto free_eeprom;
+
+	return 0;
+free_eeprom:
+	kfree(eeprom_node_name);
+free_alias:
+	kfree(alias);
+exit_error:
+	dev_err(priv->dev, "Failed to apply fixup: %i\n", ret);
+	return ret;
+}
+
+static int prt_imx6_of_fixup(struct device_node *root, void *data)
+{
+	struct prt_imx6_priv *priv = data;
+	int ret;
+
+	if (!root) {
+		dev_err(priv->dev, "Unable to find the root node\n");
+		return -ENODEV;
+	}
+
+	ret = prt_imx6_rfid_fixup(priv, root);
+	if (ret)
+		goto exit_of_fixups;
+
+	return 0;
+exit_of_fixups:
+	dev_err(priv->dev, "Failed to apply OF fixups: %i\n", ret);
+	return ret;
+}
+
+static int prt_imx6_init_kvg_set_ctrl(struct prt_imx6_priv *priv, bool val)
+{
+	int ret;
+
+	ret = gpio_direction_output(GPIO_ON1_CTRL, val);
+	if (ret)
+		return ret;
+
+	ret = gpio_direction_output(GPIO_ON2_CTRL, val);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int prt_imx6_init_kvg_power(struct prt_imx6_priv *priv,
+				   enum prt_imx6_kvg_pw_mode pw_mode)
+{
+	struct prt_imx6_kvg_yaco yaco;
+	const char *mode;
+	int ret;
+
+	ret = gpio_request_array(prt_imx6_kvg_gpios,
+				 ARRAY_SIZE(prt_imx6_kvg_gpios));
+	if (ret)
+		goto exit_init_kvg_vicut;
+
+	mdelay(1);
+
+	if (!gpio_get_value(GPIO_DIP1_FB))
+		pw_mode = PW_MODE_KUBOTA;
+
+	switch (pw_mode) {
+	case PW_MODE_KVG_WITH_YACO:
+		mode = "KVG (with YaCO)";
+
+		/* GPIO_ON1_CTRL and GPIO_ON2_CTRL are N.C. on the SoC for
+		 * older revisions */
+
+		/* Inform YaCO of power mode */
+		strncpy(&yaco.serial[0], "serial0", sizeof(yaco.serial));
+		/* We can do it only after console drivers are registered. So,
+		 * move this part in a separate driver. */
+		prt_imx6_func_add(priv, "kvg_yaco_pwinit", &yaco, sizeof(yaco));
+		break;
+	case PW_MODE_KVG_NEW:
+		mode = "KVG (new)";
+
+		ret = prt_imx6_init_kvg_set_ctrl(priv, true);
+		if (ret)
+			goto exit_init_kvg_vicut;
+		break;
+	case PW_MODE_KUBOTA:
+		mode = "Kubota";
+		ret = prt_imx6_init_kvg_set_ctrl(priv, false);
+		if (ret)
+			goto exit_init_kvg_vicut;
+		break;
+	default:
+		ret = -ENODEV;
+		goto exit_init_kvg_vicut;
+	}
+
+	dev_info(priv->dev, "Power mode: %s\n", mode);
+
+	return 0;
+
+exit_init_kvg_vicut:
+	dev_err(priv->dev, "KvG power init failed: %i\n", ret);
+
+	return ret;
+}
+
+static int prt_imx6_init_victgo(struct prt_imx6_priv *priv)
+{
+	int ret = 0;
+
+	/* Bit 1 of HW-REV is pulled low by 2k2, but must be high on some
+	 * revisions
+	 */
+	if (priv->hw_rev & 2) {
+		ret = gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
+		if (ret) {
+			dev_err(priv->dev, "Failed to set gpio up\n");
+			return ret;
+		}
+	}
+
+	return prt_imx6_init_kvg_power(priv, PW_MODE_KVG_NEW);
+}
+
+static int prt_imx6_init_kvg_new(struct prt_imx6_priv *priv)
+{
+	return prt_imx6_init_kvg_power(priv, PW_MODE_KVG_NEW);
+}
+
+static int prt_imx6_init_kvg_yaco(struct prt_imx6_priv *priv)
+{
+	return prt_imx6_init_kvg_power(priv, PW_MODE_KVG_WITH_YACO);
+}
+
+static int prt_imx6_get_id(struct prt_imx6_priv *priv)
+{
+	struct gpio gpios_type[] = GPIO_HW_TYPE_ID;
+	struct gpio gpios_rev[] = GPIO_HW_REV_ID;
+	int ret;
+
+	ret = gpio_array_to_id(gpios_type, ARRAY_SIZE(gpios_type), &priv->hw_id);
+	if (ret)
+		goto exit_get_id;
+
+	ret = gpio_array_to_id(gpios_rev, ARRAY_SIZE(gpios_rev), &priv->hw_rev);
+	if (ret)
+		goto exit_get_id;
+
+	return 0;
+exit_get_id:
+	dev_err(priv->dev, "Failed to read gpio ID: %i\n", ret);
+	return ret;
+}
+
+static int prt_imx6_get_dcfg(struct prt_imx6_priv *priv)
+{
+	const struct prt_machine_data *dcfg, *found = NULL;
+	int ret;
+
+	dcfg = of_device_get_match_data(priv->dev);
+	if (!dcfg) {
+		ret = -EINVAL;
+		goto exit_get_dcfg;
+	}
+
+	for (; dcfg->hw_id != UINT_MAX; dcfg++) {
+		if (dcfg->hw_id != priv->hw_id)
+			continue;
+		if (dcfg->hw_rev > priv->hw_rev)
+			break;
+		found = dcfg;
+	}
+
+	if (!found) {
+		ret = -ENODEV;
+		goto exit_get_dcfg;
+	}
+
+	priv->dcfg = found;
+
+	return 0;
+exit_get_dcfg:
+	dev_err(priv->dev, "Failed to get dcfg: %i\n", ret);
+	return ret;
+}
+
+static int prt_imx6_bbu(struct prt_imx6_priv *priv)
+{
+	const struct prt_machine_data *dcfg = priv->dcfg;
+	u32 emmc_flags = 0;
+	int ret;
+
+	if (dcfg->flags & PRT_IMX6_BOOTSRC_SPI_NOR) {
+		ret = imx6_bbu_internal_spi_i2c_register_handler("SPI", "/dev/m25p0.barebox",
+							 BBU_HANDLER_FLAG_DEFAULT);
+		if (ret)
+			goto exit_bbu;
+	} else {
+		emmc_flags = BBU_HANDLER_FLAG_DEFAULT;
+	}
+
+	ret = imx6_bbu_internal_mmcboot_register_handler("eMMC", "/dev/mmc2",
+						   emmc_flags);
+	if (ret)
+		goto exit_bbu;
+
+	ret = imx6_bbu_internal_mmc_register_handler("SD", "/dev/mmc0", 0);
+	if (ret)
+		goto exit_bbu;
+
+	return 0;
+exit_bbu:
+	dev_err(priv->dev, "Failed to register bbu: %i\n", ret);
+	return ret;
+}
+
+static int prt_imx6_probe(struct device_d *dev)
+{
+	struct prt_imx6_priv *priv;
+	struct param_d *p;
+	int ret;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = dev;
+
+	pr_info("Detected machine type: %s\n",
+		of_device_get_match_compatible(priv->dev));
+
+	ret = prt_imx6_get_id(priv);
+	if (ret)
+		goto free_priv;
+
+	pr_info("  HW type:     %d\n", priv->hw_id);
+	pr_info("  HW revision: %d\n", priv->hw_rev);
+
+	ret = prt_imx6_get_dcfg(priv);
+	if (ret)
+		goto free_priv;
+
+	p = dev_add_param_uint32_ro(dev, "boardrev", &priv->hw_rev, "%u");
+	if (IS_ERR(p)) {
+		ret = PTR_ERR(p);
+		goto free_priv;
+	}
+
+	p = dev_add_param_uint32_ro(dev, "boardid", &priv->hw_id, "%u");
+	if (IS_ERR(p)) {
+		ret = PTR_ERR(p);
+		goto free_priv;
+	}
+
+	if (priv->dcfg->init) {
+		ret = priv->dcfg->init(priv);
+		if (ret)
+			goto free_priv;
+	}
+
+	ret = prt_imx6_of_fixup(of_get_root_node(), priv);
+	if (ret)
+		goto free_priv;
+
+	ret = of_register_fixup(prt_imx6_of_fixup, priv);
+	if (ret) {
+		dev_err(dev, "Failed to register fixup\n");
+		goto free_priv;
+	}
+
+	ret = prt_imx6_bbu(priv);
+	if (ret)
+		goto free_priv;
+
+	return 0;
+free_priv:
+	kfree(priv);
+	return ret;
+}
+
+static const struct prt_machine_data prt_imx6_cfg_alti6p[] = {
+	{
+		.hw_id = HW_TYPE_ALTI6P,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_EMMC,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_victgo[] = {
+	{
+		.hw_id = HW_TYPE_VICTGO,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.init = prt_imx6_init_victgo,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_vicut1[] = {
+	{
+		.hw_id = HW_TYPE_VICUT1,
+		.hw_rev = 0,
+		.i2c_addr = 0x50,
+		.i2c_adapter = 1,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = HW_TYPE_VICUT1,
+		.hw_rev = 1,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.init = prt_imx6_init_kvg_yaco,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = HW_TYPE_VICUT2,
+		.hw_rev = 1,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.init = prt_imx6_init_kvg_new,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_vicut1q[] = {
+	{
+		.hw_id = HW_TYPE_VICUT1,
+		.hw_rev = 0,
+		.i2c_addr = 0x50,
+		.i2c_adapter = 1,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = HW_TYPE_VICUT1,
+		.hw_rev = 1,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.init = prt_imx6_init_kvg_yaco,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = HW_TYPE_VICUT2,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.init = prt_imx6_init_kvg_yaco,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = HW_TYPE_VICUT2,
+		.hw_rev = 1,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.init = prt_imx6_init_kvg_new,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_vicutp[] = {
+	{
+		.hw_id = HW_TYPE_VICUT2,
+		.hw_rev = 1,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.init = prt_imx6_init_kvg_new,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_lanmcu[] = {
+	{
+		.hw_id = HW_TYPE_LANMCU,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_EMMC,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_plybas[] = {
+	{
+		.hw_id = HW_TYPE_PLYBAS,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_plym2m[] = {
+	{
+		.hw_id = HW_TYPE_PLYM2M,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_prti6g[] = {
+	{
+		.hw_id = HW_TYPE_PRTI6G,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_EMMC,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_prti6q[] = {
+	{
+		.hw_id = HW_TYPE_PRTI6Q,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 2,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = HW_TYPE_PRTI6Q,
+		.hw_rev = 1,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_prtmvt[] = {
+	{
+		.hw_id = HW_TYPE_PRTMVT,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_prtrvt[] = {
+	{
+		.hw_id = HW_TYPE_PRTRVT,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_prtvt7[] = {
+	{
+		.hw_id = HW_TYPE_PRTVT7,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_EMMC,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_prtwd2[] = {
+	{
+		.hw_id = HW_TYPE_PRTWD2,
+		.hw_rev = 0,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_EMMC,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct prt_machine_data prt_imx6_cfg_prtwd3[] = {
+	{
+		.hw_id = HW_TYPE_PRTWD2,
+		.hw_rev = 2,
+		.i2c_addr = 0x51,
+		.i2c_adapter = 0,
+		.flags = PRT_IMX6_BOOTSRC_EMMC,
+	}, {
+		.hw_id = UINT_MAX
+	},
+};
+
+static const struct of_device_id prt_imx6_of_match[] = {
+	{ .compatible = "alt,alti6p", .data = &prt_imx6_cfg_alti6p },
+	{ .compatible = "kvg,victgo", .data = &prt_imx6_cfg_victgo },
+	{ .compatible = "kvg,vicut1", .data = &prt_imx6_cfg_vicut1 },
+	{ .compatible = "kvg,vicut1q", .data = &prt_imx6_cfg_vicut1q },
+	{ .compatible = "kvg,vicutp", .data = &prt_imx6_cfg_vicutp },
+	{ .compatible = "lan,lanmcu", .data = &prt_imx6_cfg_lanmcu },
+	{ .compatible = "ply,plybas", .data = &prt_imx6_cfg_plybas },
+	{ .compatible = "ply,plym2m", .data = &prt_imx6_cfg_plym2m },
+	{ .compatible = "prt,prti6g", .data = &prt_imx6_cfg_prti6g },
+	{ .compatible = "prt,prti6q", .data = &prt_imx6_cfg_prti6q },
+	{ .compatible = "prt,prtmvt", .data = &prt_imx6_cfg_prtmvt },
+	{ .compatible = "prt,prtrvt", .data = &prt_imx6_cfg_prtrvt },
+	{ .compatible = "prt,prtvt7", .data = &prt_imx6_cfg_prtvt7 },
+	{ .compatible = "prt,prtwd2", .data = &prt_imx6_cfg_prtwd2 },
+	{ .compatible = "prt,prtwd3", .data = &prt_imx6_cfg_prtwd3 },
+	{ /* sentinel */ },
+};
+
+static struct driver_d prt_imx6_board_driver = {
+	.name = "board-protonic-imx6",
+	.probe = prt_imx6_probe,
+	.of_compatible = DRV_OF_COMPAT(prt_imx6_of_match),
+};
+postcore_platform_driver(prt_imx6_board_driver);
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 12/13] of: add barebox-serial driver
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (10 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 11/13] ARM: protonic-imx6: port Protonic specific board code Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-11  8:34   ` Sascha Hauer
  2020-08-05 10:16 ` [PATCH v2 13/13] ARM: dts: imx6q-prti6q: add barebox, serial-number node Oleksij Rempel
  2020-08-11 11:12 ` [PATCH v2 00/13] prepare Protonic board code for mainline Sascha Hauer
  13 siblings, 1 reply; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Provide a driver which should act as nvmem consumer
for board serial number information.

To make use of this driver, DTS should contain a serial
node with compatibe "barebox,serial" and nvmem-cell-names
"serial-number":

...
	chosen {
		serial {
			compatible = "barebox,serial";
			nvmem-cell-names = "serial-number";
			nvmem-cells = &some_provider;
		};
	};
...

The driver will read nvmem cell on probe and register
a fixup for the kernel devicetree.

This fixup will create a "/serial-number" property, which is
used by current kernel:
https://elixir.bootlin.com/linux/v5.7/source/arch/arm/kernel/setup.c#L941

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/of/Makefile         |   2 +-
 drivers/of/barebox_serial.c | 113 ++++++++++++++++++++++++++++++++++++
 2 files changed, 114 insertions(+), 1 deletion(-)
 create mode 100644 drivers/of/barebox_serial.c

diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index b6847752d2..b4a4c36b2a 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -5,5 +5,5 @@ obj-$(CONFIG_OF_PCI) += of_pci.o
 obj-y += partition.o
 obj-y += of_net.o
 obj-$(CONFIG_MTD) += of_mtd.o
-obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o
+obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o barebox_serial.o
 obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o of_firmware.o
diff --git a/drivers/of/barebox_serial.c b/drivers/of/barebox_serial.c
new file mode 100644
index 0000000000..3c0925c8d5
--- /dev/null
+++ b/drivers/of/barebox_serial.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2020 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
+
+#include <common.h>
+#include <init.h>
+#include <linux/nvmem-consumer.h>
+
+struct bb_sernum_priv {
+	struct device_d *dev;
+	char *ser;
+};
+
+static int bb_sernum_fixup(struct device_node *root, void *data)
+{
+	struct bb_sernum_priv *priv = data;
+	int ret;
+
+	ret = of_property_write_string(root, "serial-number", priv->ser);
+	if (ret)
+		dev_err(priv->dev, "Failed to set /serial-number\n");
+
+	return ret;
+}
+
+static int bb_sernum_of_get_nvmem(struct bb_sernum_priv *priv)
+{
+	struct nvmem_cell *cell;
+	size_t len;
+	char *ser;
+
+	cell = nvmem_cell_get(priv->dev, "serial-number");
+	if (IS_ERR(cell))
+		return PTR_ERR(cell);
+
+	ser = nvmem_cell_read(cell, &len);
+	nvmem_cell_put(cell);
+
+	if (IS_ERR(ser))
+		return PTR_ERR(ser);
+
+	/* check if serial number is zero terminated */
+	if (ser[len - 1] != 0x0) {
+		char *tmp;
+
+		tmp = kzalloc(len + 1, GFP_KERNEL);
+		if (!tmp) {
+			kfree(ser);
+			return -ENOMEM;
+		}
+
+		memcpy(tmp, ser, len);
+		tmp[len] = 0x0;
+		kfree(ser);
+		ser = tmp;
+	}
+
+	priv->ser = ser;
+
+	return 0;
+}
+
+static int bb_sernum_probe(struct device_d *dev)
+{
+	struct bb_sernum_priv *priv;
+	struct param_d *p;
+	int ret;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = dev;
+
+	ret = bb_sernum_of_get_nvmem(priv);
+	if (ret) {
+		dev_err(priv->dev, "Failed to read nvmem\n");
+		goto free_priv;
+	}
+
+	p = dev_add_param_string_fixed(dev, "serial-number", priv->ser);
+	if (IS_ERR(p)) {
+		dev_err(priv->dev, "Failed to set param_string\n");
+		ret = PTR_ERR(p);
+		goto free_ser;
+	}
+
+	ret = of_register_fixup(bb_sernum_fixup, priv);
+	if (ret) {
+		dev_err(priv->dev, "Failed to register fixup\n");
+		goto free_ser;
+	}
+
+	dev_info(priv->dev, "Registered serial number: %s\n", priv->ser);
+
+	return 0;
+free_ser:
+	kfree(priv->ser);
+free_priv:
+	kfree(priv);
+	return ret;
+}
+
+static const struct of_device_id bb_sernum_of_match[] = {
+	{ .compatible = "barebox,serial-number", },
+	{ /* sentinel */ },
+};
+
+static struct driver_d bb_sernum_driver = {
+	.name = "barebox-serial-number",
+	.probe = bb_sernum_probe,
+	.of_compatible = DRV_OF_COMPAT(bb_sernum_of_match),
+};
+device_platform_driver(bb_sernum_driver);
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 13/13] ARM: dts: imx6q-prti6q: add barebox, serial-number node
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (11 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 12/13] of: add barebox-serial driver Oleksij Rempel
@ 2020-08-05 10:16 ` Oleksij Rempel
  2020-08-11 11:12 ` [PATCH v2 00/13] prepare Protonic board code for mainline Sascha Hauer
  13 siblings, 0 replies; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-05 10:16 UTC (permalink / raw)
  To: barebox, david; +Cc: Oleksij Rempel

Add serial-number node provider

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 arch/arm/dts/imx6qdl-prti6q.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/dts/imx6qdl-prti6q.dtsi b/arch/arm/dts/imx6qdl-prti6q.dtsi
index ed526d185f..968617f372 100644
--- a/arch/arm/dts/imx6qdl-prti6q.dtsi
+++ b/arch/arm/dts/imx6qdl-prti6q.dtsi
@@ -9,6 +9,12 @@
 / {
 	chosen {
 		stdout-path = &uart4;
+
+		serial {
+			compatible = "barebox,serial-number";
+			nvmem-cell-names = "serial-number";
+			/* nvmem-cells will be added board code */
+		};
 	};
 
 	reg_1v8: regulator-1v8 {
-- 
2.28.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 12/13] of: add barebox-serial driver
  2020-08-05 10:16 ` [PATCH v2 12/13] of: add barebox-serial driver Oleksij Rempel
@ 2020-08-11  8:34   ` Sascha Hauer
  2020-08-11  8:58     ` Oleksij Rempel
  0 siblings, 1 reply; 18+ messages in thread
From: Sascha Hauer @ 2020-08-11  8:34 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: barebox, david

On Wed, Aug 05, 2020 at 12:16:27PM +0200, Oleksij Rempel wrote:
> Provide a driver which should act as nvmem consumer
> for board serial number information.
> 
> To make use of this driver, DTS should contain a serial
> node with compatibe "barebox,serial" and nvmem-cell-names
> "serial-number":
> 
> ...
> 	chosen {
> 		serial {
> 			compatible = "barebox,serial";
> 			nvmem-cell-names = "serial-number";
> 			nvmem-cells = &some_provider;
> 		};
> 	};

This driver only works when the EEPROM or whatever provides the NVMEM
contains the serial number in exactly the same format as shall be added
to the /serial-number property. This seems to be a special case only and
doesn't seem to justify a generic driver.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 12/13] of: add barebox-serial driver
  2020-08-11  8:34   ` Sascha Hauer
@ 2020-08-11  8:58     ` Oleksij Rempel
  2020-08-11  9:52       ` David Jander
  0 siblings, 1 reply; 18+ messages in thread
From: Oleksij Rempel @ 2020-08-11  8:58 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, david


[-- Attachment #1.1: Type: text/plain, Size: 1547 bytes --]

On Tue, Aug 11, 2020 at 10:34:01AM +0200, Sascha Hauer wrote:
> On Wed, Aug 05, 2020 at 12:16:27PM +0200, Oleksij Rempel wrote:
> > Provide a driver which should act as nvmem consumer
> > for board serial number information.
> > 
> > To make use of this driver, DTS should contain a serial
> > node with compatibe "barebox,serial" and nvmem-cell-names
> > "serial-number":
> > 
> > ...
> > 	chosen {
> > 		serial {
> > 			compatible = "barebox,serial";
> > 			nvmem-cell-names = "serial-number";
> > 			nvmem-cells = &some_provider;
> > 		};
> > 	};
> 
> This driver only works when the EEPROM or whatever provides the NVMEM
> contains the serial number in exactly the same format as shall be added
> to the /serial-number property. This seems to be a special case only and
> doesn't seem to justify a generic driver.

As with usual devicetree based solution we can add additional
compatibles to better describe a variant or quirk which should be used
to convert raw data to the serial number in usable for environment and
device tree way. I hope, by having generic drivers other users will alight
with it by making new products or extend existing driver by mainlining
existing products.

Regards,
Oleksij
-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 149 bytes --]

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 12/13] of: add barebox-serial driver
  2020-08-11  8:58     ` Oleksij Rempel
@ 2020-08-11  9:52       ` David Jander
  0 siblings, 0 replies; 18+ messages in thread
From: David Jander @ 2020-08-11  9:52 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: barebox

On Tue, 11 Aug 2020 10:58:47 +0200
Oleksij Rempel <o.rempel@pengutronix.de> wrote:

> On Tue, Aug 11, 2020 at 10:34:01AM +0200, Sascha Hauer wrote:
> > On Wed, Aug 05, 2020 at 12:16:27PM +0200, Oleksij Rempel wrote:  
> > > Provide a driver which should act as nvmem consumer
> > > for board serial number information.
> > > 
> > > To make use of this driver, DTS should contain a serial
> > > node with compatibe "barebox,serial" and nvmem-cell-names
> > > "serial-number":
> > > 
> > > ...
> > > 	chosen {
> > > 		serial {
> > > 			compatible = "barebox,serial";
> > > 			nvmem-cell-names = "serial-number";
> > > 			nvmem-cells = &some_provider;
> > > 		};
> > > 	};  
> > 
> > This driver only works when the EEPROM or whatever provides the NVMEM
> > contains the serial number in exactly the same format as shall be added
> > to the /serial-number property. This seems to be a special case only and
> > doesn't seem to justify a generic driver.  
> 
> As with usual devicetree based solution we can add additional
> compatibles to better describe a variant or quirk which should be used
> to convert raw data to the serial number in usable for environment and
> device tree way. I hope, by having generic drivers other users will alight
> with it by making new products or extend existing driver by mainlining
> existing products.

Just for information, this is the layout used for I2C EEPROM contents in the
RFID chip (from I2C address 0x6000, device id 0x51):

struct rfid_contents {
        u8 mac[6];
        char serial[10];
        u8 cs;
} __attribute__ ((packed));

The cs field is just the bit-inverted LSB of the sum of all bytes composing
the struct up to cs.

Note, that even boards without ethernet interface use the same struct, but the
MAC address field is ignored and can be anything. The design of this struct is
quite specific, inflexible and not at all future-proof. So maybe it shouldn't
go into a full-blown driver and instead stay hidden in the board code.

Best regards,

-- 
David Jander
Protonic Holland.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 00/13] prepare Protonic board code for mainline
  2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
                   ` (12 preceding siblings ...)
  2020-08-05 10:16 ` [PATCH v2 13/13] ARM: dts: imx6q-prti6q: add barebox, serial-number node Oleksij Rempel
@ 2020-08-11 11:12 ` Sascha Hauer
  13 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2020-08-11 11:12 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: barebox, david

On Wed, Aug 05, 2020 at 12:16:15PM +0200, Oleksij Rempel wrote:
> changes v2:
> - add power init support for KvG boards
> - spell fixes
> - do not print error on probe exit
> - add of_console_get_by_alias() helper
> - free requested gpio array
> - exit fec init only in case of PROBE_DEFERED
> 
> This patch series is a preparation and actual Protonic board code.
> Following changes was made in the main code:
> - register DT root node as device to make it possible to loade board
>   code as usual driver
> - provide helpers to read ethernet mac from nvmem cell register in a
>   devicetree.
> - provide barebox-serial driver which should be a nvmem cell consumer
>   and
>   serial-number DT property provider.
> - provide gpio helper to read gpio based board revision.
> 
> Oleksij Rempel (13):
>   ARM: dts: imx6q-prti6q: fix PHY register
>   ARM: dts: imx6: vicut1: fix network support
>   of: base: register DT root as device
>   ARM: embest-riotboard: port board file to the driver model
>   net: port nvmem_get_mac_address() from linux kernel
>   of: of_net: sync of_get_mac_address() with latest kernel version
>   net: fec_imx: use of_get_mac_address() to get mac address out of DT
>   of: of_device_get_match_compatible() helper
>   gpiolib: add gpio_array_to_id helper to get ID out of GPIO array
>   common: console_common: add of_console_get_by_alias() helper
>   ARM: protonic-imx6: port Protonic specific board code
>   of: add barebox-serial driver
>   ARM: dts: imx6q-prti6q: add barebox,serial-number node

Applied 1-4 for now.

Sascha


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2020-08-11 11:13 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-05 10:16 [PATCH v2 00/13] prepare Protonic board code for mainline Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 01/13] ARM: dts: imx6q-prti6q: fix PHY register Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 02/13] ARM: dts: imx6: vicut1: fix network support Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 03/13] of: base: register DT root as device Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 04/13] ARM: embest-riotboard: port board file to the driver model Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 05/13] net: port nvmem_get_mac_address() from linux kernel Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 06/13] of: of_net: sync of_get_mac_address() with latest kernel version Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 07/13] net: fec_imx: use of_get_mac_address() to get mac address out of DT Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 08/13] of: of_device_get_match_compatible() helper Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 09/13] gpiolib: add gpio_array_to_id helper to get ID out of GPIO array Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 10/13] common: console_common: add of_console_get_by_alias() helper Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 11/13] ARM: protonic-imx6: port Protonic specific board code Oleksij Rempel
2020-08-05 10:16 ` [PATCH v2 12/13] of: add barebox-serial driver Oleksij Rempel
2020-08-11  8:34   ` Sascha Hauer
2020-08-11  8:58     ` Oleksij Rempel
2020-08-11  9:52       ` David Jander
2020-08-05 10:16 ` [PATCH v2 13/13] ARM: dts: imx6q-prti6q: add barebox, serial-number node Oleksij Rempel
2020-08-11 11:12 ` [PATCH v2 00/13] prepare Protonic board code for mainline Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox