Skip to contentSkip to conversation

Turris Omnia MCU driver

PATCH Superseded Marek Behún 5 participants 17 messages Jun 17, 2024 – Jul 15, 2024

Subsystems (7)

v12 of 13 Superseded Latest is v13 →

lore
Share & tools
lore

Marek Behún

author maintainer
#0 lore raw

v12 cover Turris Omnia MCU driver

Hello Andy, Hans, Ilpo, Arnd, Gregory, and others,

this is v12 of the series adding Turris Omnia MCU driver.

Changes since v11:
- fixed some includes, suggested by Andy
- moved #include <linux/turris-omnia-mcu-interface.h> after the other includes, since it is domain specific, suggested by Andy
- in patch 2, use sizeof() of dest buffer in memcpy call, instead of ETH_ALEN constant, as suggested by Andy
- in patch 3, dropped the .has_int member of omnia GPIO definition structure, and added is_int_bit_valid() function instead, as suggested by Andy
- in patch 3, changed int to unsigned int where appropriate, as suggested by Andy
- in patch 3, fixed docstring indentation, suggested by Andy
- in patch 4 dropped #include <linux/rtc.h>, and instead declared struct rtc_device, it is only used as a pointer, suggested by Andy
- in patch 5, renamed the completion from trng_completion to trng_entropy_available
- in patch 5, use gpio_device_get_desc() instead of gpiochip_get_desc() when mapping IRQ (as discussed with Andy and Bart)
- in patch 5, dropped setting the priv member of hwrng, and instead use container_of() to get the driver private structure, suggested by Herbert

Links to previous cover letters (v1 to v11):
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/
https://patchwork.kernel.org/project/linux-soc/cover/[email protected]/

Marek Behún (8):
dt-bindings: firmware: add cznic,turris-omnia-mcu binding
platform: cznic: Add preliminary support for Turris Omnia MCU
platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs
platform: cznic: turris-omnia-mcu: Add support for poweroff and wakeup
platform: cznic: turris-omnia-mcu: Add support for MCU watchdog
platform: cznic: turris-omnia-mcu: Add support for MCU provided TRNG
ARM: dts: turris-omnia: Add MCU system-controller node
ARM: dts: turris-omnia: Add GPIO key node for front button

 .../sysfs-bus-i2c-devices-turris-omnia-mcu    |  113 ++
 .../firmware/cznic,turris-omnia-mcu.yaml      |   86 ++
 MAINTAINERS                                   |    4 +
 .../dts/marvell/armada-385-turris-omnia.dts   |   35 +-
 drivers/platform/Kconfig                      |    2 +
 drivers/platform/Makefile                     |    1 +
 drivers/platform/cznic/Kconfig                |   48 +
 drivers/platform/cznic/Makefile               |    8 +
 .../platform/cznic/turris-omnia-mcu-base.c    |  408 +++++++
 .../platform/cznic/turris-omnia-mcu-gpio.c    | 1088 +++++++++++++++++
 .../cznic/turris-omnia-mcu-sys-off-wakeup.c   |  260 ++++
 .../platform/cznic/turris-omnia-mcu-trng.c    |  103 ++
 .../cznic/turris-omnia-mcu-watchdog.c         |  130 ++
 drivers/platform/cznic/turris-omnia-mcu.h     |  194 +++
 include/linux/turris-omnia-mcu-interface.h    |  249 ++++
 15 files changed, 2728 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
 create mode 100644 Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml
 create mode 100644 drivers/platform/cznic/Kconfig
 create mode 100644 drivers/platform/cznic/Makefile
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-base.c
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-gpio.c
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-sys-off-wakeup.c
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-trng.c
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-watchdog.c
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu.h
 create mode 100644 include/linux/turris-omnia-mcu-interface.h
Signature · 1 line
2.44.2
author maintainer
#1 lore raw

PATCH v12 1/8 dt-bindings: firmware: add cznic,turris-omnia-mcu binding

Add binding for cznic,turris-omnia-mcu, the device-tree node representing the system-controller features provided by the MCU on the Turris Omnia router.

---
 .../firmware/cznic,turris-omnia-mcu.yaml      | 86 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml
Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml new file +86 -0
new file mode 100644
index 000000000000..af9249695ef5
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/cznic,turris-omnia-mcu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: CZ.NIC's Turris Omnia MCU
+
+maintainers:
+  - Marek Behún <[email protected]>
+
+description:
+  The MCU on Turris Omnia acts as a system controller providing additional
+  GPIOs, interrupts, watchdog, system power off and wakeup configuration.
+
+properties:
+  compatible:
+    const: cznic,turris-omnia-mcu
+
+  reg:
+    description: MCU I2C slave address
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    const: 2
+    description: |
+      The first cell specifies the interrupt number (0 to 63), the second cell
+      specifies interrupt type (which can be one of IRQ_TYPE_EDGE_RISING,
+      IRQ_TYPE_EDGE_FALLING or IRQ_TYPE_EDGE_BOTH).
+      The interrupt numbers correspond sequentially to GPIO numbers, taking the
+      GPIO banks into account:
+        IRQ number   GPIO bank   GPIO pin within bank
+           0 - 15      0           0 - 15
+          16 - 47      1           0 - 31
+          48 - 63      2           0 - 15
+      There are several exceptions:
+        IRQ number   meaning
+          11           LED panel brightness changed by button press
+          13           TRNG entropy ready
+          14           ECDSA message signature computation done
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 3
+    description:
+      The first cell is bank number (0, 1 or 2), the second cell is pin number
+      within the bank (0 to 15 for banks 0 and 2, 0 to 31 for bank 1), and the
+      third cell specifies consumer flags.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - gpio-controller
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        system-controller@2a {
+            compatible = "cznic,turris-omnia-mcu";
+            reg = <0x2a>;
+
+            interrupt-parent = <&gpio1>;
+            interrupts = <11 IRQ_TYPE_NONE>;
+
+            gpio-controller;
+            #gpio-cells = <3>;
+
+            interrupt-controller;
+            #interrupt-cells = <2>;
+        };
+    };
MAINTAINERS +1 -0
index cf9c9221c388..5496c8ec3e1d 100644
@@ -2210,6 +2210,7 @@ F:	Documentation/ABI/testing/sysfs-bus-moxtet-devices
 F:	Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
 F:	Documentation/devicetree/bindings/bus/moxtet.txt
 F:	Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt
+F:	Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml
 F:	Documentation/devicetree/bindings/gpio/gpio-moxtet.txt
 F:	Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml
 F:	Documentation/devicetree/bindings/watchdog/armada-37xx-wdt.txt
Signature · 1 line
2.44.2
author maintainer
#2 lore raw

PATCH v12 2/8 platform: cznic: Add preliminary support for Turris Omnia MCU

In reply to Marek Behún

