serio.c 24.5 KB
Newer Older
L
Linus Torvalds 已提交
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
/*
 *  The Serio abstraction module
 *
 *  Copyright (c) 1999-2004 Vojtech Pavlik
 *  Copyright (c) 2004 Dmitry Torokhov
 *  Copyright (c) 2003 Daniele Bellucci
 */

/*
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Should you need to contact me, the author, you can do so either by
 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
 */

29 30
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

L
Linus Torvalds 已提交
31 32 33 34 35 36
#include <linux/stddef.h>
#include <linux/module.h>
#include <linux/serio.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/slab.h>
37
#include <linux/workqueue.h>
38
#include <linux/mutex.h>
L
Linus Torvalds 已提交
39 40 41 42 43 44

MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Serio abstraction core");
MODULE_LICENSE("GPL");

/*
45
 * serio_mutex protects entire serio subsystem and is taken every time
46
 * serio port or driver registered or unregistered.
L
Linus Torvalds 已提交
47
 */
48
static DEFINE_MUTEX(serio_mutex);
L
Linus Torvalds 已提交
49 50 51

static LIST_HEAD(serio_list);

52
static struct bus_type serio_bus;
L
Linus Torvalds 已提交
53 54

static void serio_add_port(struct serio *serio);
55
static int serio_reconnect_port(struct serio *serio);
L
Linus Torvalds 已提交
56
static void serio_disconnect_port(struct serio *serio);
57
static void serio_reconnect_subtree(struct serio *serio);
58
static void serio_attach_driver(struct serio_driver *drv);
L
Linus Torvalds 已提交
59

60 61 62 63
static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
{
	int retval;

64
	mutex_lock(&serio->drv_mutex);
65
	retval = drv->connect(serio, drv);
66
	mutex_unlock(&serio->drv_mutex);
67 68 69 70 71 72 73 74

	return retval;
}

static int serio_reconnect_driver(struct serio *serio)
{
	int retval = -1;

75
	mutex_lock(&serio->drv_mutex);
76 77
	if (serio->drv && serio->drv->reconnect)
		retval = serio->drv->reconnect(serio);
78
	mutex_unlock(&serio->drv_mutex);
79 80 81 82 83 84

	return retval;
}

static void serio_disconnect_driver(struct serio *serio)
{
85
	mutex_lock(&serio->drv_mutex);
86 87
	if (serio->drv)
		serio->drv->disconnect(serio);
88
	mutex_unlock(&serio->drv_mutex);
89 90
}

L
Linus Torvalds 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
{
	while (ids->type || ids->proto) {
		if ((ids->type == SERIO_ANY || ids->type == serio->id.type) &&
		    (ids->proto == SERIO_ANY || ids->proto == serio->id.proto) &&
		    (ids->extra == SERIO_ANY || ids->extra == serio->id.extra) &&
		    (ids->id == SERIO_ANY || ids->id == serio->id.id))
			return 1;
		ids++;
	}
	return 0;
}

/*
 * Basic serio -> driver core mappings
 */

108
static int serio_bind_driver(struct serio *serio, struct serio_driver *drv)
L
Linus Torvalds 已提交
109
{
110 111
	int error;

L
Linus Torvalds 已提交
112
	if (serio_match_port(drv->id_table, serio)) {
113

L
Linus Torvalds 已提交
114
		serio->dev.driver = &drv->driver;
115
		if (serio_connect_driver(serio, drv)) {
L
Linus Torvalds 已提交
116
			serio->dev.driver = NULL;
117
			return -ENODEV;
L
Linus Torvalds 已提交
118
		}
119

120 121
		error = device_bind_driver(&serio->dev);
		if (error) {
122 123 124 125
			dev_warn(&serio->dev,
				 "device_bind_driver() failed for %s (%s) and %s, error: %d\n",
				 serio->phys, serio->name,
				 drv->description, error);
126 127
			serio_disconnect_driver(serio);
			serio->dev.driver = NULL;
128
			return error;
129
		}
L
Linus Torvalds 已提交
130
	}
131
	return 0;
L
Linus Torvalds 已提交
132 133 134 135
}

static void serio_find_driver(struct serio *serio)
{
136 137 138 139
	int error;

	error = device_attach(&serio->dev);
	if (error < 0)
140 141 142
		dev_warn(&serio->dev,
			 "device_attach() failed for %s (%s), error: %d\n",
			 serio->phys, serio->name, error);
L
Linus Torvalds 已提交
143 144 145 146 147 148 149 150
}


