port.c 11.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * usb port device code
 *
 * Copyright (C) 2012 Intel Corp
 *
 * Author: Lan Tianyu <tianyu.lan@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 */

19
#include <linux/slab.h>
20
#include <linux/pm_qos.h>
21

22 23
#include "hub.h"

24 25
static const struct attribute_group *port_dev_group[];

26 27
static ssize_t connect_type_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
{
	struct usb_port *port_dev = to_usb_port(dev);
	char *result;

	switch (port_dev->connect_type) {
	case USB_PORT_CONNECT_TYPE_HOT_PLUG:
		result = "hotplug";
		break;
	case USB_PORT_CONNECT_TYPE_HARD_WIRED:
		result = "hardwired";
		break;
	case USB_PORT_NOT_USED:
		result = "not used";
		break;
	default:
		result = "unknown";
		break;
	}

	return sprintf(buf, "%s\n", result);
}
49
static DEVICE_ATTR_RO(connect_type);
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

static struct attribute *port_dev_attrs[] = {
	&dev_attr_connect_type.attr,
	NULL,
};

static struct attribute_group port_dev_attr_grp = {
	.attrs = port_dev_attrs,
};

static const struct attribute_group *port_dev_group[] = {
	&port_dev_attr_grp,
	NULL,
};

65 66 67 68 69 70 71
static void usb_port_device_release(struct device *dev)
{
	struct usb_port *port_dev = to_usb_port(dev);

	kfree(port_dev);
}

72
#ifdef CONFIG_PM_RUNTIME
73 74 75 76 77
static int usb_port_runtime_resume(struct device *dev)
{
	struct usb_port *port_dev = to_usb_port(dev);
	struct usb_device *hdev = to_usb_device(dev->parent->parent);
	struct usb_interface *intf = to_usb_interface(dev->parent);
78
	struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
79
	struct usb_port *peer = port_dev->peer;
80
	int port1 = port_dev->portnum;
81 82
	int retval;

83 84
	if (!hub)
		return -EINVAL;
85
	if (hub->in_reset) {
86
		set_bit(port1, hub->power_bits);
87 88
		return 0;
	}
89

90 91 92 93 94 95 96
	/*
	 * Power on our usb3 peer before this usb2 port to prevent a usb3
	 * device from degrading to its usb2 connection
	 */
	if (!port_dev->is_superspeed && peer)
		pm_runtime_get_sync(&peer->dev);

97
	usb_autopm_get_interface(intf);
98 99
	set_bit(port1, hub->busy_bits);

100
	retval = usb_hub_set_port_power(hdev, hub, port1, true);
101
	msleep(hub_power_on_good_delay(hub));
102 103
	if (port_dev->child && !retval) {
		/*
104 105 106 107
		 * Attempt to wait for usb hub port to be reconnected in order
		 * to make the resume procedure successful.  The device may have
		 * disconnected while the port was powered off, so ignore the
		 * return status.
108 109
		 */
		retval = hub_port_debounce_be_connected(hub, port1);
110
		if (retval < 0)
111 112 113 114 115 116 117
			dev_dbg(&port_dev->dev, "can't get reconnection after setting port  power on, status %d\n",
					retval);
		usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
		retval = 0;
	}

	clear_bit(port1, hub->busy_bits);
118
	usb_autopm_put_interface(intf);
119

120 121 122 123 124 125 126 127
	return retval;
}

static int usb_port_runtime_suspend(struct device *dev)
{
	struct usb_port *port_dev = to_usb_port(dev);
	struct usb_device *hdev = to_usb_device(dev->parent->parent);
	struct usb_interface *intf = to_usb_interface(dev->parent);
128
	struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
129
	struct usb_port *peer = port_dev->peer;
130
	int port1 = port_dev->portnum;
131 132
	int retval;

133 134
	if (!hub)
		return -EINVAL;
135 136
	if (hub->in_reset)
		return -EBUSY;
137

138 139 140 141 142
	if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF)
			== PM_QOS_FLAGS_ALL)
		return -EAGAIN;

	usb_autopm_get_interface(intf);
143
	set_bit(port1, hub->busy_bits);
144
	retval = usb_hub_set_port_power(hdev, hub, port1, false);
145 146 147
	usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
	usb_clear_port_feature(hdev, port1,	USB_PORT_FEAT_C_ENABLE);
	clear_bit(port1, hub->busy_bits);
148
	usb_autopm_put_interface(intf);
149 150 151 152 153 154 155 156 157

	/*
	 * Our peer usb3 port may now be able to suspend, so
	 * asynchronously queue a suspend request to observe that this
	 * usb2 port is now off.
	 */
	if (!port_dev->is_superspeed && peer)
		pm_runtime_put(&peer->dev);

158 159 160 161 162
	return retval;
}
#endif

static const struct dev_pm_ops usb_port_pm_ops = {
163
#ifdef CONFIG_PM_RUNTIME
164 165 166 167 168
	.runtime_suspend =	usb_port_runtime_suspend,
	.runtime_resume =	usb_port_runtime_resume,
#endif
};

