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

container.c (2668B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * container.c  - ACPI Generic Container Driver
      4 *
      5 * Copyright (C) 2004 Anil S Keshavamurthy (anil.s.keshavamurthy@intel.com)
      6 * Copyright (C) 2004 Keiichiro Tokunaga (tokunaga.keiich@jp.fujitsu.com)
      7 * Copyright (C) 2004 Motoyuki Ito (motoyuki@soft.fujitsu.com)
      8 * Copyright (C) 2004 FUJITSU LIMITED
      9 * Copyright (C) 2004, 2013 Intel Corp.
     10 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
     11 */
     12#include <linux/acpi.h>
     13#include <linux/container.h>
     14
     15#include "internal.h"
     16
     17static const struct acpi_device_id container_device_ids[] = {
     18	{"ACPI0004", 0},
     19	{"PNP0A05", 0},
     20	{"PNP0A06", 0},
     21	{"", 0},
     22};
     23
     24#ifdef CONFIG_ACPI_CONTAINER
     25
     26static int acpi_container_offline(struct container_dev *cdev)
     27{
     28	struct acpi_device *adev = ACPI_COMPANION(&cdev->dev);
     29	struct acpi_device *child;
     30
     31	/* Check all of the dependent devices' physical companions. */
     32	list_for_each_entry(child, &adev->children, node)
     33		if (!acpi_scan_is_offline(child, false))
     34			return -EBUSY;
     35
     36	return 0;
     37}
     38
     39static void acpi_container_release(struct device *dev)
     40{
     41	kfree(to_container_dev(dev));
     42}
     43
     44static int container_device_attach(struct acpi_device *adev,
     45				   const struct acpi_device_id *not_used)
     46{
     47	struct container_dev *cdev;
     48	struct device *dev;
     49	int ret;
     50
     51	if (adev->flags.is_dock_station)
     52		return 0;
     53
     54	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
     55	if (!cdev)
     56		return -ENOMEM;
     57
     58	cdev->offline = acpi_container_offline;
     59	dev = &cdev->dev;
     60	dev->bus = &container_subsys;
     61	dev_set_name(dev, "%s", dev_name(&adev->dev));
     62	ACPI_COMPANION_SET(dev, adev);
     63	dev->release = acpi_container_release;
     64	ret = device_register(dev);
     65	if (ret) {
     66		put_device(dev);
     67		return ret;
     68	}
     69	adev->driver_data = dev;
     70	return 1;
     71}
     72
     73static void container_device_detach(struct acpi_device *adev)
     74{
     75	struct device *dev = acpi_driver_data(adev);
     76
     77	adev->driver_data = NULL;
     78	if (dev)
     79		device_unregister(dev);
     80}
     81
     82static void container_device_online(struct acpi_device *adev)
     83{
     84	struct device *dev = acpi_driver_data(adev);
     85
     86	kobject_uevent(&dev->kobj, KOBJ_ONLINE);
     87}
     88
     89static struct acpi_scan_handler container_handler = {
     90	.ids = container_device_ids,
     91	.attach = container_device_attach,
     92	.detach = container_device_detach,
     93	.hotplug = {
     94		.enabled = true,
     95		.demand_offline = true,
     96		.notify_online = container_device_online,
     97	},
     98};
     99
    100void __init acpi_container_init(void)
    101{
    102	acpi_scan_add_handler(&container_handler);
    103}
    104
    105#else
    106
    107static struct acpi_scan_handler container_handler = {
    108	.ids = container_device_ids,
    109};
    110
    111void __init acpi_container_init(void)
    112{
    113	acpi_scan_add_handler_with_hotplug(&container_handler, "container");
    114}
    115
    116#endif /* CONFIG_ACPI_CONTAINER */