/*
 * Serio event processing.
 */

enum serio_event_type {
151 152
	SERIO_RESCAN_PORT,
	SERIO_RECONNECT_PORT,
153
	SERIO_RECONNECT_SUBTREE,
L
Linus Torvalds 已提交
154
	SERIO_REGISTER_PORT,
155
	SERIO_ATTACH_DRIVER,
L
Linus Torvalds 已提交
156 157 158 159 160 161 162 163 164 165 166 167
};

struct serio_event {
	enum serio_event_type type;
	void *object;
	struct module *owner;
	struct list_head node;
};

static DEFINE_SPINLOCK(serio_event_lock);	/* protects serio_event_list */
static LIST_HEAD(serio_event_list);

168
static struct serio_event *serio_get_event(void)
L
Linus Torvalds 已提交
169
{
170
	struct serio_event *event = NULL;
L
Linus Torvalds 已提交
171 172 173 174
	unsigned long flags;

	spin_lock_irqsave(&serio_event_lock, flags);

175 176 177 178
	if (!list_empty(&serio_event_list)) {
		event = list_first_entry(&serio_event_list,
					 struct serio_event, node);
		list_del_init(&event->node);
L
Linus Torvalds 已提交
179
	}
180

L
Linus Torvalds 已提交
181
	spin_unlock_irqrestore(&serio_event_lock, flags);
182
	return event;
L
Linus Torvalds 已提交
183 184 185 186 187 188 189 190
}

static void serio_free_event(struct serio_event *event)
{
	module_put(event->owner);
	kfree(event);
}

191 192
static void serio_remove_duplicate_events(void *object,
					  enum serio_event_type type)
L
Linus Torvalds 已提交
193
{
194
	struct serio_event *e, *next;
L
Linus Torvalds 已提交
195 196 197 198
	unsigned long flags;

	spin_lock_irqsave(&serio_event_lock, flags);

199
	list_for_each_entry_safe(e, next, &serio_event_list, node) {
200
		if (object == e->object) {
L
Linus Torvalds 已提交
201 202 203 204 205
			/*
			 * If this event is of different type we should not
			 * look further - we only suppress duplicate events
			 * that were sent back-to-back.
			 */
206
			if (type != e->type)
L
Linus Torvalds 已提交
207 208
				break;

209
			list_del_init(&e->node);
L
Linus Torvalds 已提交
210 211 212 213 214 215 216
			serio_free_event(e);
		}
	}

	spin_unlock_irqrestore(&serio_event_lock, flags);
}

217
static void serio_handle_event(struct work_struct *work)
L
Linus Torvalds 已提交
218 219 220
{
	struct serio_event *event;

221
	mutex_lock(&serio_mutex);
L
Linus Torvalds 已提交
222

223
	while ((event = serio_get_event())) {
L
Linus Torvalds 已提交
224 225 226

		switch (event->type) {

227 228 229
		case SERIO_REGISTER_PORT:
			serio_add_port(event->object);
			break;
L
Linus Torvalds 已提交
230

231 232 233
		case SERIO_RECONNECT_PORT:
			serio_reconnect_port(event->object);
			break;
L
Linus Torvalds 已提交
234

235 236 237 238
		case SERIO_RESCAN_PORT:
			serio_disconnect_port(event->object);
			serio_find_driver(event->object);
			break;
239

240 241
		case SERIO_RECONNECT_SUBTREE:
			serio_reconnect_subtree(event->object);
242
			break;
L
Linus Torvalds 已提交
243

244 245 246
		case SERIO_ATTACH_DRIVER:
			serio_attach_driver(event->object);
			break;
L
Linus Torvalds 已提交
247 248
		}

249
		serio_remove_duplicate_events(event->object, event->type);
L
Linus Torvalds 已提交
250 251 252
		serio_free_event(event);
	}

253
	mutex_unlock(&serio_mutex);
L
Linus Torvalds 已提交
254 255
}

256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
static DECLARE_WORK(serio_event_work, serio_handle_event);

static int serio_queue_event(void *object, struct module *owner,
			     enum serio_event_type event_type)
{
	unsigned long flags;
	struct serio_event *event;
	int retval = 0;

	spin_lock_irqsave(&serio_event_lock, flags);

	/*
	 * Scan event list for the other events for the same serio port,
	 * starting with the most recent one. If event is the same we
	 * do not need add new one. If event is of different type we
	 * need to add this event and should not look further because
	 * we need to preseve sequence of distinct events.
	 */
	list_for_each_entry_reverse(event, &serio_event_list, node) {
		if (event->object == object) {
			if (event->type == event_type)
				goto out;
			break;
		}
	}

