[6/9] drm/connector: Add a drm_connector privacy-screen helper functions
diff mbox series

Message ID 20200708164335.25097-7-hdegoede@redhat.com
State New
Headers show
Series
  • drm: Add privacy-screen class and connector properties
Related show

Commit Message

Hans de Goede July 8, 2020, 4:43 p.m. UTC
Add 2 drm_connector privacy-screen helper functions:

1. drm_connector_attach_privacy_screen_provider(), this function creates
and attaches the standard privacy-screen properties and registers a
generic notifier for generating sysfs-connector-status-events on external
changes to the privacy-screen status.

2. drm_connector_update_privacy_screen(), Check if the passed in atomic
state contains a privacy-screen sw_state change for the connector and if
it does, call drm_privacy_screen_set_sw_state() with the new sw_state.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/drm_connector.c | 113 ++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     |  12 ++++
 2 files changed, 125 insertions(+)

Comments

kernel test robot July 8, 2020, 8:15 p.m. UTC | #1
Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.8-rc4]
[cannot apply to drm-intel/for-linux-next drm-tip/drm-tip next-20200708]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use  as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Hans-de-Goede/drm-Add-privacy-screen-class-and-connector-properties/20200709-004703
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git dcde237b9b0eb1d19306e6f48c0a4e058907619f
config: arc-axs103_smp_defconfig (attached as .config)
compiler: arc-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "drm_privacy_screen_register_notifier" [drivers/gpu/drm/drm.ko] undefined!
>> ERROR: modpost: "drm_privacy_screen_get_state" [drivers/gpu/drm/drm.ko] undefined!
>> ERROR: modpost: "drm_privacy_screen_unregister_notifier" [drivers/gpu/drm/drm.ko] undefined!
>> ERROR: modpost: "drm_privacy_screen_put" [drivers/gpu/drm/drm.ko] undefined!
>> ERROR: modpost: "drm_privacy_screen_set_sw_state" [drivers/gpu/drm/drm.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot July 8, 2020, 8:57 p.m. UTC | #2
Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.8-rc4]
[cannot apply to drm-intel/for-linux-next drm-tip/drm-tip next-20200708]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use  as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Hans-de-Goede/drm-Add-privacy-screen-class-and-connector-properties/20200709-004703
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git dcde237b9b0eb1d19306e6f48c0a4e058907619f
config: riscv-randconfig-s031-20200708 (attached as .config)
compiler: riscv64-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.2-37-gc9676a3b-dirty
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=riscv 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   riscv64-linux-ld: drivers/gpu/drm/drm_connector.o: in function `drm_connector_register':
>> drivers/gpu/drm/drm_connector.c:533: undefined reference to `drm_privacy_screen_register_notifier'
   riscv64-linux-ld: drivers/gpu/drm/drm_connector.o: in function `drm_connector_unregister':
>> drivers/gpu/drm/drm_connector.c:567: undefined reference to `drm_privacy_screen_unregister_notifier'
   riscv64-linux-ld: drivers/gpu/drm/drm_connector.o: in function `drm_connector_set_link_status_property':
>> drivers/gpu/drm/drm_connector.c:2076: undefined reference to `drm_privacy_screen_get_state'
   riscv64-linux-ld: drivers/gpu/drm/drm_connector.o: in function `drm_connector_privacy_screen_notifier':
>> drivers/gpu/drm/drm_connector.c:2299: undefined reference to `drm_privacy_screen_set_sw_state'
   riscv64-linux-ld: drivers/gpu/drm/drm_connector.o: in function `drm_tile_group_free':
>> drivers/gpu/drm/drm_connector.c:2586: undefined reference to `drm_privacy_screen_put'

vim +533 drivers/gpu/drm/drm_connector.c