Add the basic skeleton for a new platform driver for the microcontroller found on the Turris Omnia board.

---
 .../sysfs-bus-i2c-devices-turris-omnia-mcu    |  81 ++++
 MAINTAINERS                                   |   3 +
 drivers/platform/Kconfig                      |   2 +
 drivers/platform/Makefile                     |   1 +
 drivers/platform/cznic/Kconfig                |  25 ++
 drivers/platform/cznic/Makefile               |   4 +
 .../platform/cznic/turris-omnia-mcu-base.c    | 394 ++++++++++++++++++
 drivers/platform/cznic/turris-omnia-mcu.h     |  74 ++++
 include/linux/turris-omnia-mcu-interface.h    | 249 +++++++++++
 9 files changed, 833 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
 create mode 100644 drivers/platform/cznic/Kconfig
 create mode 100644 drivers/platform/cznic/Makefile
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-base.c
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu.h
 create mode 100644 include/linux/turris-omnia-mcu-interface.h
Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu new file +81 -0
new file mode 100644
index 000000000000..9bc5aad00de0
@@ -0,0 +1,81 @@
+What:		/sys/bus/i2c/devices/<mcu_device>/board_revision
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RO) Contains board revision number.
+
+		Only available if board information is burned in the MCU (older
+		revisions have board information burned in the ATSHA204-A chip).
+
+		Format: %u.
+
+What:		/sys/bus/i2c/devices/<mcu_device>/first_mac_address
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RO) Contains device first MAC address. Each Turris Omnia is
+		allocated 3 MAC addresses. The two additional addresses are
+		computed from the first one by incrementing it.
+
+		Only available if board information is burned in the MCU (older
+		revisions have board information burned in the ATSHA204-A chip).
+
+		Format: %pM.
+
+What:		/sys/bus/i2c/devices/<mcu_device>/fw_features
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RO) Newer versions of the microcontroller firmware report the
+		features they support. These can be read from this file. If the
+		MCU firmware is too old, this file reads 0x0.
+
+		Format: 0x%x.
+
+What:		/sys/bus/i2c/devices/<mcu_device>/fw_version_hash_application
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RO) Contains the version hash (commit hash) of the application
+		part of the microcontroller firmware.
+
+		Format: %s.
+
+What:		/sys/bus/i2c/devices/<mcu_device>/fw_version_hash_bootloader
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RO) Contains the version hash (commit hash) of the bootloader
+		part of the microcontroller firmware.
+
+		Format: %s.
+
+What:		/sys/bus/i2c/devices/<mcu_device>/mcu_type
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RO) Contains the microcontroller type (STM32, GD32, MKL).
+
+		Format: %s.
+
+What:		/sys/bus/i2c/devices/<mcu_device>/reset_selector
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RO) Contains the selected factory reset level, determined by
+		how long the rear reset button was held by the user during board
+		reset.
+
+		Format: %i.
+
+What:		/sys/bus/i2c/devices/<mcu_device>/serial_number
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RO) Contains the 64-bit board serial number in hexadecimal
+		format.
+
+		Only available if board information is burned in the MCU (older
+		revisions have board information burned in the ATSHA204-A chip).
+
+		Format: %016X.
MAINTAINERS +3 -0
index 5496c8ec3e1d..6516cf669cd9 100644
@@ -2206,6 +2206,7 @@ M:	Marek Behún <[email protected]>
 S:	Maintained
 W:	https://www.turris.cz/
 F:	Documentation/ABI/testing/debugfs-moxtet
+F:	Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
 F:	Documentation/ABI/testing/sysfs-bus-moxtet-devices
 F:	Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
 F:	Documentation/devicetree/bindings/bus/moxtet.txt
@@ -2219,10 +2220,12 @@ F:	drivers/firmware/turris-mox-rwtm.c
 F:	drivers/gpio/gpio-moxtet.c
 F:	drivers/leds/leds-turris-omnia.c
 F:	drivers/mailbox/armada-37xx-rwtm-mailbox.c
+F:	drivers/platform/cznic/
 F:	drivers/watchdog/armada_37xx_wdt.c
 F:	include/dt-bindings/bus/moxtet.h
 F:	include/linux/armada-37xx-rwtm-mailbox.h
 F:	include/linux/moxtet.h
+F:	include/linux/turris-omnia-mcu-interface.h
 
 ARM/FARADAY FA526 PORT
 M:	Hans Ulli Kroll <[email protected]>
drivers/platform/Kconfig +2 -0
index 81a298517df2..960fd6a82450 100644
@@ -7,6 +7,8 @@ source "drivers/platform/goldfish/Kconfig"
 
 source "drivers/platform/chrome/Kconfig"
 
+source "drivers/platform/cznic/Kconfig"
+
 source "drivers/platform/mellanox/Kconfig"
 
 source "drivers/platform/olpc/Kconfig"
drivers/platform/Makefile +1 -0
index fbbe4f77aa5d..bf69cc8d7429 100644
@@ -10,5 +10,6 @@ obj-$(CONFIG_MIPS)		+= mips/
 obj-$(CONFIG_OLPC_EC)		+= olpc/
 obj-$(CONFIG_GOLDFISH)		+= goldfish/
 obj-$(CONFIG_CHROME_PLATFORMS)	+= chrome/
+obj-$(CONFIG_CZNIC_PLATFORMS)	+= cznic/
 obj-$(CONFIG_SURFACE_PLATFORMS)	+= surface/
 obj-$(CONFIG_ARM64)		+= arm64/
drivers/platform/cznic/Kconfig new file +25 -0
new file mode 100644
index 000000000000..db5f4a673d28
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.rst.
+#
+
+menuconfig CZNIC_PLATFORMS
+	bool "Platform support for CZ.NIC's Turris hardware"
+	help
+	  Say Y here to be able to choose driver support for CZ.NIC's Turris
+	  devices. This option alone does not add any kernel code.
+
+if CZNIC_PLATFORMS
+
+config TURRIS_OMNIA_MCU
+	tristate "Turris Omnia MCU driver"
+	depends on MACH_ARMADA_38X || COMPILE_TEST
+	depends on I2C
+	help
+	  Say Y here to add support for the features implemented by the
+	  microcontroller on the CZ.NIC's Turris Omnia SOHO router.
+	  To compile this driver as a module, choose M here; the module will be
+	  called turris-omnia-mcu.
+
+endif # CZNIC_PLATFORMS
drivers/platform/cznic/Makefile new file +4 -0
new file mode 100644
index 000000000000..31adca73bb94
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_TURRIS_OMNIA_MCU)	+= turris-omnia-mcu.o
+turris-omnia-mcu-y		:= turris-omnia-mcu-base.o
drivers/platform/cznic/turris-omnia-mcu-base.c new file +394 -0

394 lines not on this page · raw message

drivers/platform/cznic/turris-omnia-mcu.h new file +74 -0