	event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC);
	if (!event) {
		pr_err("Not enough memory to queue event %d\n", event_type);
		retval = -ENOMEM;
		goto out;
	}

	if (!try_module_get(owner)) {
		pr_warning("Can't get module reference, dropping event %d\n",
			   event_type);
		kfree(event);
		retval = -EINVAL;
		goto out;
	}

	event->type = event_type;
	event->object = object;
	event->owner = owner;

	list_add_tail(&event->node, &serio_event_list);
302
	queue_work(system_long_wq, &serio_event_work);
303 304 305 306 307 308

out:
	spin_unlock_irqrestore(&serio_event_lock, flags);
	return retval;
}

L
Linus Torvalds 已提交
309
/*
310 311
 * Remove all events that have been submitted for a given
 * object, be it serio port or driver.
L
Linus Torvalds 已提交
312
 */
313
static void serio_remove_pending_events(void *object)
L
Linus Torvalds 已提交
314
{
315
	struct serio_event *event, *next;
L
Linus Torvalds 已提交
316 317 318 319
	unsigned long flags;

	spin_lock_irqsave(&serio_event_lock, flags);

320
	list_for_each_entry_safe(event, next, &serio_event_list, node) {
321
		if (event->object == object) {
322
			list_del_init(&event->node);
L
Linus Torvalds 已提交
323 324 325 326 327 328 329 330
			serio_free_event(event);
		}
	}

	spin_unlock_irqrestore(&serio_event_lock, flags);
}

/*
331
 * Locate child serio port (if any) that has not been fully registered yet.
L
Linus Torvalds 已提交
332
 *
333 334
 * Children are registered by driver's connect() handler so there can't be a
 * grandchild pending registration together with a child.
L
Linus Torvalds 已提交
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
 */
static struct serio *serio_get_pending_child(struct serio *parent)
{
	struct serio_event *event;
	struct serio *serio, *child = NULL;
	unsigned long flags;

	spin_lock_irqsave(&serio_event_lock, flags);

	list_for_each_entry(event, &serio_event_list, node) {
		if (event->type == SERIO_REGISTER_PORT) {
			serio = event->object;
			if (serio->parent == parent) {
				child = serio;
				break;
			}
		}
	}

	spin_unlock_irqrestore(&serio_event_lock, flags);
	return child;
}

/*
 * Serio port operations
 */

