Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
d78658d
Documentation
arch
block
crypto
drivers
accessibility
acpi
amba
ata
atm
auxdisplay
base
bcma
block
bluetooth
bus
cdrom
char
clk
clocksource
connector
cpufreq
cpuidle
crypto
dca
devfreq
dio
dma
edac
eisa
extcon
firewire
firmware
gpio
gpu
hid
hsi
hv
hwmon
hwspinlock
i2c
ide
idle
iio
infiniband
input
iommu
ipack
irqchip
isdn
leds
lguest
macintosh
mailbox
md
media
memory
memstick
message
mfd
misc
mmc
mtd
net
nfc
ntb
nubus
of
oprofile
parisc
parport
pci
pcmcia
pinctrl
platform
pnp
power
pps
ps3
ptp
pwm
rapidio
regulator
remoteproc
rpmsg
rtc
s390
sbus
scsi
sfi
sh
sn
spi
ssb
staging
target
tc
thermal
tty
uio
usb
atm
c67x00
chipidea
class
core
Kconfig
Makefile
buffer.c
config.c
devices.c
devio.c
driver.c
endpoint.c
file.c
generic.c
hcd-pci.c
hcd.c
hub.c
hub.h
message.c
notify.c
otg_whitelist.h
port.c
quirks.c
sysfs.c
urb.c
usb-acpi.c
usb.c
usb.h
dwc3
early
gadget
host
image
misc
mon
musb
otg
phy
renesas_usbhs
serial
storage
wusbcore
Kconfig
Makefile
README
usb-common.c
usb-skeleton.c
uwb
vfio
vhost
video
virt
virtio
vlynq
vme
w1
watchdog
xen
zorro
Kconfig
Makefile
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
usr
virt
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
drivers
/
usb
/
core
/
usb-acpi.c
Blame
Blame
Latest commit
History
History
238 lines (212 loc) · 5.94 KB
Breadcrumbs
linux
/
drivers
/
usb
/
core
/
usb-acpi.c
Top
File metadata and controls
Code
Blame
238 lines (212 loc) · 5.94 KB
Raw
/* * USB-ACPI glue code * * Copyright 2012 Red Hat <mjg@redhat.com> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 2. * */ #include <linux/module.h> #include <linux/usb.h> #include <linux/device.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/acpi.h> #include <linux/pci.h> #include <linux/usb/hcd.h> #include <acpi/acpi_bus.h> #include "usb.h" /** * usb_acpi_power_manageable - check whether usb port has * acpi power resource. * @hdev: USB device belonging to the usb hub * @index: port index based zero * * Return true if the port has acpi power resource and false if no. */ bool usb_acpi_power_manageable(struct usb_device *hdev, int index) { acpi_handle port_handle; int port1 = index + 1; port_handle = usb_get_hub_port_acpi_handle(hdev, port1); if (port_handle) return acpi_bus_power_manageable(port_handle); else return false; } EXPORT_SYMBOL_GPL(usb_acpi_power_manageable); /** * 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) { acpi_handle port_handle; unsigned char state; int port1 = index + 1; int error = -EINVAL; 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(&hdev->dev, "The power of hub port %d was set to %d\n", port1, enable); else dev_dbg(&hdev->dev, "The power of hub port failed to be set\n"); return error; } EXPORT_SYMBOL_GPL(usb_acpi_set_power_state); static int usb_acpi_check_port_connect_type(struct usb_device *hdev, acpi_handle handle, int port1) { acpi_status status; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *upc; struct acpi_pld_info *pld; int ret = 0; /* * Accoding to ACPI Spec 9.13. PLD indicates whether usb port is * user visible and _UPC indicates whether it is connectable. If * the port was visible and connectable, it could be freely connected * and disconnected with USB devices. If no visible and connectable, * a usb device is directly hard-wired to the port. If no visible and * no connectable, the port would be not used. */ status = acpi_get_physical_device_location(handle, &pld); if (ACPI_FAILURE(status)) return -ENODEV; status = acpi_evaluate_object(handle, "_UPC", NULL, &buffer); upc = buffer.pointer; if (!upc || (upc->type != ACPI_TYPE_PACKAGE) || upc->package.count != 4) { ret = -EINVAL; goto out; } if (upc->package.elements[0].integer.value) if (pld->user_visible) usb_set_hub_port_connect_type(hdev, port1, USB_PORT_CONNECT_TYPE_HOT_PLUG); else usb_set_hub_port_connect_type(hdev, port1, USB_PORT_CONNECT_TYPE_HARD_WIRED); else if (!pld->user_visible) usb_set_hub_port_connect_type(hdev, port1, USB_PORT_NOT_USED); out: ACPI_FREE(pld); kfree(upc); return ret; } static int usb_acpi_find_device(struct device *dev, acpi_handle *handle) { struct usb_device *udev; acpi_handle *parent_handle; int port_num; /* * In the ACPI DSDT table, only usb root hub and usb ports are * acpi device nodes. The hierarchy like following. * Device (EHC1) * Device (HUBN) * Device (PR01) * Device (PR11) * Device (PR12) * Device (PR13) * ... * So all binding process is divided into two parts. binding * root hub and usb ports. */ if (is_usb_device(dev)) { udev = to_usb_device(dev); if (udev->parent) { enum usb_port_connect_type type; /* * According usb port's connect type to set usb device's * removability. */ type = usb_get_hub_port_connect_type(udev->parent, udev->portnum); switch (type) { case USB_PORT_CONNECT_TYPE_HOT_PLUG: udev->removable = USB_DEVICE_REMOVABLE; break; case USB_PORT_CONNECT_TYPE_HARD_WIRED: udev->removable = USB_DEVICE_FIXED; break; default: udev->removable = USB_DEVICE_REMOVABLE_UNKNOWN; break; } return -ENODEV; } /* root hub's parent is the usb hcd. */ parent_handle = DEVICE_ACPI_HANDLE(dev->parent); *handle = acpi_get_child(parent_handle, udev->portnum); if (!*handle) return -ENODEV; return 0; } else if (is_usb_port(dev)) { sscanf(dev_name(dev), "port%d", &port_num); /* Get the struct usb_device point of port's hub */ udev = to_usb_device(dev->parent->parent); /* * The root hub ports' parent is the root hub. The non-root-hub * ports' parent is the parent hub port which the hub is * connected to. */ if (!udev->parent) { struct usb_hcd *hcd = bus_to_hcd(udev->bus); int raw_port_num; raw_port_num = usb_hcd_find_raw_port_number(hcd, port_num); *handle = acpi_get_child(DEVICE_ACPI_HANDLE(&udev->dev), raw_port_num); if (!*handle) return -ENODEV; } else { parent_handle = usb_get_hub_port_acpi_handle(udev->parent, udev->portnum); if (!parent_handle) return -ENODEV; *handle = acpi_get_child(parent_handle, port_num); if (!*handle) return -ENODEV; } usb_acpi_check_port_connect_type(udev, *handle, port_num); } else return -ENODEV; return 0; } static bool usb_acpi_bus_match(struct device *dev) { return is_usb_device(dev) || is_usb_port(dev); } static struct acpi_bus_type usb_acpi_bus = { .name = "USB", .match = usb_acpi_bus_match, .find_device = usb_acpi_find_device, }; int usb_acpi_register(void) { return register_acpi_bus_type(&usb_acpi_bus); } void usb_acpi_unregister(void) { unregister_acpi_bus_type(&usb_acpi_bus); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
You can’t perform that action at this time.