swift: Add dbus monitor policy configurations

Swift has two power supplies, same as Witherspoon, therefore will use
the same power supply policy configuration.

Swift and Witherspoon will also share the event policy configuration for
OCC throttling.

The thermal policy configuration will be shared between Swift and
Witherspoon, but may change for air cooled Swift to not also shutdown at
3 or more cores over 115C.

The fan policy configurations will be different for Swift, therefore
they will be separate. At this time, there are some areas unknown on how
fan presence and functional states will be handled for both air and
water cooled Swift machines, so these are configured to be the same.

Tested:
    Built witherspoon phosphor-dbus-monitor resulting in no image change
    Built swift phosphor-dbus-monitor resulting in correct policies

(From meta-ibm rev: fd06a2cbfd5f6e43aba4887ae1398984410d52cc)

Change-Id: I1125f00ecd51c23aac2da4cd2a47432ac3bc2de7
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/meta-ibm/meta-witherspoon/recipes-phosphor/dbus/phosphor-dbus-monitor-config.bbappend b/meta-ibm/meta-witherspoon/recipes-phosphor/dbus/phosphor-dbus-monitor-config.bbappend
index 1bef6c3..b06da50 100644
--- a/meta-ibm/meta-witherspoon/recipes-phosphor/dbus/phosphor-dbus-monitor-config.bbappend
+++ b/meta-ibm/meta-witherspoon/recipes-phosphor/dbus/phosphor-dbus-monitor-config.bbappend
@@ -1,4 +1,4 @@
-PHOSPHOR_DBUS_MONITOR_CONFIGS_append_witherspoon = " fan-policy"
-PHOSPHOR_DBUS_MONITOR_CONFIGS_append_witherspoon = " thermal-policy"
-PHOSPHOR_DBUS_MONITOR_CONFIGS_append_witherspoon = " power-supply-policy"
-PHOSPHOR_DBUS_MONITOR_CONFIGS_append_witherspoon = " events-policy"
+PHOSPHOR_DBUS_MONITOR_CONFIGS_append = " fan-policy"
+PHOSPHOR_DBUS_MONITOR_CONFIGS_append = " thermal-policy"
+PHOSPHOR_DBUS_MONITOR_CONFIGS_append = " power-supply-policy"
+PHOSPHOR_DBUS_MONITOR_CONFIGS_append = " events-policy"
diff --git a/meta-ibm/meta-witherspoon/recipes-phosphor/events/events-policy/witherspoon/config.yaml b/meta-ibm/meta-witherspoon/recipes-phosphor/events/events-policy/config.yaml
similarity index 100%
rename from meta-ibm/meta-witherspoon/recipes-phosphor/events/events-policy/witherspoon/config.yaml
rename to meta-ibm/meta-witherspoon/recipes-phosphor/events/events-policy/config.yaml
diff --git a/meta-ibm/meta-witherspoon/recipes-phosphor/fans/fan-policy/swift/air-cooled.yaml b/meta-ibm/meta-witherspoon/recipes-phosphor/fans/fan-policy/swift/air-cooled.yaml
new file mode 100644
index 0000000..bfdcd1b
--- /dev/null
+++ b/meta-ibm/meta-witherspoon/recipes-phosphor/fans/fan-policy/swift/air-cooled.yaml
@@ -0,0 +1,274 @@
+# Air cooled Swift fan policy for PDM.
+#
+# An air cooled Swift requires a minimum of three functional fan enclosures.
+# If the number of functional fan enclosures is below three, soft poweroff
+# the system.
+
+- name: fan enclosures
+  description: >
+    'An air cooled Swift has four fan enclosures to monitor.'
+  class: group
+  group: path
+  members:
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan0
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan1
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan2
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan3
+
+- name: chassis state
+  description: >
+    'Swift has a single chassis to monitor.'
+  class: group
+  group: path
+  members:
+    - meta: CHASSISSTATE
+      path: /xyz/openbmc_project/state/chassis0
+
+- name: chassis
+  description: >
+    'Swift has a single chassis to monitor.'
+  class: group
+  group: path
+  members:
+    - meta: CHASSIS
+      path: /xyz/openbmc_project/inventory/system/chassis
+
+- name: fan present
+  description: >
+    'Monitor the presence state of each fan.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.Inventory.Item
+      meta: PRESENT
+      property: Present
+
+- name: fan functional
+  description: >
+    'Monitor the functional state of each fan.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.State.Decorator.OperationalStatus
+      meta: FUNCTIONAL
+      property: Functional
+
+- name: chassis powered
+  description: >
+    'Monitor the chassis power state.'
+  class: group
+  group: property
+  type: string
+  members:
+    - interface: xyz.openbmc_project.State.Chassis
+      meta: CHASSIS_STATE
+      property: CurrentPowerState
+
+- name: chassis air cooled
+  description: >
+    'Monitor the chassis cooling type.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.Inventory.Decorator.CoolingType
+      meta: COOLING_TYPE
+      property: WaterCooled
+
+- name: watch fan present
+  description: >
+    'Trigger logic on fan enclosure presence state changes.'
+  class: watch
+  watch: property
+  paths: fan enclosures
+  properties: fan present
+  callback: check cooling type
+
+- name: watch fan functional
+  description: >
+    'Trigger logic on fan enclosure functional state changes.'
+  class: watch
+  watch: property
+  paths: fan enclosures
+  properties: fan functional
+  callback: check cooling type
+
+- name: watch chassis state
+  description: >
+    'Trigger logic on chassis power state changes.'
+  class: watch
+  watch: property
+  paths: chassis state
+  properties: chassis powered
+  callback: check cooling type
+
+- name: watch cooling type
+  description: >
+    'Maintain a cache of the chassis cooling type.'
+  class: watch
+  watch: property
+  paths: chassis
+  properties: chassis air cooled
+
+- name: check cooling type
+  description: >
+    'If this condition passes the chassis is air cooled.'
+  class: condition
+  condition: count
+  paths: chassis
+  properties: chassis air cooled
+  callback: check power
+  countop: '=='
+  countbound: 0
+  op: '=='
+  bound: true
+
+- name: check power
+  description: >
+    'If the chassis has power, check fans.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fans
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check fans
+  description: >
+    'Verify there are at least three functional fan enclosures,
+    power off if not.'
+  class: callback
+  callback: group
+  members:
+    - check group presence
+    - check group functional enclosures
+
+- name: check group presence
+  description: >
+    'If this condition passes more than one fan has been unplugged
+    for more than 25 seconds.  Shut the system down.  Count present
+    fans rather than non-present fans since the latter would pass
+    if the fan has not been created for some reason.
+
+    For a more detailed definition of unplugged, consult the documentation
+    of xyz.openbmc_project.Inventory.Item and/or the documentation
+    of the fan inventory object implementation.'
+  class: condition
+  condition: count
+  paths: fan enclosures
+  properties: fan present
+  defer: 25000000us
+  callback: log and shutdown
+  countop: '<'
+  countbound: 3
+  op: '=='
+  bound: true
+
+- name: check group functional enclosures
+  description: >
+    'If this condition passes more than one fan enclosure in the group has been
+    marked as nonfunctional for five seconds. Shut the system down.
+
+    For a more detailed definition of nonfunctional, consult the documentation
+    of xyz.openbmc_project.State.Decorator.OperationalStatus and/or the
+    documentation of the fan inventory object implementation.'
+  class: condition
+  condition: count
+  paths: fan enclosures
+  properties: fan functional
+  defer: 5000000us
+  callback: log and shutdown
+  countop: '>'
+  countbound: 1
+  op: '=='
+  bound: false
+
+- name: log and poweroff
+  description: >
+    'Immediately poweroff, log an event in the journal, and create an
+     error log.'
+  class: callback
+  callback: group
+  members:
+    - hard poweroff
+    - log hard poweroff
+    - create shutdown error
+
+- name: log and shutdown
+  description: >
+    'Shut the system down, log an event in the journal, and create an
+     error log.'
+  class: callback
+  callback: group
+  members:
+    - shutdown
+    - log shutdown
+    - create shutdown error
+
+- name: hard poweroff
+  description: >
+    'Immediately power off the system.'
+  class: callback
+  callback: method
+  service: org.freedesktop.systemd1
+  path: /org/freedesktop/systemd1
+  interface: org.freedesktop.systemd1.Manager
+  method: StartUnit
+  args:
+    - value: obmc-chassis-hard-poweroff@0.target
+      type: string
+    - value: replace
+      type: string
+
+- name: shutdown
+  description: >
+    'Shut down the system.'
+  class: callback
+  callback: method
+  service: org.freedesktop.systemd1
+  path: /org/freedesktop/systemd1
+  interface: org.freedesktop.systemd1.Manager
+  method: StartUnit
+  args:
+    - value: obmc-host-shutdown@0.target
+      type: string
+    - value: replace
+      type: string
+
+- name: log hard poweroff
+  description: >
+    'Log a hard poweroff event to the systemd journal.'
+  class: callback
+  callback: journal
+  paths: chassis state
+  properties: chassis powered
+  severity: ERR
+  message: Immediate poweroff of system. There are not enough functional fans.
+
+- name: log shutdown
+  description: >
+    'Log a shutdown event to the systemd journal.'
+  class: callback
+  callback: journal
+  paths: chassis state
+  properties: chassis powered
+  severity: ERR
+  message: Request shutdown of system. There are not enough functional fans.
+
+- name: create shutdown error
+  description: >
+    'Create a Fan Shutdown Error log.'
+  class: callback
+  callback: elog
+  paths: chassis state
+  properties: chassis powered
+  error: xyz::openbmc_project::State::Shutdown::Inventory::Error::Fan
diff --git a/meta-ibm/meta-witherspoon/recipes-phosphor/fans/fan-policy/swift/fan-errors.yaml b/meta-ibm/meta-witherspoon/recipes-phosphor/fans/fan-policy/swift/fan-errors.yaml
new file mode 100644
index 0000000..794d91f
--- /dev/null
+++ b/meta-ibm/meta-witherspoon/recipes-phosphor/fans/fan-policy/swift/fan-errors.yaml
@@ -0,0 +1,671 @@
+# Swift fan error policy for PDM.
+#
+# * Create a NotPresent error if fan 0, 1, 2, or 3 is not present for more
+#   than 20 seconds.
+# * Create a Nonfunctional error if fan 0, 1, 2, or 3 is not
+#   functional for any amount of time.
+#
+# The system must be powered on in both of these cases.
+# Note: An error is created each time the chassis powers on.
+#
+# * Watch for fans to become both present and functional, and then resolve
+#   their errors
+
+- name: fan0
+  class: group
+  group: path
+  members:
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan0
+
+- name: fan1
+  class: group
+  group: path
+  members:
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan1
+
+- name: fan2
+  class: group
+  group: path
+  members:
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan2
+
+- name: fan3
+  class: group
+  group: path
+  members:
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan3
+
+- name: chassis state
+  description: >
+    'Swift has a single chassis to monitor.'
+  class: group
+  group: path
+  members:
+    - meta: CHASSISSTATE
+      path: /xyz/openbmc_project/state/chassis0
+
+- name: chassis
+  description: >
+    'Swift has a single chassis to monitor.'
+  class: group
+  group: path
+  members:
+    - meta: CHASSIS
+      path: /xyz/openbmc_project/inventory/system/chassis
+
+
+- name: fan present
+  description: >
+    'Monitor the presence state of each fan.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.Inventory.Item
+      meta: PRESENT
+      property: Present
+
+- name: fan functional
+  description: >
+    'Monitor the functional state of each fan.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.State.Decorator.OperationalStatus
+      meta: FUNCTIONAL
+      property: Functional
+
+- name: fan present and functional
+  description: >
+    'Monitor the present and functional state of each fan.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.Inventory.Item
+      meta: PRESENT
+      property: Present
+    - interface: xyz.openbmc_project.State.Decorator.OperationalStatus
+      meta: FUNCTIONAL
+      property: Functional
+
+- name: chassis powered
+  description: >
+    'Monitor the chassis power state.'
+  class: group
+  group: property
+  type: string
+  members:
+    - interface: xyz.openbmc_project.State.Chassis
+      meta: CHASSIS_STATE
+      property: CurrentPowerState
+
+- name: chassis air cooled
+  description: >
+    'The chassis cooling type.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.Inventory.Decorator.CoolingType
+      meta: COOLING_TYPE
+      property: WaterCooled
+
+- name: watch chassis state
+  description: >
+    'Trigger logic on chassis power state changes.'
+  class: watch
+  watch: property
+  paths: chassis state
+  properties: chassis powered
+  callback: check power
+
+- name: watch fan0 presence
+  description: >
+    'Trigger logic on fan0 presence state changes.'
+  class: watch
+  watch: property
+  paths: fan0
+  properties: fan present
+  callback: check power fan0 presence
+
+- name: watch fan0 functional
+  description: >
+    'Trigger logic on fan0 functional state changes.'
+  class: watch
+  watch: property
+  paths: fan0
+  properties: fan functional
+  callback: check power fan0 functional
+
+- name: watch fan1 presence
+  description: >
+    'Trigger logic on fan1 presence state changes.'
+  class: watch
+  watch: property
+  paths: fan1
+  properties: fan present
+  callback: check power fan1 presence
+
+- name: watch fan1 functional
+  description: >
+    'Trigger logic on fan1 functional state changes.'
+  class: watch
+  watch: property
+  paths: fan1
+  properties: fan functional
+  callback: check power fan1 functional
+
+- name: watch fan2 presence
+  description: >
+    'Trigger logic on fan2 presence state changes.'
+  class: watch
+  watch: property
+  paths: fan2
+  properties: fan present
+  callback: check power fan2 presence
+
+- name: watch fan2 functional
+  description: >
+    'Trigger logic on fan2 functional state changes.'
+  class: watch
+  watch: property
+  paths: fan2
+  properties: fan functional
+  callback: check power fan2 functional
+
+- name: watch fan3 presence
+  description: >
+    'Trigger logic on fan3 presence state changes.'
+  class: watch
+  watch: property
+  paths: fan3
+  properties: fan present
+  callback: check power fan3 presence
+
+- name: watch fan3 functional
+  description: >
+    'Trigger logic on fan3 functional state changes.'
+  class: watch
+  watch: property
+  paths: fan3
+  properties: fan functional
+  callback: check power fan3 functional
+
+- name: watch fan0 present and functional for resolving error logs
+  description: >
+    'On fan present or functional state changes, check if errors need to be resolved.'
+  class: watch
+  watch: property
+  paths: fan0
+  properties: fan present and functional
+  callback: resolve fan0 errors if present and functional
+
+- name: watch fan1 present and functional for resolving error logs
+  description: >
+    'On fan present or functional state changes, check if errors need to be resolved.'
+  class: watch
+  watch: property
+  paths: fan1
+  properties: fan present and functional
+  callback: resolve fan1 errors if present and functional
+
+- name: watch fan2 present and functional for resolving error logs
+  description: >
+    'On fan present or functional state changes, check if errors need to be resolved.'
+  class: watch
+  watch: property
+  paths: fan2
+  properties: fan present and functional
+  callback: resolve fan2 errors if present and functional
+
+- name: watch fan3 present and functional for resolving error logs
+  description: >
+    'On fan present or functional state changes, check if errors need to be resolved.'
+  class: watch
+  watch: property
+  paths: fan3
+  properties: fan present and functional
+  callback: resolve fan3 errors if present and functional
+
+- name: check power
+  description: >
+    'If the chassis has power, check all fans.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fans
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check power fan0 presence
+  description: >
+    'If the chassis has power, check presence of fan0.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fan0 presence
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check power fan0 functional
+  description: >
+    'If the chassis has power, check functional of fan0.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fan0 functional
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check power fan1 presence
+  description: >
+    'If the chassis has power, check presence of fan1.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fan1 presence
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check power fan1 functional
+  description: >
+    'If the chassis has power, check functional of fan1.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fan1 functional
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check power fan2 presence
+  description: >
+    'If the chassis has power, check presence of fan2.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fan2 presence
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check power fan2 functional
+  description: >
+    'If the chassis has power, check functional of fan2.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fan2 functional
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check power fan3 presence
+  description: >
+    'If the chassis has power, check presence of fan3.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fan3 presence
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check power fan3 functional
+  description: >
+    'If the chassis has power, check functional of fan3.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fan3 functional
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check fans
+  description: >
+    'Verify each of the 3 fans are present.'
+  class: callback
+  callback: group
+  members:
+    - check fan0 presence
+    - check fan1 presence
+    - check fan2 presence
+    - check fan3 presence
+    - check fan0 functional
+    - check fan1 functional
+    - check fan2 functional
+    - check fan3 functional
+
+- name: check fan0 presence
+  description: >
+    'If this condition passes fan0 has been unplugged for more than 20 seconds.'
+  class: condition
+  condition: count
+  paths: fan0
+  properties: fan present
+  defer: 20000000us
+  callback: notpresent fan0 error
+  countop: '<'
+  countbound: 1
+  op: '=='
+  bound: true
+
+- name: check fan0 functional
+  description: >
+    'If this condition passes fan0 has been marked as nonfunctional.'
+  class: condition
+  condition: count
+  paths: fan0
+  properties: fan functional
+  callback: nonfunctional fan0 error
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: false
+
+- name: check fan1 presence
+  description: >
+    'If this condition passes fan1 has been unplugged for more than 20 seconds.'
+  class: condition
+  condition: count
+  paths: fan1
+  properties: fan present
+  defer: 20000000us
+  callback: notpresent fan1 error
+  countop: '<'
+  countbound: 1
+  op: '=='
+  bound: true
+
+- name: check fan1 functional
+  description: >
+    'If this condition passes fan1 has been marked as nonfunctional.'
+  class: condition
+  condition: count
+  paths: fan1
+  properties: fan functional
+  callback: nonfunctional fan1 error
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: false
+
+- name: check fan2 presence
+  description: >
+    'If this condition passes fan2 has been unplugged for more than 20 seconds.'
+  class: condition
+  condition: count
+  paths: fan2
+  properties: fan present
+  defer: 20000000us
+  callback: notpresent fan2 error
+  countop: '<'
+  countbound: 1
+  op: '=='
+  bound: true
+
+- name: check fan2 functional
+  description: >
+    'If this condition passes fan2 has been marked as nonfunctional.'
+  class: condition
+  condition: count
+  paths: fan2
+  properties: fan functional
+  callback: nonfunctional fan2 error
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: false
+
+- name: check fan3 presence
+  description: >
+    'If this condition passes fan3 has been unplugged for more than 20 seconds.'
+  class: condition
+  condition: count
+  paths: fan3
+  properties: fan present
+  defer: 20000000us
+  callback: notpresent fan3 error
+  countop: '<'
+  countbound: 1
+  op: '=='
+  bound: true
+
+- name: check fan3 functional
+  description: >
+    'If this condition passes fan3 has been marked as nonfunctional.'
+  class: condition
+  condition: count
+  paths: fan3
+  properties: fan functional
+  callback: nonfunctional fan3 error
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: false
+
+- name: check cooling type nonfunctional error
+  description: >
+    'If this condition passes the chassis is air cooled and will create a
+     nonfunctional error for fan 1.'
+  class: condition
+  condition: count
+  paths: chassis
+  properties: chassis air cooled
+  callback: nonfunctional fan1 error
+  countop: '=='
+  countbound: 0
+  op: '=='
+  bound: true
+
+- name: check cooling type notpresent error
+  description: >
+    'If this condition passes the chassis is air cooled and will create a
+     notpresent error for fan 1.'
+  class: condition
+  condition: count
+  paths: chassis
+  properties: chassis air cooled
+  callback: notpresent fan1 error
+  countop: '=='
+  countbound: 0
+  op: '=='
+  bound: true
+
+- name: notpresent fan0 error
+  class: callback
+  callback: elog
+  paths: fan0
+  properties: fan present
+  error: xyz::openbmc_project::Inventory::Error::NotPresent
+  metadata:
+    - name: xyz::openbmc_project::Inventory::NotPresent::CALLOUT_INVENTORY_PATH
+      value: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan0
+      type: string
+
+- name: nonfunctional fan0 error
+  class: callback
+  callback: elog
+  paths: fan0
+  properties: fan functional
+  error: xyz::openbmc_project::Inventory::Error::Nonfunctional
+  metadata:
+    - name: xyz::openbmc_project::Inventory::Nonfunctional::CALLOUT_INVENTORY_PATH
+      value: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan0
+      type: string
+
+- name: notpresent fan1 error
+  class: callback
+  callback: elog
+  paths: fan1
+  properties: fan present
+  error: xyz::openbmc_project::Inventory::Error::NotPresent
+  metadata:
+    - name: xyz::openbmc_project::Inventory::NotPresent::CALLOUT_INVENTORY_PATH
+      value: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan1
+      type: string
+
+- name: nonfunctional fan1 error
+  class: callback
+  callback: elog
+  paths: fan1
+  properties: fan functional
+  error: xyz::openbmc_project::Inventory::Error::Nonfunctional
+  metadata:
+    - name: xyz::openbmc_project::Inventory::Nonfunctional::CALLOUT_INVENTORY_PATH
+      value: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan1
+      type: string
+
+- name: notpresent fan2 error
+  class: callback
+  callback: elog
+  paths: fan2
+  properties: fan present
+  error: xyz::openbmc_project::Inventory::Error::NotPresent
+  metadata:
+    - name: xyz::openbmc_project::Inventory::NotPresent::CALLOUT_INVENTORY_PATH
+      value: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan2
+      type: string
+
+- name: nonfunctional fan2 error
+  class: callback
+  callback: elog
+  paths: fan2
+  properties: fan functional
+  error: xyz::openbmc_project::Inventory::Error::Nonfunctional
+  metadata:
+    - name: xyz::openbmc_project::Inventory::Nonfunctional::CALLOUT_INVENTORY_PATH
+      value: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan2
+      type: string
+
+- name: notpresent fan3 error
+  class: callback
+  callback: elog
+  paths: fan3
+  properties: fan present
+  error: xyz::openbmc_project::Inventory::Error::NotPresent
+  metadata:
+    - name: xyz::openbmc_project::Inventory::NotPresent::CALLOUT_INVENTORY_PATH
+      value: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan3
+      type: string
+
+- name: nonfunctional fan3 error
+  class: callback
+  callback: elog
+  paths: fan3
+  properties: fan functional
+  error: xyz::openbmc_project::Inventory::Error::Nonfunctional
+  metadata:
+    - name: xyz::openbmc_project::Inventory::Nonfunctional::CALLOUT_INVENTORY_PATH
+      value: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan3
+      type: string
+
+- name: resolve fan0 errors if present and functional
+  description: >
+    'If fan0 is present and functional, call the resolve fan0 errors callback.'
+  class: condition
+  condition: count
+  paths: fan0
+  properties: fan present and functional
+  callback: resolve fan0 errors
+  countop: '=='
+  countbound: 2
+  op: '=='
+  bound: true
+
+#Go ahead and do this on water cooled as well
+- name: resolve fan1 errors if present and functional
+  description: >
+    'If fan1 is present and functional, call the resolve fan1 errors callback.'
+  class: condition
+  condition: count
+  paths: fan1
+  properties: fan present and functional
+  callback: resolve fan1 errors
+  countop: '=='
+  countbound: 2
+  op: '=='
+  bound: true
+
+- name: resolve fan2 errors if present and functional
+  description: >
+    'If fan2 is present and functional, call the resolve fan2 errors callback.'
+  class: condition
+  condition: count
+  paths: fan2
+  properties: fan present and functional
+  callback: resolve fan2 errors
+  countop: '=='
+  countbound: 2
+  op: '=='
+  bound: true
+
+- name: resolve fan3 errors if present and functional
+  description: >
+    'If fan3 is present and functional, call the resolve fan3 errors callback.'
+  class: condition
+  condition: count
+  paths: fan3
+  properties: fan present and functional
+  callback: resolve fan3 errors
+  countop: '=='
+  countbound: 2
+  op: '=='
+  bound: true
+
+- name: resolve fan0 errors
+  class: callback
+  callback: resolve callout
+  paths: fan0
+  properties: fan present and functional
+  callout: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan0
+
+- name: resolve fan1 errors
+  class: callback
+  callback: resolve callout
+  paths: fan1
+  properties: fan present and functional
+  callout: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan1
+
+- name: resolve fan2 errors
+  class: callback
+  callback: resolve callout
+  paths: fan2
+  properties: fan present and functional
+  callout: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan2
+
+- name: resolve fan3 errors
+  class: callback
+  callback: resolve callout
+  paths: fan3
+  properties: fan present and functional
+  callout: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan3
diff --git a/meta-ibm/meta-witherspoon/recipes-phosphor/fans/fan-policy/swift/water-cooled.yaml b/meta-ibm/meta-witherspoon/recipes-phosphor/fans/fan-policy/swift/water-cooled.yaml
new file mode 100644
index 0000000..661021a
--- /dev/null
+++ b/meta-ibm/meta-witherspoon/recipes-phosphor/fans/fan-policy/swift/water-cooled.yaml
@@ -0,0 +1,274 @@
+# Water cooled Swift fan policy for PDM.
+#
+# A water cooled Swift requires a minimum of three functional fan
+# enclosures. If the number of functional fan enclosures is below three,
+# soft poweroff the system.
+
+- name: fan enclosures
+  description: >
+    'A water cooled Swift has four fan enclosures to monitor.'
+  class: group
+  group: path
+  members:
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan0
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan1
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan2
+    - meta: FAN
+      path: /xyz/openbmc_project/inventory/system/chassis/motherboard/fan3
+
+- name: chassis state
+  description: >
+    'Swift has a single chassis to monitor.'
+  class: group
+  group: path
+  members:
+    - meta: CHASSISSTATE
+      path: /xyz/openbmc_project/state/chassis0
+
+- name: chassis
+  description: >
+    'Swift has a single chassis to monitor.'
+  class: group
+  group: path
+  members:
+    - meta: CHASSIS
+      path: /xyz/openbmc_project/inventory/system/chassis
+
+- name: fan present
+  description: >
+    'Monitor the presence state of each fan.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.Inventory.Item
+      meta: PRESENT
+      property: Present
+
+- name: fan functional
+  description: >
+    'Monitor the functional state of each fan.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.State.Decorator.OperationalStatus
+      meta: FUNCTIONAL
+      property: Functional
+
+- name: chassis powered
+  description: >
+    'Monitor the chassis power state.'
+  class: group
+  group: property
+  type: string
+  members:
+    - interface: xyz.openbmc_project.State.Chassis
+      meta: CHASSIS_STATE
+      property: CurrentPowerState
+
+- name: chassis water cooled
+  description: >
+    'Monitor the chassis cooling type.'
+  class: group
+  group: property
+  type: boolean
+  members:
+    - interface: xyz.openbmc_project.Inventory.Decorator.CoolingType
+      meta: COOLING_TYPE
+      property: WaterCooled
+
+- name: watch fan present
+  description: >
+    'Trigger logic on fan enclosure presence state changes.'
+  class: watch
+  watch: property
+  paths: fan enclosures
+  properties: fan present
+  callback: check cooling type
+
+- name: watch fan functional
+  description: >
+    'Trigger logic on fan enclosure functional state changes.'
+  class: watch
+  watch: property
+  paths: fan enclosures
+  properties: fan functional
+  callback: check cooling type
+
+- name: watch chassis state
+  description: >
+    'Trigger logic on chassis power state changes.'
+  class: watch
+  watch: property
+  paths: chassis state
+  properties: chassis powered
+  callback: check cooling type
+
+- name: watch cooling type
+  description: >
+    'Maintain a cache of the chassis cooling type.'
+  class: watch
+  watch: property
+  paths: chassis
+  properties: chassis water cooled
+
+- name: check cooling type
+  description: >
+    'If this condition passes the chassis is water cooled.'
+  class: condition
+  condition: count
+  paths: chassis
+  properties: chassis water cooled
+  callback: check power
+  countop: '=='
+  countbound: 1
+  op: '=='
+  bound: true
+
+- name: check power
+  description: >
+    'If the chassis has power, check fans.'
+  class: condition
+  condition: count
+  paths: chassis state
+  properties: chassis powered
+  callback: check fans
+  countop: '>'
+  countbound: 0
+  op: '=='
+  bound: xyz.openbmc_project.State.Chassis.PowerState.On
+
+- name: check fans
+  description: >
+    'Verify there are at least three functional fan enclosures,
+    power off if not.'
+  class: callback
+  callback: group
+  members:
+    - check group presence
+    - check group functional enclosures
+
+- name: check group presence
+  description: >
+    'If this condition passes more than one fan has been unplugged
+    for more than 25 seconds.  Shut the system down.  Count present
+    fans rather than non-present fans since the latter would pass
+    if the fan has not been created for some reason.
+
+    For a more detailed definition of unplugged, consult the documentation
+    of xyz.openbmc_project.Inventory.Item and/or the documentation
+    of the fan inventory object implementation.'
+  class: condition
+  condition: count
+  paths: fan enclosures
+  properties: fan present
+  defer: 25000000us
+  callback: log and shutdown
+  countop: '<'
+  countbound: 3
+  op: '=='
+  bound: true
+
+- name: check group functional enclosures
+  description: >
+    'If this condition passes more than one fan enclosure in the group has been
+    marked as nonfunctional for five seconds. Shut the system down.
+
+    For a more detailed definition of nonfunctional, consult the documentation
+    of xyz.openbmc_project.State.Decorator.OperationalStatus and/or the
+    documentation of the fan inventory object implementation.'
+  class: condition
+  condition: count
+  paths: fan enclosures
+  properties: fan functional
+  defer: 5000000us
+  callback: log and shutdown
+  countop: '>'
+  countbound: 1
+  op: '=='
+  bound: false
+
+- name: log and poweroff
+  description: >
+    'Immediately poweroff, log an event in the journal, and create an
+     error log.'
+  class: callback
+  callback: group
+  members:
+    - hard poweroff
+    - log hard poweroff
+    - create shutdown error
+
+- name: log and shutdown
+  description: >
+    'Shut the system down, log an event in the journal, and create an
+     error log.'
+  class: callback
+  callback: group
+  members:
+    - shutdown
+    - log shutdown
+    - create shutdown error
+
+- name: hard poweroff
+  description: >
+    'Immediately power off the system.'
+  class: callback
+  callback: method
+  service: org.freedesktop.systemd1
+  path: /org/freedesktop/systemd1
+  interface: org.freedesktop.systemd1.Manager
+  method: StartUnit
+  args:
+    - value: obmc-chassis-hard-poweroff@0.target
+      type: string
+    - value: replace
+      type: string
+
+- name: shutdown
+  description: >
+    'Shut down the system.'
+  class: callback
+  callback: method
+  service: org.freedesktop.systemd1
+  path: /org/freedesktop/systemd1
+  interface: org.freedesktop.systemd1.Manager
+  method: StartUnit
+  args:
+    - value: obmc-host-shutdown@0.target
+      type: string
+    - value: replace
+      type: string
+
+- name: log hard poweroff
+  description: >
+    'Log a hard poweroff event to the systemd journal.'
+  class: callback
+  callback: journal
+  paths: chassis state
+  properties: chassis powered
+  severity: ERR
+  message: Immediate poweroff of system. There are not enough functional fans.
+
+- name: log shutdown
+  description: >
+    'Log a shutdown event to the systemd journal.'
+  class: callback
+  callback: journal
+  paths: chassis state
+  properties: chassis powered
+  severity: ERR
+  message: Request shutdown of system. There are not enough functional fans.
+
+- name: create shutdown error
+  description: >
+    'Create a Fan Shutdown Error log.'
+  class: callback
+  callback: elog
+  paths: chassis state
+  properties: chassis powered
+  error: xyz::openbmc_project::State::Shutdown::Inventory::Error::Fan
diff --git a/meta-ibm/meta-witherspoon/recipes-phosphor/fans/thermal-policy/witherspoon/thermal-policy.yaml b/meta-ibm/meta-witherspoon/recipes-phosphor/fans/thermal-policy/thermal-policy.yaml
similarity index 97%
rename from meta-ibm/meta-witherspoon/recipes-phosphor/fans/thermal-policy/witherspoon/thermal-policy.yaml
rename to meta-ibm/meta-witherspoon/recipes-phosphor/fans/thermal-policy/thermal-policy.yaml
index 1dd2306..7c48509 100644
--- a/meta-ibm/meta-witherspoon/recipes-phosphor/fans/thermal-policy/witherspoon/thermal-policy.yaml
+++ b/meta-ibm/meta-witherspoon/recipes-phosphor/fans/thermal-policy/thermal-policy.yaml
@@ -1,12 +1,12 @@
-# Witherspoon thermal policy for PDM.
+# Machine thermal policy for PDM.
 #