362
static ssize_t serio_show_description(struct device *dev, struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
363 364 365 366 367
{
	struct serio *serio = to_serio_port(dev);
	return sprintf(buf, "%s\n", serio->name);
}

368
static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
369 370 371 372 373 374 375
{
	struct serio *serio = to_serio_port(dev);

	return sprintf(buf, "serio:ty%02Xpr%02Xid%02Xex%02X\n",
			serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
}

376
static ssize_t type_show(struct device *dev, struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
377 378 379 380 381
{
	struct serio *serio = to_serio_port(dev);
	return sprintf(buf, "%02x\n", serio->id.type);
}

382
static ssize_t proto_show(struct device *dev, struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
383 384 385 386 387
{
	struct serio *serio = to_serio_port(dev);
	return sprintf(buf, "%02x\n", serio->id.proto);
}

388
static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
389 390 391 392 393
{
	struct serio *serio = to_serio_port(dev);
	return sprintf(buf, "%02x\n", serio->id.id);
}

394
static ssize_t extra_show(struct device *dev, struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
395 396 397 398 399
{
	struct serio *serio = to_serio_port(dev);
	return sprintf(buf, "%02x\n", serio->id.extra);
}

400
static ssize_t drvctl_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
L
Linus Torvalds 已提交
401 402 403
{
	struct serio *serio = to_serio_port(dev);
	struct device_driver *drv;
404
	int error;
L
Linus Torvalds 已提交
405

406 407 408
	error = mutex_lock_interruptible(&serio_mutex);
	if (error)
		return error;
L
Linus Torvalds 已提交
409 410 411 412

	if (!strncmp(buf, "none", count)) {
		serio_disconnect_port(serio);
	} else if (!strncmp(buf, "reconnect", count)) {
413
		serio_reconnect_subtree(serio);
L
Linus Torvalds 已提交
414 415 416
	} else if (!strncmp(buf, "rescan", count)) {
		serio_disconnect_port(serio);
		serio_find_driver(serio);
417
		serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
L
Linus Torvalds 已提交
418 419
	} else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
		serio_disconnect_port(serio);
420
		error = serio_bind_driver(serio, to_serio_driver(drv));
421
		serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
L
Linus Torvalds 已提交
422
	} else {
423
		error = -EINVAL;
L
Linus Torvalds 已提交
424 425
	}

426
	mutex_unlock(&serio_mutex);
L
Linus Torvalds 已提交
427

428
	return error ? error : count;
L
Linus Torvalds 已提交
429 430
}

431
static ssize_t serio_show_bind_mode(struct device *dev, struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
432 433 434 435 436
{
	struct serio *serio = to_serio_port(dev);
	return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto");
}

437
static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
L
Linus Torvalds 已提交
438 439 440 441 442 443
{
	struct serio *serio = to_serio_port(dev);
	int retval;

	retval = count;
	if (!strncmp(buf, "manual", count)) {
444
		serio->manual_bind = true;
L
Linus Torvalds 已提交
445
	} else if (!strncmp(buf, "auto", count)) {
446
		serio->manual_bind = false;
L
Linus Torvalds 已提交
447 448 449 450 451 452 453
	} else {
		retval = -EINVAL;
	}

	return retval;
}

454 455 456 457 458 459 460
static ssize_t firmware_id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct serio *serio = to_serio_port(dev);

	return sprintf(buf, "%s\n", serio->firmware_id);
}

461 462 463 464 465 466 467 468 469 470
static DEVICE_ATTR_RO(type);
static DEVICE_ATTR_RO(proto);
static DEVICE_ATTR_RO(id);
static DEVICE_ATTR_RO(extra);

static struct attribute *serio_device_id_attrs[] = {
	&dev_attr_type.attr,
	&dev_attr_proto.attr,
	&dev_attr_id.attr,
	&dev_attr_extra.attr,
D
Dmitry Torokhov 已提交
471 472 473 474 475 476 477 478 479 480 481 482
	NULL
};

static struct attribute_group serio_id_attr_group = {
	.name	= "id",
	.attrs	= serio_device_id_attrs,
};

static DEVICE_ATTR_RO(modalias);
static DEVICE_ATTR_WO(drvctl);
static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL);
static DEVICE_ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode);
483
static DEVICE_ATTR_RO(firmware_id);
D
Dmitry Torokhov 已提交
484 485

static struct attribute *serio_device_attrs[] = {
486 487 488 489
	&dev_attr_modalias.attr,
	&dev_attr_description.attr,
	&dev_attr_drvctl.attr,
	&dev_attr_bind_mode.attr,
490
	&dev_attr_firmware_id.attr,
491 492 493
	NULL
};

D
Dmitry Torokhov 已提交
494 495
static struct attribute_group serio_device_attr_group = {
	.attrs	= serio_device_attrs,
L
Linus Torvalds 已提交
496 497
};

498 499
static const struct attribute_group *serio_device_attr_groups[] = {
	&serio_id_attr_group,
D
Dmitry Torokhov 已提交
500
	&serio_device_attr_group,
501 502
	NULL
};
L
Linus Torvalds 已提交
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520

static void serio_release_port(struct device *dev)
{
	struct serio *serio = to_serio_port(dev);

	kfree(serio);
	module_put(THIS_MODULE);
}

/*
 * Prepare serio port for registration.
 */
static void serio_init_port(struct serio *serio)
{
	static atomic_t serio_no = ATOMIC_INIT(0);

	__module_get(THIS_MODULE);

521
	INIT_LIST_HEAD(&serio->node);
522 523
	INIT_LIST_HEAD(&serio->child_node);
	INIT_LIST_HEAD(&serio->children);
L
Linus Torvalds 已提交
524
	spin_lock_init(&serio->lock);
525
	mutex_init(&serio->drv_mutex);
L
Linus Torvalds 已提交
526
	device_initialize(&serio->dev);
527 528
	dev_set_name(&serio->dev, "serio%lu",
		     (unsigned long)atomic_inc_return(&serio_no) - 1);
L
Linus Torvalds 已提交
529 530
	serio->dev.bus = &serio_bus;
	serio->dev.release = serio_release_port;
531
	serio->dev.groups = serio_device_attr_groups;
532
	if (serio->parent) {
L
Linus Torvalds 已提交
533
		serio->dev.parent = &serio->parent->dev;
534 535 536 537
		serio->depth = serio->parent->depth + 1;
	} else
		serio->depth = 0;
	lockdep_set_subclass(&serio->lock, serio->depth);
L
Linus Torvalds 已提交
538 539 540 541 542 543 544 545
}

/*
 * Complete serio port registration.
 * Driver core will attempt to find appropriate driver for the port.
 */
static void serio_add_port(struct serio *serio)
{
546
	struct serio *parent = serio->parent;
547 548
	int error;

549 550 551 552
	if (parent) {
		serio_pause_rx(parent);
		list_add_tail(&serio->child_node, &parent->children);
		serio_continue_rx(parent);
L
Linus Torvalds 已提交
553 554 555
	}

	list_add_tail(&serio->node, &serio_list);
556

L
Linus Torvalds 已提交
557 558
	if (serio->start)
		serio->start(serio);
559

560 561
	error = device_add(&serio->dev);
	if (error)
562 563
		dev_err(&serio->dev,
			"device_add() failed for %s (%s), error: %d\n",
564
			serio->phys, serio->name, error);
L
Linus Torvalds 已提交
565 566 567
}

/*
568
 * serio_destroy_port() completes unregistration process and removes
L
Linus Torvalds 已提交
569 570 571 572 573 574
 * port from the system
 */
static void serio_destroy_port(struct serio *serio)
{
	struct serio *child;

575
	while ((child = serio_get_pending_child(serio)) != NULL) {
L
Linus Torvalds 已提交
576 577 578 579 580 581 582 583 584
		serio_remove_pending_events(child);
		put_device(&child->dev);
	}

	if (serio->stop)
		serio->stop(serio);

	if (serio->parent) {
		serio_pause_rx(serio->parent);
585
		list_del_init(&serio->child_node);
L
Linus Torvalds 已提交
586 587 588 589
		serio_continue_rx(serio->parent);
		serio->parent = NULL;
	}

590
	if (device_is_registered(&serio->dev))
L
Linus Torvalds 已提交
591 592
		device_del(&serio->dev);

593
	list_del_init(&serio->node);
L
Linus Torvalds 已提交
594 595 596 597
	serio_remove_pending_events(serio);
	put_device(&serio->dev);
}

598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
/*
 * Reconnect serio port (re-initialize attached device).
 * If reconnect fails (old device is no longer attached or
 * there was no device to begin with) we do full rescan in
 * hope of finding a driver for the port.
 */
static int serio_reconnect_port(struct serio *serio)
{
	int error = serio_reconnect_driver(serio);

	if (error) {
		serio_disconnect_port(serio);
		serio_find_driver(serio);
	}

	return error;
}

L
Linus Torvalds 已提交
616
/*
617 618
 * Reconnect serio port and all its children (re-initialize attached
 * devices).
L
Linus Torvalds 已提交
619
 */
620
static void serio_reconnect_subtree(struct serio *root)
L
Linus Torvalds 已提交
621
{
622 623 624
	struct serio *s = root;
	int error;

L
Linus Torvalds 已提交
625
	do {
626 627 628 629 630 631 632 633 634 635 636
		error = serio_reconnect_port(s);
		if (!error) {
			/*
			 * Reconnect was successful, move on to do the
			 * first child.
			 */
			if (!list_empty(&s->children)) {
				s = list_first_entry(&s->children,
						     struct serio, child_node);
				continue;
			}
L
Linus Torvalds 已提交
637
		}
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655

		/*
		 * Either it was a leaf node or reconnect failed and it
		 * became a leaf node. Continue reconnecting starting with
		 * the next sibling of the parent node.
		 */
		while (s != root) {
			struct serio *parent = s->parent;

			if (!list_is_last(&s->child_node, &parent->children)) {
				s = list_entry(s->child_node.next,
					       struct serio, child_node);
				break;
			}

			s = parent;
		}
	} while (s != root);
L
Linus Torvalds 已提交
656 657 658 659
}

/*
 * serio_disconnect_port() unbinds a port from its driver. As a side effect
660
 * all children ports are unbound and destroyed.
L
Linus Torvalds 已提交
661 662 663
 */
static void serio_disconnect_port(struct serio *serio)
{
664 665 666 667 668 669 670 671 672 673 674 675
	struct serio *s = serio;

	/*
	 * Children ports should be disconnected and destroyed
	 * first; we travel the tree in depth-first order.
	 */
	while (!list_empty(&serio->children)) {

		/* Locate a leaf */
		while (!list_empty(&s->children))
			s = list_first_entry(&s->children,
					     struct serio, child_node);
L
Linus Torvalds 已提交
676 677

		/*
678 679
		 * Prune this leaf node unless it is the one we
		 * started with.
L
Linus Torvalds 已提交
680
		 */
681 682
		if (s != serio) {
			struct serio *parent = s->parent;
L
Linus Torvalds 已提交
683

684
			device_release_driver(&s->dev);
L
Linus Torvalds 已提交
685
			serio_destroy_port(s);
686 687 688

			s = parent;
		}
L
Linus Torvalds 已提交
689 690 691
	}

	/*
692
	 * OK, no children left, now disconnect this port.
L
Linus Torvalds 已提交
693
	 */
694
	device_release_driver(&serio->dev);
L
Linus Torvalds 已提交
695 696 697 698
}

void serio_rescan(struct serio *serio)
{
699
	serio_queue_event(serio, NULL, SERIO_RESCAN_PORT);
L
Linus Torvalds 已提交
700
}
701
EXPORT_SYMBOL(serio_rescan);
L
Linus Torvalds 已提交
702 703 704

void serio_reconnect(struct serio *serio)
{
705
	serio_queue_event(serio, NULL, SERIO_RECONNECT_SUBTREE);
L
Linus Torvalds 已提交
706
}
707
EXPORT_SYMBOL(serio_reconnect);
L
Linus Torvalds 已提交
708 709 710 711 712 713 714 715 716 717

/*
 * Submits register request to kseriod for subsequent execution.
 * Note that port registration is always asynchronous.
 */
void __serio_register_port(struct serio *serio, struct module *owner)
{
	serio_init_port(serio);
	serio_queue_event(serio, owner, SERIO_REGISTER_PORT);
}
718
EXPORT_SYMBOL(__serio_register_port);
L
Linus Torvalds 已提交
719 720 721 722 723 724

/*
 * Synchronously unregisters serio port.
 */
void serio_unregister_port(struct serio *serio)
{
725
	mutex_lock(&serio_mutex);
L
Linus Torvalds 已提交
726 727
	serio_disconnect_port(serio);
	serio_destroy_port(serio);
728
	mutex_unlock(&serio_mutex);
L
Linus Torvalds 已提交
729
}
730
EXPORT_SYMBOL(serio_unregister_port);
L
Linus Torvalds 已提交
731

732
/*
733
 * Safely unregisters children ports if they are present.
734 735 736
 */
void serio_unregister_child_port(struct serio *serio)
{
737 738
	struct serio *s, *next;

739
	mutex_lock(&serio_mutex);
740 741 742
	list_for_each_entry_safe(s, next, &serio->children, child_node) {
		serio_disconnect_port(s);
		serio_destroy_port(s);
743
	}
744
	mutex_unlock(&serio_mutex);
745
}
746
EXPORT_SYMBOL(serio_unregister_child_port);
747

L
Linus Torvalds 已提交
748 749 750 751 752

/*
 * Serio driver operations
 */

753
static ssize_t description_show(struct device_driver *drv, char *buf)
L
Linus Torvalds 已提交
754 755 756 757
{
	struct serio_driver *driver = to_serio_driver(drv);
	return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)");
}
758
static DRIVER_ATTR_RO(description);
L
Linus Torvalds 已提交
759

760
static ssize_t bind_mode_show(struct device_driver *drv, char *buf)
L
Linus Torvalds 已提交
761 762 763 764 765
{
	struct serio_driver *serio_drv = to_serio_driver(drv);
	return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto");
}

766
static ssize_t bind_mode_store(struct device_driver *drv, const char *buf, size_t count)
L
Linus Torvalds 已提交
767 768 769 770 771 772
{
	struct serio_driver *serio_drv = to_serio_driver(drv);
	int retval;

	retval = count;
	if (!strncmp(buf, "manual", count)) {
773
		serio_drv->manual_bind = true;
L
Linus Torvalds 已提交
774
	} else if (!strncmp(buf, "auto", count)) {
775
		serio_drv->manual_bind = false;
L
Linus Torvalds 已提交
776 777 778 779 780 781
	} else {
		retval = -EINVAL;
	}

	return retval;
}
782
static DRIVER_ATTR_RW(bind_mode);
L
Linus Torvalds 已提交
783

784 785 786 787
static struct attribute *serio_driver_attrs[] = {
	&driver_attr_description.attr,
	&driver_attr_bind_mode.attr,
	NULL,
L
Linus Torvalds 已提交
788
};
789
ATTRIBUTE_GROUPS(serio_driver);
L
Linus Torvalds 已提交
790 791 792 793 794 795

static int serio_driver_probe(struct device *dev)
{
	struct serio *serio = to_serio_port(dev);
	struct serio_driver *drv = to_serio_driver(dev->driver);

796
	return serio_connect_driver(serio, drv);
L
Linus Torvalds 已提交
797 798 799 800 801 802
}

static int serio_driver_remove(struct device *dev)
{
	struct serio *serio = to_serio_port(dev);

803
	serio_disconnect_driver(serio);
L
Linus Torvalds 已提交
804 805 806
	return 0;
}

807 808
static void serio_cleanup(struct serio *serio)
{
809
	mutex_lock(&serio->drv_mutex);
810 811
	if (serio->drv && serio->drv->cleanup)
		serio->drv->cleanup(serio);
812
	mutex_unlock(&serio->drv_mutex);
813 814 815 816 817 818 819 820 821
}

static void serio_shutdown(struct device *dev)
{
	struct serio *serio = to_serio_port(dev);

	serio_cleanup(serio);
}

822
static void serio_attach_driver(struct serio_driver *drv)
823 824 825
{
	int error;

826
	error = driver_attach(&drv->driver);
827
	if (error)
828 829
		pr_warning("driver_attach() failed for %s with error %d\n",
			   drv->driver.name, error);
830 831
}

832
int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name)
L
Linus Torvalds 已提交
833
{
834
	bool manual_bind = drv->manual_bind;
835 836
	int error;

L
Linus Torvalds 已提交
837
	drv->driver.bus = &serio_bus;
838 839
	drv->driver.owner = owner;
	drv->driver.mod_name = mod_name;
L
Linus Torvalds 已提交
840

841 842 843 844
	/*
	 * Temporarily disable automatic binding because probing
	 * takes long time and we are better off doing it in kseriod
	 */
845
	drv->manual_bind = true;
846 847 848

	error = driver_register(&drv->driver);
	if (error) {
849
		pr_err("driver_register() failed for %s, error: %d\n",
850 851 852 853 854 855 856 857 858
			drv->driver.name, error);
		return error;
	}

	/*
	 * Restore original bind mode and let kseriod bind the
	 * driver to free ports
	 */
	if (!manual_bind) {
859
		drv->manual_bind = false;
860 861 862 863 864 865 866 867
		error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER);
		if (error) {
			driver_unregister(&drv->driver);
			return error;
		}
	}

	return 0;