52217195176115 Daniel Vetter      2016-08-12  495  
52217195176115 Daniel Vetter      2016-08-12  496  /**
52217195176115 Daniel Vetter      2016-08-12  497   * drm_connector_register - register a connector
52217195176115 Daniel Vetter      2016-08-12  498   * @connector: the connector to register
52217195176115 Daniel Vetter      2016-08-12  499   *
69b22f51e6644b Daniel Vetter      2019-09-17  500   * Register userspace interfaces for a connector. Only call this for connectors
69b22f51e6644b Daniel Vetter      2019-09-17  501   * which can be hotplugged after drm_dev_register() has been called already,
69b22f51e6644b Daniel Vetter      2019-09-17  502   * e.g. DP MST connectors. All other connectors will be registered automatically
69b22f51e6644b Daniel Vetter      2019-09-17  503   * when calling drm_dev_register().
52217195176115 Daniel Vetter      2016-08-12  504   *
52217195176115 Daniel Vetter      2016-08-12  505   * Returns:
52217195176115 Daniel Vetter      2016-08-12  506   * Zero on success, error code on failure.
52217195176115 Daniel Vetter      2016-08-12  507   */
52217195176115 Daniel Vetter      2016-08-12  508  int drm_connector_register(struct drm_connector *connector)
52217195176115 Daniel Vetter      2016-08-12  509  {
e73ab00e9a0f17 Daniel Vetter      2016-12-18  510  	int ret = 0;
52217195176115 Daniel Vetter      2016-08-12  511  
e6e7b48b295afa Daniel Vetter      2017-01-12  512  	if (!connector->dev->registered)
e6e7b48b295afa Daniel Vetter      2017-01-12  513  		return 0;
e6e7b48b295afa Daniel Vetter      2017-01-12  514  
e73ab00e9a0f17 Daniel Vetter      2016-12-18  515  	mutex_lock(&connector->mutex);
39b50c603878f4 Lyude Paul         2018-10-16  516  	if (connector->registration_state != DRM_CONNECTOR_INITIALIZING)
e73ab00e9a0f17 Daniel Vetter      2016-12-18  517  		goto unlock;
52217195176115 Daniel Vetter      2016-08-12  518  
52217195176115 Daniel Vetter      2016-08-12  519  	ret = drm_sysfs_connector_add(connector);
52217195176115 Daniel Vetter      2016-08-12  520  	if (ret)
e73ab00e9a0f17 Daniel Vetter      2016-12-18  521  		goto unlock;
52217195176115 Daniel Vetter      2016-08-12  522  
b792e64021ecde Greg Kroah-Hartman 2019-06-13  523  	drm_debugfs_connector_add(connector);
52217195176115 Daniel Vetter      2016-08-12  524  
52217195176115 Daniel Vetter      2016-08-12  525  	if (connector->funcs->late_register) {
52217195176115 Daniel Vetter      2016-08-12  526  		ret = connector->funcs->late_register(connector);
52217195176115 Daniel Vetter      2016-08-12  527  		if (ret)
52217195176115 Daniel Vetter      2016-08-12  528  			goto err_debugfs;
52217195176115 Daniel Vetter      2016-08-12  529  	}
52217195176115 Daniel Vetter      2016-08-12  530  
52217195176115 Daniel Vetter      2016-08-12  531  	drm_mode_object_register(connector->dev, &connector->base);
52217195176115 Daniel Vetter      2016-08-12  532  
39b50c603878f4 Lyude Paul         2018-10-16 @533  	connector->registration_state = DRM_CONNECTOR_REGISTERED;
968d81a64a883a Jeykumar Sankaran  2020-06-02  534  
968d81a64a883a Jeykumar Sankaran  2020-06-02  535  	/* Let userspace know we have a new connector */
968d81a64a883a Jeykumar Sankaran  2020-06-02  536  	drm_sysfs_hotplug_event(connector->dev);
968d81a64a883a Jeykumar Sankaran  2020-06-02  537  
3823adf8dc676e Hans de Goede      2020-07-08  538  	if (connector->privacy_screen)
3823adf8dc676e Hans de Goede      2020-07-08  539  		drm_privacy_screen_register_notifier(connector->privacy_screen,
3823adf8dc676e Hans de Goede      2020-07-08  540  					   &connector->privacy_screen_notifier);
3823adf8dc676e Hans de Goede      2020-07-08  541  
e73ab00e9a0f17 Daniel Vetter      2016-12-18  542  	goto unlock;
52217195176115 Daniel Vetter      2016-08-12  543  
52217195176115 Daniel Vetter      2016-08-12  544  err_debugfs:
52217195176115 Daniel Vetter      2016-08-12  545  	drm_debugfs_connector_remove(connector);
52217195176115 Daniel Vetter      2016-08-12  546  	drm_sysfs_connector_remove(connector);
e73ab00e9a0f17 Daniel Vetter      2016-12-18  547  unlock:
e73ab00e9a0f17 Daniel Vetter      2016-12-18  548  	mutex_unlock(&connector->mutex);
52217195176115 Daniel Vetter      2016-08-12  549  	return ret;
52217195176115 Daniel Vetter      2016-08-12  550  }
52217195176115 Daniel Vetter      2016-08-12  551  EXPORT_SYMBOL(drm_connector_register);
52217195176115 Daniel Vetter      2016-08-12  552  
52217195176115 Daniel Vetter      2016-08-12  553  /**
52217195176115 Daniel Vetter      2016-08-12  554   * drm_connector_unregister - unregister a connector
52217195176115 Daniel Vetter      2016-08-12  555   * @connector: the connector to unregister
52217195176115 Daniel Vetter      2016-08-12  556   *
69b22f51e6644b Daniel Vetter      2019-09-17  557   * Unregister userspace interfaces for a connector. Only call this for
69b22f51e6644b Daniel Vetter      2019-09-17  558   * connectors which have registered explicitly by calling drm_dev_register(),
69b22f51e6644b Daniel Vetter      2019-09-17  559   * since connectors are unregistered automatically when drm_dev_unregister() is
69b22f51e6644b Daniel Vetter      2019-09-17  560   * called.
52217195176115 Daniel Vetter      2016-08-12  561   */
52217195176115 Daniel Vetter      2016-08-12  562  void drm_connector_unregister(struct drm_connector *connector)
52217195176115 Daniel Vetter      2016-08-12  563  {
e73ab00e9a0f17 Daniel Vetter      2016-12-18  564  	mutex_lock(&connector->mutex);
39b50c603878f4 Lyude Paul         2018-10-16  565  	if (connector->registration_state != DRM_CONNECTOR_REGISTERED) {
e73ab00e9a0f17 Daniel Vetter      2016-12-18  566  		mutex_unlock(&connector->mutex);
52217195176115 Daniel Vetter      2016-08-12 @567  		return;
e73ab00e9a0f17 Daniel Vetter      2016-12-18  568  	}
52217195176115 Daniel Vetter      2016-08-12  569  
3823adf8dc676e Hans de Goede      2020-07-08  570  	if (connector->privacy_screen)
3823adf8dc676e Hans de Goede      2020-07-08  571  		drm_privacy_screen_unregister_notifier(
3823adf8dc676e Hans de Goede      2020-07-08  572  					connector->privacy_screen,
3823adf8dc676e Hans de Goede      2020-07-08  573  					&connector->privacy_screen_notifier);
3823adf8dc676e Hans de Goede      2020-07-08  574  
52217195176115 Daniel Vetter      2016-08-12  575  	if (connector->funcs->early_unregister)
52217195176115 Daniel Vetter      2016-08-12  576  		connector->funcs->early_unregister(connector);
52217195176115 Daniel Vetter      2016-08-12  577  
52217195176115 Daniel Vetter      2016-08-12  578  	drm_sysfs_connector_remove(connector);
52217195176115 Daniel Vetter      2016-08-12  579  	drm_debugfs_connector_remove(connector);
52217195176115 Daniel Vetter      2016-08-12  580  
39b50c603878f4 Lyude Paul         2018-10-16  581  	connector->registration_state = DRM_CONNECTOR_UNREGISTERED;
e73ab00e9a0f17 Daniel Vetter      2016-12-18  582  	mutex_unlock(&connector->mutex);
52217195176115 Daniel Vetter      2016-08-12  583  }
52217195176115 Daniel Vetter      2016-08-12  584  EXPORT_SYMBOL(drm_connector_unregister);
52217195176115 Daniel Vetter      2016-08-12  585  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Patch
diff mbox series

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index bce5e0cc5884..37e985756890 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -20,6 +20,7 @@ 
  * OF THIS SOFTWARE.
  */
 
