Add support to watch for OCC errors

Change-Id: I98d95020a2d01e281e5c8efa825d6b4bd4c6c160
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 25e1358..5042ec5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,19 +2,22 @@
 noinst_HEADERS = \
 	occ_pass_through.hpp \
 	occ_status.hpp \
-	powercap.hpp
+	powercap.hpp \
+	occ_errors.hpp \
+	occ_events.hpp
 
 sbin_PROGRAMS = openpower-occ-control
 openpower_occ_control_SOURCES = \
 	occ_pass_through.cpp \
 	occ_status.cpp \
 	occ_device.cpp \
+	occ_errors.cpp \
 	app.cpp \
-	org/open_power/OCC/PassThrough/error.cpp \
-	powercap.cpp
+	powercap.cpp \
+	org/open_power/OCC/Device/error.cpp
 
-BUILT_SOURCES =  org/open_power/OCC/PassThrough/error.hpp \
-                 org/open_power/OCC/PassThrough/error.cpp
+BUILT_SOURCES =  org/open_power/OCC/Device/error.hpp \
+                 org/open_power/OCC/Device/error.cpp
 
 CLEANFILES = ${BUILT_SOURCES}
 
@@ -22,19 +25,21 @@
 	$(SDBUSPLUS_LIBS) \
 	$(PHOSPHOR_LOGGING_LIBS) \
 	$(OPENPOWER_DBUS_INTERFACES_LIBS) \
+	$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
         -lstdc++fs
 
 openpower_occ_control_CXXFLAGS =
 	$(SDBUSPLUS_CFLAGS) \
 	$(PHOSPHOR_LOGGING_CFLAGS) \
-	$(OPENPOWER_DBUS_INTERFACES_CFLAGS)
+	$(OPENPOWER_DBUS_INTERFACES_CFLAGS) \
+	$(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
 
-org/open_power/OCC/PassThrough/error.hpp: ${top_srcdir}/org/open_power/OCC/PassThrough.errors.yaml
+org/open_power/OCC/Device/error.hpp: ${top_srcdir}/org/open_power/OCC/Device.errors.yaml
 	@mkdir -p `dirname $@`
-	$(SDBUSPLUSPLUS) -r $(top_srcdir) error exception-header org.open_power.OCC.PassThrough > $@
+	$(SDBUSPLUSPLUS) -r $(top_srcdir) error exception-header org.open_power.OCC.Device > $@
 
-org/open_power/OCC/PassThrough/error.cpp: ${top_srcdir}/org/open_power/OCC/PassThrough.errors.yaml
+org/open_power/OCC/Device/error.cpp: ${top_srcdir}/org/open_power/OCC/Device.errors.yaml
 	@mkdir -p `dirname $@`
-	$(SDBUSPLUSPLUS) -r $(top_srcdir) error exception-cpp org.open_power.OCC.PassThrough > $@
+	$(SDBUSPLUSPLUS) -r $(top_srcdir) error exception-cpp org.open_power.OCC.Device > $@
 
-SUBDIRS = . test
\ No newline at end of file
+SUBDIRS = . test
diff --git a/app.cpp b/app.cpp
index 449bea3..ee02949 100644
--- a/app.cpp
+++ b/app.cpp
@@ -1,32 +1,44 @@
 #include <phosphor-logging/log.hpp>
-#include <exception>
+#include <phosphor-logging/elog.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <org/open_power/OCC/Device/error.hpp>
 #include "occ_manager.hpp"
+#include "occ_events.hpp"
+#include "elog-errors.hpp"
 #include "config.h"
 
+using namespace phosphor::logging;
+
+using namespace sdbusplus::org::open_power::OCC::Device::Error;
+using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
+                                Error::InternalFailure;
+
 int main(int argc, char* argv[])
 {
-    try
+    auto bus = sdbusplus::bus::new_default();
+
+    // Need sd_event to watch for OCC device errors
+    sd_event* event = nullptr;
+    auto r = sd_event_default(&event);
+    if (r < 0)
     {
-        auto bus = sdbusplus::bus::new_default();
-        bus.request_name(OCC_CONTROL_BUSNAME);
-
-        sdbusplus::server::manager::manager objManager(bus,
-                                                       OCC_CONTROL_ROOT);
-
-        open_power::occ::Manager mgr(bus);
-
-        while (true)
-        {
-            bus.process_discard();
-            bus.wait();
-        }
+        log<level::ERR>("Error creating a default sd_event handler");
+        return r;
     }
-    catch (const std::exception& e)
-    {
-        using namespace phosphor::logging;
-        log<level::ERR>(e.what());
-        return -1;
-    }
+    open_power::occ::EventPtr eventP{event};
+    event = nullptr;
+
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL);
+
+    sdbusplus::server::manager::manager objManager(bus, OCC_CONTROL_ROOT);
+    open_power::occ::Manager mgr(bus, eventP);
+
+    // Claim the bus since all the house keeping is done now
+    bus.request_name(OCC_CONTROL_BUSNAME);
+
+    // Wait for requests
+    sd_event_loop(eventP.get());
 
     return 0;
 }
diff --git a/configure.ac b/configure.ac
index e20fe7f..dadc118 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,6 +43,8 @@
     AC_MSG_ERROR(["Requires phosphor-logging package."]))
 PKG_CHECK_MODULES([OPENPOWER_DBUS_INTERFACES], [openpower-dbus-interfaces],,\
     AC_MSG_ERROR(["Requires openpower-dbus-interfaces package."]))
+PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces],,\
+    AC_MSG_ERROR(["Requires phosphor-dbus-interfaces package."]))
 
 # Check for sdbusplus
 PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus],, [AC_MSG_ERROR(["sdbusplus packaged required and not found"])])
@@ -91,6 +93,10 @@
 AS_IF([test "x$OCC_HWMON_PATH" == "x"], [OCC_HWMON_PATH="/sys/bus/platform/drivers/occ-hwmon/"])
 AC_DEFINE_UNQUOTED([OCC_HWMON_PATH], ["$OCC_HWMON_PATH"], [The OCC hwmon path])
 
+AC_ARG_VAR(DEV_PATH, [The device path])
+AS_IF([test "x$DEV_PATH" == "x"], [DEV_PATH="/sys/bus/platform/devices/"])
+AC_DEFINE_UNQUOTED([DEV_PATH], ["$DEV_PATH"], [The device path])
+
 AC_ARG_VAR(PS_DERATING_FACTOR, [The power supply derating factor])
 AS_IF([test "x$PS_DERATING_FACTOR" == "x"], [PS_DERATING_FACTOR=90])
 AC_DEFINE_UNQUOTED([PS_DERATING_FACTOR], [$PS_DERATING_FACTOR], [The power supply derating factor])
diff --git a/elog-errors.hpp b/elog-errors.hpp
index c9abdfa..823ffdb 100644
--- a/elog-errors.hpp
+++ b/elog-errors.hpp
@@ -65,6 +65,26 @@
 
 namespace sdbusplus
 {
+namespace org
+{
+namespace open_power
+{
+namespace OCC
+{
+namespace Device
+{
+namespace Error
+{
+    struct WriteFailure;
+} // namespace Error
+} // namespace Device
+} // namespace OCC
+} // namespace open_power
+} // namespace org
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
 namespace xyz
 {
 namespace openbmc_project
@@ -206,6 +226,26 @@
 {
 namespace openbmc_project
 {
+namespace Sensor
+{
+namespace Device
+{
+namespace Error
+{
+    struct ReadFailure;
+} // namespace Error
+} // namespace Device
+} // namespace Sensor
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
 namespace Common
 {
 namespace File
@@ -228,36 +268,16 @@
 {
 namespace OCC
 {
-namespace PassThrough
-{
-namespace Error
-{
-    struct OpenFailure;
-} // namespace Error
-} // namespace PassThrough
-} // namespace OCC
-} // namespace open_power
-} // namespace org
-} // namespace sdbusplus
-
-namespace sdbusplus
-{
-namespace xyz
-{
-namespace openbmc_project
-{
-namespace Sensor
-{
 namespace Device
 {
 namespace Error
 {
-    struct ReadFailure;
+    struct ConfigFailure;
 } // namespace Error
 } // namespace Device
-} // namespace Sensor
-} // namespace openbmc_project
-} // namespace xyz
+} // namespace OCC
+} // namespace open_power
+} // namespace org
 } // namespace sdbusplus
 
 namespace sdbusplus