169 170 171
struct device_type usb_port_device_type = {
	.name =		"usb_port",
	.release =	usb_port_device_release,
172
	.pm =		&usb_port_pm_ops,
173 174
};

175 176 177 178 179
static struct device_driver usb_port_driver = {
	.name = "usb",
	.owner = THIS_MODULE,
};

D
Dan Williams 已提交
180
static int link_peers(struct usb_port *left, struct usb_port *right)
181
{
182
	struct usb_port *ss_port, *hs_port;
D
Dan Williams 已提交
183 184
	int rc;

185
	if (left->peer == right && right->peer == left)
D
Dan Williams 已提交
186
		return 0;
187 188 189 190 191 192 193 194 195

	if (left->peer || right->peer) {
		struct usb_port *lpeer = left->peer;
		struct usb_port *rpeer = right->peer;

		WARN(1, "failed to peer %s and %s (%s -> %p) (%s -> %p)\n",
			dev_name(&left->dev), dev_name(&right->dev),
			dev_name(&left->dev), lpeer,
			dev_name(&right->dev), rpeer);
D
Dan Williams 已提交
196 197 198 199 200 201 202 203 204 205
		return -EBUSY;
	}

	rc = sysfs_create_link(&left->dev.kobj, &right->dev.kobj, "peer");
	if (rc)
		return rc;
	rc = sysfs_create_link(&right->dev.kobj, &left->dev.kobj, "peer");
	if (rc) {
		sysfs_remove_link(&left->dev.kobj, "peer");
		return rc;
206 207
	}

208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
	/*
	 * We need to wake the HiSpeed port to make sure we don't race
	 * setting ->peer with usb_port_runtime_suspend().  Otherwise we
	 * may miss a suspend event for the SuperSpeed port.
	 */
	if (left->is_superspeed) {
		ss_port = left;
		WARN_ON(right->is_superspeed);
		hs_port = right;
	} else {
		ss_port = right;
		WARN_ON(!right->is_superspeed);
		hs_port = left;
	}
	pm_runtime_get_sync(&hs_port->dev);

224 225
	left->peer = right;
	right->peer = left;
D
Dan Williams 已提交
226

227 228 229 230 231 232 233 234 235 236 237
	/*
	 * The SuperSpeed reference is dropped when the HiSpeed port in
	 * this relationship suspends, i.e. when it is safe to allow a
	 * SuperSpeed connection to drop since there is no risk of a
	 * device degrading to its powered-off HiSpeed connection.
	 *
	 * Also, drop the HiSpeed ref taken above.
	 */
	pm_runtime_get_sync(&ss_port->dev);
	pm_runtime_put(&hs_port->dev);

D
Dan Williams 已提交
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
	return 0;
}

static void link_peers_report(struct usb_port *left, struct usb_port *right)
{
	int rc;

	rc = link_peers(left, right);
	if (rc == 0) {
		dev_dbg(&left->dev, "peered to %s\n", dev_name(&right->dev));
	} else {
		dev_warn(&left->dev, "failed to peer to %s (%d)\n",
				dev_name(&right->dev), rc);
		pr_warn_once("usb: port power management may be unreliable\n");
	}
253 254 255 256
}

static void unlink_peers(struct usb_port *left, struct usb_port *right)
{
257 258
	struct usb_port *ss_port, *hs_port;

259 260 261 262
	WARN(right->peer != left || left->peer != right,
			"%s and %s are not peers?\n",
			dev_name(&left->dev), dev_name(&right->dev));

263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
	/*
	 * We wake the HiSpeed port to make sure we don't race its
	 * usb_port_runtime_resume() event which takes a SuperSpeed ref
	 * when ->peer is !NULL.
	 */
	if (left->is_superspeed) {
		ss_port = left;
		hs_port = right;
	} else {
		ss_port = right;
		hs_port = left;
	}

	pm_runtime_get_sync(&hs_port->dev);

D
Dan Williams 已提交
278
	sysfs_remove_link(&left->dev.kobj, "peer");
279
	right->peer = NULL;
D
Dan Williams 已提交
280
	sysfs_remove_link(&right->dev.kobj, "peer");
281
	left->peer = NULL;
282 283 284 285 286 287

	/* Drop the SuperSpeed ref held on behalf of the active HiSpeed port */
	pm_runtime_put(&ss_port->dev);

	/* Drop the ref taken above */
	pm_runtime_put(&hs_port->dev);
288 289
}

290
/*
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
 * For each usb hub device in the system check to see if it is in the
 * peer domain of the given port_dev, and if it is check to see if it
 * has a port that matches the given port by location
 */
