// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Generic System Framebuffers
 * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
 */

/*
 * Simple-Framebuffer support
 * Create a platform-device for any available boot framebuffer. The
 * simple-framebuffer platform device is already available on DT systems, so
 * this module parses the global "screen_info" object and creates a suitable
 * platform device compatible with the "simple-framebuffer" DT object. If
 * the framebuffer is incompatible, we instead create a legacy
 * "vesa-framebuffer", "efi-framebuffer" or "platform-framebuffer" device and
 * pass the screen_info as platform_data. This allows legacy drivers
 * to pick these devices up without messing with simple-framebuffer drivers.
 * The global "screen_info" is still valid at all times.
 *
 * If CONFIG_SYSFB_SIMPLEFB is not selected, never register "simple-framebuffer"
 * platform devices, but only use legacy framebuffer devices for
 * backwards compatibility.
 *
 * TODO: We set the dev_id field of all platform-devices to 0. This allows
 * other OF/DT parsers to create such devices, too. However, they must
 * start at offset 1 for this to work.
 */

#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/platform_data/simplefb.h>
#include <linux/platform_device.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>

static struct platform_device *pd;
static DEFINE_MUTEX(disable_lock);
static bool disabled;

static struct device *sysfb_parent_dev(const struct screen_info *si);

static bool sysfb_unregister(void)
{
	if (IS_ERR_OR_NULL(pd))
		return false;

	platform_device_unregister(pd);
	pd = NULL;

	return true;
}

/**
 * sysfb_disable() - disable the Generic System Framebuffers support
 * @dev:	the device to check if non-NULL
 *
 * This disables the registration of system framebuffer devices that match the
 * generic drivers that make use of the system framebuffer set up by firmware.
 *
 * It also unregisters a device if this was already registered by sysfb_init().
 *
 * Context: The function can sleep. A @disable_lock mutex is acquired to serialize
 *          against sysfb_init(), that registers a system framebuffer device.
 */
void sysfb_disable(struct device *dev)
{
	struct screen_info *si = &sysfb_primary_display.screen;
	struct device *parent;

	mutex_lock(&disable_lock);
	parent = sysfb_parent_dev(si);
	if (!dev || !parent || dev == parent) {
		sysfb_unregister();
		disabled = true;
	}
	mutex_unlock(&disable_lock);
}
EXPORT_SYMBOL_GPL(sysfb_disable);

/**
 * sysfb_handles_screen_info() - reports if sysfb handles the global screen_info
 *
 * Callers can use sysfb_handles_screen_info() to determine whether the Generic
 * System Framebuffers (sysfb) can handle the global screen_info data structure
 * or not. Drivers might need this information to know if they have to setup the
 * system framebuffer, or if they have to delegate this action to sysfb instead.
 *
 * Returns:
 * True if sysfb handles the global screen_info data structure.
 */
bool sysfb_handles_screen_info(void)
{
	const struct screen_info *si = &sysfb_primary_display.screen;

	return !!screen_info_video_type(si);
}
EXPORT_SYMBOL_GPL(sysfb_handles_screen_info);

#if defined(CONFIG_PCI)
static bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
{
	/*
	 * TODO: Try to integrate this code into the PCI subsystem
	 */
	int ret;
	u16 command;

	ret = pci_read_config_word(pdev, PCI_COMMAND, &command);
	if (ret != PCIBIOS_SUCCESSFUL)
		return false;
	if (!(command & PCI_COMMAND_MEMORY))
		return false;
	return true;
}
#else
static bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
{
	return false;
}
#endif

static struct device *sysfb_parent_dev(const struct screen_info *si)
{
	struct pci_dev *pdev;

	pdev = screen_info_pci_dev(si);
	if (IS_ERR(pdev)) {
		return ERR_CAST(pdev);
	} else if (pdev) {
		if (!sysfb_pci_dev_is_enabled(pdev)) {
			pci_dev_put(pdev);
			return ERR_PTR(-ENODEV);
		}
		return &pdev->dev;
	}

	return NULL;
}

static __init int sysfb_init(void)
{
	struct sysfb_display_info *dpy = &sysfb_primary_display;
	struct screen_info *si = &dpy->screen;
	struct device *parent;
	unsigned int type;
	struct simplefb_platform_data mode;
	const char *name;
	bool compatible;
	int ret = 0;

	screen_info_apply_fixups();

	mutex_lock(&disable_lock);
	if (disabled)
		goto unlock_mutex;

	sysfb_apply_efi_quirks(si);

	parent = sysfb_parent_dev(si);
	if (IS_ERR(parent)) {
		ret = PTR_ERR(parent);
		goto unlock_mutex;
	}

	/* try to create a simple-framebuffer device */
	compatible = sysfb_parse_mode(si, &mode);
	if (compatible) {
		pd = sysfb_create_simplefb(si, &mode, parent);
		if (!IS_ERR(pd))
			goto put_device;
	}

	type = screen_info_video_type(si);

	/* if the FB is incompatible, create a legacy framebuffer device */
	switch (type) {
	case VIDEO_TYPE_EGAC:
		name = "ega-framebuffer";
		break;
	case VIDEO_TYPE_VGAC:
		name = "vga-framebuffer";
		break;
	case VIDEO_TYPE_VLFB:
		name = "vesa-framebuffer";
		break;
	case VIDEO_TYPE_EFI:
		name = "efi-framebuffer";
		break;
	default:
		name = "platform-framebuffer";
		break;
	}

	pd = platform_device_alloc(name, 0);
	if (!pd) {
		ret = -ENOMEM;
		goto put_device;
	}

	pd->dev.parent = parent;

	sysfb_set_efifb_fwnode(si, pd);

	ret = platform_device_add_data(pd, dpy, sizeof(*dpy));
	if (ret)
		goto err;

	ret = platform_device_add(pd);
	if (ret)
		goto err;

	goto put_device;
err:
	platform_device_put(pd);
put_device:
	put_device(parent);
unlock_mutex:
	mutex_unlock(&disable_lock);
	return ret;
}

/* must execute after PCI subsystem for EFI quirks */
device_initcall(sysfb_init);