@@ -268,13 +288,13 @@
 {
 namespace OCC
 {
-namespace PassThrough
+namespace Device
 {
 namespace Error
 {
-    struct ReadFailure;
+    struct OpenFailure;
 } // namespace Error
-} // namespace PassThrough
+} // namespace Device
 } // namespace OCC
 } // namespace open_power
 } // namespace org
@@ -308,13 +328,13 @@
 {
 namespace OCC
 {
-namespace PassThrough
+namespace Device
 {
 namespace Error
 {
-    struct WriteFailure;
+    struct ReadFailure;
 } // namespace Error
-} // namespace PassThrough
+} // namespace Device
 } // namespace OCC
 } // namespace open_power
 } // namespace org
@@ -351,6 +371,44 @@
 {
 namespace openbmc_project
 {
+namespace Control
+{
+namespace Host
+{
+namespace _CommandNotSupported
+{
+
+
+}  // namespace _CommandNotSupported
+
+struct CommandNotSupported
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+
+};
+
+} // namespace Host
+} // namespace Control
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Control::Host::Error::CommandNotSupported>
+{
+    using type = xyz::openbmc_project::Control::Host::CommandNotSupported;
+};
+
+}
+
+namespace xyz
+{
+namespace openbmc_project
+{
 namespace Common
 {
 namespace _Timeout
@@ -367,28 +425,12 @@
 
 }  // namespace _Timeout
 
-struct Timeout : public sdbusplus::exception_t
+struct Timeout
 {
-    static constexpr auto errName = "xyz.openbmc_project.Common.Timeout";
-    static constexpr auto errDesc = "Operation timed out.";
-    static constexpr auto L = level::INFO;
+    static constexpr auto L = level::ERR;
     using TIMEOUT_IN_MSEC = _Timeout::TIMEOUT_IN_MSEC;
     using metadata_types = std::tuple<TIMEOUT_IN_MSEC>;
 
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
 };
 
 } // namespace Common
@@ -413,6 +455,41 @@
 {
 namespace Common
 {
+namespace _InternalFailure
+{
+
+
+}  // namespace _InternalFailure
+
+struct InternalFailure
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+
+};
+
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>
+{
+    using type = xyz::openbmc_project::Common::InternalFailure;
+};
+
+}
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
 namespace _InvalidArgument
 {
 
@@ -435,29 +512,13 @@
 
 }  // namespace _InvalidArgument
 
-struct InvalidArgument : public sdbusplus::exception_t
+struct InvalidArgument
 {
-    static constexpr auto errName = "xyz.openbmc_project.Common.InvalidArgument";
-    static constexpr auto errDesc = "Invalid argument was given.";
-    static constexpr auto L = level::INFO;
+    static constexpr auto L = level::ERR;
     using ARGUMENT_NAME = _InvalidArgument::ARGUMENT_NAME;
     using ARGUMENT_VALUE = _InvalidArgument::ARGUMENT_VALUE;
     using metadata_types = std::tuple<ARGUMENT_NAME, ARGUMENT_VALUE>;
 
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
 };
 
 } // namespace Common
@@ -482,427 +543,41 @@
 {
 namespace Common
 {
-namespace _InternalFailure
+namespace File
+{
+namespace _Open
 {
 
-
-}  // namespace _InternalFailure
-
-struct InternalFailure : public sdbusplus::exception_t
+struct ERRNO
 {
-    static constexpr auto errName = "xyz.openbmc_project.Common.InternalFailure";
-    static constexpr auto errDesc = "The operation failed internally.";
-    static constexpr auto L = level::ERR;
-    using metadata_types = std::tuple<>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
-};
-
-} // namespace Common
-} // namespace openbmc_project
-} // namespace xyz
-
-
-namespace details
-{
-
-template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>
-{
-    using type = xyz::openbmc_project::Common::InternalFailure;
-};
-
-}
-
-namespace xyz
-{
-namespace openbmc_project
-{
-namespace Common
-{
-namespace Callout
-{
-namespace _Device
-{
-
-struct CALLOUT_ERRNO
-{
-    static constexpr auto str = "CALLOUT_ERRNO=%d";
-    static constexpr auto str_short = "CALLOUT_ERRNO";
+    static constexpr auto str = "ERRNO=%d";
+    static constexpr auto str_short = "ERRNO";
     using type = std::tuple<std::decay_t<decltype(str)>,int32_t>;
-    explicit constexpr CALLOUT_ERRNO(int32_t a) : _entry(entry(str, a)) {};
+    explicit constexpr ERRNO(int32_t a) : _entry(entry(str, a)) {};
     type _entry;
 };
-struct CALLOUT_DEVICE_PATH
+struct PATH
 {
-    static constexpr auto str = "CALLOUT_DEVICE_PATH=%s";
-    static constexpr auto str_short = "CALLOUT_DEVICE_PATH";
+    static constexpr auto str = "PATH=%s";
+    static constexpr auto str_short = "PATH";
     using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
-    explicit constexpr CALLOUT_DEVICE_PATH(const char* a) : _entry(entry(str, a)) {};
+    explicit constexpr PATH(const char* a) : _entry(entry(str, a)) {};
     type _entry;
 };
 
-}  // namespace _Device
+}  // namespace _Open
 
-struct Device : public sdbusplus::exception_t
+struct Open
 {
-    static constexpr auto errName = "xyz.openbmc_project.Common.Callout.Device";
-    static constexpr auto errDesc = "Generic device callout";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_ERRNO = _Device::CALLOUT_ERRNO;
-    using CALLOUT_DEVICE_PATH = _Device::CALLOUT_DEVICE_PATH;
-    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
-};
-
-} // namespace Callout
-} // namespace Common
-} // namespace openbmc_project
-} // namespace xyz
-
-
-namespace details
-{
-
-template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::Device>
-{
-    using type = xyz::openbmc_project::Common::Callout::Device;
-};
-
-}
-
-namespace xyz
-{
-namespace openbmc_project
-{
-namespace Common
-{
-namespace Callout
-{
-namespace _GPIO
-{
-
-struct CALLOUT_GPIO_NUM
-{
-    static constexpr auto str = "CALLOUT_GPIO_NUM=%u";
-    static constexpr auto str_short = "CALLOUT_GPIO_NUM";
-    using type = std::tuple<std::decay_t<decltype(str)>,uint32_t>;
-    explicit constexpr CALLOUT_GPIO_NUM(uint32_t a) : _entry(entry(str, a)) {};
-    type _entry;
-};
-
-}  // namespace _GPIO
-
-struct GPIO : public sdbusplus::exception_t
-{
-    static constexpr auto errName = "xyz.openbmc_project.Common.Callout.GPIO";
-    static constexpr auto errDesc = "Callout GPIO pin";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_GPIO_NUM = _GPIO::CALLOUT_GPIO_NUM;
-    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
-    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
-    using metadata_types = std::tuple<CALLOUT_GPIO_NUM, CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
-};
-
-} // namespace Callout
-} // namespace Common
-} // namespace openbmc_project
-} // namespace xyz
-
-
-namespace details
-{
-
-template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::GPIO>
-{
-    using type = xyz::openbmc_project::Common::Callout::GPIO;
-};
-
-}
-
-namespace xyz
-{
-namespace openbmc_project
-{
-namespace Common
-{
-namespace Callout
-{
-namespace _IIC
-{
-
-struct CALLOUT_IIC_BUS
-{
-    static constexpr auto str = "CALLOUT_IIC_BUS=%s";
-    static constexpr auto str_short = "CALLOUT_IIC_BUS";
-    using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
-    explicit constexpr CALLOUT_IIC_BUS(const char* a) : _entry(entry(str, a)) {};
-    type _entry;
-};
-struct CALLOUT_IIC_ADDR
-{
-    static constexpr auto str = "CALLOUT_IIC_ADDR=0x%hx";
-    static constexpr auto str_short = "CALLOUT_IIC_ADDR";
-    using type = std::tuple<std::decay_t<decltype(str)>,uint16_t>;
-    explicit constexpr CALLOUT_IIC_ADDR(uint16_t a) : _entry(entry(str, a)) {};
-    type _entry;
-};
-
-}  // namespace _IIC
-
-struct IIC : public sdbusplus::exception_t
-{
-    static constexpr auto errName = "xyz.openbmc_project.Common.Callout.IIC";
-    static constexpr auto errDesc = "Callout IIC device";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_IIC_BUS = _IIC::CALLOUT_IIC_BUS;
-    using CALLOUT_IIC_ADDR = _IIC::CALLOUT_IIC_ADDR;
-    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
-    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
-    using metadata_types = std::tuple<CALLOUT_IIC_BUS, CALLOUT_IIC_ADDR, CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
-};
-
-} // namespace Callout
-} // namespace Common
-} // namespace openbmc_project
-} // namespace xyz
-
-
-namespace details
-{
-
-template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::IIC>
-{
-    using type = xyz::openbmc_project::Common::Callout::IIC;
-};
-
-}
-
-namespace xyz
-{
-namespace openbmc_project
-{
-namespace Common
-{
-namespace Callout
-{
-namespace _Inventory
-{
-
-struct CALLOUT_INVENTORY_PATH
-{
-    static constexpr auto str = "CALLOUT_INVENTORY_PATH=%s";
-    static constexpr auto str_short = "CALLOUT_INVENTORY_PATH";
-    using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
-    explicit constexpr CALLOUT_INVENTORY_PATH(const char* a) : _entry(entry(str, a)) {};
-    type _entry;
-};
-
-}  // namespace _Inventory
-
-struct Inventory : public sdbusplus::exception_t
-{
-    static constexpr auto errName = "xyz.openbmc_project.Common.Callout.Inventory";
-    static constexpr auto errDesc = "Inventory item callout";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_INVENTORY_PATH = _Inventory::CALLOUT_INVENTORY_PATH;
-    using metadata_types = std::tuple<CALLOUT_INVENTORY_PATH>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
-};
-
-} // namespace Callout
-} // namespace Common
-} // namespace openbmc_project
-} // namespace xyz
-
-
-namespace details
-{
-
-template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::Inventory>
-{
-    using type = xyz::openbmc_project::Common::Callout::Inventory;
-};
-
-}
-
-namespace xyz
-{
-namespace openbmc_project
-{
-namespace Common
-{
-namespace Callout
-{
-namespace _IPMISensor
-{
-
-struct CALLOUT_IPMI_SENSOR_NUM
-{
-    static constexpr auto str = "CALLOUT_IPMI_SENSOR_NUM=%u";
-    static constexpr auto str_short = "CALLOUT_IPMI_SENSOR_NUM";
-    using type = std::tuple<std::decay_t<decltype(str)>,uint32_t>;
-    explicit constexpr CALLOUT_IPMI_SENSOR_NUM(uint32_t a) : _entry(entry(str, a)) {};
-    type _entry;
-};
-
-}  // namespace _IPMISensor
-
-struct IPMISensor : public sdbusplus::exception_t
-{
-    static constexpr auto errName = "xyz.openbmc_project.Common.Callout.IPMISensor";
-    static constexpr auto errDesc = "Callout IPMI sensor";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_IPMI_SENSOR_NUM = _IPMISensor::CALLOUT_IPMI_SENSOR_NUM;
-    using metadata_types = std::tuple<CALLOUT_IPMI_SENSOR_NUM>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
-};
-
-} // namespace Callout
-} // namespace Common
-} // namespace openbmc_project
-} // namespace xyz
-
-
-namespace details
-{
-
-template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::IPMISensor>
-{
-    using type = xyz::openbmc_project::Common::Callout::IPMISensor;
-};
-
-}
-
-namespace xyz
-{
-namespace openbmc_project
-{
-namespace Control
-{
-namespace Host
-{
-namespace _CommandNotSupported
-{
-
-
-}  // namespace _CommandNotSupported
-
-struct CommandNotSupported : public sdbusplus::exception_t
-{
-    static constexpr auto errName = "xyz.openbmc_project.Control.Host.CommandNotSupported";
-    static constexpr auto errDesc = "Command is not supported";
     static constexpr auto L = level::ERR;
-    using metadata_types = std::tuple<>;
+    using ERRNO = _Open::ERRNO;
+    using PATH = _Open::PATH;
+    using metadata_types = std::tuple<ERRNO, PATH>;
 
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
 };
 
-} // namespace Host
-} // namespace Control
+} // namespace File
+} // namespace Common
 } // namespace openbmc_project
 } // namespace xyz
 
