diff --git a/private/compat/26.0/26.0.ignore.cil b/private/compat/26.0/26.0.ignore.cil
index 96b3b078dc0bbb0d4fd10c10491e2c0060bfed3f..5a961076a52831b8a71adcfcaedbcc9cc32eac4d 100644
--- a/private/compat/26.0/26.0.ignore.cil
+++ b/private/compat/26.0/26.0.ignore.cil
@@ -62,6 +62,9 @@
     hal_lowpan_hwservice
     hal_neuralnetworks_hwservice
     hal_secure_element_hwservice
+    hal_system_suspend_default
+    hal_system_suspend_default_exec
+    hal_system_suspend_default_tmpfs
     hal_tetheroffload_hwservice
     hal_wifi_hostapd_hwservice
     hal_usb_gadget_hwservice
@@ -113,6 +116,7 @@
     system_boot_reason_prop
     system_lmk_prop
     system_net_netd_hwservice
+    system_suspend_hwservice
     system_update_service
     test_boot_reason_prop
     thermal_service
diff --git a/private/compat/27.0/27.0.ignore.cil b/private/compat/27.0/27.0.ignore.cil
index 2772cd729e3939f16e151d9dcc7ccaeab1903de2..9120694d81894ca7f888330cda3826fe296f4223 100644
--- a/private/compat/27.0/27.0.ignore.cil
+++ b/private/compat/27.0/27.0.ignore.cil
@@ -55,6 +55,9 @@
     hal_health_filesystem_hwservice
     hal_lowpan_hwservice
     hal_secure_element_hwservice
+    hal_system_suspend_default
+    hal_system_suspend_default_exec
+    hal_system_suspend_default_tmpfs
     hal_usb_gadget_hwservice
     hal_vehicle_hwservice
     hal_wifi_hostapd_hwservice
@@ -98,6 +101,7 @@
     storaged_data_file
     system_boot_reason_prop
     system_lmk_prop
+    system_suspend_hwservice
     system_update_service
     test_boot_reason_prop
     time_prop
