drivers/usb/core/usb-acpi.c

Source file repositories/reference/linux-study-clean/drivers/usb/core/usb-acpi.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/core/usb-acpi.c
Extension
.c
Size
10618 bytes
Lines
387
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

BIT(USB_DSM_DISABLE_U1_U2_FOR_PORT))) {
		dev_dbg(&hdev->dev, "port-%d no _DSM function %d\n",
			port1, USB_DSM_DISABLE_U1_U2_FOR_PORT);
		return -ENODEV;
	}

	obj = acpi_evaluate_dsm_typed(port_handle, &guid, 0,
				      USB_DSM_DISABLE_U1_U2_FOR_PORT, NULL,
				      ACPI_TYPE_INTEGER);
	if (!obj) {
		dev_dbg(&hdev->dev, "evaluate port-%d _DSM failed\n", port1);
		return -EINVAL;
	}

	if (obj->integer.value == 0x01)
		ret = 1;

	ACPI_FREE(obj);

	return ret;
}
EXPORT_SYMBOL_GPL(usb_acpi_port_lpm_incapable);

/**
 * usb_acpi_set_power_state - control usb port's power via acpi power
 * resource
 * @hdev: USB device belonging to the usb hub
 * @index: port index based zero
 * @enable: power state expected to be set
 *
 * Notice to use usb_acpi_power_manageable() to check whether the usb port
 * has acpi power resource before invoking this function.
 *
 * Returns 0 on success, else negative errno.
 */
int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
{
	struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
	struct usb_port *port_dev;
	acpi_handle port_handle;
	unsigned char state;
	int port1 = index + 1;
	int error = -EINVAL;

	if (!hub)
		return -ENODEV;
	port_dev = hub->ports[port1 - 1];

	port_handle = (acpi_handle) usb_get_hub_port_acpi_handle(hdev, port1);
	if (!port_handle)
		return error;

	if (enable)
		state = ACPI_STATE_D0;
	else
		state = ACPI_STATE_D3_COLD;

	error = acpi_bus_set_power(port_handle, state);
	if (!error)
		dev_dbg(&port_dev->dev, "acpi: power was set to %d\n", enable);
	else
		dev_dbg(&port_dev->dev, "acpi: power failed to be set\n");

	return error;
}
EXPORT_SYMBOL_GPL(usb_acpi_set_power_state);

/**
 * usb_acpi_add_usb4_devlink - add device link to USB4 Host Interface for tunneled USB3 devices
 *
 * @udev: Tunneled USB3 device connected to a roothub.
 *
 * Adds a device link between a tunneled USB3 device and the USB4 Host Interface
 * device to ensure correct runtime PM suspend and resume order. This function
 * should only be called for tunneled USB3 devices.
 * The USB4 Host Interface this tunneled device depends on is found from the roothub
 * port ACPI device specific data _DSD entry.
 *
 * Return: negative error code on failure, 0 otherwise
 */
static int usb_acpi_add_usb4_devlink(struct usb_device *udev)
{
	struct device_link *link;
	struct usb_port *port_dev;
	struct usb_hub *hub;

	if (!udev->parent || udev->parent->parent)
		return 0;

	hub = usb_hub_to_struct_hub(udev->parent);

Annotation

Implementation Notes