Commit the manual part of the input layer merge.
git did actually warn me about the fact that I hadn't actually done an "update-cache" on these two files, but the warning was at the bottom of a list of all the files that _did_ change in the merge, so I never noticed. My bad.
This commit is contained in:
parent
c47abbbffd
commit
3c803e8e2f
2 changed files with 74 additions and 46 deletions
|
@ -17,11 +17,10 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/gameport.h>
|
#include <linux/gameport.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/completion.h>
|
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/smp_lock.h>
|
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/kthread.h>
|
||||||
|
|
||||||
/*#include <asm/io.h>*/
|
/*#include <asm/io.h>*/
|
||||||
|
|
||||||
|
@ -238,8 +237,7 @@ struct gameport_event {
|
||||||
static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */
|
static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */
|
||||||
static LIST_HEAD(gameport_event_list);
|
static LIST_HEAD(gameport_event_list);
|
||||||
static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
|
static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
|
||||||
static DECLARE_COMPLETION(gameport_exited);
|
static struct task_struct *gameport_task;
|
||||||
static int gameport_pid;
|
|
||||||
|
|
||||||
static void gameport_queue_event(void *object, struct module *owner,
|
static void gameport_queue_event(void *object, struct module *owner,
|
||||||
enum gameport_event_type event_type)
|
enum gameport_event_type event_type)
|
||||||
|
@ -432,20 +430,15 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
|
||||||
|
|
||||||
static int gameport_thread(void *nothing)
|
static int gameport_thread(void *nothing)
|
||||||
{
|
{
|
||||||
lock_kernel();
|
|
||||||
daemonize("kgameportd");
|
|
||||||
allow_signal(SIGTERM);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
gameport_handle_events();
|
gameport_handle_events();
|
||||||
wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list));
|
wait_event_interruptible(gameport_wait,
|
||||||
|
kthread_should_stop() || !list_empty(&gameport_event_list));
|
||||||
try_to_freeze();
|
try_to_freeze();
|
||||||
} while (!signal_pending(current));
|
} while (!kthread_should_stop());
|
||||||
|
|
||||||
printk(KERN_DEBUG "gameport: kgameportd exiting\n");
|
printk(KERN_DEBUG "gameport: kgameportd exiting\n");
|
||||||
|
return 0;
|
||||||
unlock_kernel();
|
|
||||||
complete_and_exit(&gameport_exited, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -773,9 +766,10 @@ void gameport_close(struct gameport *gameport)
|
||||||
|
|
||||||
static int __init gameport_init(void)
|
static int __init gameport_init(void)
|
||||||
{
|
{
|
||||||
if (!(gameport_pid = kernel_thread(gameport_thread, NULL, CLONE_KERNEL))) {
|
gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
|
||||||
|
if (IS_ERR(gameport_task)) {
|
||||||
printk(KERN_ERR "gameport: Failed to start kgameportd\n");
|
printk(KERN_ERR "gameport: Failed to start kgameportd\n");
|
||||||
return -1;
|
return PTR_ERR(gameport_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
gameport_bus.dev_attrs = gameport_device_attrs;
|
gameport_bus.dev_attrs = gameport_device_attrs;
|
||||||
|
@ -789,8 +783,7 @@ static int __init gameport_init(void)
|
||||||
static void __exit gameport_exit(void)
|
static void __exit gameport_exit(void)
|
||||||
{
|
{
|
||||||
bus_unregister(&gameport_bus);
|
bus_unregister(&gameport_bus);
|
||||||
kill_proc(gameport_pid, SIGTERM, 1);
|
kthread_stop(gameport_task);
|
||||||
wait_for_completion(&gameport_exited);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(gameport_init);
|
module_init(gameport_init);
|
||||||
|
|
|
@ -31,10 +31,9 @@
|
||||||
#include <linux/serio.h>
|
#include <linux/serio.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/completion.h>
|
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/smp_lock.h>
|
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/kthread.h>
|
||||||
|
|
||||||
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
|
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
|
||||||
MODULE_DESCRIPTION("Serio abstraction core");
|
MODULE_DESCRIPTION("Serio abstraction core");
|
||||||
|
@ -43,6 +42,7 @@ MODULE_LICENSE("GPL");
|
||||||
EXPORT_SYMBOL(serio_interrupt);
|
EXPORT_SYMBOL(serio_interrupt);
|
||||||
EXPORT_SYMBOL(__serio_register_port);
|
EXPORT_SYMBOL(__serio_register_port);
|
||||||
EXPORT_SYMBOL(serio_unregister_port);
|
EXPORT_SYMBOL(serio_unregister_port);
|
||||||
|
EXPORT_SYMBOL(serio_unregister_child_port);
|
||||||
EXPORT_SYMBOL(__serio_unregister_port_delayed);
|
EXPORT_SYMBOL(__serio_unregister_port_delayed);
|
||||||
EXPORT_SYMBOL(__serio_register_driver);
|
EXPORT_SYMBOL(__serio_register_driver);
|
||||||
EXPORT_SYMBOL(serio_unregister_driver);
|
EXPORT_SYMBOL(serio_unregister_driver);
|
||||||
|
@ -68,6 +68,37 @@ static void serio_destroy_port(struct serio *serio);
|
||||||
static void serio_reconnect_port(struct serio *serio);
|
static void serio_reconnect_port(struct serio *serio);
|
||||||
static void serio_disconnect_port(struct serio *serio);
|
static void serio_disconnect_port(struct serio *serio);
|
||||||
|
|
||||||
|
static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
down(&serio->drv_sem);
|
||||||
|
retval = drv->connect(serio, drv);
|
||||||
|
up(&serio->drv_sem);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int serio_reconnect_driver(struct serio *serio)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
|
||||||
|
down(&serio->drv_sem);
|
||||||
|
if (serio->drv && serio->drv->reconnect)
|
||||||
|
retval = serio->drv->reconnect(serio);
|
||||||
|
up(&serio->drv_sem);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serio_disconnect_driver(struct serio *serio)
|
||||||
|
{
|
||||||
|
down(&serio->drv_sem);
|
||||||
|
if (serio->drv)
|
||||||
|
serio->drv->disconnect(serio);
|
||||||
|
up(&serio->drv_sem);
|
||||||
|
}
|
||||||
|
|
||||||
static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
|
static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
|
||||||
{
|
{
|
||||||
while (ids->type || ids->proto) {
|
while (ids->type || ids->proto) {
|
||||||
|
@ -91,7 +122,7 @@ static void serio_bind_driver(struct serio *serio, struct serio_driver *drv)
|
||||||
|
|
||||||
if (serio_match_port(drv->id_table, serio)) {
|
if (serio_match_port(drv->id_table, serio)) {
|
||||||
serio->dev.driver = &drv->driver;
|
serio->dev.driver = &drv->driver;
|
||||||
if (drv->connect(serio, drv)) {
|
if (serio_connect_driver(serio, drv)) {
|
||||||
serio->dev.driver = NULL;
|
serio->dev.driver = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -138,8 +169,7 @@ struct serio_event {
|
||||||
static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */
|
static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */
|
||||||
static LIST_HEAD(serio_event_list);
|
static LIST_HEAD(serio_event_list);
|
||||||
static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
|
static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
|
||||||
static DECLARE_COMPLETION(serio_exited);
|
static struct task_struct *serio_task;
|
||||||
static int serio_pid;
|
|
||||||
|
|
||||||
static void serio_queue_event(void *object, struct module *owner,
|
static void serio_queue_event(void *object, struct module *owner,
|
||||||
enum serio_event_type event_type)
|
enum serio_event_type event_type)
|
||||||
|
@ -337,20 +367,15 @@ static struct serio *serio_get_pending_child(struct serio *parent)
|
||||||
|
|
||||||
static int serio_thread(void *nothing)
|
static int serio_thread(void *nothing)
|
||||||
{
|
{
|
||||||
lock_kernel();
|
|
||||||
daemonize("kseriod");
|
|
||||||
allow_signal(SIGTERM);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
serio_handle_events();
|
serio_handle_events();
|
||||||
wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
|
wait_event_interruptible(serio_wait,
|
||||||
|
kthread_should_stop() || !list_empty(&serio_event_list));
|
||||||
try_to_freeze();
|
try_to_freeze();
|
||||||
} while (!signal_pending(current));
|
} while (!kthread_should_stop());
|
||||||
|
|
||||||
printk(KERN_DEBUG "serio: kseriod exiting\n");
|
printk(KERN_DEBUG "serio: kseriod exiting\n");
|
||||||
|
return 0;
|
||||||
unlock_kernel();
|
|
||||||
complete_and_exit(&serio_exited, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -557,7 +582,7 @@ static void serio_destroy_port(struct serio *serio)
|
||||||
static void serio_reconnect_port(struct serio *serio)
|
static void serio_reconnect_port(struct serio *serio)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
|
if (serio_reconnect_driver(serio)) {
|
||||||
serio_disconnect_port(serio);
|
serio_disconnect_port(serio);
|
||||||
serio_find_driver(serio);
|
serio_find_driver(serio);
|
||||||
/* Ok, old children are now gone, we are done */
|
/* Ok, old children are now gone, we are done */
|
||||||
|
@ -629,6 +654,19 @@ void serio_unregister_port(struct serio *serio)
|
||||||
up(&serio_sem);
|
up(&serio_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Safely unregisters child port if one is present.
|
||||||
|
*/
|
||||||
|
void serio_unregister_child_port(struct serio *serio)
|
||||||
|
{
|
||||||
|
down(&serio_sem);
|
||||||
|
if (serio->child) {
|
||||||
|
serio_disconnect_port(serio->child);
|
||||||
|
serio_destroy_port(serio->child);
|
||||||
|
}
|
||||||
|
up(&serio_sem);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Submits register request to kseriod for subsequent execution.
|
* Submits register request to kseriod for subsequent execution.
|
||||||
* Can be used when it is not obvious whether the serio_sem is
|
* Can be used when it is not obvious whether the serio_sem is
|
||||||
|
@ -686,15 +724,14 @@ static int serio_driver_probe(struct device *dev)
|
||||||
struct serio *serio = to_serio_port(dev);
|
struct serio *serio = to_serio_port(dev);
|
||||||
struct serio_driver *drv = to_serio_driver(dev->driver);
|
struct serio_driver *drv = to_serio_driver(dev->driver);
|
||||||
|
|
||||||
return drv->connect(serio, drv);
|
return serio_connect_driver(serio, drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serio_driver_remove(struct device *dev)
|
static int serio_driver_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
struct serio *serio = to_serio_port(dev);
|
struct serio *serio = to_serio_port(dev);
|
||||||
struct serio_driver *drv = to_serio_driver(dev->driver);
|
|
||||||
|
|
||||||
drv->disconnect(serio);
|
serio_disconnect_driver(serio);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,11 +767,9 @@ void serio_unregister_driver(struct serio_driver *drv)
|
||||||
|
|
||||||
static void serio_set_drv(struct serio *serio, struct serio_driver *drv)
|
static void serio_set_drv(struct serio *serio, struct serio_driver *drv)
|
||||||
{
|
{
|
||||||
down(&serio->drv_sem);
|
|
||||||
serio_pause_rx(serio);
|
serio_pause_rx(serio);
|
||||||
serio->drv = drv;
|
serio->drv = drv;
|
||||||
serio_continue_rx(serio);
|
serio_continue_rx(serio);
|
||||||
up(&serio->drv_sem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serio_bus_match(struct device *dev, struct device_driver *drv)
|
static int serio_bus_match(struct device *dev, struct device_driver *drv)
|
||||||
|
@ -794,7 +829,7 @@ static int serio_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct serio *serio = to_serio_port(dev);
|
struct serio *serio = to_serio_port(dev);
|
||||||
|
|
||||||
if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
|
if (serio_reconnect_driver(serio)) {
|
||||||
/*
|
/*
|
||||||
* Driver re-probing can take a while, so better let kseriod
|
* Driver re-probing can take a while, so better let kseriod
|
||||||
* deal with it.
|
* deal with it.
|
||||||
|
@ -848,9 +883,10 @@ irqreturn_t serio_interrupt(struct serio *serio,
|
||||||
|
|
||||||
static int __init serio_init(void)
|
static int __init serio_init(void)
|
||||||
{
|
{
|
||||||
if (!(serio_pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL))) {
|
serio_task = kthread_run(serio_thread, NULL, "kseriod");
|
||||||
|
if (IS_ERR(serio_task)) {
|
||||||
printk(KERN_ERR "serio: Failed to start kseriod\n");
|
printk(KERN_ERR "serio: Failed to start kseriod\n");
|
||||||
return -1;
|
return PTR_ERR(serio_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
serio_bus.dev_attrs = serio_device_attrs;
|
serio_bus.dev_attrs = serio_device_attrs;
|
||||||
|
@ -866,8 +902,7 @@ static int __init serio_init(void)
|
||||||
static void __exit serio_exit(void)
|
static void __exit serio_exit(void)
|
||||||
{
|
{
|
||||||
bus_unregister(&serio_bus);
|
bus_unregister(&serio_bus);
|
||||||
kill_proc(serio_pid, SIGTERM, 1);
|
kthread_stop(serio_task);
|
||||||
wait_for_completion(&serio_exited);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(serio_init);
|
module_init(serio_init);
|
||||||
|
|
Loading…
Reference in a new issue