2961 lines · 74.5 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* * scan.c - support for transforming the ACPI namespace into individual objects */ #define pr_fmt(fmt) "ACPI: " fmt #include <linux/async.h>#include <linux/auxiliary_bus.h>#include <linux/module.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/kernel.h>#include <linux/acpi.h>#include <linux/acpi_iort.h>#include <linux/acpi_rimt.h>#include <linux/acpi_viot.h>#include <linux/iommu.h>#include <linux/signal.h>#include <linux/kthread.h>#include <linux/dmi.h>#include <linux/dma-map-ops.h>#include <linux/platform_data/x86/apple.h>#include <linux/pgtable.h>#include <linux/crc32.h>#include <linux/dma-direct.h> #include "internal.h"#include "sleep.h" #define ACPI_BUS_HID			"LNXSYBUS" #define INVALID_ACPI_HANDLE	((acpi_handle)ZERO_PAGE(0)) static const char *dummy_hid = "device"; static LIST_HEAD(acpi_dep_list);static DEFINE_MUTEX(acpi_dep_list_lock);LIST_HEAD(acpi_bus_id_list);static DEFINE_MUTEX(acpi_scan_lock);static LIST_HEAD(acpi_scan_handlers_list);DEFINE_MUTEX(acpi_device_lock);LIST_HEAD(acpi_wakeup_device_list);static DEFINE_MUTEX(acpi_hp_context_lock);static LIST_HEAD(acpi_scan_system_dev_list); /* * The UART device described by the SPCR table is the only object which needs * special-casing. Everything else is covered by ACPI namespace paths in STAO * table. */static u64 spcr_uart_addr; void acpi_scan_lock_acquire(void){	mutex_lock(&acpi_scan_lock);}EXPORT_SYMBOL_GPL(acpi_scan_lock_acquire); void acpi_scan_lock_release(void){	mutex_unlock(&acpi_scan_lock);}EXPORT_SYMBOL_GPL(acpi_scan_lock_release); void acpi_lock_hp_context(void){	mutex_lock(&acpi_hp_context_lock);} void acpi_unlock_hp_context(void){	mutex_unlock(&acpi_hp_context_lock);} void acpi_initialize_hp_context(struct acpi_device *adev,				struct acpi_hotplug_context *hp,				acpi_hp_notify notify, acpi_hp_uevent uevent){	acpi_lock_hp_context();	hp->notify = notify;	hp->uevent = uevent;	acpi_set_hp_context(adev, hp);	acpi_unlock_hp_context();}EXPORT_SYMBOL_GPL(acpi_initialize_hp_context); int acpi_scan_add_handler(struct acpi_scan_handler *handler){	if (!handler)		return -EINVAL; 	list_add_tail(&handler->list_node, &acpi_scan_handlers_list);	return 0;} int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,				       const char *hotplug_profile_name){	int error; 	error = acpi_scan_add_handler(handler);	if (error)		return error; 	acpi_sysfs_add_hotplug_profile(&handler->hotplug, hotplug_profile_name);	return 0;} bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent){	struct acpi_device_physical_node *pn;	bool offline = true;	char *envp[] = { "EVENT=offline", NULL }; 	/*	 * acpi_container_offline() calls this for all of the container's	 * children under the container's physical_node_lock lock.	 */	mutex_lock_nested(&adev->physical_node_lock, SINGLE_DEPTH_NESTING); 	list_for_each_entry(pn, &adev->physical_node_list, node)		if (device_supports_offline(pn->dev) && !dev_offline(pn->dev)) {			if (uevent)				kobject_uevent_env(&pn->dev->kobj, KOBJ_CHANGE, envp); 			offline = false;			break;		} 	mutex_unlock(&adev->physical_node_lock);	return offline;} static acpi_status acpi_bus_offline(acpi_handle handle, u32 lvl, void *data,				    void **ret_p){	struct acpi_device *device = acpi_fetch_acpi_dev(handle);	struct acpi_device_physical_node *pn;	bool second_pass = (bool)data;	acpi_status status = AE_OK; 	if (!device)		return AE_OK; 	if (device->handler && !device->handler->hotplug.enabled) {		*ret_p = &device->dev;		return AE_SUPPORT;	} 	mutex_lock(&device->physical_node_lock); 	list_for_each_entry(pn, &device->physical_node_list, node) {		int ret; 		if (second_pass) {			/* Skip devices offlined by the first pass. */			if (pn->put_online)				continue;		} else {			pn->put_online = false;		}		ret = device_offline(pn->dev);		if (ret >= 0) {			pn->put_online = !ret;		} else {			*ret_p = pn->dev;			if (second_pass) {				status = AE_ERROR;				break;			}		}	} 	mutex_unlock(&device->physical_node_lock); 	return status;} static acpi_status acpi_bus_online(acpi_handle handle, u32 lvl, void *data,				   void **ret_p){	struct acpi_device *device = acpi_fetch_acpi_dev(handle);	struct acpi_device_physical_node *pn; 	if (!device)		return AE_OK; 	mutex_lock(&device->physical_node_lock); 	list_for_each_entry(pn, &device->physical_node_list, node)		if (pn->put_online) {			device_online(pn->dev);			pn->put_online = false;		} 	mutex_unlock(&device->physical_node_lock); 	return AE_OK;} static int acpi_scan_try_to_offline(struct acpi_device *device){	acpi_handle handle = device->handle;	struct device *errdev = NULL;	acpi_status status; 	/*	 * Carry out two passes here and ignore errors in the first pass,	 * because if the devices in question are memory blocks and	 * CONFIG_MEMCG is set, one of the blocks may hold data structures	 * that the other blocks depend on, but it is not known in advance which	 * block holds them.	 *	 * If the first pass is successful, the second one isn't needed, though.	 */	status = acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,				     NULL, acpi_bus_offline, (void *)false,				     (void **)&errdev);	if (status == AE_SUPPORT) {		dev_warn(errdev, "Offline disabled.\n");		acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,				    acpi_bus_online, NULL, NULL, NULL);		return -EPERM;	}	acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev);	if (errdev) {		errdev = NULL;		acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,				    NULL, acpi_bus_offline, (void *)true,				    (void **)&errdev);		if (!errdev)			acpi_bus_offline(handle, 0, (void *)true,					 (void **)&errdev); 		if (errdev) {			dev_warn(errdev, "Offline failed.\n");			acpi_bus_online(handle, 0, NULL, NULL);			acpi_walk_namespace(ACPI_TYPE_ANY, handle,					    ACPI_UINT32_MAX, acpi_bus_online,					    NULL, NULL, NULL);			return -EBUSY;		}	}	return 0;} #define ACPI_SCAN_CHECK_FLAG_STATUS	BIT(0)#define ACPI_SCAN_CHECK_FLAG_EJECT	BIT(1) static int acpi_scan_check_and_detach(struct acpi_device *adev, void *p){	struct acpi_scan_handler *handler = adev->handler;	uintptr_t flags = (uintptr_t)p; 	acpi_dev_for_each_child_reverse(adev, acpi_scan_check_and_detach, p); 	if (flags & ACPI_SCAN_CHECK_FLAG_STATUS) {		acpi_bus_get_status(adev);		/*		 * Skip devices that are still there and take the enabled		 * flag into account.		 */		if (acpi_device_is_enabled(adev))			return 0; 		/* Skip device that have not been enumerated. */		if (!acpi_device_enumerated(adev)) {			dev_dbg(&adev->dev, "Still not enumerated\n");			return 0;		}	} 	if (handler && handler->detach)		handler->detach(adev); 	/*	 * Most likely, the device is going away, so put it into D3cold before	 * that.	 */	acpi_device_set_power(adev, ACPI_STATE_D3_COLD);	adev->flags.initialized = false; 	/* For eject this is deferred to acpi_bus_post_eject() */	if (!(flags & ACPI_SCAN_CHECK_FLAG_EJECT)) {		adev->handler = NULL;		acpi_device_clear_enumerated(adev);	}	return 0;} static int acpi_bus_post_eject(struct acpi_device *adev, void *not_used){	struct acpi_scan_handler *handler = adev->handler; 	acpi_dev_for_each_child_reverse(adev, acpi_bus_post_eject, NULL); 	if (handler) {		if (handler->post_eject)			handler->post_eject(adev); 		adev->handler = NULL;	} 	acpi_device_clear_enumerated(adev); 	return 0;} static void acpi_scan_check_subtree(struct acpi_device *adev){	uintptr_t flags = ACPI_SCAN_CHECK_FLAG_STATUS; 	acpi_scan_check_and_detach(adev, (void *)flags);} static int acpi_scan_hot_remove(struct acpi_device *device){	acpi_handle handle = device->handle;	unsigned long long sta;	acpi_status status;	uintptr_t flags = ACPI_SCAN_CHECK_FLAG_EJECT; 	if (device->handler && device->handler->hotplug.demand_offline) {		if (!acpi_scan_is_offline(device, true))			return -EBUSY;	} else {		int error = acpi_scan_try_to_offline(device);		if (error)			return error;	} 	acpi_handle_debug(handle, "Ejecting\n"); 	acpi_scan_check_and_detach(device, (void *)flags); 	acpi_evaluate_lck(handle, 0);	/*	 * TBD: _EJD support.	 */	status = acpi_evaluate_ej0(handle);	if (status == AE_NOT_FOUND)		return -ENODEV;	else if (ACPI_FAILURE(status))		return -EIO; 	/*	 * Verify if eject was indeed successful.  If not, log an error	 * message.  No need to call _OST since _EJ0 call was made OK.	 */	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);	if (ACPI_FAILURE(status)) {		acpi_handle_warn(handle,			"Status check after eject failed (0x%x)\n", status);	} else if (sta & ACPI_STA_DEVICE_ENABLED) {		acpi_handle_warn(handle,			"Eject incomplete - status 0x%llx\n", sta);	} else {		acpi_bus_post_eject(device, NULL);	} 	return 0;} static int acpi_scan_rescan_bus(struct acpi_device *adev){	struct acpi_scan_handler *handler = adev->handler;	int ret; 	if (handler && handler->hotplug.scan_dependent)		ret = handler->hotplug.scan_dependent(adev);	else		ret = acpi_bus_scan(adev->handle); 	if (ret)		dev_info(&adev->dev, "Namespace scan failure\n"); 	return ret;} static int acpi_scan_device_check(struct acpi_device *adev){	struct acpi_device *parent; 	acpi_scan_check_subtree(adev); 	if (!acpi_device_is_present(adev))		return 0; 	/*	 * This function is only called for device objects for which matching	 * scan handlers exist.  The only situation in which the scan handler	 * is not attached to this device object yet is when the device has	 * just appeared (either it wasn't present at all before or it was	 * removed and then added again).	 */	if (adev->handler) {		dev_dbg(&adev->dev, "Already enumerated\n");		return 0;	} 	parent = acpi_dev_parent(adev);	if (!parent)		parent = adev; 	return acpi_scan_rescan_bus(parent);} static int acpi_scan_bus_check(struct acpi_device *adev){	acpi_scan_check_subtree(adev); 	return acpi_scan_rescan_bus(adev);} static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type){	switch (type) {	case ACPI_NOTIFY_BUS_CHECK:		return acpi_scan_bus_check(adev);	case ACPI_NOTIFY_DEVICE_CHECK:		return acpi_scan_device_check(adev);	case ACPI_NOTIFY_EJECT_REQUEST:	case ACPI_OST_EC_OSPM_EJECT:		if (adev->handler && !adev->handler->hotplug.enabled) {			dev_info(&adev->dev, "Eject disabled\n");			return -EPERM;		}		acpi_evaluate_ost(adev->handle, ACPI_NOTIFY_EJECT_REQUEST,				  ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);		return acpi_scan_hot_remove(adev);	}	return -EINVAL;} void acpi_device_hotplug(struct acpi_device *adev, u32 src){	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;	int error = -ENODEV; 	lock_device_hotplug();	mutex_lock(&acpi_scan_lock); 	/*	 * The device object's ACPI handle cannot become invalid as long as we	 * are holding acpi_scan_lock, but it might have become invalid before	 * that lock was acquired.	 */	if (adev->handle == INVALID_ACPI_HANDLE)		goto err_out; 	if (adev->flags.is_dock_station) {		error = dock_notify(adev, src);	} else if (adev->flags.hotplug_notify) {		error = acpi_generic_hotplug_event(adev, src);	} else {		acpi_hp_notify notify; 		acpi_lock_hp_context();		notify = adev->hp ? adev->hp->notify : NULL;		acpi_unlock_hp_context();		/*		 * There may be additional notify handlers for device objects		 * without the .event() callback, so ignore them here.		 */		if (notify)			error = notify(adev, src);		else			goto out;	}	switch (error) {	case 0:		ost_code = ACPI_OST_SC_SUCCESS;		break;	case -EPERM:		ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;		break;	case -EBUSY:		ost_code = ACPI_OST_SC_DEVICE_BUSY;		break;	default:		ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;		break;	}  err_out:	acpi_evaluate_ost(adev->handle, src, ost_code, NULL);  out:	acpi_put_acpi_dev(adev);	mutex_unlock(&acpi_scan_lock);	unlock_device_hotplug();} static void acpi_free_power_resources_lists(struct acpi_device *device){	int i; 	if (device->wakeup.flags.valid)		acpi_power_resources_list_free(&device->wakeup.resources);

Lines 1–500 of 2961.