L
Linus Torvalds 已提交
868
}
869
EXPORT_SYMBOL(__serio_register_driver);
L
Linus Torvalds 已提交
870 871 872 873 874

void serio_unregister_driver(struct serio_driver *drv)
{
	struct serio *serio;

875
	mutex_lock(&serio_mutex);
876

877
	drv->manual_bind = true;	/* so serio_find_driver ignores it */
878
	serio_remove_pending_events(drv);
L
Linus Torvalds 已提交
879 880 881 882 883 884 885 886 887 888 889 890

start_over:
	list_for_each_entry(serio, &serio_list, node) {
		if (serio->drv == drv) {
			serio_disconnect_port(serio);
			serio_find_driver(serio);
			/* we could've deleted some ports, restart */
			goto start_over;
		}
	}

	driver_unregister(&drv->driver);
891
	mutex_unlock(&serio_mutex);
L
Linus Torvalds 已提交
892
}
893
EXPORT_SYMBOL(serio_unregister_driver);
L
Linus Torvalds 已提交
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912

static void serio_set_drv(struct serio *serio, struct serio_driver *drv)
{
	serio_pause_rx(serio);
	serio->drv = drv;
	serio_continue_rx(serio);
}

static int serio_bus_match(struct device *dev, struct device_driver *drv)
{
	struct serio *serio = to_serio_port(dev);
	struct serio_driver *serio_drv = to_serio_driver(drv);

	if (serio->manual_bind || serio_drv->manual_bind)
		return 0;

	return serio_match_port(serio_drv->id_table, serio);
}

