serio.c 24.2 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 369 370 371 372 373 374 375
static ssize_t serio_show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
	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 serio_show_id_type(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 serio_show_id_proto(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 serio_show_id_id(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 serio_show_id_extra(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);
}

D
Dmitry Torokhov 已提交
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
static DEVICE_ATTR(type, S_IRUGO, serio_show_id_type, NULL);
static DEVICE_ATTR(proto, S_IRUGO, serio_show_id_proto, NULL);
static DEVICE_ATTR(id, S_IRUGO, serio_show_id_id, NULL);
static DEVICE_ATTR(extra, S_IRUGO, serio_show_id_extra, NULL);

static struct attribute *serio_device_id_attrs[] = {
	&dev_attr_type.attr,
	&dev_attr_proto.attr,
	&dev_attr_id.attr,
	&dev_attr_extra.attr,
	NULL
};

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

418 419 420 421 422
static const struct attribute_group *serio_device_attr_groups[] = {
	&serio_id_attr_group,
	NULL
};

423
static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
L
Linus Torvalds 已提交
424 425 426
{
	struct serio *serio = to_serio_port(dev);
	struct device_driver *drv;
427
	int error;
L
Linus Torvalds 已提交
428

429 430 431
	error = mutex_lock_interruptible(&serio_mutex);
	if (error)
		return error;
L
Linus Torvalds 已提交
432 433 434 435

	if (!strncmp(buf, "none", count)) {
		serio_disconnect_port(serio);
	} else if (!strncmp(buf, "reconnect", count)) {
436
		serio_reconnect_subtree(serio);
L
Linus Torvalds 已提交
437 438 439
	} else if (!strncmp(buf, "rescan", count)) {
		serio_disconnect_port(serio);
		serio_find_driver(serio);
440
		serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
L
Linus Torvalds 已提交
441 442
	} else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
		serio_disconnect_port(serio);
443
		error = serio_bind_driver(serio, to_serio_driver(drv));
444
		serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
L
Linus Torvalds 已提交
445
	} else {
446
		error = -EINVAL;
L
Linus Torvalds 已提交
447 448
	}

449
	mutex_unlock(&serio_mutex);
L
Linus Torvalds 已提交
450

451
	return error ? error : count;
L
Linus Torvalds 已提交
452 453
}

454
static ssize_t serio_show_bind_mode(struct device *dev, struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
455 456 457 458 459
{
	struct serio *serio = to_serio_port(dev);
	return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto");
}

460
static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
L
Linus Torvalds 已提交
461 462 463 464 465 466
{
	struct serio *serio = to_serio_port(dev);
	int retval;

	retval = count;
	if (!strncmp(buf, "manual", count)) {
467
		serio->manual_bind = true;
L
Linus Torvalds 已提交
468
	} else if (!strncmp(buf, "auto", count)) {
469
		serio->manual_bind = false;
L
Linus Torvalds 已提交
470 471 472 473 474 475 476 477 478
	} else {
		retval = -EINVAL;
	}

	return retval;
}

static struct device_attribute serio_device_attrs[] = {
	__ATTR(description, S_IRUGO, serio_show_description, NULL),
479
	__ATTR(modalias, S_IRUGO, serio_show_modalias, NULL),
L
Linus Torvalds 已提交
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
	__ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver),
	__ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode),
	__ATTR_NULL
};


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);

503
	INIT_LIST_HEAD(&serio->node);
504 505
	INIT_LIST_HEAD(&serio->child_node);
	INIT_LIST_HEAD(&serio->children);
L
Linus Torvalds 已提交
506
	spin_lock_init(&serio->lock);
507
	mutex_init(&serio->drv_mutex);
L
Linus Torvalds 已提交
508
	device_initialize(&serio->dev);
509 510
	dev_set_name(&serio->dev, "serio%ld",
			(long)atomic_inc_return(&serio_no) - 1);
L
Linus Torvalds 已提交
511 512
	serio->dev.bus = &serio_bus;
	serio->dev.release = serio_release_port;
513
	serio->dev.groups = serio_device_attr_groups;
514
	if (serio->parent) {
L
Linus Torvalds 已提交
515
		serio->dev.parent = &serio->parent->dev;
516 517 518 519
		serio->depth = serio->parent->depth + 1;
	} else
		serio->depth = 0;
	lockdep_set_subclass(&serio->lock, serio->depth);
L
Linus Torvalds 已提交
520 521 522 523 524 525 526 527
}

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