@@ -911,177 +586,9 @@
 {
 
 template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Control::Host::Error::CommandNotSupported>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::File::Error::Open>
 {
-    using type = xyz::openbmc_project::Control::Host::CommandNotSupported;
-};
-
-}
-
-namespace org
-{
-namespace open_power
-{
-namespace OCC
-{
-namespace PassThrough
-{
-namespace _OpenFailure
-{
-
-
-}  // namespace _OpenFailure
-
-struct OpenFailure : public sdbusplus::exception_t
-{
-    static constexpr auto errName = "org.open_power.OCC.PassThrough.OpenFailure";
-    static constexpr auto errDesc = "Opening OCC device failed.";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
-    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
-    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
-};
-
-} // namespace PassThrough
-} // namespace OCC
-} // namespace open_power
-} // namespace org
-
-
-namespace details
-{
-
-template <>
-struct map_exception_type<sdbusplus::org::open_power::OCC::PassThrough::Error::OpenFailure>
-{
-    using type = org::open_power::OCC::PassThrough::OpenFailure;
-};
-
-}
-
-namespace org
-{
-namespace open_power
-{
-namespace OCC
-{
-namespace PassThrough
-{
-namespace _ReadFailure
-{
-
-
-}  // namespace _ReadFailure
-
-struct ReadFailure : public sdbusplus::exception_t
-{
-    static constexpr auto errName = "org.open_power.OCC.PassThrough.ReadFailure";
-    static constexpr auto errDesc = "Reading from OCC failed.";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
-    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
-    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
-};
-
-} // namespace PassThrough
-} // namespace OCC
-} // namespace open_power
-} // namespace org
-
-
-namespace details
-{
-
-template <>
-struct map_exception_type<sdbusplus::org::open_power::OCC::PassThrough::Error::ReadFailure>
-{
-    using type = org::open_power::OCC::PassThrough::ReadFailure;
-};
-
-}
-
-namespace org
-{
-namespace open_power
-{
-namespace OCC
-{
-namespace PassThrough
-{
-namespace _WriteFailure
-{
-
-
-}  // namespace _WriteFailure
-
-struct WriteFailure : public sdbusplus::exception_t
-{
-    static constexpr auto errName = "org.open_power.OCC.PassThrough.WriteFailure";
-    static constexpr auto errDesc = "Writing to OCC failed.";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
-    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
-    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
-};
-
-} // namespace PassThrough
-} // namespace OCC
-} // namespace open_power
-} // namespace org
-
-
-namespace details
-{
-
-template <>
-struct map_exception_type<sdbusplus::org::open_power::OCC::PassThrough::Error::WriteFailure>
-{
-    using type = org::open_power::OCC::PassThrough::WriteFailure;
+    using type = xyz::openbmc_project::Common::File::Open;
 };
 
 }
