// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2020 Google LLC
 *
 * This driver serves as the receiver of cros_ec PD host events.
 */

#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_data/cros_usbpd_notify.h>
#include <linux/platform_device.h>

#define DRV_NAME "cros-usbpd-notify"
#define DRV_NAME_PLAT_ACPI "cros-usbpd-notify-acpi"
#define ACPI_DRV_NAME "GOOG0003"

static BLOCKING_NOTIFIER_HEAD(cros_usbpd_notifier_list);

struct cros_usbpd_notify_data {
	struct device *dev;
	struct cros_ec_device *ec;
	struct notifier_block nb;
};

/**
 * cros_usbpd_register_notify - Register a notifier callback for PD events.
 * @nb: Notifier block pointer to register
 *
 * On ACPI platforms this corresponds to host events on the ECPD
 * "GOOG0003" ACPI device. On non-ACPI platforms this will filter mkbp events
 * for USB PD events.
 *
 * Return: 0 on success or negative error code.
 */
int cros_usbpd_register_notify(struct notifier_block *nb)
{
	return blocking_notifier_chain_register(&cros_usbpd_notifier_list,
						nb);
}
EXPORT_SYMBOL_GPL(cros_usbpd_register_notify);

/**
 * cros_usbpd_unregister_notify - Unregister notifier callback for PD events.
 * @nb: Notifier block pointer to unregister
 *
 * Unregister a notifier callback that was previously registered with
 * cros_usbpd_register_notify().
 */
void cros_usbpd_unregister_notify(struct notifier_block *nb)
{
	blocking_notifier_chain_unregister(&cros_usbpd_notifier_list, nb);
}
EXPORT_SYMBOL_GPL(cros_usbpd_unregister_notify);

static void cros_usbpd_get_event_and_notify(struct device  *dev,
					    struct cros_ec_device *ec_dev)
{
	struct ec_response_host_event_status host_event_status;
	u32 event = 0;
	int ret;

	/*
	 * We still send a 0 event out to older devices which don't
	 * have the updated device heirarchy.
	 */
	if (!ec_dev) {
		dev_dbg(dev,
			"EC device inaccessible; sending 0 event status.\n");
		goto send_notify;
	}

	/* Check for PD host events on EC. */
	ret = cros_ec_cmd(ec_dev, 0, EC_CMD_PD_HOST_EVENT_STATUS,
			  NULL, 0, &host_event_status, sizeof(host_event_status));
	if (ret < 0) {
		dev_warn(dev, "Can't get host event status (err: %d)\n", ret);
		goto send_notify;
	}

	event = host_event_status.status;

send_notify:
	blocking_notifier_call_chain(&cros_usbpd_notifier_list, event, NULL);
}

#ifdef CONFIG_ACPI

static void cros_usbpd_notify_acpi(acpi_handle device, u32 event, void *data)
{
	struct cros_usbpd_notify_data *pdnotify = data;

	cros_usbpd_get_event_and_notify(pdnotify->dev, pdnotify->ec);
}

static int cros_usbpd_notify_probe_acpi(struct platform_device *pdev)
{
	struct cros_usbpd_notify_data *pdnotify;
	struct device *dev = &pdev->dev;
	struct acpi_device *adev;
	struct cros_ec_device *ec_dev;
	acpi_status status;

	adev = ACPI_COMPANION(dev);

	pdnotify = devm_kzalloc(dev, sizeof(*pdnotify), GFP_KERNEL);
	if (!pdnotify)
		return -ENOMEM;

	/* Get the EC device pointer needed to talk to the EC. */
	ec_dev = dev_get_drvdata(dev->parent);
	if (!ec_dev) {
		/*
		 * We continue even for older devices which don't have the
		 * correct device heirarchy, namely, GOOG0003 is a child
		 * of GOOG0004.
		 */
		dev_warn(dev, "Couldn't get Chrome EC device pointer.\n");
	}

	pdnotify->dev = dev;
	pdnotify->ec = ec_dev;

	status = acpi_install_notify_handler(adev->handle,
					     ACPI_ALL_NOTIFY,
					     cros_usbpd_notify_acpi,
					     pdnotify);
	if (ACPI_FAILURE(status)) {
		dev_warn(dev, "Failed to register notify handler %08x\n",
			 status);
		return -EINVAL;
	}

	return 0;
}