static int match_location(struct usb_device *peer_hdev, void *p)
{
	int port1;
	struct usb_hcd *hcd, *peer_hcd;
	struct usb_port *port_dev = p, *peer;
	struct usb_hub *peer_hub = usb_hub_to_struct_hub(peer_hdev);
	struct usb_device *hdev = to_usb_device(port_dev->dev.parent->parent);

	if (!peer_hub)
		return 0;

	hcd = bus_to_hcd(hdev->bus);
	peer_hcd = bus_to_hcd(peer_hdev->bus);
	/* peer_hcd is provisional until we verify it against the known peer */
	if (peer_hcd != hcd->shared_hcd)
		return 0;

	for (port1 = 1; port1 <= peer_hdev->maxchild; port1++) {
		peer = peer_hub->ports[port1 - 1];
		if (peer && peer->location == port_dev->location) {
D
Dan Williams 已提交
315
			link_peers_report(port_dev, peer);
316 317 318 319 320 321 322 323 324 325 326
			return 1; /* done */
		}
	}

	return 0;
}

/*
 * Find the peer port either via explicit platform firmware "location"
 * data, the peer hcd for root hubs, or the upstream peer relationship
 * for all other hubs.
327
 */
328 329 330 331
static void find_and_link_peer(struct usb_hub *hub, int port1)
{
	struct usb_port *port_dev = hub->ports[port1 - 1], *peer;
	struct usb_device *hdev = hub->hdev;
332 333
	struct usb_device *peer_hdev;
	struct usb_hub *peer_hub;
334

335 336 337 338 339 340 341 342 343 344 345
	/*
	 * If location data is available then we can only peer this port
	 * by a location match, not the default peer (lest we create a
	 * situation where we need to go back and undo a default peering
	 * when the port is later peered by location data)
	 */
	if (port_dev->location) {
		/* we link the peer in match_location() if found */
		usb_for_each_dev(port_dev, match_location);
		return;
	} else if (!hdev->parent) {
346 347 348 349 350 351 352
		struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
		struct usb_hcd *peer_hcd = hcd->shared_hcd;

		if (!peer_hcd)
			return;

		peer_hdev = peer_hcd->self.root_hub;
353 354 355 356 357 358
	} else {
		struct usb_port *upstream;
		struct usb_device *parent = hdev->parent;
		struct usb_hub *parent_hub = usb_hub_to_struct_hub(parent);

		if (!parent_hub)
359 360
			return;

361 362 363
		upstream = parent_hub->ports[hdev->portnum - 1];
		if (!upstream || !upstream->peer)
			return;
364

365
		peer_hdev = upstream->peer->child;
366
	}
367 368 369 370 371

	peer_hub = usb_hub_to_struct_hub(peer_hdev);
	if (!peer_hub || port1 > peer_hdev->maxchild)
		return;

372 373 374 375
	/*
	 * we found a valid default peer, last check is to make sure it
	 * does not have location data
	 */
376
	peer = peer_hub->ports[port1 - 1];
377
	if (peer && peer->location == 0)
D
Dan Williams 已提交
378
		link_peers_report(port_dev, peer);
379 380
}

381 382
int usb_hub_create_port_device(struct usb_hub *hub, int port1)
{
383
	struct usb_port *port_dev;
384 385 386 387 388 389 390 391 392
	int retval;

	port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
	if (!port_dev) {
		retval = -ENOMEM;
		goto exit;
	}

	hub->ports[port1 - 1] = port_dev;
393
	port_dev->portnum = port1;
394
	set_bit(port1, hub->power_bits);
395
	port_dev->dev.parent = hub->intfdev;
396
	port_dev->dev.groups = port_dev_group;
397
	port_dev->dev.type = &usb_port_device_type;
398
	port_dev->dev.driver = &usb_port_driver;
399 400
	if (hub_is_superspeed(hub->hdev))
		port_dev->is_superspeed = 1;
401 402
	dev_set_name(&port_dev->dev, "%s-port%d", dev_name(&hub->hdev->dev),
			port1);
403 404 405 406
	retval = device_register(&port_dev->dev);
	if (retval)
		goto error_register;

407 408
	find_and_link_peer(hub, port1);

409
	pm_runtime_set_active(&port_dev->dev);
410

411 412 413 414 415
	/*
	 * Do not enable port runtime pm if the hub does not support
	 * power switching.  Also, userspace must have final say of
	 * whether a port is permitted to power-off.  Do not enable
	 * runtime pm if we fail to expose pm_qos_no_power_off.
416
	 */
417 418 419
	if (hub_is_port_power_switchable(hub)
			&& dev_pm_qos_expose_flags(&port_dev->dev,
			PM_QOS_FLAG_NO_POWER_OFF) == 0)
420 421
		pm_runtime_enable(&port_dev->dev);

422
	device_enable_async_suspend(&port_dev->dev);
423 424 425 426 427 428 429 430
	return 0;

error_register:
	put_device(&port_dev->dev);
exit:
	return retval;
}

431
void usb_hub_remove_port_device(struct usb_hub *hub, int port1)
432
{
433 434
	struct usb_port *port_dev = hub->ports[port1 - 1];
	struct usb_port *peer;
435

436 437 438 439 440
	peer = port_dev->peer;
	if (peer)
		unlink_peers(port_dev, peer);
	device_unregister(&port_dev->dev);
}