@@ -1090,122 +597,75 @@
 {
 namespace openbmc_project
 {
-namespace Control
+namespace Common
 {
-namespace Device
+namespace File
 {
-namespace _WriteFailure
+namespace _Seek
 {
 
-
-}  // namespace _WriteFailure
-
-struct WriteFailure : public sdbusplus::exception_t
+struct OFFSET
 {
-    static constexpr auto errName = "xyz.openbmc_project.Control.Device.WriteFailure";
-    static constexpr auto errDesc = "Failed to write to device.";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
-    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
-    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
-
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
+    static constexpr auto str = "OFFSET=%ll";
+    static constexpr auto str_short = "OFFSET";
+    using type = std::tuple<std::decay_t<decltype(str)>,int64_t>;
+    explicit constexpr OFFSET(int64_t a) : _entry(entry(str, a)) {};
+    type _entry;
 };
-
-} // namespace Device
-} // namespace Control
-} // namespace openbmc_project
-} // namespace xyz
-
-
-namespace details
+struct WHENCE
 {
-
-template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Control::Device::Error::WriteFailure>
-{
-    using type = xyz::openbmc_project::Control::Device::WriteFailure;
-};
-
-}
-
-namespace example
-{
-namespace xyz
-{
-namespace openbmc_project
-{
-namespace Example
-{
-namespace Device
-{
-namespace _Callout
-{
-
-struct CALLOUT_ERRNO_TEST
-{
-    static constexpr auto str = "CALLOUT_ERRNO_TEST=%d";
-    static constexpr auto str_short = "CALLOUT_ERRNO_TEST";
+    static constexpr auto str = "WHENCE=%d";
+    static constexpr auto str_short = "WHENCE";
     using type = std::tuple<std::decay_t<decltype(str)>,int32_t>;
-    explicit constexpr CALLOUT_ERRNO_TEST(int32_t a) : _entry(entry(str, a)) {};
+    explicit constexpr WHENCE(int32_t a) : _entry(entry(str, a)) {};
     type _entry;
 };
-struct CALLOUT_DEVICE_PATH_TEST
+struct ERRNO
 {
-    static constexpr auto str = "CALLOUT_DEVICE_PATH_TEST=%s";
-    static constexpr auto str_short = "CALLOUT_DEVICE_PATH_TEST";
+    static constexpr auto str = "ERRNO=%d";
+    static constexpr auto str_short = "ERRNO";
+    using type = std::tuple<std::decay_t<decltype(str)>,int32_t>;
+    explicit constexpr ERRNO(int32_t a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+struct PATH
+{
+    static constexpr auto str = "PATH=%s";
+    static constexpr auto str_short = "PATH";
     using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
-    explicit constexpr CALLOUT_DEVICE_PATH_TEST(const char* a) : _entry(entry(str, a)) {};
+    explicit constexpr PATH(const char* a) : _entry(entry(str, a)) {};
     type _entry;
 };
 
-}  // namespace _Callout
+}  // namespace _Seek
 
-struct Callout : public sdbusplus::exception_t
+struct Seek
 {
-    static constexpr auto errName = "example.xyz.openbmc_project.Example.Device.Callout";
-    static constexpr auto errDesc = "Generic device callout";
-    static constexpr auto L = level::INFO;
-    using CALLOUT_ERRNO_TEST = _Callout::CALLOUT_ERRNO_TEST;
-    using CALLOUT_DEVICE_PATH_TEST = _Callout::CALLOUT_DEVICE_PATH_TEST;
-    using metadata_types = std::tuple<CALLOUT_ERRNO_TEST, CALLOUT_DEVICE_PATH_TEST>;
+    static constexpr auto L = level::ERR;
+    using OFFSET = _Seek::OFFSET;
+    using WHENCE = _Seek::WHENCE;
+    using ERRNO = _Seek::ERRNO;
+    using PATH = _Seek::PATH;
+    using metadata_types = std::tuple<OFFSET, WHENCE, ERRNO, PATH>;
 
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
 };
 
-} // namespace Device
-} // namespace Example
+} // namespace File
+} // namespace Common
 } // namespace openbmc_project
 } // namespace xyz
-} // namespace example
 
 
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::File::Error::Seek>
+{
+    using type = xyz::openbmc_project::Common::File::Seek;
+};
+
+}
 
 namespace example
 {
@@ -1345,31 +805,38 @@
 {
 namespace Example
 {
-namespace Elog
+namespace Device
 {
-namespace _TestCallout
+namespace _Callout
 {
 
-struct DEV_ADDR
+struct CALLOUT_ERRNO_TEST
 {
-    static constexpr auto str = "DEV_ADDR=0x%.8X";
-    static constexpr auto str_short = "DEV_ADDR";
-    using type = std::tuple<std::decay_t<decltype(str)>,uint32_t>;
-    explicit constexpr DEV_ADDR(uint32_t a) : _entry(entry(str, a)) {};
+    static constexpr auto str = "CALLOUT_ERRNO_TEST=%d";
+    static constexpr auto str_short = "CALLOUT_ERRNO_TEST";
+    using type = std::tuple<std::decay_t<decltype(str)>,int32_t>;
+    explicit constexpr CALLOUT_ERRNO_TEST(int32_t a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+struct CALLOUT_DEVICE_PATH_TEST
+{
+    static constexpr auto str = "CALLOUT_DEVICE_PATH_TEST=%s";
+    static constexpr auto str_short = "CALLOUT_DEVICE_PATH_TEST";
+    using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
+    explicit constexpr CALLOUT_DEVICE_PATH_TEST(const char* a) : _entry(entry(str, a)) {};
     type _entry;
 };
 
-}  // namespace _TestCallout
+}  // namespace _Callout
 
-struct TestCallout : public sdbusplus::exception_t
+struct Callout : public sdbusplus::exception_t
 {
-    static constexpr auto errName = "example.xyz.openbmc_project.Example.Elog.TestCallout";
-    static constexpr auto errDesc = "This is test error TestCallout";
+    static constexpr auto errName = "example.xyz.openbmc_project.Example.Device.Callout";
+    static constexpr auto errDesc = "Generic device callout";
     static constexpr auto L = level::ERR;
-    using DEV_ADDR = _TestCallout::DEV_ADDR;
-    using CALLOUT_ERRNO_TEST = example::xyz::openbmc_project::Example::Device::Callout::CALLOUT_ERRNO_TEST;
-    using CALLOUT_DEVICE_PATH_TEST = example::xyz::openbmc_project::Example::Device::Callout::CALLOUT_DEVICE_PATH_TEST;
-    using metadata_types = std::tuple<DEV_ADDR, CALLOUT_ERRNO_TEST, CALLOUT_DEVICE_PATH_TEST>;
+    using CALLOUT_ERRNO_TEST = _Callout::CALLOUT_ERRNO_TEST;
+    using CALLOUT_DEVICE_PATH_TEST = _Callout::CALLOUT_DEVICE_PATH_TEST;
+    using metadata_types = std::tuple<CALLOUT_ERRNO_TEST, CALLOUT_DEVICE_PATH_TEST>;
 
     const char* name() const noexcept
     {
@@ -1387,7 +854,7 @@
     }
 };
 
-} // namespace Elog
+} // namespace Device
 } // namespace Example
 } // namespace openbmc_project
 } // namespace xyz
@@ -1401,56 +868,40 @@
 {
 namespace Common
 {
-namespace File
+namespace Callout
 {
-namespace _Open
+namespace _Device
 {
 
-struct ERRNO
+struct CALLOUT_ERRNO
 {
-    static constexpr auto str = "ERRNO=%d";
-    static constexpr auto str_short = "ERRNO";
+    static constexpr auto str = "CALLOUT_ERRNO=%d";
+    static constexpr auto str_short = "CALLOUT_ERRNO";
     using type = std::tuple<std::decay_t<decltype(str)>,int32_t>;
-    explicit constexpr ERRNO(int32_t a) : _entry(entry(str, a)) {};
+    explicit constexpr CALLOUT_ERRNO(int32_t a) : _entry(entry(str, a)) {};
     type _entry;
 };
-struct PATH
+struct CALLOUT_DEVICE_PATH
 {
-    static constexpr auto str = "PATH=%s";
-    static constexpr auto str_short = "PATH";
+    static constexpr auto str = "CALLOUT_DEVICE_PATH=%s";
+    static constexpr auto str_short = "CALLOUT_DEVICE_PATH";
     using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
-    explicit constexpr PATH(const char* a) : _entry(entry(str, a)) {};
+    explicit constexpr CALLOUT_DEVICE_PATH(const char* a) : _entry(entry(str, a)) {};
     type _entry;
 };
 
-}  // namespace _Open
+}  // namespace _Device
 
-struct Open : public sdbusplus::exception_t
+struct Device
 {
-    static constexpr auto errName = "xyz.openbmc_project.Common.File.Open";
-    static constexpr auto errDesc = "Failed to open a file";
-    static constexpr auto L = level::INFO;
-    using ERRNO = _Open::ERRNO;
-    using PATH = _Open::PATH;
-    using metadata_types = std::tuple<ERRNO, PATH>;
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO = _Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH = _Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
 
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
 };
 
-} // namespace File
+} // namespace Callout
 } // namespace Common
 } // namespace openbmc_project
 } // namespace xyz
