#include <drm/drm_print.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
+#include <drm/drm_privacy_screen_consumer.h>
 #include <drm/drm_sysfs.h>
 
 #include <linux/uaccess.h>
                    DRM_CONNECTOR_REGISTERED))
                drm_connector_unregister(connector);
 
+       if (connector->privacy_screen) {
+               drm_privacy_screen_put(connector->privacy_screen);
+               connector->privacy_screen = NULL;
+       }
+
        if (connector->tile_group) {
                drm_mode_put_tile_group(dev, connector->tile_group);
                connector->tile_group = NULL;
        /* Let userspace know we have a new connector */
        drm_sysfs_hotplug_event(connector->dev);
 
+       if (connector->privacy_screen)
+               drm_privacy_screen_register_notifier(connector->privacy_screen,
+                                          &connector->privacy_screen_notifier);
+
        mutex_lock(&connector_list_lock);
        list_add_tail(&connector->global_connector_list_entry, &connector_list);
        mutex_unlock(&connector_list_lock);
        list_del_init(&connector->global_connector_list_entry);
        mutex_unlock(&connector_list_lock);
 
+       if (connector->privacy_screen)
+               drm_privacy_screen_unregister_notifier(
+                                       connector->privacy_screen,
+                                       &connector->privacy_screen_notifier);
+
        if (connector->funcs->early_unregister)
                connector->funcs->early_unregister(connector);
 
 }
 EXPORT_SYMBOL(drm_connector_attach_privacy_screen_properties);
 
+static void drm_connector_update_privacy_screen_properties(
+       struct drm_connector *connector, bool set_sw_state)
+{
+       enum drm_privacy_screen_status sw_state, hw_state;
+
+       drm_privacy_screen_get_state(connector->privacy_screen,
+                                    &sw_state, &hw_state);
+
+       if (set_sw_state)
+               connector->state->privacy_screen_sw_state = sw_state;
+       drm_object_property_set_value(&connector->base,
+                       connector->privacy_screen_hw_state_property, hw_state);
+}
+
+static int drm_connector_privacy_screen_notifier(
+       struct notifier_block *nb, unsigned long action, void *data)
+{
+       struct drm_connector *connector =
+               container_of(nb, struct drm_connector, privacy_screen_notifier);
+       struct drm_device *dev = connector->dev;
+
+       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+       drm_connector_update_privacy_screen_properties(connector, true);
+       drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+       drm_sysfs_connector_status_event(connector,
+                               connector->privacy_screen_sw_state_property);
+       drm_sysfs_connector_status_event(connector,
+                               connector->privacy_screen_hw_state_property);
+
+       return NOTIFY_DONE;
+}
+
+/**
+ * drm_connector_attach_privacy_screen_provider - attach a privacy-screen to
+ *    the connector
+ * @connector: connector to attach the privacy-screen to
+ * @priv: drm_privacy_screen to attach
+ *
+ * Create and attach the standard privacy-screen properties and register
+ * a generic notifier for generating sysfs-connector-status-events
+ * on external changes to the privacy-screen status.
+ * This function takes ownership of the passed in drm_privacy_screen and will
+ * call drm_privacy_screen_put() on it when the connector is destroyed.
+ */
+void drm_connector_attach_privacy_screen_provider(
+       struct drm_connector *connector, struct drm_privacy_screen *priv)
+{
+       connector->privacy_screen = priv;
+       connector->privacy_screen_notifier.notifier_call =
+               drm_connector_privacy_screen_notifier;
+
+       drm_connector_create_privacy_screen_properties(connector);
+       drm_connector_update_privacy_screen_properties(connector, true);
+       drm_connector_attach_privacy_screen_properties(connector);
+}
+EXPORT_SYMBOL(drm_connector_attach_privacy_screen_provider);
+
+/**
+ * drm_connector_update_privacy_screen - update connector's privacy-screen sw-state
+ * @connector_state: connector-state to update the privacy-screen for
+ *
+ * This function calls drm_privacy_screen_set_sw_state() on the connector's
+ * privacy-screen.
+ *
+ * If the connector has no privacy-screen, then this is a no-op.
+ */
+void drm_connector_update_privacy_screen(const struct drm_connector_state *connector_state)
+{
+       struct drm_connector *connector = connector_state->connector;
+       int ret;
+
+       if (!connector->privacy_screen)
+               return;
+
+       ret = drm_privacy_screen_set_sw_state(connector->privacy_screen,
+                                             connector_state->privacy_screen_sw_state);
+       if (ret) {
+               drm_err(connector->dev, "Error updating privacy-screen sw_state\n");
+               return;
+       }
+
+       /* The hw_state property value may have changed, update it. */
+       drm_connector_update_privacy_screen_properties(connector, false);
+}
+EXPORT_SYMBOL(drm_connector_update_privacy_screen);
+
 int drm_connector_set_obj_prop(struct drm_mode_object *obj,
                                    struct drm_property *property,
                                    uint64_t value)
 
 #include <linux/llist.h>
 #include <linux/ctype.h>
 #include <linux/hdmi.h>
+#include <linux/notifier.h>
 #include <drm/drm_mode_object.h>
 #include <drm/drm_util.h>
 
 struct drm_property;
 struct drm_property_blob;
 struct drm_printer;
+struct drm_privacy_screen;
 struct edid;
 struct i2c_adapter;
 
         */
        struct drm_property *max_bpc_property;
 
+       /** @privacy_screen: drm_privacy_screen for this connector, or NULL. */
+       struct drm_privacy_screen *privacy_screen;
+
+       /** @privacy_screen_notifier: privacy-screen notifier_block */
+       struct notifier_block privacy_screen_notifier;
+
        /**
         * @privacy_screen_sw_state_property: Optional atomic property for the
         * connector to control the integrated privacy screen.
                                          int min, int max);
 void drm_connector_create_privacy_screen_properties(struct drm_connector *conn);
 void drm_connector_attach_privacy_screen_properties(struct drm_connector *conn);
+void drm_connector_attach_privacy_screen_provider(
+       struct drm_connector *connector, struct drm_privacy_screen *priv);
+void drm_connector_update_privacy_screen(const struct drm_connector_state *connector_state);
 
 /**
  * struct drm_tile_group - Tile group metadata