diff --git a/private/compat/28.0/28.0.ignore.cil b/private/compat/28.0/28.0.ignore.cil
index 91ef8df4a7f373950d1ed46100fed15070b07431..18955b2eaf3cb5ebe7b841096fb638f9c6051004 100644
--- a/private/compat/28.0/28.0.ignore.cil
+++ b/private/compat/28.0/28.0.ignore.cil
@@ -6,12 +6,16 @@
   ( activity_task_service
     adb_service
     hal_health_filesystem_hwservice
+    hal_system_suspend_default
+    hal_system_suspend_default_exec
+    hal_system_suspend_default_tmpfs
     llkd
     llkd_exec
     llkd_tmpfs
     mnt_product_file
     overlayfs_file
     system_lmk_prop
+    system_suspend_hwservice
     time_prop
     timedetector_service
     timezonedetector_service
diff --git a/private/file_contexts b/private/file_contexts
index 6c753857b487d5837a6b55b1ca40ae2518e456c3..003d66c0216cb8c74efbc040e2f9f66bcd36e1bd 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -279,6 +279,7 @@
 /system/bin/wpantund             u:object_r:wpantund_exec:s0
 /system/bin/virtual_touchpad     u:object_r:virtual_touchpad_exec:s0
 /system/bin/hw/android\.hidl\.allocator@1\.0-service          u:object_r:hal_allocator_default_exec:s0
+/system/bin/hw/android\.system\.suspend@1\.0-service          u:object_r:hal_system_suspend_default_exec:s0
 /system/etc/selinux/mapping/[0-9]+\.[0-9]+\.cil       u:object_r:sepolicy_file:s0
 /system/etc/selinux/plat_mac_permissions\.xml u:object_r:mac_perms_file:s0
 /system/etc/selinux/plat_property_contexts  u:object_r:property_contexts_file:s0
diff --git a/private/hal_system_suspend_default.te b/private/hal_system_suspend_default.te
new file mode 100644
index 0000000000000000000000000000000000000000..293f3ded59e5ef8a18ad7f578a9a59e6d910a6cf
--- /dev/null
+++ b/private/hal_system_suspend_default.te
@@ -0,0 +1,5 @@
+type hal_system_suspend_default, domain, coredomain;
+hal_server_domain(hal_system_suspend_default, hal_system_suspend)
+
+type hal_system_suspend_default_exec, exec_type, file_type;
+init_daemon_domain(hal_system_suspend_default)
diff --git a/private/hwservice_contexts b/private/hwservice_contexts
index 377901172e5b9003a19fbe70a09f69eaddda249a..508d9256b7bbcdc919bbd60238177d2de8e0eb5c 100644
--- a/private/hwservice_contexts
+++ b/private/hwservice_contexts
@@ -67,5 +67,6 @@ android.hidl.manager::IServiceManager                           u:object_r:hidl_
 android.hidl.memory::IMapper                                    u:object_r:hidl_memory_hwservice:s0
 android.hidl.token::ITokenManager                               u:object_r:hidl_token_hwservice:s0
 android.system.net.netd::INetd                                  u:object_r:system_net_netd_hwservice:s0
+android.system.suspend::ISystemSuspend                          u:object_r:system_suspend_hwservice:s0
 android.system.wifi.keystore::IKeystore                         u:object_r:system_wifi_keystore_hwservice:s0
 *                                                               u:object_r:default_android_hwservice:s0
diff --git a/private/perfprofd.te b/private/perfprofd.te
index 25f97111f9e9c810a06c2761045a9abc68004c0a..dfe4c3c32d662614e2acd36dc3b3d77402efa861 100644
--- a/private/perfprofd.te
+++ b/private/perfprofd.te
@@ -3,6 +3,13 @@ userdebug_or_eng(`
   init_daemon_domain(perfprofd)
 ')
 
-# Only servicemanager, statsd, su, systemserver, hwservicemanager, health HAL can communicate.
-neverallow { domain userdebug_or_eng(`-statsd -system_server -hal_health_server -hwservicemanager') } perfprofd:binder call;
-neverallow perfprofd { domain userdebug_or_eng(`-servicemanager -statsd -su -system_server -hal_health_server -hwservicemanager') }:binder call;
+neverallow {
+  domain
+  -hal_system_suspend_server
+  userdebug_or_eng(`-statsd -system_server -hal_health_server -hwservicemanager')
+} perfprofd:binder call;
+neverallow perfprofd {
+  domain
+  -hal_system_suspend_server
+  userdebug_or_eng(`-servicemanager -statsd -su -system_server -hal_health_server -hwservicemanager')
+}:binder call;
diff --git a/private/system_server.te b/private/system_server.te
index d1e09be0b33b91698597d55dd454d2afa3e70911..750ee3ec61d938dd4c7477a5c6ad1cf47ffb4af8 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -208,6 +208,7 @@ hal_client_domain(system_server, hal_oemlock)
 hal_client_domain(system_server, hal_omx)
 hal_client_domain(system_server, hal_power)
 hal_client_domain(system_server, hal_sensors)
+hal_client_domain(system_server, hal_system_suspend)
 hal_client_domain(system_server, hal_tetheroffload)
 hal_client_domain(system_server, hal_thermal)
 hal_client_domain(system_server, hal_tv_cec)
diff --git a/public/attributes b/public/attributes
index 7dadf9e1d499cfd30b9f429101441966fd5faee3..738512887c95d9b377532b11111a88c9be514515 100644
--- a/public/attributes
+++ b/public/attributes
@@ -266,6 +266,7 @@ hal_attribute(omx);
 hal_attribute(power);
 hal_attribute(secure_element);
 hal_attribute(sensors);
+hal_attribute(system_suspend);
 hal_attribute(telephony);
 hal_attribute(tetheroffload);
 hal_attribute(thermal);
diff --git a/public/hal_system_suspend.te b/public/hal_system_suspend.te
new file mode 100644
index 0000000000000000000000000000000000000000..21c6cb63a29c4f6378656698480185a9fb8f86c6
--- /dev/null
+++ b/public/hal_system_suspend.te
@@ -0,0 +1,11 @@
+binder_call(hal_system_suspend_client, hal_system_suspend_server)
+binder_call(hal_system_suspend_server, hal_system_suspend_client)
+
+# To preserve the semantics of wakelock_use macro, not all clients of
+# system_suspend_hwservice have hal_system_suspend_client attribute. For that
+# reason we don't use hal_attribute_hwservice macro here.
+add_hwservice(hal_system_suspend_server, system_suspend_hwservice)
+allow hal_system_suspend_client system_suspend_hwservice:hwservice_manager find;
+
+allow hal_system_suspend_server sysfs_power:file rw_file_perms;
+allow hal_system_suspend_server system_server:fd use;
diff --git a/public/hwservice.te b/public/hwservice.te
index fba108f84544fafe63654118aa36476c584d10c0..2153547339a1cd539f86ced83b0b5945ea702e30 100644
--- a/public/hwservice.te
+++ b/public/hwservice.te
@@ -59,4 +59,5 @@ type hidl_manager_hwservice, hwservice_manager_type, coredomain_hwservice;
 type hidl_memory_hwservice, hwservice_manager_type, coredomain_hwservice;
 type hidl_token_hwservice, hwservice_manager_type, coredomain_hwservice;
 type system_net_netd_hwservice, hwservice_manager_type, coredomain_hwservice;
+type system_suspend_hwservice, hwservice_manager_type, coredomain_hwservice;
 type system_wifi_keystore_hwservice, hwservice_manager_type, coredomain_hwservice;
diff --git a/public/su.te b/public/su.te
index c2a4b2bc22779aff5d97a9043db150fc98de6858..f397d73dd2969a4433bcec5df278a390fae6ba81 100644
--- a/public/su.te
+++ b/public/su.te
@@ -85,6 +85,7 @@ userdebug_or_eng(`
   typeattribute su hal_power_client;
   typeattribute su hal_secure_element_client;
   typeattribute su hal_sensors_client;
+  typeattribute su hal_system_suspend_client;
   typeattribute su hal_telephony_client;
   typeattribute su hal_tetheroffload_client;
   typeattribute su hal_thermal_client;
diff --git a/public/te_macros b/public/te_macros
index febfe557fa3c5deaeafc07bf8919bf5910b9a19c..67df3071f87cf8d4591735f7c086b7d645435df9 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -406,6 +406,18 @@ define(`wakelock_use', `
 allow $1 sysfs_wake_lock:file rw_file_perms;
 # Accessing these files requires CAP_BLOCK_SUSPEND
 allow $1 self:global_capability2_class_set block_suspend;
+# TODO(b/36375663): wake lock clients should be tagged with
+# hal_system_suspend_client and halclientdomain attributes. However,
+# typeattribute statements don't allow applying attributes to other attributes,
+# so instead we grant appropriate permissions directly within this macro.
+# hal_system_suspend_client permissions
+binder_call($1, hal_system_suspend_server)
+binder_call(hal_system_suspend_server, $1)
+allow $1 system_suspend_hwservice:hwservice_manager find;
+# halclientdomain perimssions
+hwbinder_use($1)
+get_prop($1, hwservicemanager_prop)
+allow $1 hidl_manager_hwservice:hwservice_manager find;
 ')
 
 #####################################
diff --git a/public/vold.te b/public/vold.te
index a2ddb05e8adc590e7ef3201d65a54083f1dc8139..e40c251b1ff8bbcabd1551125befe063aee82f31 100644
--- a/public/vold.te
+++ b/public/vold.te
@@ -268,8 +268,9 @@ neverallow { domain -vold -init } restorecon_prop:property_service set;
 neverallow { domain -system_server -vdc -vold } vold_service:service_manager find;
 neverallow vold {
   domain
-  -hal_keymaster_server
   -hal_health_filesystem_server
+  -hal_keymaster_server
+  -hal_system_suspend_server
   -healthd
   -hwservicemanager
   -servicemanager