// SPDX-License-Identifier: MIT
/*
 * Copyright (C) 2020 - 2021 Red Hat, Inc.
 *
 * Authors:
 * Hans de Goede <hdegoede@redhat.com>
 */

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <drm/drm_privacy_screen_machine.h>
#include <drm/drm_privacy_screen_consumer.h>
#include <drm/drm_privacy_screen_driver.h>
#include "drm_internal.h"

/**
 * DOC: overview
 *
 * This class allows non KMS drivers, from e.g. drivers/platform/x86 to
 * register a privacy-screen device, which the KMS drivers can then use
 * to implement the standard privacy-screen properties, see
 * :ref:`Standard Connector Properties<standard_connector_properties>`.
 *
 * KMS drivers using a privacy-screen class device are advised to use the
 * drm_connector_attach_privacy_screen_provider() and
 * drm_connector_update_privacy_screen() helpers for dealing with this.
 */

#define to_drm_privacy_screen(dev) \
	container_of(dev, struct drm_privacy_screen, dev)

static DEFINE_MUTEX(drm_privacy_screen_lookup_lock);
static LIST_HEAD(drm_privacy_screen_lookup_list);

static DEFINE_MUTEX(drm_privacy_screen_devs_lock);
static LIST_HEAD(drm_privacy_screen_devs);

/*** drm_privacy_screen_machine.h functions ***/

/**
 * drm_privacy_screen_lookup_add - add an entry to the static privacy-screen
 *    lookup list
 * @lookup: lookup list entry to add
 *
 * Add an entry to the static privacy-screen lookup list. Note the
 * &struct list_head which is part of the &struct drm_privacy_screen_lookup
 * gets added to a list owned by the privacy-screen core. So the passed in
 * &struct drm_privacy_screen_lookup must not be free-ed until it is removed
 * from the lookup list by calling drm_privacy_screen_lookup_remove().
 */
void drm_privacy_screen_lookup_add(struct drm_privacy_screen_lookup *lookup)
{
	mutex_lock(&drm_privacy_screen_lookup_lock);
	list_add(&lookup->list, &drm_privacy_screen_lookup_list);
	mutex_unlock(&drm_privacy_screen_lookup_lock);
}
EXPORT_SYMBOL(drm_privacy_screen_lookup_add);

/**
 * drm_privacy_screen_lookup_remove - remove an entry to the static
 *    privacy-screen lookup list
 * @lookup: lookup list entry to remove
 *
 * Remove an entry previously added with drm_privacy_screen_lookup_add()
 * from the static privacy-screen lookup list.
 */
void drm_privacy_screen_lookup_remove(struct drm_privacy_screen_lookup *lookup)
{
	mutex_lock(&drm_privacy_screen_lookup_lock);
	list_del(&lookup->list);
	mutex_unlock(&drm_privacy_screen_lookup_lock);
}
EXPORT_SYMBOL(drm_privacy_screen_lookup_remove);

/*** drm_privacy_screen_consumer.h functions ***/

static struct drm_privacy_screen *drm_privacy_screen_get_by_name(
	const char *name)
{
	struct drm_privacy_screen *priv;
	struct device *dev = NULL;

	mutex_lock(&drm_privacy_screen_devs_lock);

	list_for_each_entry(priv, &drm_privacy_screen_devs, list) {
		if (strcmp(dev_name(&priv->dev), name) == 0) {
			dev = get_device(&priv->dev);
			break;
		}
	}

	mutex_unlock(&drm_privacy_screen_devs_lock);

	return dev ? to_drm_privacy_screen(dev) : NULL;
}

/**
 * drm_privacy_screen_get - get a privacy-screen provider
 * @dev: consumer-device for which to get a privacy-screen provider
 * @con_id: (video)connector name for which to get a privacy-screen provider
 *
 * Get a privacy-screen provider for a privacy-screen attached to the
 * display described by the @dev and @con_id parameters.
 *
 * Return:
 * * A pointer to a &struct drm_privacy_screen on success.
 * * ERR_PTR(-ENODEV) if no matching privacy-screen is found
 * * ERR_PTR(-EPROBE_DEFER) if there is a matching privacy-screen,
 *                          but it has not been registered yet.
 */
