Multihost Physical LED Design
Design proposal for multi-host physical LED support.
Signed-off-by: Jayashree Dhanapal <jayashree-d@hcl.com>
Change-Id: I4a07aa084eaf8e911c380327a4884e4d1fe488a9
diff --git a/designs/multihost-physical-led.md b/designs/multihost-physical-led.md
new file mode 100644
index 0000000..0b538d7
--- /dev/null
+++ b/designs/multihost-physical-led.md
@@ -0,0 +1,244 @@
+# Physical LED Design Support
+
+Author: Velumani T (Velu), [velumanit@hcl](mailto:velumanit@hcl.com) Jayashree D
+(Jayashree), [jayashree-d@hcl](mailto:jayashree-d@hcl.com)
+
+Other contributors: None
+
+Created: July 10, 2022
+
+## Problem Description
+
+The existing phosphor-led-sysfs design exposes one service per LED configuration
+in device tree. Hence, multiple services will be created for multiple GPIO pins
+configured for LEDs.
+
+There are cases where multiple LEDs were configured in the device tree for each
+host and needs to be paired as a group of LEDs for the specified host in the
+multi host platform.
+
+For example, Power LED and System Identification LED combines into a single
+bicolor blue-yellow LED per host. A total of 4 × LEDs will be placed along the
+front edge of the board in a grid. The grid will be 2 × rows of 2 × LEDs to
+match the layout of the card slots.
+
+Depending on the status of each host, blue or yellow LED needs to be Blink, OFF
+or ON and other LEDs needs to be in OFF state. Therefore, bi-color LED needs to
+be paired as a group and exposed in the userspace.
+
+Based on the current design in phosphor-led-sysfs application, pairing groups
+will be difficult, since it exposes one service per LED. To abstract this method
+and also to create LEDs under a single service, a new application is proposed.
+
+## Background and References
+
+The below diagram represents the overview for current physical LED design.
+
+```
+
+ KERNEL META-PHOSPHOR PHOSPHOR-LED-SYSFS SERVICE
+
+ +------------+ Event 1 +----------+ LED 1 +-----------------------------+
+ | |----------->| |-------->| |
+ | LED 1 | Event 2 | | LED 2 | Service 1 : |
+ | |----------->| UDEV |-------->| xyz.openbmc_project. |
+ | LED 2 | ..... | Events | .... | Led.Controller.LED1 |
+ | | ..... | | .... | Service 2 : |
+ | LED 3 | Event N | | LED N | xyz.openbmc_project. |
+ | |----------->| |-------->| Led.Controller.LED2 |
+ | LED 4 | +----------+ | ....... |
+ | | | ....... |
+ | ....... | | Service N : |
+ | ....... | | xyz.openbmc_project. |
+ | ....... | | Led.Controller.LEDN |
+ | | +-----------------------------+
+ | LED N | |
+ | | |
+ +------------+ V
+ +----------------------------------+
+ | |
+ | Service 1 : |
+ | /xyz/openbmc_project/<led1> |
+ | |
+ | Service 2 : |
+ | /xyz/openbmc_project/<led2> |
+ | ....... |
+ | ....... |
+ | |
+ | Service N : |
+ | /xyz/openbmc_project/<ledN> |
+ | |
+ +----------------------------------+
+
+ PHOSPHSOR-LED-SYSFS DAEMON
+
+```
+
+The existing design uses sysfs entry as udev events for particular LED and
+triggers the necessary action to generate the dbus object path and interface for
+that specified service. It exposes one service per LED.
+
+**Example**
+
+```
+ busctl tree xyz.openbmc_project.LED.Controller.led1
+ `-/xyz
+ `-/xyz/openbmc_project
+ `-/xyz/openbmc_project/led
+ `-/xyz/openbmc_project/led/physical
+ `-/xyz/openbmc_project/led/physical/led1
+
+ busctl tree xyz.openbmc_project.LED.Controller.led2
+ `-/xyz
+ `-/xyz/openbmc_project
+ `-/xyz/openbmc_project/led
+ `-/xyz/openbmc_project/led/physical
+ `-/xyz/openbmc_project/led/physical/led2
+
+```
+
+## Requirements
+
+- To support the systemd service to trigger script.
+
+- Add DBUS API method for phosphor-led-sysfs daemon.
+
+## Proposed Design
+
+The below diagram represents the overview for proposed physical LED design.
+
+```
+
+ KERNEL PHOSPHOR-LED-SYSFS DAEMON
+
+ +------------+ Event 1 +--------+ +---------+ +--------------+
+ | |----------> | | | | | |
+ | LED 1 | Event 2 | UDEV | | SYSFS | | EXECUTABLE |
+ | |----------> | Events |----->| SERVICE |----->| (DBUS Method |
+ | LED 2 | ..... | | | | | call) |
+ | | Event N | | | | | |
+ | LED 3 |----------> +--------+ +---------+ +--------------+
+ | | |
+ | | V
+ | LED 4 | +------------------------------------------------------+
+ | | | +-----------+ +---------------------------------+ |
+ | ....... | | | | | Service : | |
+ | ....... | | | SYSTEMD | | | |
+ | ....... | | | SERVICE | | /xyz/openbmc_project/led/<led1>| |
+ | | | | ( LED. |-->| /xyz/openbmc_project/led/<led2>| |
+ | LED N | | |Controller)| | ..... | |
+ | | | | | | ..... | |
+ | | | | | | /xyz/openbmc_project/led/<ledN>| |
+ +------------+ | +-----------+ +---------------------------------+ |
+ +------------------------------------------------------+
+
+```
+
+This document proposes a new design for physical LED implementation.
+
+- Physical Leds are defined in the device tree under "leds" section and
+ corresponding GPIO pins are configured.
+
+```
+ leds {
+ compatible = "gpio-leds";
+
+ ledName {
+ label = "devicename:color:function";
+ gpios = <&gpio ASPEED_GPIO(M, 0) GPIO_ACTIVE_HIGH>;
+ };
+ };
+```
+
+- Dbus API method will be created in the phosphor-led-sysfs repository under
+ **_xyz.openbmc_project.Led.Sysfs.Internal_** interface name to add or remove
+ the LED, which will be coming from each udev LED event.
+
+```
+ NAME TYPE SIGNATURE RESULT/VALUE FLAGS
+
+ xyz.openbmc_project.Led.Sysfs.Internal interface - - -
+ .AddLED method s - -
+ .RemoveLED method s - -
+
+```
+
+- udev event will be triggered for each LED and service will be invoked to run
+ the executable for each LED event.
+
+- Executable will call Dbus API method in the phosphor-led-sysfs repository to
+ pass LED name as argument from udev, after the primary service started.
+
+- Phosphor-led-sysfs will have a single systemd service (primary service)
+ **_(xyz.openbmc_project.LED.Controller.service)_** running by default at
+ system startup.
+
+- Once Dbus API method call invoked, phosphor-led-sysfs daemon will retrieve the
+ LED name as parameter and map the name with /sys/class/leds path in the
+ hardware. Next, the dbus pbject path and interface will be created under
+ single systemd service (xyz.openbmc_project.LED.Controller).
+
+- The schema will be implemented in the phosphor-led-sysfs daemon. A group of
+ LEDs is paired for each host and the schema handles color control for that
+ group to activate one LED which must be Blink/ON/OFF state and set the
+ remaining LEDs in the group as OFF state.
+
+**_Example_**
+
+```
+
+ SERVICE xyz.openbmc_project.LED.Controller
+
+ INTERFACE xyz.openbmc_project.LED.Physical
+
+ OBJECT PATH
+
+ busctl tree xyz.openbmc_project.LED.Controller
+ `-/xyz
+ `-/xyz/openbmc_project
+ `-/xyz/openbmc_project/led
+ `-/xyz/openbmc_project/led/physical
+ `-/xyz/openbmc_project/led/physical/led1
+ `-/xyz/openbmc_project/led/physical/led2
+ ............
+ ............
+ `-/xyz/openbmc_project/led/physical/ledN
+```
+
+## Alternatives Considered
+
+**Approach 1**
+
+When the udev event is initialized for the LED, it will save those LED names in
+a file utilizing the script. Phosphor-led-sysfs will monitor the file using
+inotify to handle the changes. By reading the file, all the LEDs name will be
+retrieved and dbus path will be created for all the LEDs under single systemd
+service.
+
+inotify will monitor the file continuously and it needs to communicate between
+udev events and phosphor-led-sysfs application. Since, udev events can be
+generated before systemd service, inotify does not need to monitor the file
+afterwards and also it is not a well used mechanism to communicate.
+
+Executable for Dbus method is a better way to communicate with the application
+after the system startup and populate the dbus path for LEDs under single
+service.
+
+## Impacts
+
+These changes will have API impact since the dbus objects will exposes multiple
+LEDs path in single service. The systemd service will have single name
+**_xyz.openbmc_project.LED.Controller_** instead of multiple services.
+
+## Testing
+
+The proposed design is tested in a multiple hosts platform.
+
+**_Manual Test_** - The physical LEDs status will be tested using busctl
+commands in the hardware.
+
+**_Robot Test_** - The physical LEDs will be tested under robotframework using
+REST API in the system LEDs suite.
+
+**_Unit Test_** - The proposed code can be covered by the unit tests which are
+already present.