cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sysfb.c (3441B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Generic System Framebuffers
      4 * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
      5 */
      6
      7/*
      8 * Simple-Framebuffer support
      9 * Create a platform-device for any available boot framebuffer. The
     10 * simple-framebuffer platform device is already available on DT systems, so
     11 * this module parses the global "screen_info" object and creates a suitable
     12 * platform device compatible with the "simple-framebuffer" DT object. If
     13 * the framebuffer is incompatible, we instead create a legacy
     14 * "vesa-framebuffer", "efi-framebuffer" or "platform-framebuffer" device and
     15 * pass the screen_info as platform_data. This allows legacy drivers
     16 * to pick these devices up without messing with simple-framebuffer drivers.
     17 * The global "screen_info" is still valid at all times.
     18 *
     19 * If CONFIG_SYSFB_SIMPLEFB is not selected, never register "simple-framebuffer"
     20 * platform devices, but only use legacy framebuffer devices for
     21 * backwards compatibility.
     22 *
     23 * TODO: We set the dev_id field of all platform-devices to 0. This allows
     24 * other OF/DT parsers to create such devices, too. However, they must
     25 * start at offset 1 for this to work.
     26 */
     27
     28#include <linux/err.h>
     29#include <linux/init.h>
     30#include <linux/kernel.h>
     31#include <linux/mm.h>
     32#include <linux/platform_data/simplefb.h>
     33#include <linux/platform_device.h>
     34#include <linux/screen_info.h>
     35#include <linux/sysfb.h>
     36
     37static struct platform_device *pd;
     38static DEFINE_MUTEX(disable_lock);
     39static bool disabled;
     40
     41static bool sysfb_unregister(void)
     42{
     43	if (IS_ERR_OR_NULL(pd))
     44		return false;
     45
     46	platform_device_unregister(pd);
     47	pd = NULL;
     48
     49	return true;
     50}
     51
     52/**
     53 * sysfb_disable() - disable the Generic System Framebuffers support
     54 *
     55 * This disables the registration of system framebuffer devices that match the
     56 * generic drivers that make use of the system framebuffer set up by firmware.
     57 *
     58 * It also unregisters a device if this was already registered by sysfb_init().
     59 *
     60 * Context: The function can sleep. A @disable_lock mutex is acquired to serialize
     61 *          against sysfb_init(), that registers a system framebuffer device.
     62 */
     63void sysfb_disable(void)
     64{
     65	mutex_lock(&disable_lock);
     66	sysfb_unregister();
     67	disabled = true;
     68	mutex_unlock(&disable_lock);
     69}
     70EXPORT_SYMBOL_GPL(sysfb_disable);
     71
     72static __init int sysfb_init(void)
     73{
     74	struct screen_info *si = &screen_info;
     75	struct simplefb_platform_data mode;
     76	const char *name;
     77	bool compatible;
     78	int ret = 0;
     79
     80	mutex_lock(&disable_lock);
     81	if (disabled)
     82		goto unlock_mutex;
     83
     84	/* try to create a simple-framebuffer device */
     85	compatible = sysfb_parse_mode(si, &mode);
     86	if (compatible) {
     87		pd = sysfb_create_simplefb(si, &mode);
     88		if (!IS_ERR(pd))
     89			goto unlock_mutex;
     90	}
     91
     92	/* if the FB is incompatible, create a legacy framebuffer device */
     93	if (si->orig_video_isVGA == VIDEO_TYPE_EFI)
     94		name = "efi-framebuffer";
     95	else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB)
     96		name = "vesa-framebuffer";
     97	else
     98		name = "platform-framebuffer";
     99
    100	pd = platform_device_alloc(name, 0);
    101	if (!pd) {
    102		ret = -ENOMEM;
    103		goto unlock_mutex;
    104	}
    105
    106	sysfb_apply_efi_quirks(pd);
    107
    108	ret = platform_device_add_data(pd, si, sizeof(*si));
    109	if (ret)
    110		goto err;
    111
    112	ret = platform_device_add(pd);
    113	if (ret)
    114		goto err;
    115
    116	goto unlock_mutex;
    117err:
    118	platform_device_put(pd);
    119unlock_mutex:
    120	mutex_unlock(&disable_lock);
    121	return ret;
    122}
    123
    124/* must execute after PCI subsystem for EFI quirks */
    125device_initcall(sysfb_init);