1 /**
2  * Copyright © 2020 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "device.hpp"
18 
19 #include "chassis.hpp"
20 #include "error_logging_utils.hpp"
21 #include "exception_utils.hpp"
22 #include "system.hpp"
23 
24 #include <exception>
25 
26 namespace phosphor::power::regulators
27 {
28 
29 void Device::addToIDMap(IDMap& idMap)
30 {
31     // Add this device to the map
32     idMap.addDevice(*this);
33 
34     // Add rails to the map
35     for (std::unique_ptr<Rail>& rail : rails)
36     {
37         idMap.addRail(*rail);
38     }
39 }
40 
41 void Device::clearCache()
42 {
43     // If presence detection is defined for this device
44     if (presenceDetection)
45     {
46         // Clear cached presence data
47         presenceDetection->clearCache();
48     }
49 }
50 
51 void Device::clearErrorHistory()
52 {
53     // Clear error history in each rail
54     for (std::unique_ptr<Rail>& rail : rails)
55     {
56         rail->clearErrorHistory();
57     }
58 }
59 
60 void Device::close(Services& services)
61 {
62     try
63     {
64         // Close I2C interface if it is open
65         if (i2cInterface->isOpen())
66         {
67             i2cInterface->close();
68         }
69     }
70     catch (const std::exception& e)
71     {
72         // Log error messages in journal
73         services.getJournal().logError(exception_utils::getMessages(e));
74         services.getJournal().logError("Unable to close device " + id);
75 
76         // Create error log entry
77         error_logging_utils::logError(std::current_exception(),
78                                       Entry::Level::Notice, services);
79     }
80 }
81 
82 void Device::configure(Services& services, System& system, Chassis& chassis)
83 {
84     // Verify device is present
85     if (isPresent(services, system, chassis))
86     {
87         // If configuration changes are defined for this device, apply them
88         if (configuration)
89         {
90             configuration->execute(services, system, chassis, *this);
91         }
92 
93         // Configure rails
94         for (std::unique_ptr<Rail>& rail : rails)
95         {
96             rail->configure(services, system, chassis, *this);
97         }
98     }
99 }
100 
101 void Device::detectPhaseFaults(Services& services, System& system,
102                                Chassis& chassis)
103 {
104     // Verify device is present
105     if (isPresent(services, system, chassis))
106     {
107         // If phase fault detection is defined for this device, execute it
108         if (phaseFaultDetection)
109         {
110             phaseFaultDetection->execute(services, system, chassis, *this);
111         }
112     }
113 }
114 
115 void Device::monitorSensors(Services& services, System& system,
116                             Chassis& chassis)
117 {
118     // Verify device is present
119     if (isPresent(services, system, chassis))
120     {
121         // Monitor sensors in each rail
122         for (std::unique_ptr<Rail>& rail : rails)
123         {
124             rail->monitorSensors(services, system, chassis, *this);
125         }
126     }
127 }
128 
129 } // namespace phosphor::power::regulators
130