913
#define SERIO_ADD_UEVENT_VAR(fmt, val...)				\
914
	do {								\
915
		int err = add_uevent_var(env, fmt, val);		\
916 917 918 919
		if (err)						\
			return err;					\
	} while (0)

920
static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
L
Linus Torvalds 已提交
921 922 923 924 925 926 927 928
{
	struct serio *serio;

	if (!dev)
		return -ENODEV;

	serio = to_serio_port(dev);

929 930 931 932
	SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type);
	SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto);
	SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id);
	SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
933

934
	SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
935
				serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
L
Linus Torvalds 已提交
936

937 938 939 940
	if (serio->firmware_id[0])
		SERIO_ADD_UEVENT_VAR("SERIO_FIRMWARE_ID=%s",
				     serio->firmware_id);

L
Linus Torvalds 已提交
941 942
	return 0;
}
943
#undef SERIO_ADD_UEVENT_VAR
L
Linus Torvalds 已提交
944

945
#ifdef CONFIG_PM
946
static int serio_suspend(struct device *dev)
947
{
948
	struct serio *serio = to_serio_port(dev);
949

950
	serio_cleanup(serio);
951 952 953 954

	return 0;
}

L
Linus Torvalds 已提交
955 956
static int serio_resume(struct device *dev)
{
957 958
	struct serio *serio = to_serio_port(dev);

959 960 961 962
	/*
	 * Driver reconnect can take a while, so better let kseriod
	 * deal with it.
	 */
963
	serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT);