@@ -1460,9 +911,9 @@
 {
 
 template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::File::Error::Open>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::Device>
 {
-    using type = xyz::openbmc_project::Common::File::Open;
+    using type = xyz::openbmc_project::Common::Callout::Device;
 };
 
 }
@@ -1473,74 +924,33 @@
 {
 namespace Common
 {
-namespace File
+namespace Callout
 {
-namespace _Seek
+namespace _GPIO
 {
 
-struct OFFSET
+struct CALLOUT_GPIO_NUM
 {
-    static constexpr auto str = "OFFSET=%ll";
-    static constexpr auto str_short = "OFFSET";
-    using type = std::tuple<std::decay_t<decltype(str)>,int64_t>;
-    explicit constexpr OFFSET(int64_t a) : _entry(entry(str, a)) {};
-    type _entry;
-};
-struct WHENCE
-{
-    static constexpr auto str = "WHENCE=%d";
-    static constexpr auto str_short = "WHENCE";
-    using type = std::tuple<std::decay_t<decltype(str)>,int32_t>;
-    explicit constexpr WHENCE(int32_t a) : _entry(entry(str, a)) {};
-    type _entry;
-};
-struct ERRNO
-{
-    static constexpr auto str = "ERRNO=%d";
-    static constexpr auto str_short = "ERRNO";
-    using type = std::tuple<std::decay_t<decltype(str)>,int32_t>;
-    explicit constexpr ERRNO(int32_t a) : _entry(entry(str, a)) {};
-    type _entry;
-};
-struct PATH
-{
-    static constexpr auto str = "PATH=%s";
-    static constexpr auto str_short = "PATH";
-    using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
-    explicit constexpr PATH(const char* a) : _entry(entry(str, a)) {};
+    static constexpr auto str = "CALLOUT_GPIO_NUM=%u";
+    static constexpr auto str_short = "CALLOUT_GPIO_NUM";
+    using type = std::tuple<std::decay_t<decltype(str)>,uint32_t>;
+    explicit constexpr CALLOUT_GPIO_NUM(uint32_t a) : _entry(entry(str, a)) {};
     type _entry;
 };
 
-}  // namespace _Seek
+}  // namespace _GPIO
 
-struct Seek : public sdbusplus::exception_t
+struct GPIO
 {
-    static constexpr auto errName = "xyz.openbmc_project.Common.File.Seek";
-    static constexpr auto errDesc = "Failed to seek a file";
-    static constexpr auto L = level::INFO;
-    using OFFSET = _Seek::OFFSET;
-    using WHENCE = _Seek::WHENCE;
-    using ERRNO = _Seek::ERRNO;
-    using PATH = _Seek::PATH;
-    using metadata_types = std::tuple<OFFSET, WHENCE, ERRNO, PATH>;
+    static constexpr auto L = level::ERR;
+    using CALLOUT_GPIO_NUM = _GPIO::CALLOUT_GPIO_NUM;
+    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_GPIO_NUM, CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
 
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
 };
 
-} // namespace File
+} // namespace Callout
 } // namespace Common
 } // namespace openbmc_project
 } // namespace xyz
@@ -1550,9 +960,161 @@
 {
 
 template <>
-struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::File::Error::Seek>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::GPIO>
 {
-    using type = xyz::openbmc_project::Common::File::Seek;
+    using type = xyz::openbmc_project::Common::Callout::GPIO;
+};
+
+}
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace _IIC
+{
+
+struct CALLOUT_IIC_BUS
+{
+    static constexpr auto str = "CALLOUT_IIC_BUS=%s";
+    static constexpr auto str_short = "CALLOUT_IIC_BUS";
+    using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
+    explicit constexpr CALLOUT_IIC_BUS(const char* a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+struct CALLOUT_IIC_ADDR
+{
+    static constexpr auto str = "CALLOUT_IIC_ADDR=0x%hx";
+    static constexpr auto str_short = "CALLOUT_IIC_ADDR";
+    using type = std::tuple<std::decay_t<decltype(str)>,uint16_t>;
+    explicit constexpr CALLOUT_IIC_ADDR(uint16_t a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+
+}  // namespace _IIC
+
+struct IIC
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_IIC_BUS = _IIC::CALLOUT_IIC_BUS;
+    using CALLOUT_IIC_ADDR = _IIC::CALLOUT_IIC_ADDR;
+    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_IIC_BUS, CALLOUT_IIC_ADDR, CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+
+};
+
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::IIC>
+{
+    using type = xyz::openbmc_project::Common::Callout::IIC;
+};
+
+}
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace _Inventory
+{
+
+struct CALLOUT_INVENTORY_PATH
+{
+    static constexpr auto str = "CALLOUT_INVENTORY_PATH=%s";
+    static constexpr auto str_short = "CALLOUT_INVENTORY_PATH";
+    using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
+    explicit constexpr CALLOUT_INVENTORY_PATH(const char* a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+
+}  // namespace _Inventory
+
+struct Inventory
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_INVENTORY_PATH = _Inventory::CALLOUT_INVENTORY_PATH;
+    using metadata_types = std::tuple<CALLOUT_INVENTORY_PATH>;
+
+};
+
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::Inventory>
+{
+    using type = xyz::openbmc_project::Common::Callout::Inventory;
+};
+
+}
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace _IPMISensor
+{
+
+struct CALLOUT_IPMI_SENSOR_NUM
+{
+    static constexpr auto str = "CALLOUT_IPMI_SENSOR_NUM=%u";
+    static constexpr auto str_short = "CALLOUT_IPMI_SENSOR_NUM";
+    using type = std::tuple<std::decay_t<decltype(str)>,uint32_t>;
+    explicit constexpr CALLOUT_IPMI_SENSOR_NUM(uint32_t a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+
+}  // namespace _IPMISensor
+
+struct IPMISensor
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_IPMI_SENSOR_NUM = _IPMISensor::CALLOUT_IPMI_SENSOR_NUM;
+    using metadata_types = std::tuple<CALLOUT_IPMI_SENSOR_NUM>;
+
+};
+
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Common::Callout::Error::IPMISensor>
+{
+    using type = xyz::openbmc_project::Common::Callout::IPMISensor;
 };
 
 }
@@ -1571,28 +1133,12 @@
 
 }  // namespace _SoftOffTimeout
 
-struct SoftOffTimeout : public sdbusplus::exception_t
+struct SoftOffTimeout
 {
-    static constexpr auto errName = "xyz.openbmc_project.State.Host.SoftOffTimeout";
-    static constexpr auto errDesc = "Host did not shutdown within configured time.";
-    static constexpr auto L = level::INFO;
+    static constexpr auto L = level::ERR;
     using TIMEOUT_IN_MSEC = xyz::openbmc_project::Common::Timeout::TIMEOUT_IN_MSEC;
     using metadata_types = std::tuple<TIMEOUT_IN_MSEC>;
 
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
 };
 
 } // namespace Host