74 lines not on this page · raw message

include/linux/turris-omnia-mcu-interface.h new file +249 -0

249 lines not on this page · raw message

Signature · 1 line
2.44.2
author maintainer
#3 lore raw

PATCH v12 3/8 platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs

In reply to Marek Behún

Add support for GPIOs connected to the MCU on the Turris Omnia board.

This includes:
- front button pin
- enable pins for USB regulators
- MiniPCIe / mSATA card presence pins in MiniPCIe port 0
- LED output pins from WAN ethernet PHY, LAN switch and MiniPCIe ports
- on board revisions 32+ also various peripheral resets and another voltage regulator enable pin

---
 .../sysfs-bus-i2c-devices-turris-omnia-mcu    |   16 +
 drivers/platform/cznic/Kconfig                |   15 +
 drivers/platform/cznic/Makefile               |    1 +
 .../platform/cznic/turris-omnia-mcu-base.c    |    3 +-
 .../platform/cznic/turris-omnia-mcu-gpio.c    | 1088 +++++++++++++++++
 drivers/platform/cznic/turris-omnia-mcu.h     |   68 ++
 6 files changed, 1190 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-gpio.c
Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu +16 -0
index 9bc5aad00de0..86360249080c 100644
@@ -22,6 +22,22 @@ Description:	(RO) Contains device first MAC address. Each Turris Omnia is
 
 		Format: %pM.
 
+What:		/sys/bus/i2c/devices/<mcu_device>/front_button_mode
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RW) The front button on the Turris Omnia router can be
+		configured either to change the intensity of all the LEDs on the
+		front panel, or to send the press event to the CPU as an
+		interrupt.
+
+		This file switches between these two modes:
+		- "mcu" makes the button press event be handled by the MCU to
+		  change the LEDs panel intensity.
+		- "cpu" makes the button press event be handled by the CPU.
+
+		Format: %s.
+
 What:		/sys/bus/i2c/devices/<mcu_device>/fw_features
 Date:		September 2024
 KernelVersion:	6.11
drivers/platform/cznic/Kconfig +15 -0
index db5f4a673d28..d95e7c83c7ae 100644
@@ -16,9 +16,24 @@ config TURRIS_OMNIA_MCU
 	tristate "Turris Omnia MCU driver"
 	depends on MACH_ARMADA_38X || COMPILE_TEST
 	depends on I2C
+	select GPIOLIB
+	select GPIOLIB_IRQCHIP
 	help
 	  Say Y here to add support for the features implemented by the
 	  microcontroller on the CZ.NIC's Turris Omnia SOHO router.
+	  The features include:
+	  - GPIO pins
+	    - to get front button press events (the front button can be
+	      configured either to generate press events to the CPU or to change
+	      front LEDs panel brightness)
+	    - to enable / disable USB port voltage regulators and to detect
+	      USB overcurrent
+	    - to detect MiniPCIe / mSATA card presence in MiniPCIe port 0
+	    - to configure resets of various peripherals on board revisions 32+
+	    - to enable / disable the VHV voltage regulator to the SOC in order
+	      to be able to program SOC's OTP on board revisions 32+
+	    - to get input from the LED output pins of the WAN ethernet PHY, LAN
+	      switch and MiniPCIe ports
 	  To compile this driver as a module, choose M here; the module will be
 	  called turris-omnia-mcu.
 
drivers/platform/cznic/Makefile +1 -0
index 31adca73bb94..53fd8f1777a3 100644
@@ -2,3 +2,4 @@
 
 obj-$(CONFIG_TURRIS_OMNIA_MCU)	+= turris-omnia-mcu.o
 turris-omnia-mcu-y		:= turris-omnia-mcu-base.o
+turris-omnia-mcu-y		+= turris-omnia-mcu-gpio.o
drivers/platform/cznic/turris-omnia-mcu-base.c +2 -1
index 47513ba9b128..4481484b2f94 100644
@@ -197,6 +197,7 @@ static const struct attribute_group omnia_mcu_base_group = {
 
 static const struct attribute_group *omnia_mcu_groups[] = {
 	&omnia_mcu_base_group,
+	&omnia_mcu_gpio_group,
 	NULL
 };
 
@@ -371,7 +372,7 @@ static int omnia_mcu_probe(struct i2c_client *client)
 					     "Cannot read board info\n");
 	}
 