531 532 533 534
	if (parent) {
		serio_pause_rx(parent);
		list_add_tail(&serio->child_node, &parent->children);
		serio_continue_rx(parent);
L
Linus Torvalds 已提交
535 536 537
	}

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

L
Linus Torvalds 已提交
539 540
	if (serio->start)
		serio->start(serio);
541

542 543
	error = device_add(&serio->dev);
	if (error)
544 545
		dev_err(&serio->dev,
			"device_add() failed for %s (%s), error: %d\n",
546
			serio->phys, serio->name, error);
L
Linus Torvalds 已提交
547 548 549
}

/*
550
 * serio_destroy_port() completes unregistration process and removes
L
Linus Torvalds 已提交
551 552 553 554 555 556
 * port from the system
 */
static void serio_destroy_port(struct serio *serio)
{
	struct serio *child;

557
	while ((child = serio_get_pending_child(serio)) != NULL) {
L
Linus Torvalds 已提交
558 559 560 561 562 563 564 565 566
		serio_remove_pending_events(child);
		put_device(&child->dev);
	}

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

	if (serio->parent) {
		serio_pause_rx(serio->parent);
567
		list_del_init(&serio->child_node);
L
Linus Torvalds 已提交
568 569 570 571
		serio_continue_rx(serio->parent);
		serio->parent = NULL;
	}

572
	if (device_is_registered(&serio->dev))
L
Linus Torvalds 已提交
573 574
		device_del(&serio->dev);

575
	list_del_init(&serio->node);
L
Linus Torvalds 已提交
576 577 578 579
	serio_remove_pending_events(serio);
	put_device(&serio->dev);
}

580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
/*
 * 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 已提交
598
/*
599 600
 * Reconnect serio port and all its children (re-initialize attached
 * devices).
L
Linus Torvalds 已提交
601
 */
602
static void serio_reconnect_subtree(struct serio *root)
L
Linus Torvalds 已提交
603
{
604 605 606
	struct serio *s = root;
	int error;

L
Linus Torvalds 已提交
607
	do {
608 609 610 611 612 613 614 615 616 617 618
		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 已提交
619
		}
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637

		/*
		 * 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 已提交
638 639 640 641
}

/*
 * serio_disconnect_port() unbinds a port from its driver. As a side effect
642
 * all children ports are unbound and destroyed.
L
Linus Torvalds 已提交
643 644 645
 */
static void serio_disconnect_port(struct serio *serio)
{
646 647 648 649 650 651 652 653 654 655 656 657
	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 已提交
658 659

		/*
660 661
		 * Prune this leaf node unless it is the one we
		 * started with.
L
Linus Torvalds 已提交
662
		 */
663 664
		if (s != serio) {
			struct serio *parent = s->parent;
L
Linus Torvalds 已提交
665

666
			device_release_driver(&s->dev);
L
Linus Torvalds 已提交
667
			serio_destroy_port(s);
668 669 670

			s = parent;
		}
L
Linus Torvalds 已提交
671 672 673
	}

	/*
674
	 * OK, no children left, now disconnect this port.
L
Linus Torvalds 已提交
675
	 */
676
	device_release_driver(&serio->dev);
L
Linus Torvalds 已提交
677 678 679 680
}

void serio_rescan(struct serio *serio)
{
681
	serio_queue_event(serio, NULL, SERIO_RESCAN_PORT);
L
Linus Torvalds 已提交
682
}
683
EXPORT_SYMBOL(serio_rescan);
L
Linus Torvalds 已提交
684 685 686

void serio_reconnect(struct serio *serio)
{
687
	serio_queue_event(serio, NULL, SERIO_RECONNECT_SUBTREE);
L
Linus Torvalds 已提交
688
}
689
EXPORT_SYMBOL(serio_reconnect);
L
Linus Torvalds 已提交
690 691 692 693 694 695 696 697 698 699

/*
 * 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);
}
700
EXPORT_SYMBOL(__serio_register_port);
L
Linus Torvalds 已提交
701 702 703 704 705 706

/*
 * Synchronously unregisters serio port.
 */
void serio_unregister_port(struct serio *serio)
{
707
	mutex_lock(&serio_mutex);
L
Linus Torvalds 已提交
708 709
	serio_disconnect_port(serio);
	serio_destroy_port(serio);
710
	mutex_unlock(&serio_mutex);
L
Linus Torvalds 已提交
711
}
712
EXPORT_SYMBOL(serio_unregister_port);
L
Linus Torvalds 已提交
713

714
/*
715
 * Safely unregisters children ports if they are present.
716 717 718
 */
void serio_unregister_child_port(struct serio *serio)
{
719 720
	struct serio *s, *next;

721
	mutex_lock(&serio_mutex);
722 723 724
	list_for_each_entry_safe(s, next, &serio->children, child_node) {
		serio_disconnect_port(s);
		serio_destroy_port(s);
725
	}
726
	mutex_unlock(&serio_mutex);
727
}
728
EXPORT_SYMBOL(serio_unregister_child_port);
729

L
Linus Torvalds 已提交
730 731 732 733 734

/*
 * Serio driver operations
 */

735
static ssize_t description_show(struct device_driver *drv, char *buf)
L
Linus Torvalds 已提交
736 737 738 739
{
	struct serio_driver *driver = to_serio_driver(drv);
	return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)");
}
740
static DRIVER_ATTR_RO(description);
L
Linus Torvalds 已提交
741

742
static ssize_t bind_mode_show(struct device_driver *drv, char *buf)
L
Linus Torvalds 已提交
743 744 745 746 747
{
	struct serio_driver *serio_drv = to_serio_driver(drv);
	return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto");
}

748
static ssize_t bind_mode_store(struct device_driver *drv, const char *buf, size_t count)
L
Linus Torvalds 已提交
749 750 751 752 753 754
{
	struct serio_driver *serio_drv = to_serio_driver(drv);
	int retval;

	retval = count;
	if (!strncmp(buf, "manual", count)) {
755
		serio_drv->manual_bind = true;
L
Linus Torvalds 已提交
756
	} else if (!strncmp(buf, "auto", count)) {
757
		serio_drv->manual_bind = false;
L
Linus Torvalds 已提交
758 759 760 761 762 763
	} else {
		retval = -EINVAL;
	}

	return retval;
}
764
static DRIVER_ATTR_RW(bind_mode);
L
Linus Torvalds 已提交
765

766 767 768 769
static struct attribute *serio_driver_attrs[] = {
	&driver_attr_description.attr,
	&driver_attr_bind_mode.attr,
	NULL,
L
Linus Torvalds 已提交
770
};
771
ATTRIBUTE_GROUPS(serio_driver);
L
Linus Torvalds 已提交
772 773 774 775 776 777

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

778
	return serio_connect_driver(serio, drv);
L
Linus Torvalds 已提交
779 780 781 782 783 784
}

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

785
	serio_disconnect_driver(serio);
L
Linus Torvalds 已提交
786 787 788
	return 0;
}

789 790
static void serio_cleanup(struct serio *serio)
{
791
	mutex_lock(&serio->drv_mutex);
792 793
	if (serio->drv && serio->drv->cleanup)
		serio->drv->cleanup(serio);
794
	mutex_unlock(&serio->drv_mutex);
795 796 797 798 799 800 801 802 803
}

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

	serio_cleanup(serio);
}

804
static void serio_attach_driver(struct serio_driver *drv)
805 806 807
{
	int error;

808
	error = driver_attach(&drv->driver);
809
	if (error)
810 811
		pr_warning("driver_attach() failed for %s with error %d\n",
			   drv->driver.name, error);
812 813
}

814
int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name)
L
Linus Torvalds 已提交
815
{
816
	bool manual_bind = drv->manual_bind;
817 818
	int error;

L
Linus Torvalds 已提交
819
	drv->driver.bus = &serio_bus;
820 821
	drv->driver.owner = owner;
	drv->driver.mod_name = mod_name;
L
Linus Torvalds 已提交
822

823 824 825 826
	/*
	 * Temporarily disable automatic binding because probing
	 * takes long time and we are better off doing it in kseriod
	 */
827
	drv->manual_bind = true;
828 829 830

	error = driver_register(&drv->driver);
	if (error) {
831
		pr_err("driver_register() failed for %s, error: %d\n",
832 833 834 835 836 837 838 839 840
			drv->driver.name, error);
		return error;
	}

	/*
	 * Restore original bind mode and let kseriod bind the
	 * driver to free ports
	 */
	if (!manual_bind) {
841
		drv->manual_bind = false;
842 843 844 845 846 847 848 849
		error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER);
		if (error) {
			driver_unregister(&drv->driver);
			return error;
		}
	}

	return 0;
L
Linus Torvalds 已提交
850
}
851
EXPORT_SYMBOL(__serio_register_driver);
L
Linus Torvalds 已提交
852 853 854 855 856

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

857
	mutex_lock(&serio_mutex);
858

859
	drv->manual_bind = true;	/* so serio_find_driver ignores it */
860
	serio_remove_pending_events(drv);
L
Linus Torvalds 已提交
861 862 863 864 865 866 867 868 869 870 871 872

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);
873
	mutex_unlock(&serio_mutex);
L
Linus Torvalds 已提交
874
}
875
EXPORT_SYMBOL(serio_unregister_driver);
L
Linus Torvalds 已提交
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894

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);
}

895
#define SERIO_ADD_UEVENT_VAR(fmt, val...)				\
896
	do {								\
897
		int err = add_uevent_var(env, fmt, val);		\
898 899 900 901
		if (err)						\
			return err;					\
	} while (0)

902
static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
L
Linus Torvalds 已提交
903 904 905 906 907 908 909 910
{
	struct serio *serio;

	if (!dev)
		return -ENODEV;

	serio = to_serio_port(dev);

911 912 913 914 915
	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);
	SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
916
				serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
L
Linus Torvalds 已提交
917 918 919

	return 0;
}
920
#undef SERIO_ADD_UEVENT_VAR
L
Linus Torvalds 已提交
921

922
#ifdef CONFIG_PM
923
static int serio_suspend(struct device *dev)
924
{
925
	struct serio *serio = to_serio_port(dev);
926

927
	serio_cleanup(serio);
928 929 930 931

	return 0;
}

L
Linus Torvalds 已提交
932 933
static int serio_resume(struct device *dev)
{
934 935
	struct serio *serio = to_serio_port(dev);

936 937 938 939
	/*
	 * Driver reconnect can take a while, so better let kseriod
	 * deal with it.
	 */
940
	serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT);
L
Linus Torvalds 已提交
941 942 943

	return 0;
}
944 945 946 947 948 949 950

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

953
/* called from serio_driver->connect/disconnect methods under serio_mutex */
L
Linus Torvalds 已提交
954 955 956 957 958 959 960 961 962 963
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;
}
964
EXPORT_SYMBOL(serio_open);
L
Linus Torvalds 已提交
965

966
/* called from serio_driver->connect/disconnect methods under serio_mutex */
L
Linus Torvalds 已提交
967 968 969 970 971 972 973
void serio_close(struct serio *serio)
{
	if (serio->close)
		serio->close(serio);

	serio_set_drv(serio, NULL);
}
974
EXPORT_SYMBOL(serio_close);
L
Linus Torvalds 已提交
975 976

irqreturn_t serio_interrupt(struct serio *serio,
977
		unsigned char data, unsigned int dfl)
L
Linus Torvalds 已提交
978 979 980 981 982 983 984
{
	unsigned long flags;
	irqreturn_t ret = IRQ_NONE;

	spin_lock_irqsave(&serio->lock, flags);

        if (likely(serio->drv)) {
985
                ret = serio->drv->interrupt(serio, data, dfl);
986
	} else if (!dfl && device_is_registered(&serio->dev)) {
L
Linus Torvalds 已提交
987 988 989 990 991 992 993 994
		serio_rescan(serio);
		ret = IRQ_HANDLED;
	}

	spin_unlock_irqrestore(&serio->lock, flags);

	return ret;
}
995
EXPORT_SYMBOL(serio_interrupt);
L
Linus Torvalds 已提交
996

997 998 999
static struct bus_type serio_bus = {
	.name		= "serio",
	.dev_attrs	= serio_device_attrs,
1000
	.drv_groups	= serio_driver_groups,
1001 1002 1003 1004
	.match		= serio_bus_match,
	.uevent		= serio_uevent,
	.probe		= serio_driver_probe,
	.remove		= serio_driver_remove,
1005 1006
	.shutdown	= serio_shutdown,
#ifdef CONFIG_PM
1007
	.pm		= &serio_pm_ops,
1008
#endif
1009 1010
};

L
Linus Torvalds 已提交
1011 1012
static int __init serio_init(void)
{
1013
	int error;
L
Linus Torvalds 已提交
1014

1015 1016
	error = bus_register(&serio_bus);
	if (error) {
1017
		pr_err("Failed to register serio bus, error: %d\n", error);
1018 1019 1020
		return error;
	}

L
Linus Torvalds 已提交
1021 1022 1023 1024 1025 1026
	return 0;
}

static void __exit serio_exit(void)
{
	bus_unregister(&serio_bus);
1027 1028 1029 1030 1031 1032

	/*
	 * 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 已提交
1033 1034
}

1035
subsys_initcall(serio_init);
L
Linus Torvalds 已提交
1036
module_exit(serio_exit);