struct drm_privacy_screen *drm_privacy_screen_get(struct device *dev,
						  const char *con_id)
{
	const char *dev_id = dev ? dev_name(dev) : NULL;
	struct drm_privacy_screen_lookup *l;
	struct drm_privacy_screen *priv;
	const char *provider = NULL;
	int match, best = -1;

	/*
	 * For now we only support using a static lookup table, which is
	 * populated by the drm_privacy_screen_arch_init() call. This should
	 * be extended with device-tree / fw_node lookup when support is added
	 * for device-tree using hardware with a privacy-screen.
	 *
	 * The lookup algorithm was shamelessly taken from the clock
	 * framework:
	 *
	 * We do slightly fuzzy matching here:
	 *  An entry with a NULL ID is assumed to be a wildcard.
	 *  If an entry has a device ID, it must match
	 *  If an entry has a connection ID, it must match
	 * Then we take the most specific entry - with the following order
	 * of precedence: dev+con > dev only > con only.
	 */
	mutex_lock(&drm_privacy_screen_lookup_lock);

	list_for_each_entry(l, &drm_privacy_screen_lookup_list, list) {
		match = 0;

		if (l->dev_id) {
			if (!dev_id || strcmp(l->dev_id, dev_id))
				continue;

			match += 2;
		}

		if (l->con_id) {
			if (!con_id || strcmp(l->con_id, con_id))
				continue;

			match += 1;
		}

		if (match > best) {
			provider = l->provider;
			best = match;
		}
	}

	mutex_unlock(&drm_privacy_screen_lookup_lock);

	if (!provider)
		return ERR_PTR(-ENODEV);

	priv = drm_privacy_screen_get_by_name(provider);
	if (!priv)
		return ERR_PTR(-EPROBE_DEFER);

	return priv;
}
EXPORT_SYMBOL(drm_privacy_screen_get);

/**
 * drm_privacy_screen_put - release a privacy-screen reference
 * @priv: privacy screen reference to release
 *
 * Release a privacy-screen provider reference gotten through
 * drm_privacy_screen_get(). May be called with a NULL or ERR_PTR,
 * in which case it is a no-op.
 */
void drm_privacy_screen_put(struct drm_privacy_screen *priv)
{
	if (IS_ERR_OR_NULL(priv))
		return;

	put_device(&priv->dev);
}
EXPORT_SYMBOL(drm_privacy_screen_put);

/**
 * drm_privacy_screen_set_sw_state - set a privacy-screen's sw-state
 * @priv: privacy screen to set the sw-state for
 * @sw_state: new sw-state value to set
 *
 * Set the sw-state of a privacy screen. If the privacy-screen is not
 * in a locked hw-state, then the actual and hw-state of the privacy-screen
 * will be immediately updated to the new value. If the privacy-screen is
 * in a locked hw-state, then the new sw-state will be remembered as the
 * requested state to put the privacy-screen in when it becomes unlocked.
 *
 * Return: 0 on success, negative error code on failure.
 */
int drm_privacy_screen_set_sw_state(struct drm_privacy_screen *priv,
				    enum drm_privacy_screen_status sw_state)
{
	int ret = 0;

	mutex_lock(&priv->lock);

	if (!priv->ops) {
		ret = -ENODEV;
		goto out;
	}

	/*
	 * As per the DRM connector properties documentation, setting the
	 * sw_state while the hw_state is locked is allowed. In this case
	 * it is a no-op other then storing the new sw_state so that it
	 * can be honored when the state gets unlocked.
	 * Also skip the set if the hw already is in the desired state.
	 */
	if (priv->hw_state >= PRIVACY_SCREEN_DISABLED_LOCKED ||
	    priv->hw_state == sw_state) {
		priv->sw_state = sw_state;
		goto out;
	}