@@ -1616,6 +1162,206 @@
 {
 namespace openbmc_project
 {
+namespace Control
+{
+namespace Device
+{
+namespace _WriteFailure
+{
+
+
+}  // namespace _WriteFailure
+
+struct WriteFailure
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+
+};
+
+} // namespace Device
+} // namespace Control
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Control::Device::Error::WriteFailure>
+{
+    using type = xyz::openbmc_project::Control::Device::WriteFailure;
+};
+
+}
+
+namespace org
+{
+namespace open_power
+{
+namespace OCC
+{
+namespace Device
+{
+namespace _OpenFailure
+{
+
+
+}  // namespace _OpenFailure
+
+struct OpenFailure
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+
+};
+
+} // namespace Device
+} // namespace OCC
+} // namespace open_power
+} // namespace org
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::org::open_power::OCC::Device::Error::OpenFailure>
+{
+    using type = org::open_power::OCC::Device::OpenFailure;
+};
+
+}
+
+namespace org
+{
+namespace open_power
+{
+namespace OCC
+{
+namespace Device
+{
+namespace _ReadFailure
+{
+
+
+}  // namespace _ReadFailure
+
+struct ReadFailure
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+
+};
+
+} // namespace Device
+} // namespace OCC
+} // namespace open_power
+} // namespace org
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::org::open_power::OCC::Device::Error::ReadFailure>
+{
+    using type = org::open_power::OCC::Device::ReadFailure;
+};
+
+}
+
+namespace org
+{
+namespace open_power
+{
+namespace OCC
+{
+namespace Device
+{
+namespace _WriteFailure
+{
+
+
+}  // namespace _WriteFailure
+
+struct WriteFailure
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+
+};
+
+} // namespace Device
+} // namespace OCC
+} // namespace open_power
+} // namespace org
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::org::open_power::OCC::Device::Error::WriteFailure>
+{
+    using type = org::open_power::OCC::Device::WriteFailure;
+};
+
+}
+
+namespace org
+{
+namespace open_power
+{
+namespace OCC
+{
+namespace Device
+{
+namespace _ConfigFailure
+{
+
+
+}  // namespace _ConfigFailure
+
+struct ConfigFailure
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+
+};
+
+} // namespace Device
+} // namespace OCC
+} // namespace open_power
+} // namespace org
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::org::open_power::OCC::Device::Error::ConfigFailure>
+{
+    using type = org::open_power::OCC::Device::ConfigFailure;
+};
+
+}
+
+namespace xyz
+{
+namespace openbmc_project
+{
 namespace Sensor
 {
 namespace Device
@@ -1626,29 +1372,13 @@
 
 }  // namespace _ReadFailure
 
-struct ReadFailure : public sdbusplus::exception_t
+struct ReadFailure
 {
-    static constexpr auto errName = "xyz.openbmc_project.Sensor.Device.ReadFailure";
-    static constexpr auto errDesc = "Failed to read from device.";
-    static constexpr auto L = level::INFO;
+    static constexpr auto L = level::ERR;
     using CALLOUT_ERRNO = xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
     using CALLOUT_DEVICE_PATH = xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
     using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
 
-    const char* name() const noexcept
-    {
-        return errName;
-    }
-
-    const char* description() const noexcept
-    {
-        return errDesc;
-    }
-
-    const char* what() const noexcept
-    {
-        return errName;
-    }
 };
 
 } // namespace Device
@@ -1753,6 +1483,64 @@
 {
 namespace Example
 {
+namespace Elog
+{
+namespace _TestCallout
+{
+
+struct DEV_ADDR
+{
+    static constexpr auto str = "DEV_ADDR=0x%.8X";
+    static constexpr auto str_short = "DEV_ADDR";
+    using type = std::tuple<std::decay_t<decltype(str)>,uint32_t>;
+    explicit constexpr DEV_ADDR(uint32_t a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+
+}  // namespace _TestCallout
+
+struct TestCallout : public sdbusplus::exception_t
+{
+    static constexpr auto errName = "example.xyz.openbmc_project.Example.Elog.TestCallout";
+    static constexpr auto errDesc = "This is test error TestCallout";
+    static constexpr auto L = level::ERR;
+    using DEV_ADDR = _TestCallout::DEV_ADDR;
+    using CALLOUT_ERRNO_TEST = example::xyz::openbmc_project::Example::Device::Callout::CALLOUT_ERRNO_TEST;
+    using CALLOUT_DEVICE_PATH_TEST = example::xyz::openbmc_project::Example::Device::Callout::CALLOUT_DEVICE_PATH_TEST;
+    using metadata_types = std::tuple<DEV_ADDR, CALLOUT_ERRNO_TEST, CALLOUT_DEVICE_PATH_TEST>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Elog
+} // namespace Example
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace example
+
+
+
+namespace example
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Example
+{
 namespace Foo
 {
 namespace _Foo
diff --git a/occ_device.hpp b/occ_device.hpp
index dc057be..6538597 100644
--- a/occ_device.hpp
+++ b/occ_device.hpp
@@ -2,6 +2,8 @@
 
 #include <fstream>
 #include <experimental/filesystem>
+#include "occ_events.hpp"
+#include "occ_errors.hpp"
 #include "config.h"
 namespace open_power
 {
@@ -25,10 +27,16 @@
 
         /** @brief Constructs the Device object
          *
-         *  @param[in] name - OCC instance name
+         *  @param[in] event    - Unique ptr reference to sd_event
+         *  @param[in] name     - OCC instance name
+         *  @param[in] callback - Optional callback on errors
          */
-        Device(const std::string& name) :
-            config(name + '-' + "dev0")
+        Device(EventPtr& event,
+               const std::string& name,
+               std::function<void()> callBack = nullptr) :
+            config(name + '-' + "dev0"),
+            errorFile(fs::path(config) / "occ_error"),
+            error(event, errorFile, callBack)
         {
             // Nothing to do here
         }
@@ -36,20 +44,38 @@
         /** @brief Binds device to the OCC driver */
         inline void bind()
         {
+            // Bind the device
             return write(bindPath, config);
         }
 
         /** @brief Un-binds device from the OCC driver */
         inline void unBind()
         {
-            return write(unBindPath, config);
+           // Unbind the device
+           return write(unBindPath, config);
+        }
+
+        /** @brief Starts to monitor for errors */
+        inline void addErrorWatch()
+        {
+            return error.addWatch();
+        }
+
+        /** @brief stops monitoring for errors */
+        inline void removeErrorWatch()
+        {
+           return error.removeWatch();
         }
 
     private:
         /** @brief Config value to be used to do bind and unbind */
         const std::string config;
 
+        /** @brief This file contains 0 for success, non-zero for errors */
+        const fs::path errorFile;
+
         /**  @brief To bind the device to the OCC driver, do:
+         *
          *    Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
          */
         static fs::path bindPath;
@@ -59,6 +85,9 @@
          */
         static fs::path unBindPath;
 
+        /** Abstraction of error monitoring */
+        Error error;
+
         /** @brief file writer to achieve bind and unbind
          *
          *  @param[in] filename - Name of file to be written
diff --git a/occ_errors.cpp b/occ_errors.cpp
new file mode 100644
index 0000000..f2da49f
--- /dev/null
+++ b/occ_errors.cpp
@@ -0,0 +1,145 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <org/open_power/OCC/Device/error.hpp>
+#include "occ_errors.hpp"
+#include "elog-errors.hpp"
+namespace open_power
+{
+namespace occ
+{
+
+// Value in error file indicating success
+constexpr auto NO_ERROR = '0';
+
+using namespace phosphor::logging;
+using namespace sdbusplus::org::open_power::OCC::Device::Error;
+using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
+                                Error::InternalFailure;
+
+// Populate the file descriptor on the error file
+void Error::openFile()
+{
+    using namespace phosphor::logging;
+
+    fd = open(file.c_str(), O_RDONLY | O_NONBLOCK);
+    if (fd < 0)
+    {
+        elog<OpenFailure>(
+            phosphor::logging::org::open_power::OCC::Device::
+                OpenFailure::CALLOUT_ERRNO(errno),
+            phosphor::logging::org::open_power::OCC::Device::
+                OpenFailure::CALLOUT_DEVICE_PATH(file.c_str()));
+    }
+}
+
+// Attaches the FD to event loop and registers the callback handler
+void Error::registerCallBack()
+{
+    decltype(eventSource.get()) sourcePtr = nullptr;
+    auto r = sd_event_add_io(event.get(), &sourcePtr, fd,
+                             EPOLLIN, processEvents, this);
+    eventSource.reset(sourcePtr);
+
+    if (r < 0)
+    {
+        log<level::ERR>("Failed to register callback handler",
+                entry("ERROR=%s", strerror(-r)));
+        elog<InternalFailure>();
+    }
+}
+
+// Starts to watch for errors
+void Error::addWatch()
+{
+    // Open the file
+    openFile();
+
+    // register the callback handler
+    registerCallBack();
+}
+
+// Stops watching for errors
+void Error::removeWatch()
+{
+    // Close the file
+    if (fd >= 0)
+    {
+        close(fd);
+    }
+
+    // Reduce the reference count. Since there is only one instances
+    // of add_io, this will result empty loop
+    eventSource.reset();
+}
+
+// Callback handler when there is an activity on the FD
+int Error::processEvents(sd_event_source* es, int fd,
+                         uint32_t revents, void* userData)
+{
+    log<level::INFO>("Error file updated");
+    auto error = static_cast<Error*>(userData);
+
+    error->analyzeEvent();
+    return 0;
+}
+
+// Reads the error file and analyzes the data
+void Error::analyzeEvent()
+{
+    // Get the number of bytes to read
+    int len = -1;
+    auto r = ioctl(fd, FIONREAD, &len);
+    if (r < 0)
+    {
+        elog<ConfigFailure>(
+            phosphor::logging::org::open_power::OCC::Device::
+                ConfigFailure::CALLOUT_ERRNO(errno),
+            phosphor::logging::org::open_power::OCC::Device::
+                ConfigFailure::CALLOUT_DEVICE_PATH(file.c_str()));
+    }
+
+    // A non-zero data indicates an error condition
+    // Let the caller take appropriate action on this
+    auto data = readFile(len);
+    if (data.empty() ||
+            data.front() == NO_ERROR)
+    {
+        return;
+    }
+
+    // This must be an error
+    if (callBack)
+    {
+        callBack();
+    }
+    return;
+}
+
+// Reads so many bytes as passed in
+std::string Error::readFile(int len) const
+{
+    auto data = std::make_unique<char[]>(len+1);
+
+    // This file get created soon after binding. A value of 0 is
+    // deemed success and anything else is a Failure
+    // Since all the sysfs files would have size of 4096, if we read 0
+    // bytes -or- value '0', then it just means we are fine
+    auto r = read(fd, data.get(), len);
+    if (r < 0)
+    {
+        elog<ReadFailure>(
+            phosphor::logging::org::open_power::OCC::Device::
+                ReadFailure::CALLOUT_ERRNO(errno),
+            phosphor::logging::org::open_power::OCC::Device::
+                ReadFailure::CALLOUT_DEVICE_PATH(file.c_str()));
+    }
+    return std::string(data.get());
+}
+
+} // namespace occ
+} // namespace open_power
diff --git a/occ_errors.hpp b/occ_errors.hpp
new file mode 100644
index 0000000..1e66ffc
--- /dev/null
+++ b/occ_errors.hpp
@@ -0,0 +1,107 @@
+#pragma once
+
+#include <unistd.h>
+#include <functional>
+#include <experimental/filesystem>
+#include "occ_events.hpp"
+#include "config.h"
+namespace open_power
+{
+namespace occ
+{
+
+namespace fs = std::experimental::filesystem;
+
+/** @class Error
+ *  @brief Monitors for OCC device error condition
+ */
+class Error
+{
+    public:
+        Error() = delete;
+        Error(const Error&) = delete;
+        Error& operator=(const Error&) = delete;
+        Error(Error&&) = default;
+        Error& operator=(Error&&) = default;
+
+        /** @brief Constructs the Error object
+         *
+         *  @param[in] event    - reference to sd_event unique_ptr
+         *  @param[in] file     - File used by driver to communicate errors
+         *  @param[in] callBack - Optional function callback on error condition
+         */
+        Error(EventPtr& event,
+              const fs::path& file,
+              std::function<void()> callBack = nullptr) :
+            event(event),
+            file(fs::path(DEV_PATH) / file),
+            callBack(callBack)
+        {
+            // Nothing to do here.
+        }
+
+        ~Error()
+        {
+            if (fd>= 0)
+            {
+                close(fd);
+            }
+        }
+
+        /** @brief Starts to monitor for error conditions */
+        void addWatch();
+
+        /** @brief Removes error watch */
+        void removeWatch();
+
+    private:
+        /** @brief sd_event wrapped in unique_ptr */
+        EventPtr& event;
+
+        /** @brief event source wrapped in unique_ptr */
+        EventSourcePtr eventSource;
+
+        /** Error file */
+        const fs::path file;
+
+        /** @brief Optional function to call on error scenario */
+        std::function<void()> callBack;
+
+        /** @brief File descriptor to watch for errors */
+        int fd = -1;
+
+        /** @brief attaches FD to events and sets up callback handler */
+        void registerCallBack();
+
+        /** @brief Opens the file and populates fd */
+        void openFile();
+
+        /** @brief Reads file data
+         *
+         *  @return data read. Since its a /sysfs entry,
+         *          it would be a string
+         */
+        std::string readFile(int) const;
+
+        /** @brief Callback handler when the FD has some activity on it
+         *
+         *  @param[in] es       - Populated event source
+         *  @param[in] fd       - Associated File descriptor
+         *  @param[in] revents  - Type of event
+         *  @param[in] userData - User data that was passed during registration
+         *
+         *  @return             - 0 or positive number on success and negative
+         *                        errno otherwise
+         */
+        static int processEvents(sd_event_source* es, int fd,
+                                 uint32_t revents, void* userData);
+
+        /** @brief When the error event is received, analyzes it
+         *         and makes a callback to error handler if the
+         *         content denotes an error condition
+         */
+        void analyzeEvent();
+};
+
+} // namespace occ
+} // namespace open_power
diff --git a/occ_events.hpp b/occ_events.hpp
new file mode 100644
index 0000000..cc6f616
--- /dev/null
+++ b/occ_events.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <systemd/sd-event.h>
+namespace open_power
+{
+namespace occ
+{
+
+/* Need a custom deleter for freeing up sd_event */
+struct EventDeleter
+{
+    void operator()(sd_event* event) const
+    {
+        event = sd_event_unref(event);
+    }
+};
+using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
+
+/* Need a custom deleter for freeing up sd_event_source */
+struct EventSourceDeleter
+{
+    void operator()(sd_event_source* eventSource) const
+    {
+        eventSource = sd_event_source_unref(eventSource);
+    }
+};
+using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
+
+} // namespace occ
+} // namespace open_power
diff --git a/occ_manager.hpp b/occ_manager.hpp
index 48cd9c8..4430d74 100644
--- a/occ_manager.hpp
+++ b/occ_manager.hpp
@@ -32,10 +32,14 @@
 
         /** @brief Adds OCC pass-through and status objects on the bus
          *         when corresponding CPU inventory is created.
-         *  @param[in] bus - handle to the bus
+         *
+         *  @param[in] bus   - handle to the bus
+         *  @param[in] event - Unique ptr reference to sd_event
          */
-        Manager(sdbusplus::bus::bus& bus):
-            bus(bus)
+        Manager(sdbusplus::bus::bus& bus,
+                EventPtr& event) :
+            bus(bus),
+            event(event)
         {
             for (auto id = 0; id < MAX_CPUS; ++id)
             {
@@ -50,7 +54,7 @@
         }
 
         /** @brief Callback that responds to cpu creation in the inventory -
-         *         by creating the occ passthrough and status objects.
+         *         by creating the needed objects.
          *
          *  @param[in] msg - bus message
          *
@@ -78,6 +82,7 @@
             statusObjects.emplace_back(
                 std::make_unique<Status>(
                     bus,
+                    event,
                     path.c_str()));
 
             // Create the power cap monitor object for master occ (0)
@@ -94,6 +99,9 @@
         /** @brief reference to the bus */
         sdbusplus::bus::bus& bus;
 
+        /** @brief reference to sd_event wrapped in unique_ptr */
+        EventPtr& event;
+
         /** @brief OCC pass-through objects */
         std::vector<std::unique_ptr<PassThrough>> passThroughObjects;
 
diff --git a/occ_pass_through.cpp b/occ_pass_through.cpp
index fbb98c2..2846dda 100644
--- a/occ_pass_through.cpp
+++ b/occ_pass_through.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 #include <phosphor-logging/log.hpp>
 #include <phosphor-logging/elog.hpp>
-#include <org/open_power/OCC/PassThrough/error.hpp>
+#include <org/open_power/OCC/Device/error.hpp>
 #include "occ_pass_through.hpp"
 #include "elog-errors.hpp"
 namespace open_power
@@ -25,7 +25,7 @@
 int PassThrough::openDevice()
 {
     using namespace phosphor::logging;
-    using namespace sdbusplus::org::open_power::OCC::PassThrough::Error;
+    using namespace sdbusplus::org::open_power::OCC::Device::Error;
 
     // Device instance number starts from 1.
     devicePath.append(std::to_string((this->path.back() - '0') + 1));
@@ -35,9 +35,9 @@
     {
         // This would log and terminate since its not handled.
         elog<OpenFailure>(
-            phosphor::logging::org::open_power::OCC::PassThrough::
+            phosphor::logging::org::open_power::OCC::Device::
                 OpenFailure::CALLOUT_ERRNO(errno),
-            phosphor::logging::org::open_power::OCC::PassThrough::
+            phosphor::logging::org::open_power::OCC::Device::
                 OpenFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
     }
     return fd;
@@ -46,7 +46,7 @@
 std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
 {
     using namespace phosphor::logging;
-    using namespace sdbusplus::org::open_power::OCC::PassThrough::Error;
+    using namespace sdbusplus::org::open_power::OCC::Device::Error;
 
     std::vector<int32_t> response {};
 
@@ -65,9 +65,9 @@
     {
         // This would log and terminate since its not handled.
         elog<WriteFailure>(
-            phosphor::logging::org::open_power::OCC::PassThrough::
+            phosphor::logging::org::open_power::OCC::Device::
                 WriteFailure::CALLOUT_ERRNO(errno),
-            phosphor::logging::org::open_power::OCC::PassThrough::
+            phosphor::logging::org::open_power::OCC::Device::
                 WriteFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
     }
 
@@ -95,9 +95,9 @@
         {
             // This would log and terminate since its not handled.
             elog<ReadFailure>(
-                phosphor::logging::org::open_power::OCC::PassThrough::
+                phosphor::logging::org::open_power::OCC::Device::
                     ReadFailure::CALLOUT_ERRNO(errno),
-                phosphor::logging::org::open_power::OCC::PassThrough::
+                phosphor::logging::org::open_power::OCC::Device::
                     ReadFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
         }
     }
diff --git a/occ_status.cpp b/occ_status.cpp
index ca8a1f9..83825c5 100644
--- a/occ_status.cpp
+++ b/occ_status.cpp
@@ -13,15 +13,28 @@
         {
             // Bind the device
             device.bind();
+
+            // And watch for errors
+            device.addErrorWatch();
         }
         else
         {
-            // Do the unbind
+            // Stop watching for errors
+            device.removeErrorWatch();
+
+            // Do the unbind.
             device.unBind();
         }
     }
     return Base::Status::occActive(value);
 }
 
+// Callback handler when a device error is reported.
+void Status::deviceErrorHandler()
+{
+    // This would deem OCC inactive
+    this->occActive(false);
+}
+
 } // namespace occ
 } // namespace open_power
diff --git a/occ_status.hpp b/occ_status.hpp
index 5d092b7..f426048 100644
--- a/occ_status.hpp
+++ b/occ_status.hpp
@@ -3,6 +3,7 @@
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/server/object.hpp>
 #include <org/open_power/OCC/Status/server.hpp>
+#include "occ_events.hpp"
 #include "occ_device.hpp"
 namespace open_power
 {
@@ -25,15 +26,18 @@
         Status(Status&&) = default;
         Status& operator=(Status&&) = default;
 
-        /** @brief Constructs the Status object
+        /** @brief Constructs the Status object and
+         *         the underlying device object
          *
          *  @param[in] bus  - DBus bus to attach to
          *  @param[in] path - DBus object path
          */
-        Status(sdbusplus::bus::bus& bus, const char* path)
+        Status(sdbusplus::bus::bus& bus, EventPtr& event, const char* path)
             : Interface(bus, path),
               path(path),
-              device(name + std::to_string((this->path.back() - '0') + 1))
+              device(event,
+                     name + std::to_string((this->path.back() - '0') + 1),
+                     std::bind(&Status::deviceErrorHandler, this))
         {
             // Nothing to do here
         }
@@ -61,6 +65,9 @@
 
         /** @brief OCC device object to do bind and unbind */
         Device device;
+
+        /** @brief Callback handler when device errors are detected */
+        void deviceErrorHandler();
 };
 
 } // namespace occ
diff --git a/org/open_power/OCC/Device.errors.yaml b/org/open_power/OCC/Device.errors.yaml
new file mode 100644
index 0000000..9e8d09a
--- /dev/null
+++ b/org/open_power/OCC/Device.errors.yaml
@@ -0,0 +1,15 @@
+# org.open_power.OCC.Device.OpenFailure
+- name: OpenFailure
+  description: Opening OCC device failed.
+
+# org.open_power.OCC.Device.ReadFailure
+- name: ReadFailure
+  description: Reading from OCC failed.
+
+# org.open_power.OCC.Device.WriteFailure
+- name: WriteFailure
+  description: Writing to OCC failed.
+
+# org.open_power.OCC.Device.ConfigFailure
+- name: ConfigFailure
+  description: Configuring device failed.
diff --git a/org/open_power/OCC/PassThrough.metadata.yaml b/org/open_power/OCC/Device.metadata.yaml
similarity index 74%
rename from org/open_power/OCC/PassThrough.metadata.yaml
rename to org/open_power/OCC/Device.metadata.yaml
index 0b1c4f5..ee79e2d 100644
--- a/org/open_power/OCC/PassThrough.metadata.yaml
+++ b/org/open_power/OCC/Device.metadata.yaml
@@ -9,3 +9,7 @@
 - name: WriteFailure
   inherits:
       - xyz.openbmc_project.Common.Callout.Device
+
+- name: ConfigFailure
+  inherits:
+      - xyz.openbmc_project.Common.Callout.Device
diff --git a/org/open_power/OCC/PassThrough.errors.yaml b/org/open_power/OCC/PassThrough.errors.yaml
deleted file mode 100644
index 4be6325..0000000
--- a/org/open_power/OCC/PassThrough.errors.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-# org.open_power.OCC.PassThrough.OpenFailure
-- name: OpenFailure
-  description: Opening OCC device failed.
-
-# org.open_power.OCC.PassThrough.ReadFailure
-- name: ReadFailure
-  description: Reading from OCC failed.
-
-# org.open_power.OCC.PassThrough.WriteFailure
-- name: WriteFailure
-  description: Writing to OCC failed.
diff --git a/test/Makefile.am b/test/Makefile.am
index 6022c65..a680245 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,8 +13,11 @@
                  $(SYSTEMD_LIBS) \
                  ${SDBUSPLUS_LIBS} \
                  $(OPENPOWER_DBUS_INTERFACES_LIBS) \
+                 $(PHOSPHOR_DBUS_INTERFACES_LIBS) \
                  -lstdc++fs
 utest_SOURCES = utest.cpp
 utest_LDADD = $(top_builddir)/powercap.o \
               $(top_builddir)/occ_status.o \
-              $(top_builddir)/occ_device.o
+              $(top_builddir)/occ_device.o \
+              $(top_builddir)/occ_errors.o \
+              $(top_builddir)/org/open_power/OCC/Device/error.o
diff --git a/test/utest.cpp b/test/utest.cpp
index e99d996..44691c2 100644
--- a/test/utest.cpp
+++ b/test/utest.cpp
@@ -1,4 +1,5 @@
 #include <gtest/gtest.h>
+#include <occ_events.hpp>
 #include "powercap.hpp"
 
 using namespace open_power::occ;
@@ -8,13 +9,22 @@
     public:
         VerifyOccInput() :
             bus(sdbusplus::bus::new_default()),
-            occStatus(bus,"/test/path"),
+            rc(sd_event_default(&event)),
+            eventP(event),
+            occStatus(bus, eventP, "/test/path"),
             pcap(bus,occStatus)
-        {}
+        {
+            EXPECT_GE(rc, 0);
+            event = nullptr;
+        }
         ~VerifyOccInput()
         {}
 
         sdbusplus::bus::bus bus;
+        sd_event* event;
+        int rc;
+        open_power::occ::EventPtr eventP;
+
         Status occStatus;
         powercap::PowerCap pcap;
 };