+#include <drm/drm_atomic.h>
 #include <drm/drm_connector.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
@@ -27,6 +28,7 @@ 
 #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>
@@ -449,6 +451,11 @@  void drm_connector_cleanup(struct drm_connector *connector)
 		    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;
@@ -528,6 +535,10 @@  int drm_connector_register(struct drm_connector *connector)
 	/* 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);
+
 	goto unlock;
 
 err_debugfs:
@@ -556,6 +567,11 @@  void drm_connector_unregister(struct drm_connector *connector)
 		return;
 	}
 
+	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);
 
@@ -2260,6 +2276,103 @@  drm_connector_attach_privacy_screen_properties(struct drm_connector *connector)
 }
 EXPORT_SYMBOL(drm_connector_attach_privacy_screen_properties);
 
+static void drm_connector_update_privacy_screen_properties(
+	struct drm_connector *connector)
+{
+	enum drm_privacy_screen_status sw_state, hw_state;
+
+	drm_privacy_screen_get_state(connector->privacy_screen,
+				     &sw_state, &hw_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);
+	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);
+	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
+ *    state (if changed)
+ * @connector: connector to update the privacy-screen for
+ * @state: drm_atomic state describing the state change
+ *
+ * This function checks if the passed in connector has a privacy-screen
+ * attached and if it does, it checks if the
+ * drm_connector_state.privacy_screen_sw_state setting has changed.
+ * If both conditions are true it calls drm_privacy_screen_set_sw_state() on
+ * the connector's privacy-screen to update the privacy-screen's state.
+ */
+void drm_connector_update_privacy_screen(struct drm_connector *connector,
+					 struct drm_atomic_state *state)
+{
+	struct drm_connector_state *new_connector_state, *old_connector_state;
+	int ret;
+
+	if (!connector->privacy_screen)
+		return;
+
+	new_connector_state = drm_atomic_get_new_connector_state(state, connector);
+	old_connector_state = drm_atomic_get_old_connector_state(state, connector);
+
+	if (new_connector_state->privacy_screen_sw_state ==
+	    old_connector_state->privacy_screen_sw_state)
+		return;
+
+	ret = drm_privacy_screen_set_sw_state(connector->privacy_screen,
+				new_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 the props. */
+	drm_connector_update_privacy_screen_properties(connector);
+}
+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)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 9c77865e4093..d7f4b8434df1 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -27,6 +27,7 @@ 
 #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>
 
@@ -40,6 +41,7 @@  struct drm_encoder;
 struct drm_property;
 struct drm_property_blob;
 struct drm_printer;
+struct drm_privacy_screen;
 struct edid;
 struct i2c_adapter;
 
@@ -1315,6 +1317,12 @@  struct drm_connector {
 	 */
 	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.
@@ -1642,6 +1650,10 @@  int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
 					  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(struct drm_connector *connector,
+					 struct drm_atomic_state *state);
 
 /**
  * struct drm_tile_group - Tile group metadata