Timer for fan speed increases

A oneshot timer is started on each target speed increase where the
amount of time configured is how long the fans within the zone are
allowed to reach the new target speed before additional speed increase
requests will be processed. Any speed increase request deltas that are
above the current speed increase delta being processed as the new target
speed will cause the timer to stop and the difference between the deltas
are added onto the target speed.

Change-Id: I064941c4e12c3e44be90880d6f32c6fbcf7ae32d
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/zone.cpp b/control/zone.cpp
index f5099c1..a4a0325 100644
--- a/control/zone.cpp
+++ b/control/zone.cpp
@@ -42,6 +42,7 @@
     _zoneNum(std::get<zoneNumPos>(def)),
     _defFloorSpeed(std::get<floorSpeedPos>(def)),
     _defCeilingSpeed(std::get<fullSpeedPos>(def)),
+    _incTimer(events, [this](){ this->incTimerExpired(); }),
     _decTimer(events, [this](){ this->decTimerExpired(); })
 {
     auto& fanDefs = std::get<fanListPos>(def);
@@ -100,7 +101,6 @@
     {
         _targetSpeed = (targetDelta - _incSpeedDelta) + _targetSpeed;
         _incSpeedDelta = targetDelta;
-        //TODO openbmc/openbmc#1625 Cancel current timer countdown
         //TODO Floor speed above target, update target to floor speed
         if (_targetSpeed < _floorSpeed)
         {
@@ -111,11 +111,23 @@
         {
             _targetSpeed = _ceilingSpeed;
         }
-
+        // Cancel current timer countdown
+        if (_incTimer.running())
+        {
+            _incTimer.stop();
+        }
         setSpeed(_targetSpeed);
-        //TODO openbmc/openbmc#1625 Start timer countdown for fan speed increase
+        // Start timer countdown for fan speed increase
+        //TODO Update time value to what's given in zones yaml
+        _incTimer.start(seconds(5),
+                        phosphor::fan::util::Timer::TimerType::oneshot);
     }
-    //TODO openbmc/openbmc#1625 Clear increase delta when timer expires
+}
+
+void Zone::incTimerExpired()
+{
+    // Clear increase delta when timer expires allowing additional speed
+    // increase requests or speed decreases to occur
     _incSpeedDelta = 0;
 }
 
@@ -130,9 +142,9 @@
 
 void Zone::decTimerExpired()
 {
-    // Only decrease speeds when no requested increases exist
-    //TODO Add increase timer not running (i.e. not in the middle of increasing)
-    if (_incSpeedDelta == 0)
+    // Only decrease speeds when no requested increases exist and
+    // the increase timer is not running (i.e. not in the middle of increasing)
+    if (_incSpeedDelta == 0 && !_incTimer.running())
     {
         // Target speed can not go below the defined floor speed
         if ((_targetSpeed < _decSpeedDelta) ||
diff --git a/control/zone.hpp b/control/zone.hpp
index bdde64a..dc5771c 100644
--- a/control/zone.hpp
+++ b/control/zone.hpp
@@ -208,6 +208,12 @@
         void requestSpeedDecrease(uint64_t targetDelta);
 
         /**
+         * @brief Callback function for the increase timer that delays
+         * processing of requested speed increases while fans are increasing
+         */
+        void incTimerExpired();
+
+        /**
          * @brief Callback function for the decrease timer that processes any
          * requested speed decreases if allowed
          */
@@ -276,6 +282,11 @@
         uint64_t _decSpeedDelta = 0;
 
         /**
+         * The increase timer object
+         */
+        phosphor::fan::util::Timer _incTimer;
+
+        /**
          * The decrease timer object
          */
         phosphor::fan::util::Timer _decTimer;