L
Linus Torvalds 已提交
964 965 966

	return 0;
}
967 968 969 970 971 972 973

static const struct dev_pm_ops serio_pm_ops = {
	.suspend	= serio_suspend,
	.resume		= serio_resume,
	.poweroff	= serio_suspend,
	.restore	= serio_resume,
};
974
#endif /* CONFIG_PM */
L
Linus Torvalds 已提交
975

976
/* called from serio_driver->connect/disconnect methods under serio_mutex */
L
Linus Torvalds 已提交
977 978 979 980 981 982 983 984 985 986
int serio_open(struct serio *serio, struct serio_driver *drv)
{
	serio_set_drv(serio, drv);

	if (serio->open && serio->open(serio)) {
		serio_set_drv(serio, NULL);
		return -1;
	}
	return 0;
}
987
EXPORT_SYMBOL(serio_open);
L
Linus Torvalds 已提交
988

989
/* called from serio_driver->connect/disconnect methods under serio_mutex */
L
Linus Torvalds 已提交
990 991 992 993 994 995 996
void serio_close(struct serio *serio)
{
	if (serio->close)
		serio->close(serio);

	serio_set_drv(serio, NULL);
}
997
EXPORT_SYMBOL(serio_close);
L
Linus Torvalds 已提交
998 999