-	return 0;
+	return omnia_mcu_register_gpiochip(mcu);
 }
 
 static const struct of_device_id of_omnia_mcu_match[] = {
drivers/platform/cznic/turris-omnia-mcu-gpio.c new file +1088 -0

1,088 lines not on this page · raw message

drivers/platform/cznic/turris-omnia-mcu.h +68 -0

98 lines not on this page · raw message

Signature · 1 line
2.44.2
Acked-by on v12 3/8
#4 lore raw

Re: [PATCH v12 3/8] platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs

Quoted 11 lines · Marek Behún

Add support for GPIOs connected to the MCU on the Turris Omnia board.

This includes:
- front button pin
- enable pins for USB regulators
- MiniPCIe / mSATA card presence pins in MiniPCIe port 0
- LED output pins from WAN ethernet PHY, LAN switch and MiniPCIe ports
- on board revisions 32+ also various peripheral resets and another voltage regulator enable pin

Quoted 1 line

This is one heck of a complex GPIO driver!

Quoted 35 lines
drivers/platform/cznic/turris-omnia-mcu-gpio.c new file +35 -0
+
+#define _DEF_GPIO(_cmd, _ctl_cmd, _bit, _ctl_bit, _int_bit, _feat, _feat_mask) \
+       {                                                               \
+               .cmd = _cmd,                                            \
+               .ctl_cmd = _ctl_cmd,                                    \
+               .bit = _bit,                                            \
+               .ctl_bit = _ctl_bit,                                    \
+               .int_bit = (_int_bit) < 0 ? OMNIA_GPIO_INVALID_INT_BIT  \
+                                         : (_int_bit),                 \
+               .feat = _feat,                                          \
+               .feat_mask = _feat_mask,                                \
+       }
+#define _DEF_GPIO_STS(_name) \
+       _DEF_GPIO(OMNIA_CMD_GET_STATUS_WORD, 0, __bf_shf(OMNIA_STS_ ## _name), \
+                 0, __bf_shf(OMNIA_INT_ ## _name), 0, 0)
+#define _DEF_GPIO_CTL(_name) \
+       _DEF_GPIO(OMNIA_CMD_GET_STATUS_WORD, OMNIA_CMD_GENERAL_CONTROL, \
+                 __bf_shf(OMNIA_STS_ ## _name), __bf_shf(OMNIA_CTL_ ## _name), \
+                 -1, 0, 0)
+#define _DEF_GPIO_EXT_STS(_name, _feat) \
+       _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
+                 __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
+                 __bf_shf(OMNIA_INT_ ## _name), \
+                 OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS, \
+                 OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS)
+#define _DEF_GPIO_EXT_STS_LED(_name, _ledext) \
+       _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
+                 __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
+                 __bf_shf(OMNIA_INT_ ## _name), \
+                 OMNIA_FEAT_LED_STATE_ ## _ledext, \
+                 OMNIA_FEAT_LED_STATE_EXT_MASK)
+#define _DEF_GPIO_EXT_STS_LEDALL(_name) \
+       _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
+                 __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
+                 __bf_shf(OMNIA_INT_ ## _name), \

drivers/platform/cznic/turris-omnia-mcu-gpio.c line 130

Quoted 10 lines
drivers/platform/cznic/turris-omnia-mcu-gpio.c new file +10 -0
+                 OMNIA_FEAT_LED_STATE_EXT_MASK, 0)
+#define _DEF_GPIO_EXT_CTL(_name, _feat) \
+       _DEF_GPIO(OMNIA_CMD_GET_EXT_CONTROL_STATUS, OMNIA_CMD_EXT_CONTROL, \
+                 __bf_shf(OMNIA_EXT_CTL_ ## _name), \
+                 __bf_shf(OMNIA_EXT_CTL_ ## _name), -1, \
+                 OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS, \
+                 OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS)
+#define _DEF_INT(_name) \
+       _DEF_GPIO(0, 0, 0, 0, __bf_shf(OMNIA_INT_ ## _name), 0, 0)
+

One coding-style nit: can you add newlines between these macros?

I'm having a hard-time understanding the entire architecture of this MCU but the code overall looks good to me so I trust you know what you're doing.

author maintainer
#5 lore raw

Re: [PATCH v12 3/8] platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs

Quoted 12 lines · On Mon, 1 Jul 2024 11:37:44 +0200 Bartosz Golaszewski <[email protected]> wrote:
Quoted 11 lines · Marek Behún

Add support for GPIOs connected to the MCU on the Turris Omnia board.

This includes:
- front button pin
- enable pins for USB regulators
- MiniPCIe / mSATA card presence pins in MiniPCIe port 0
- LED output pins from WAN ethernet PHY, LAN switch and MiniPCIe ports
- on board revisions 32+ also various peripheral resets and another voltage regulator enable pin

Quoted 3 lines
Quoted 1 line

This is one heck of a complex GPIO driver!

The complexity comes from how the MCU command API was engineered and then when I took over the MCU firmware, I had to extend the command in a way that would ensure backwards compatibility.

Quoted 39 lines
Quoted 39 lines
drivers/platform/cznic/turris-omnia-mcu-gpio.c new file +39 -0
+
+#define _DEF_GPIO(_cmd, _ctl_cmd, _bit, _ctl_bit, _int_bit, _feat, _feat_mask) \
+       {                                                               \
+               .cmd = _cmd,                                            \
+               .ctl_cmd = _ctl_cmd,                                    \
+               .bit = _bit,                                            \
+               .ctl_bit = _ctl_bit,                                    \
+               .int_bit = (_int_bit) < 0 ? OMNIA_GPIO_INVALID_INT_BIT  \
+                                         : (_int_bit),                 \
+               .feat = _feat,                                          \
+               .feat_mask = _feat_mask,                                \
+       }
+#define _DEF_GPIO_STS(_name) \
+       _DEF_GPIO(OMNIA_CMD_GET_STATUS_WORD, 0, __bf_shf(OMNIA_STS_ ## _name), \
+                 0, __bf_shf(OMNIA_INT_ ## _name), 0, 0)
+#define _DEF_GPIO_CTL(_name) \
+       _DEF_GPIO(OMNIA_CMD_GET_STATUS_WORD, OMNIA_CMD_GENERAL_CONTROL, \
+                 __bf_shf(OMNIA_STS_ ## _name), __bf_shf(OMNIA_CTL_ ## _name), \
+                 -1, 0, 0)
+#define _DEF_GPIO_EXT_STS(_name, _feat) \
+       _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
+                 __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
+                 __bf_shf(OMNIA_INT_ ## _name), \
+                 OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS, \
+                 OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS)
+#define _DEF_GPIO_EXT_STS_LED(_name, _ledext) \
+       _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
+                 __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
+                 __bf_shf(OMNIA_INT_ ## _name), \
+                 OMNIA_FEAT_LED_STATE_ ## _ledext, \
+                 OMNIA_FEAT_LED_STATE_EXT_MASK)
+#define _DEF_GPIO_EXT_STS_LEDALL(_name) \
+       _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
+                 __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
+                 __bf_shf(OMNIA_INT_ ## _name), \
+                 OMNIA_FEAT_LED_STATE_EXT_MASK, 0)
+#define _DEF_GPIO_EXT_CTL(_name, _feat) \
+       _DEF_GPIO(OMNIA_CMD_GET_EXT_CONTROL_STATUS, OMNIA_CMD_EXT_CONTROL, \
+                 __bf_shf(OMNIA_EXT_CTL_ ## _name), \
Quoted 8 lines

drivers/platform/cznic/turris-omnia-mcu-gpio.c line 130

Quoted 6 lines
drivers/platform/cznic/turris-omnia-mcu-gpio.c new file +6 -0
+                 __bf_shf(OMNIA_EXT_CTL_ ## _name), -1, \
+                 OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS, \
+                 OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS)
+#define _DEF_INT(_name) \
+       _DEF_GPIO(0, 0, 0, 0, __bf_shf(OMNIA_INT_ ## _name), 0, 0)
+  

One coding-style nit: can you add newlines between these macros?

Sent v13 with this change.

Quoted 5 lines

I'm having a hard-time understanding the entire architecture of this MCU but the code overall looks good to me so I trust you know what you're doing.

Thanks.

Marek

author maintainer
#6 lore raw

PATCH v12 4/8 platform: cznic: turris-omnia-mcu: Add support for poweroff and wakeup

In reply to Marek Behún

Add support for true board poweroff (MCU can disable all unnecessary voltage regulators) and wakeup at a specified time, implemented via a RTC driver so that the rtcwake utility can be used to configure it.

---
 .../sysfs-bus-i2c-devices-turris-omnia-mcu    |  16 ++
 drivers/platform/cznic/Kconfig                |   4 +
 drivers/platform/cznic/Makefile               |   1 +
 .../platform/cznic/turris-omnia-mcu-base.c    |   5 +
 .../cznic/turris-omnia-mcu-sys-off-wakeup.c   | 260 ++++++++++++++++++
 drivers/platform/cznic/turris-omnia-mcu.h     |  20 ++
 6 files changed, 306 insertions(+)
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-sys-off-wakeup.c
Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu +16 -0
index 86360249080c..307a55f599cb 100644
@@ -38,6 +38,22 @@ Description:	(RW) The front button on the Turris Omnia router can be
 
 		Format: %s.
 
+What:		/sys/bus/i2c/devices/<mcu_device>/front_button_poweron
+Date:		September 2024
+KernelVersion:	6.11
+Contact:	Marek Behún <[email protected]>
+Description:	(RW) Newer versions of the microcontroller firmware of the
+		Turris Omnia router support powering off the router into true
+		low power mode. The router can be powered on by pressing the
+		front button.
+
+		This file configures whether front button power on is enabled.
+
+		This file is present only if the power off feature is supported
+		by the firmware.
+
+		Format: %i.
+
 What:		/sys/bus/i2c/devices/<mcu_device>/fw_features
 Date:		September 2024
 KernelVersion:	6.11
drivers/platform/cznic/Kconfig +4 -0
index d95e7c83c7ae..c1e719235517 100644
@@ -18,10 +18,14 @@ config TURRIS_OMNIA_MCU
 	depends on I2C
 	select GPIOLIB
 	select GPIOLIB_IRQCHIP
+	select RTC_CLASS
 	help
 	  Say Y here to add support for the features implemented by the
 	  microcontroller on the CZ.NIC's Turris Omnia SOHO router.
 	  The features include:
+	  - board poweroff into true low power mode (with voltage regulators
+	    disabled) and the ability to configure wake up from this mode (via
+	    rtcwake)
 	  - GPIO pins
 	    - to get front button press events (the front button can be
 	      configured either to generate press events to the CPU or to change
drivers/platform/cznic/Makefile +1 -0
index 53fd8f1777a3..a185ef882e44 100644
@@ -3,3 +3,4 @@
 obj-$(CONFIG_TURRIS_OMNIA_MCU)	+= turris-omnia-mcu.o
 turris-omnia-mcu-y		:= turris-omnia-mcu-base.o
 turris-omnia-mcu-y		+= turris-omnia-mcu-gpio.o
+turris-omnia-mcu-y		+= turris-omnia-mcu-sys-off-wakeup.o
drivers/platform/cznic/turris-omnia-mcu-base.c +5 -0
index 4481484b2f94..338a7ab12bd0 100644
@@ -198,6 +198,7 @@ static const struct attribute_group omnia_mcu_base_group = {
 static const struct attribute_group *omnia_mcu_groups[] = {
 	&omnia_mcu_base_group,
 	&omnia_mcu_gpio_group,
+	&omnia_mcu_poweroff_group,
 	NULL
 };
 
@@ -372,6 +373,10 @@ static int omnia_mcu_probe(struct i2c_client *client)
 					     "Cannot read board info\n");
 	}
 
+	err = omnia_mcu_register_sys_off_and_wakeup(mcu);
+	if (err)
+		return err;
+
 	return omnia_mcu_register_gpiochip(mcu);
 }
 
drivers/platform/cznic/turris-omnia-mcu-sys-off-wakeup.c new file +260 -0

260 lines not on this page · raw message

drivers/platform/cznic/turris-omnia-mcu.h +20 -0
index 3d2dd0054499..2a1c68ba9b7f 100644
@@ -15,8 +15,10 @@
 #include <linux/types.h>
 #include <linux/workqueue.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 
 struct i2c_client;
+struct rtc_device;
 
 struct omnia_mcu {
 	struct i2c_client *client;
@@ -36,6 +38,11 @@ struct omnia_mcu {
 	struct delayed_work button_release_emul_work;
 	unsigned long last_status;
 	bool button_pressed_emul;
+
+	/* RTC device for configuring wake-up */
+	struct rtc_device *rtcdev;
+	u32 rtc_alarm;
+	bool front_button_poweron;
 };
 
 int omnia_cmd_write_read(const struct i2c_client *client,
@@ -48,6 +55,17 @@ static inline int omnia_cmd_write(const struct i2c_client *client, void *cmd,
 	return omnia_cmd_write_read(client, cmd, len, NULL, 0);
 }
 
+static inline int omnia_cmd_write_u32(const struct i2c_client *client, u8 cmd,
+				      u32 val)
+{
+	u8 buf[5];
+
+	buf[0] = cmd;
+	put_unaligned_le32(val, &buf[1]);
+
+	return omnia_cmd_write(client, buf, sizeof(buf));
+}
+
 static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
 				 void *reply, unsigned int len)
 {
@@ -136,7 +154,9 @@ static inline int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd,
 }
 
 extern const struct attribute_group omnia_mcu_gpio_group;
+extern const struct attribute_group omnia_mcu_poweroff_group;
 
 int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
+int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
 
 #endif /* __TURRIS_OMNIA_MCU_H */
Signature · 1 line
2.44.2
#7 lore raw

Re: [PATCH v12 4/8] platform: cznic: turris-omnia-mcu: Add support for poweroff and wakeup

Hi Marek,

Quoted 7 lines · Marek Behún

Add support for true board poweroff (MCU can disable all unnecessary voltage regulators) and wakeup at a specified time, implemented via a RTC driver so that the rtcwake utility can be used to configure it.

...

Quoted 9 lines
drivers/platform/cznic/Kconfig +1 -0
index d95e7c83c7ae..c1e719235517 100644
@@ -18,10 +18,14 @@ config TURRIS_OMNIA_MCU
 	depends on I2C
 	select GPIOLIB
 	select GPIOLIB_IRQCHIP
+	select RTC_CLASS

drivers/platform/cznic/Kconfig config TURRIS_OMNIA_MCU · line 31

Quoted 10 lines
drivers/platform/cznic/Kconfig +3 -0
 	help
 	  Say Y here to add support for the features implemented by the
 	  microcontroller on the CZ.NIC's Turris Omnia SOHO router.
 	  The features include:
+	  - board poweroff into true low power mode (with voltage regulators
+	    disabled) and the ability to configure wake up from this mode (via
+	    rtcwake)
 	  - GPIO pins
 	    - to get front button press events (the front button can be
 	      configured either to generate press events to the CPU or to change

I am seeing the following Kconfig warning from ARCH=s390 allmodconfig:

WARNING: unmet direct dependencies detected for RTC_CLASS
Depends on [n]: !S390 [=y]
Selected by [m]:
- TURRIS_OMNIA_MCU [=m] && CZNIC_PLATFORMS [=y] && (MACH_ARMADA_38X || COMPILE_TEST [=y]) && I2C [=m] && OF [=y] && WATCHDOG [=y]

because of:

menuconfig RTC_CLASS
bool "Real Time Clock"
default n
depends on !S390

which appears to have ultimately come from commit 9556fb73edfc ("[S390]
Kconfig: unwanted menus for s390."). No other driver appears to unconditionally select this (I only see it selected within arch/*/Kconfig), so it does not look like this has come up before. Should s390 be excluded from the COMPILE_TEST dependency?

Cheers,
Nathan

#8 lore raw

Re: [PATCH v12 4/8] platform: cznic: turris-omnia-mcu: Add support for poweroff and wakeup

Quoted 44 lines · Nathan Chancellor
Quoted 7 lines · Marek Behún

Add support for true board poweroff (MCU can disable all unnecessary voltage regulators) and wakeup at a specified time, implemented via a RTC driver so that the rtcwake utility can be used to configure it.

...

Quoted 9 lines
drivers/platform/cznic/Kconfig +1 -0
index d95e7c83c7ae..c1e719235517 100644
@@ -18,10 +18,14 @@ config TURRIS_OMNIA_MCU
 	depends on I2C
 	select GPIOLIB
 	select GPIOLIB_IRQCHIP
+	select RTC_CLASS

drivers/platform/cznic/Kconfig config TURRIS_OMNIA_MCU · line 31

Quoted 10 lines
drivers/platform/cznic/Kconfig +3 -0
 	help
 	  Say Y here to add support for the features implemented by the
 	  microcontroller on the CZ.NIC's Turris Omnia SOHO router.
 	  The features include:
+	  - board poweroff into true low power mode (with voltage regulators
+	    disabled) and the ability to configure wake up from this mode (via
+	    rtcwake)
 	  - GPIO pins
 	    - to get front button press events (the front button can be
 	      configured either to generate press events to the CPU or to change

I am seeing the following Kconfig warning from ARCH=s390 allmodconfig:

WARNING: unmet direct dependencies detected for RTC_CLASS
Depends on [n]: !S390 [=y]
Selected by [m]:
- TURRIS_OMNIA_MCU [=m] && CZNIC_PLATFORMS [=y] && (MACH_ARMADA_38X
|| COMPILE_TEST [=y]) && I2C [=m] && OF [=y] && WATCHDOG [=y]

because of:

menuconfig RTC_CLASS
bool "Real Time Clock"
default n
depends on !S390

Quoted 5 lines

which appears to have ultimately come from commit 9556fb73edfc ("[S390]
Kconfig: unwanted menus for s390."). No other driver appears to unconditionally select this (I only see it selected within arch/*/Kconfig), so it does not look like this has come up before. Should s390 be excluded from the COMPILE_TEST dependency?

There is really no reason for a driver to select another subsystem, it not just causes problems like this one but also leads to circular dependencies and surprises when someone turns on a random driver and then turns it off again, leaving the the other subsystems accidentally enabled.

I've applied the fixup below now, leaving GPIOLIB_IRQCHIP as the only selected symbol since this is not user-visible.

Marek, you could consider changing the driver so it doesn't actually require all those subsystems at build time but instead just leaves out the functionality. Some subsystems actually have a stub implementation that makes it work by just dropping the dependency, but I did not try that here.

Arnd

8<------------
commit ed46f1f7731d2cd77d623c0f895df9e23c0bffb6

Author: Arnd Bergmann <[email protected]>
Date:   Mon Jul 15 08:02:30 2024 +0200

platform: cznic: turris-omnia-mcu: fix Kconfig dependencies

The newly added driver causes a Kconfig warning:

WARNING: unmet direct dependencies detected for RTC_CLASS
Depends on [n]: !S390 [=y]
Selected by [m]:
- TURRIS_OMNIA_MCU [=m] && CZNIC_PLATFORMS [=y] && (MACH_ARMADA_38X || COMPILE_TEST [=y]) && I2C [=m] && OF [=y] && WATCHDOG [=y]

The problem here is that it selects entire subsystems, which normal device drivers should not do. Changes all of these to 'depends on' instead.

Fixes dfa556e45ae9e ("platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs")
Fixes 90e700fd12b61 ("platform: cznic: turris-omnia-mcu: Add support for poweroff and wakeup")
Fixes ab89fb5fb92c7 ("platform: cznic: turris-omnia-mcu: Add support for MCU watchdog")
Fixes 41bb142a40289 ("platform: cznic: turris-omnia-mcu: Add support for MCU provided TRNG")
drivers/platform/cznic/Kconfig +4 -4
index 2a5235cf6844..cb0d4d686d8a 100644
@@ -18,11 +18,11 @@ config TURRIS_OMNIA_MCU
 	depends on I2C
 	depends on OF
 	depends on WATCHDOG
-	select GPIOLIB
+	depends on GPIOLIB
+	depends on HW_RANDOM
+	depends on RTC_CLASS
+	depends on WATCHDOG_CORE
 	select GPIOLIB_IRQCHIP
-	select HW_RANDOM
-	select RTC_CLASS
-	select WATCHDOG_CORE
 	help
 	  Say Y here to add support for the features implemented by the
 	  microcontroller on the CZ.NIC's Turris Omnia SOHO router.
author maintainer
#9 lore raw

Re: [PATCH v12 4/8] platform: cznic: turris-omnia-mcu: Add support for poweroff and wakeup

Quoted 2 lines · Arnd Bergmann
Quoted 1 line · Nathan Chancellor

On Mon, Jun 17, 2024 at 05:26:02PM +0200, Marek Behún wrote:

...

Quoted 22 lines
Quoted 16 lines

I am seeing the following Kconfig warning from ARCH=s390 allmodconfig:

WARNING: unmet direct dependencies detected for RTC_CLASS
Depends on [n]: !S390 [=y]
Selected by [m]:
- TURRIS_OMNIA_MCU [=m] && CZNIC_PLATFORMS [=y] && (MACH_ARMADA_38X
|| COMPILE_TEST [=y]) && I2C [=m] && OF [=y] && WATCHDOG [=y]

because of:

menuconfig RTC_CLASS
bool "Real Time Clock"
default n
depends on !S390

Quoted 5 lines

which appears to have ultimately come from commit 9556fb73edfc ("[S390]
Kconfig: unwanted menus for s390."). No other driver appears to unconditionally select this (I only see it selected within arch/*/Kconfig), so it does not look like this has come up before. Should s390 be excluded from the COMPILE_TEST dependency?

Quoted 5 lines

There is really no reason for a driver to select another subsystem, it not just causes problems like this one but also leads to circular dependencies and surprises when someone turns on a random driver and then turns it off again, leaving the the other subsystems accidentally enabled.

Makes sense.

Quoted 2 lines

I've applied the fixup below now, leaving GPIOLIB_IRQCHIP as the only selected symbol since this is not user-visible.

Thanks.

Quoted 5 lines

Marek, you could consider changing the driver so it doesn't actually require all those subsystems at build time but instead just leaves out the functionality. Some subsystems actually have a stub implementation that makes it work by just dropping the dependency, but I did not try that here.

I will look into that.

Marek

author maintainer
#10 lore raw

PATCH v12 5/8 platform: cznic: turris-omnia-mcu: Add support for MCU watchdog

In reply to Marek Behún

Add support for the watchdog mechanism provided by the MCU.

---
 drivers/platform/cznic/Kconfig                |   2 +
 drivers/platform/cznic/Makefile               |   1 +
 .../platform/cznic/turris-omnia-mcu-base.c    |   4 +
 .../cznic/turris-omnia-mcu-watchdog.c         | 130 ++++++++++++++++++
 drivers/platform/cznic/turris-omnia-mcu.h     |  24 ++++
 5 files changed, 161 insertions(+)
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-watchdog.c
drivers/platform/cznic/Kconfig +2 -0
index c1e719235517..e262930b3faf 100644
@@ -19,6 +19,7 @@ config TURRIS_OMNIA_MCU
 	select GPIOLIB
 	select GPIOLIB_IRQCHIP
 	select RTC_CLASS
+	select WATCHDOG_CORE
 	help
 	  Say Y here to add support for the features implemented by the
 	  microcontroller on the CZ.NIC's Turris Omnia SOHO router.
@@ -26,6 +27,7 @@ config TURRIS_OMNIA_MCU
 	  - board poweroff into true low power mode (with voltage regulators
 	    disabled) and the ability to configure wake up from this mode (via
 	    rtcwake)
+	  - MCU watchdog
 	  - GPIO pins
 	    - to get front button press events (the front button can be
 	      configured either to generate press events to the CPU or to change
drivers/platform/cznic/Makefile +1 -0
index a185ef882e44..687f7718c0a1 100644
@@ -4,3 +4,4 @@ obj-$(CONFIG_TURRIS_OMNIA_MCU)	+= turris-omnia-mcu.o
 turris-omnia-mcu-y		:= turris-omnia-mcu-base.o
 turris-omnia-mcu-y		+= turris-omnia-mcu-gpio.o
 turris-omnia-mcu-y		+= turris-omnia-mcu-sys-off-wakeup.o
+turris-omnia-mcu-y		+= turris-omnia-mcu-watchdog.o
drivers/platform/cznic/turris-omnia-mcu-base.c +4 -0
index 338a7ab12bd0..2d8e5c9a8dd1 100644
@@ -377,6 +377,10 @@ static int omnia_mcu_probe(struct i2c_client *client)
 	if (err)
 		return err;
 
+	err = omnia_mcu_register_watchdog(mcu);
+	if (err)
+		return err;
+
 	return omnia_mcu_register_gpiochip(mcu);
 }
 
drivers/platform/cznic/turris-omnia-mcu-watchdog.c new file +130 -0

130 lines not on this page · raw message

drivers/platform/cznic/turris-omnia-mcu.h +24 -0
index 2a1c68ba9b7f..dc59f415f611 100644
@@ -13,6 +13,7 @@
 #include <linux/if_ether.h>
 #include <linux/mutex.h>
 #include <linux/types.h>
+#include <linux/watchdog.h>
 #include <linux/workqueue.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
@@ -43,6 +44,9 @@ struct omnia_mcu {
 	struct rtc_device *rtcdev;
 	u32 rtc_alarm;
 	bool front_button_poweron;
+
+	/* MCU watchdog */
+	struct watchdog_device wdt;
 };
 
 int omnia_cmd_write_read(const struct i2c_client *client,
@@ -55,6 +59,25 @@ static inline int omnia_cmd_write(const struct i2c_client *client, void *cmd,
 	return omnia_cmd_write_read(client, cmd, len, NULL, 0);
 }
 
+static inline int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd,
+				     u8 val)
+{
+	u8 buf[2] = { cmd, val };
+
+	return omnia_cmd_write(client, buf, sizeof(buf));
+}
+
+static inline int omnia_cmd_write_u16(const struct i2c_client *client, u8 cmd,
+				      u16 val)
+{
+	u8 buf[3];
+
+	buf[0] = cmd;
+	put_unaligned_le16(val, &buf[1]);
+
+	return omnia_cmd_write(client, buf, sizeof(buf));
+}
+
 static inline int omnia_cmd_write_u32(const struct i2c_client *client, u8 cmd,
 				      u32 val)
 {
@@ -158,5 +181,6 @@ extern const struct attribute_group omnia_mcu_poweroff_group;
 
 int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
 int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
+int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
 
 #endif /* __TURRIS_OMNIA_MCU_H */
Signature · 1 line
2.44.2
maintainer Reviewed-by on v12 5/8
#11 lore raw

Re: [PATCH v12 5/8] platform: cznic: turris-omnia-mcu: Add support for MCU watchdog

Quoted 5 lines · Marek Behún

Add support for the watchdog mechanism provided by the MCU.

---

[ ... ]

drivers/platform/cznic/turris-omnia-mcu-watchdog.c line 70

Quoted 11 lines
drivers/platform/cznic/turris-omnia-mcu-watchdog.c new file +11 -0
+static unsigned int omnia_wdt_get_timeleft(struct watchdog_device *wdt)
+{
+	struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
+	u16 timeleft;
+	int err;
+
+	err = omnia_cmd_read_u16(mcu->client, OMNIA_CMD_GET_WDT_TIMELEFT,
+				 &timeleft);
+	if (err) {
+		dev_err(&mcu->client->dev, "Cannot get watchdog timeleft: %d\n",
+			err);

If that ever happens, it is likely going to be persistent, and will clog the kernel log. But then I figure it is not really worth arguing about, so

Guenter

author maintainer
#12 lore raw

PATCH v12 6/8 platform: cznic: turris-omnia-mcu: Add support for MCU provided TRNG

In reply to Marek Behún

Add support for true random number generator provided by the MCU. New Omnia boards come without the Atmel SHA204-A chip. Instead the crypto functionality is provided by new microcontroller, which has a TRNG peripheral.

---
 drivers/platform/cznic/Kconfig                |   2 +
 drivers/platform/cznic/Makefile               |   1 +
 .../platform/cznic/turris-omnia-mcu-base.c    |   6 +-
 .../platform/cznic/turris-omnia-mcu-gpio.c    |   2 +-
 .../platform/cznic/turris-omnia-mcu-trng.c    | 103 ++++++++++++++++++
 drivers/platform/cznic/turris-omnia-mcu.h     |   8 ++
 6 files changed, 120 insertions(+), 2 deletions(-)
 create mode 100644 drivers/platform/cznic/turris-omnia-mcu-trng.c
drivers/platform/cznic/Kconfig +2 -0
index e262930b3faf..6edac80d5fa3 100644
@@ -18,6 +18,7 @@ config TURRIS_OMNIA_MCU
 	depends on I2C
 	select GPIOLIB
 	select GPIOLIB_IRQCHIP
+	select HW_RANDOM
 	select RTC_CLASS
 	select WATCHDOG_CORE
 	help
@@ -27,6 +28,7 @@ config TURRIS_OMNIA_MCU
 	  - board poweroff into true low power mode (with voltage regulators
 	    disabled) and the ability to configure wake up from this mode (via
 	    rtcwake)
+	  - true random number generator (if available on the MCU)
 	  - MCU watchdog
 	  - GPIO pins
 	    - to get front button press events (the front button can be
drivers/platform/cznic/Makefile +1 -0
index 687f7718c0a1..eae4c6b341ff 100644
@@ -4,4 +4,5 @@ obj-$(CONFIG_TURRIS_OMNIA_MCU)	+= turris-omnia-mcu.o
 turris-omnia-mcu-y		:= turris-omnia-mcu-base.o
 turris-omnia-mcu-y		+= turris-omnia-mcu-gpio.o
 turris-omnia-mcu-y		+= turris-omnia-mcu-sys-off-wakeup.o
+turris-omnia-mcu-y		+= turris-omnia-mcu-trng.o
 turris-omnia-mcu-y		+= turris-omnia-mcu-watchdog.o
drivers/platform/cznic/turris-omnia-mcu-base.c +5 -1
index 2d8e5c9a8dd1..c68a7a84a951 100644
@@ -381,7 +381,11 @@ static int omnia_mcu_probe(struct i2c_client *client)
 	if (err)
 		return err;
 
-	return omnia_mcu_register_gpiochip(mcu);
+	err = omnia_mcu_register_gpiochip(mcu);
+	if (err)
+		return err;
+
+	return omnia_mcu_register_trng(mcu);
 }
 
 static const struct of_device_id of_omnia_mcu_match[] = {
drivers/platform/cznic/turris-omnia-mcu-gpio.c +1 -1
index 471dda5d7e1c..2d970c7f1937 100644
@@ -188,7 +188,7 @@ static const struct omnia_gpio omnia_gpios[64] = {
 };
 
 /* mapping from interrupts to indexes of GPIOs in the omnia_gpios array */
-static const u8 omnia_int_to_gpio_idx[32] = {
+const u8 omnia_int_to_gpio_idx[32] = {
 	[__bf_shf(OMNIA_INT_CARD_DET)]			= 4,
 	[__bf_shf(OMNIA_INT_MSATA_IND)]			= 5,
 	[__bf_shf(OMNIA_INT_USB30_OVC)]			= 6,
drivers/platform/cznic/turris-omnia-mcu-trng.c new file +103 -0

103 lines not on this page · raw message

drivers/platform/cznic/turris-omnia-mcu.h +8 -0
index dc59f415f611..2ca56ae13aa9 100644
@@ -9,7 +9,9 @@
 #define __TURRIS_OMNIA_MCU_H
 
 #include <linux/bitops.h>
+#include <linux/completion.h>
 #include <linux/gpio/driver.h>
+#include <linux/hw_random.h>
 #include <linux/if_ether.h>
 #include <linux/mutex.h>
 #include <linux/types.h>
@@ -47,6 +49,10 @@ struct omnia_mcu {
 
 	/* MCU watchdog */
 	struct watchdog_device wdt;
+
+	/* true random number generator */
+	struct hwrng trng;
+	struct completion trng_entropy_ready;
 };
 
 int omnia_cmd_write_read(const struct i2c_client *client,
@@ -176,11 +182,13 @@ static inline int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd,
 	return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
 }
 
+extern const u8 omnia_int_to_gpio_idx[32];
 extern const struct attribute_group omnia_mcu_gpio_group;
 extern const struct attribute_group omnia_mcu_poweroff_group;
 
 int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
 int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
+int omnia_mcu_register_trng(struct omnia_mcu *mcu);
 int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
 
 #endif /* __TURRIS_OMNIA_MCU_H */
Signature · 1 line
2.44.2
author maintainer
#13 lore raw

PATCH v12 7/8 ARM: dts: turris-omnia: Add MCU system-controller node

In reply to Marek Behún

Turris Omnia's MCU provides various features that can be configured over I2C at address 0x2a. Add device-tree node.

This does not carry a Fixes tag - we do not want this to get backported to stable kernels for the following reason: U-Boot since v2022.10 inserts a phy-reset-gpio property into the WAN ethernet node pointing to the MCU node if it finds the MCU node with a cznic,turris-omnia-mcu compatible. Thus if this change got backported to a stable kernel, the WAN interface driver would defer probe indefinitely (since it would wait for the turris-omnia-mcu driver which would not be present).

---
 .../dts/marvell/armada-385-turris-omnia.dts   | 22 ++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)
arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts +21 -1
index 7b755bb4e4e7..59079d63fe27 100644
@@ -218,7 +218,22 @@ i2c@0 {
 			#size-cells = <0>;
 			reg = <0>;
 
-			/* STM32F0 command interface at address 0x2a */
+			mcu: system-controller@2a {
+				compatible = "cznic,turris-omnia-mcu";
+				reg = <0x2a>;
+
+				pinctrl-names = "default";
+				pinctrl-0 = <&mcu_pins>;
+
+				interrupt-parent = <&gpio1>;
+				interrupts = <11 IRQ_TYPE_NONE>;
+
+				gpio-controller;
+				#gpio-cells = <3>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
 
 			led-controller@2b {
 				compatible = "cznic,turris-omnia-leds";
@@ -501,6 +516,11 @@ fixed-link {
 };
 
 &pinctrl {
+	mcu_pins: mcu-pins {
+		marvell,pins = "mpp43";
+		marvell,function = "gpio";
+	};
+
 	pcawan_pins: pcawan-pins {
 		marvell,pins = "mpp46";
 		marvell,function = "gpio";
Signature · 1 line
2.44.2
author maintainer
#14 lore raw

PATCH v12 8/8 ARM: dts: turris-omnia: Add GPIO key node for front button

In reply to Marek Behún

Now that we have the MCU device-tree node, which acts as a GPIO controller, add GPIO key node for the front button.

---
 .../boot/dts/marvell/armada-385-turris-omnia.dts    | 13 +++++++++++++
 1 file changed, 13 insertions(+)
arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts +13 -0
index 59079d63fe27..43202890c959 100644
@@ -112,6 +112,19 @@ sfp: sfp {
 		status = "disabled";
 	};
 
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		front-button {
+			label = "Front Button";
+			linux,code = <KEY_VENDOR>;
+			linux,can-disable;
+			gpios = <&mcu 0 12 GPIO_ACTIVE_HIGH>;
+			/* debouncing is done by the microcontroller */
+			debounce-interval = <0>;
+		};
+	};
+
 	sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,name = "SPDIF";
Signature · 1 line
2.44.2
author maintainer
#16 lore raw
Quoted 3 lines · On Mon, 1 Jul 2024 10:41:15 +0200 Marek Behún <[email protected]> wrote:

Hi Arnd,

will you be merging this series?

Just to clear up, I wanted to ask whether you will be merging or someone else should take stuff to drivers/platform.

Anyway, I sent v13 with one more cosmetic change, requested by Bart.

Marek