psu-ng: Move psu validation to event timer

During a BMC reset at power on, the validation would be performed while
the entity manager interfaces are still being added to D-Bus, therefore
causing an error log created because the information to determine which
power supplies may be present is missing from the configuration
information that entity manager publishes on D-Bus.

Move the validation to be called on a timer, so that every time an EM
interface is added, the timer resets, and the validation is called once
no more interfaces are detected.

Also call the validation through the timer during a power on in case EM
has not started yet (this is less common but still possible). The side
effect is that the validation occurs 2s after it's called during a power
on, but it doesn't delay the power on as it's scheduled through the
timer event.

Tested with debug traces:
- Reboot at power on performs validation after the EM interfaces are
  added and does not log an error.
Oct 05 14:33:52 p10bmc phosphor-psu-monitor[3472]: EM interface added
Oct 05 14:33:52 p10bmc phosphor-psu-monitor[3472]: EM interface added
Oct 05 14:33:53 p10bmc phosphor-psu-monitor[3472]: EM interface added: Start timer
Oct 05 14:33:53 p10bmc phosphor-psu-monitor[3472]: EM interface added
Oct 05 14:33:54 p10bmc phosphor-psu-monitor[3472]: EM interface added
Oct 05 14:33:54 p10bmc phosphor-psu-monitor[3472]: EM interface added: Start timer
Oct 05 14:33:54 p10bmc phosphor-psu-monitor[3472]: EM interface added
Oct 05 14:33:54 p10bmc phosphor-psu-monitor[3472]: EM interface added: Start timer
Oct 05 14:33:56 p10bmc phosphor-psu-monitor[3472]: validateConfig()
Oct 05 14:33:56 p10bmc phosphor-psu-monitor[3472]: validateConfig() validated

- Validation runs when power on is requested.
Oct 05 14:43:31 p10bmc phosphor-host-state-manager[714]: Change to Host State: xyz.openbmc_project.State.Host.HostState.TransitioningToRunning
Oct 05 14:43:31 p10bmc phosphor-psu-monitor[622]: powerOn: Start timer
Oct 05 14:43:33 p10bmc phosphor-psu-monitor[622]: validateConfig
Oct 05 14:43:33 p10bmc phosphor-psu-monitor[622]: validateConfig validated

- Validation runs when the phosphor-psu-monitor service is restarted at
  power on:
Oct 07 15:15:02 p10bmc phosphor-psu-monitor[19762]: initialize(): Start timer
Oct 07 15:15:04 p10bmc phosphor-psu-monitor[19762]: validateConfig
Oct 07 15:15:04 p10bmc phosphor-psu-monitor[19762]: validateConfig validated

Change-Id: I9f788622754604e5feb10cfec1ddc341c04c52a0
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/phosphor-power-supply/psu_manager.cpp b/phosphor-power-supply/psu_manager.cpp
index ee21a81..1afdfd2 100644
--- a/phosphor-power-supply/psu_manager.cpp
+++ b/phosphor-power-supply/psu_manager.cpp
@@ -44,6 +44,9 @@
     timer = std::make_unique<utility::Timer<ClockId::Monotonic>>(
         e, std::bind(&PSUManager::analyze, this), interval);
 
+    validationTimer = std::make_unique<utility::Timer<ClockId::Monotonic>>(
+        e, std::bind(&PSUManager::validateConfig, this));
+
     // Subscribe to power state changes
     powerService = util::getService(POWER_OBJ_PATH, POWER_IFACE, bus);
     powerOnMatch = std::make_unique<sdbusplus::bus::match_t>(
@@ -285,7 +288,7 @@
         // processed
         if (powerOn && !psus.empty() && !supportedConfigs.empty())
         {
-            validateConfig();
+            validationTimer->restartOnce(validationTimeout);
         }
     }
     catch (const std::exception& e)
@@ -311,7 +314,7 @@
         if (state)
         {
             powerOn = true;
-            validateConfig();
+            validationTimer->restartOnce(validationTimeout);
             clearFaults();
         }
         else
diff --git a/phosphor-power-supply/psu_manager.hpp b/phosphor-power-supply/psu_manager.hpp
index d95caa3..9a94b64 100644
--- a/phosphor-power-supply/psu_manager.hpp
+++ b/phosphor-power-supply/psu_manager.hpp
@@ -21,6 +21,10 @@
 namespace phosphor::power::manager
 {
 
+// Validation timeout. The EM interfaces are added about every second or less,
+// so double that time to 2s for the timeout value.
+constexpr auto validationTimeout = std::chrono::milliseconds(2000);
+
 /**
  * @class PSUManager
  *
@@ -84,7 +88,7 @@
             if (state)
             {
                 powerOn = true;
-                validateConfig();
+                validationTimer->restartOnce(validationTimeout);
             }
             else
             {
@@ -154,6 +158,14 @@
         timer;
 
     /**
+     * The timer that performs power supply validation as the entity manager
+     * interfaces show up in d-bus.
+     */
+    std::unique_ptr<
+        sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
+        validationTimer;
+
+    /**
      * Create an error
      *
      * @param[in] faultName - 'name' message for the BMC error log entry