	ret = priv->ops->set_sw_state(priv, sw_state);
out:
	mutex_unlock(&priv->lock);
	return ret;
}
EXPORT_SYMBOL(drm_privacy_screen_set_sw_state);

/**
 * drm_privacy_screen_get_state - get privacy-screen's current state
 * @priv: privacy screen to get the state for
 * @sw_state_ret: address where to store the privacy-screens current sw-state
 * @hw_state_ret: address where to store the privacy-screens current hw-state
 *
 * Get the current state of a privacy-screen, both the sw-state and the
 * hw-state.
 */
void drm_privacy_screen_get_state(struct drm_privacy_screen *priv,
				  enum drm_privacy_screen_status *sw_state_ret,
				  enum drm_privacy_screen_status *hw_state_ret)
{
	mutex_lock(&priv->lock);
	*sw_state_ret = priv->sw_state;
	*hw_state_ret = priv->hw_state;
	mutex_unlock(&priv->lock);
}
EXPORT_SYMBOL(drm_privacy_screen_get_state);

/**
 * drm_privacy_screen_register_notifier - register a notifier
 * @priv: Privacy screen to register the notifier with
 * @nb: Notifier-block for the notifier to register
 *
 * Register a notifier with the privacy-screen to be notified of changes made
 * to the privacy-screen state from outside of the privacy-screen class.
 * E.g. the state may be changed by the hardware itself in response to a
 * hotkey press.
 *
 * The notifier is called with no locks held. The new hw_state and sw_state
 * can be retrieved using the drm_privacy_screen_get_state() function.
 * A pointer to the drm_privacy_screen's struct is passed as the void *data
 * argument of the notifier_block's notifier_call.
 *
 * The notifier will NOT be called when changes are made through
 * drm_privacy_screen_set_sw_state(). It is only called for external changes.
 *
 * Return: 0 on success, negative error code on failure.
 */
int drm_privacy_screen_register_notifier(struct drm_privacy_screen *priv,
					 struct notifier_block *nb)
{
	return blocking_notifier_chain_register(&priv->notifier_head, nb);
}
EXPORT_SYMBOL(drm_privacy_screen_register_notifier);

/**
 * drm_privacy_screen_unregister_notifier - unregister a notifier
 * @priv: Privacy screen to register the notifier with
 * @nb: Notifier-block for the notifier to register
 *
 * Unregister a notifier registered with drm_privacy_screen_register_notifier().
 *
 * Return: 0 on success, negative error code on failure.
 */
int drm_privacy_screen_unregister_notifier(struct drm_privacy_screen *priv,
					   struct notifier_block *nb)
{
	return blocking_notifier_chain_unregister(&priv->notifier_head, nb);
}
EXPORT_SYMBOL(drm_privacy_screen_unregister_notifier);

/*** drm_privacy_screen_driver.h functions ***/

static ssize_t sw_state_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct drm_privacy_screen *priv = to_drm_privacy_screen(dev);
	const char * const sw_state_names[] = {
		"Disabled",
		"Enabled",
	};
	ssize_t ret;

	mutex_lock(&priv->lock);

	if (!priv->ops)
		ret = -ENODEV;
	else if (WARN_ON(priv->sw_state >= ARRAY_SIZE(sw_state_names)))
		ret = -ENXIO;
	else
		ret = sprintf(buf, "%s\n", sw_state_names[priv->sw_state]);

	mutex_unlock(&priv->lock);
	return ret;
}
/*
 * RO: Do not allow setting the sw_state through sysfs, this MUST be done
 * through the drm_properties on the drm_connector.
 */
static DEVICE_ATTR_RO(sw_state);

static ssize_t hw_state_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct drm_privacy_screen *priv = to_drm_privacy_screen(dev);
	const char * const hw_state_names[] = {
		"Disabled",
		"Enabled",
		"Disabled, locked",
		"Enabled, locked",
	};
	ssize_t ret;

	mutex_lock(&priv->lock);

	if (!priv->ops)
		ret = -ENODEV;
	else if (WARN_ON(priv->hw_state >= ARRAY_SIZE(hw_state_names)))
		ret = -ENXIO;
	else
		ret = sprintf(buf, "%s\n", hw_state_names[priv->hw_state]);

	mutex_unlock(&priv->lock);
	return ret;
}
static DEVICE_ATTR_RO(hw_state);