static int cros_usbpd_notify_remove_acpi(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct acpi_device *adev = ACPI_COMPANION(dev);

	acpi_remove_notify_handler(adev->handle, ACPI_ALL_NOTIFY,
				   cros_usbpd_notify_acpi);

	return 0;
}

static const struct acpi_device_id cros_usbpd_notify_acpi_device_ids[] = {
	{ ACPI_DRV_NAME, 0 },
	{ }
};
MODULE_DEVICE_TABLE(acpi, cros_usbpd_notify_acpi_device_ids);

static struct platform_driver cros_usbpd_notify_acpi_driver = {
	.driver = {
		.name = DRV_NAME_PLAT_ACPI,
		.acpi_match_table = cros_usbpd_notify_acpi_device_ids,
	},
	.probe = cros_usbpd_notify_probe_acpi,
	.remove = cros_usbpd_notify_remove_acpi,
};

#endif /* CONFIG_ACPI */

static int cros_usbpd_notify_plat(struct notifier_block *nb,
				  unsigned long queued_during_suspend,
				  void *data)
{
	struct cros_usbpd_notify_data *pdnotify = container_of(nb,
			struct cros_usbpd_notify_data, nb);
	struct cros_ec_device *ec_dev = (struct cros_ec_device *)data;
	u32 host_event = cros_ec_get_host_event(ec_dev);

	if (!host_event)
		return NOTIFY_DONE;

	if (host_event & (EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU) |
			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_USB_MUX))) {
		cros_usbpd_get_event_and_notify(pdnotify->dev, ec_dev);
		return NOTIFY_OK;
	}
	return NOTIFY_DONE;
}

static int cros_usbpd_notify_probe_plat(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct cros_ec_dev *ecdev = dev_get_drvdata(dev->parent);
	struct cros_usbpd_notify_data *pdnotify;
	int ret;

	pdnotify = devm_kzalloc(dev, sizeof(*pdnotify), GFP_KERNEL);
	if (!pdnotify)
		return -ENOMEM;

	pdnotify->dev = dev;
	pdnotify->ec = ecdev->ec_dev;
	pdnotify->nb.notifier_call = cros_usbpd_notify_plat;

	dev_set_drvdata(dev, pdnotify);

	ret = blocking_notifier_chain_register(&ecdev->ec_dev->event_notifier,
					       &pdnotify->nb);
	if (ret < 0) {
		dev_err(dev, "Failed to register notifier\n");
		return ret;
	}

	return 0;
}

static int cros_usbpd_notify_remove_plat(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct cros_ec_dev *ecdev = dev_get_drvdata(dev->parent);
	struct cros_usbpd_notify_data *pdnotify =
		(struct cros_usbpd_notify_data *)dev_get_drvdata(dev);

	blocking_notifier_chain_unregister(&ecdev->ec_dev->event_notifier,
					   &pdnotify->nb);

	return 0;
}

static struct platform_driver cros_usbpd_notify_plat_driver = {
	.driver = {
		.name = DRV_NAME,
	},
	.probe = cros_usbpd_notify_probe_plat,
	.remove = cros_usbpd_notify_remove_plat,
};

static int __init cros_usbpd_notify_init(void)
{
	int ret;

	ret = platform_driver_register(&cros_usbpd_notify_plat_driver);
	if (ret < 0)
		return ret;

#ifdef CONFIG_ACPI
	platform_driver_register(&cros_usbpd_notify_acpi_driver);
#endif
	return 0;
}

static void __exit cros_usbpd_notify_exit(void)
{
#ifdef CONFIG_ACPI
	platform_driver_unregister(&cros_usbpd_notify_acpi_driver);
#endif
	platform_driver_unregister(&cros_usbpd_notify_plat_driver);
}

module_init(cros_usbpd_notify_init);
module_exit(cros_usbpd_notify_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ChromeOS power delivery notifier device");
MODULE_AUTHOR("Jon Flatley <jflat@chromium.org>");
MODULE_ALIAS("platform:" DRV_NAME);