-# Shut down a Witherspoon system if more than three POWER9 cores
+# Shut down the system if more than three cores
 # have a temperature greater than 115 degrees Celcius.
 
 
 - name: core sensors
   description: >
-    'Witherspoon has two POWER9 chips with 24 cores each.'
+    'The machine has two processor chips with 24 cores each.'
   class: group
   group: path
   members:
diff --git a/meta-ibm/meta-witherspoon/recipes-phosphor/power/power-supply-policy/witherspoon/power-supply-policy.yaml b/meta-ibm/meta-witherspoon/recipes-phosphor/power/power-supply-policy/power-supply-policy.yaml
similarity index 97%
rename from meta-ibm/meta-witherspoon/recipes-phosphor/power/power-supply-policy/witherspoon/power-supply-policy.yaml
rename to meta-ibm/meta-witherspoon/recipes-phosphor/power/power-supply-policy/power-supply-policy.yaml
index 20141c9..e00e747 100644
--- a/meta-ibm/meta-witherspoon/recipes-phosphor/power/power-supply-policy/witherspoon/power-supply-policy.yaml
+++ b/meta-ibm/meta-witherspoon/recipes-phosphor/power/power-supply-policy/power-supply-policy.yaml
@@ -1,4 +1,4 @@
-# Witherspoon power supply policy for PDM.
+# Machine power supply policy for PDM.
 #
 # Create an error if a power supply is removed while the system is powered on
 
@@ -18,7 +18,7 @@
 
 - name: power supplies
   description: >
-    'A Witherspoon has two power supplies to monitor.'
+    'The machine has two power supplies to monitor.'
   class: group
   group: path
   members:
@@ -29,7 +29,7 @@
 
 - name: chassis state
   description: >
-    'A Witherspoon has a single chassis to monitor.'
+    'The machine has a single chassis to monitor.'
   class: group
   group: path
   members: