serio.c 24.0 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 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
static DEVICE_ATTR_RO(type);
static DEVICE_ATTR_RO(proto);
static DEVICE_ATTR_RO(id);
static DEVICE_ATTR_RO(extra);
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);

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

static struct attribute_group serio_id_attr_group = {
	.name	= "id",
	.attrs	= serio_device_id_attrs,
L
Linus Torvalds 已提交
478 479
};

480 481 482 483
static const struct attribute_group *serio_device_attr_groups[] = {
	&serio_id_attr_group,
	NULL
};
L
Linus Torvalds 已提交
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

L
Linus Torvalds 已提交
729 730 731 732 733

/*
 * Serio driver operations
 */

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

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

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

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

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

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

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

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

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

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

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

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

	serio_cleanup(serio);
}

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

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

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

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

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

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

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

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

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

856
	mutex_lock(&serio_mutex);
857

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

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

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

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

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

	if (!dev)
		return -ENODEV;

	serio = to_serio_port(dev);

910 911 912 913 914
	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",
915
				serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
L
Linus Torvalds 已提交
916 917 918

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

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

926
	serio_cleanup(serio);
927 928 929 930

	return 0;
}

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

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

	return 0;
}
943 944 945 946 947 948 949

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

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

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

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

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

	spin_lock_irqsave(&serio->lock, flags);

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

	spin_unlock_irqrestore(&serio->lock, flags);

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

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

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

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

L
Linus Torvalds 已提交
1019 1020 1021 1022 1023 1024
	return 0;
}

static void __exit serio_exit(void)
{
	bus_unregister(&serio_bus);
1025 1026 1027 1028 1029 1030

	/*
	 * 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 已提交
1031 1032
}

1033
subsys_initcall(serio_init);
L
Linus Torvalds 已提交
1034
module_exit(serio_exit);