static struct attribute *drm_privacy_screen_attrs[] = {
	&dev_attr_sw_state.attr,
	&dev_attr_hw_state.attr,
	NULL
};
ATTRIBUTE_GROUPS(drm_privacy_screen);

static struct device_type drm_privacy_screen_type = {
	.name = "privacy_screen",
	.groups = drm_privacy_screen_groups,
};

static void drm_privacy_screen_device_release(struct device *dev)
{
	struct drm_privacy_screen *priv = to_drm_privacy_screen(dev);

	kfree(priv);
}

/**
 * drm_privacy_screen_register - register a privacy-screen
 * @parent: parent-device for the privacy-screen
 * @ops: &struct drm_privacy_screen_ops pointer with ops for the privacy-screen
 *
 * Create and register a privacy-screen.
 *
 * Return:
 * * A pointer to the created privacy-screen on success.
 * * An ERR_PTR(errno) on failure.
 */
struct drm_privacy_screen *drm_privacy_screen_register(
	struct device *parent, const struct drm_privacy_screen_ops *ops)
{
	struct drm_privacy_screen *priv;
	int ret;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return ERR_PTR(-ENOMEM);

	mutex_init(&priv->lock);
	BLOCKING_INIT_NOTIFIER_HEAD(&priv->notifier_head);

	priv->dev.class = drm_class;
	priv->dev.type = &drm_privacy_screen_type;
	priv->dev.parent = parent;
	priv->dev.release = drm_privacy_screen_device_release;
	dev_set_name(&priv->dev, "privacy_screen-%s", dev_name(parent));
	priv->ops = ops;

	priv->ops->get_hw_state(priv);

	ret = device_register(&priv->dev);
	if (ret) {
		put_device(&priv->dev);
		return ERR_PTR(ret);
	}

	mutex_lock(&drm_privacy_screen_devs_lock);
	list_add(&priv->list, &drm_privacy_screen_devs);
	mutex_unlock(&drm_privacy_screen_devs_lock);

	return priv;
}
EXPORT_SYMBOL(drm_privacy_screen_register);

/**
 * drm_privacy_screen_unregister - unregister privacy-screen
 * @priv: privacy-screen to unregister
 *
 * Unregister a privacy-screen registered with drm_privacy_screen_register().
 * May be called with a NULL or ERR_PTR, in which case it is a no-op.
 */
void drm_privacy_screen_unregister(struct drm_privacy_screen *priv)
{
	if (IS_ERR_OR_NULL(priv))
		return;

	mutex_lock(&drm_privacy_screen_devs_lock);
	list_del(&priv->list);
	mutex_unlock(&drm_privacy_screen_devs_lock);

	mutex_lock(&priv->lock);
	priv->ops = NULL;
	mutex_unlock(&priv->lock);

	device_unregister(&priv->dev);
}
EXPORT_SYMBOL(drm_privacy_screen_unregister);

/**
 * drm_privacy_screen_call_notifier_chain - notify consumers of state change
 * @priv: Privacy screen to register the notifier with
 *
 * A privacy-screen provider driver can call this functions upon external
 * changes to the privacy-screen state. E.g. the state may be changed by the
 * hardware itself in response to a hotkey press.
 * This function must be called without holding the privacy-screen lock.
 * the driver must update sw_state and hw_state to reflect the new state before
 * calling this function.
 * The expected behavior from the driver upon receiving an external state
 * change event is: 1. Take the lock; 2. Update sw_state and hw_state;
 * 3. Release the lock. 4. Call drm_privacy_screen_call_notifier_chain().
 */
void drm_privacy_screen_call_notifier_chain(struct drm_privacy_screen *priv)
{
	blocking_notifier_call_chain(&priv->notifier_head, 0, priv);
}
EXPORT_SYMBOL(drm_privacy_screen_call_notifier_chain);