irqreturn_t serio_interrupt(struct serio *serio,
1000
		unsigned char data, unsigned int dfl)
L
Linus Torvalds 已提交
1001 1002 1003 1004 1005 1006 1007
{
	unsigned long flags;
	irqreturn_t ret = IRQ_NONE;

	spin_lock_irqsave(&serio->lock, flags);

        if (likely(serio->drv)) {
1008
                ret = serio->drv->interrupt(serio, data, dfl);
1009
	} else if (!dfl && device_is_registered(&serio->dev)) {
L
Linus Torvalds 已提交
1010 1011 1012 1013 1014 1015 1016 1017
		serio_rescan(serio);
		ret = IRQ_HANDLED;
	}

	spin_unlock_irqrestore(&serio->lock, flags);

	return ret;
}
1018
EXPORT_SYMBOL(serio_interrupt);
L
Linus Torvalds 已提交
1019

1020 1021
static struct bus_type serio_bus = {
	.name		= "serio",
1022
	.drv_groups	= serio_driver_groups,
1023 1024 1025 1026
	.match		= serio_bus_match,
	.uevent		= serio_uevent,
	.probe		= serio_driver_probe,
	.remove		= serio_driver_remove,
1027 1028
	.shutdown	= serio_shutdown,
#ifdef CONFIG_PM
1029
	.pm		= &serio_pm_ops,
1030
#endif
1031 1032
};

L
Linus Torvalds 已提交
1033 1034
static int __init serio_init(void)
{
1035
	int error;
L
Linus Torvalds 已提交
1036

1037 1038
	error = bus_register(&serio_bus);
	if (error) {
1039
		pr_err("Failed to register serio bus, error: %d\n", error);
1040 1041 1042
		return error;
	}

L
Linus Torvalds 已提交
1043 1044 1045 1046 1047 1048
	return 0;
}

static void __exit serio_exit(void)
{
	bus_unregister(&serio_bus);
1049 1050 1051 1052 1053 1054

	/*
	 * There should not be any outstanding events but work may
	 * still be scheduled so simply cancel it.
	 */
	cancel_work_sync(&serio_event_work);
L
Linus Torvalds 已提交
1055 1056
}

1057
subsys_initcall(serio_init);
L
Linus Torvalds 已提交
1058
module_exit(serio_exit);