Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a517e87c authored by Sudip Mukherjee's avatar Sudip Mukherjee Committed by Dmitry Torokhov
Browse files

Input: gamecon - use parallel port device model



Modify gamecon driver to use the new Parallel Port device model.

Signed-off-by: default avatarSudip Mukherjee <sudip@vectorindia.org>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 379d7cfa
Loading
Loading
Loading
Loading
+53 −47
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ struct gc_config {
	unsigned int nargs;
};

static struct gc_config gc_cfg[GC_MAX_PORTS] __initdata;
static struct gc_config gc_cfg[GC_MAX_PORTS];

module_param_array_named(map, gc_cfg[0].args, int, &gc_cfg[0].nargs, 0);
MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
@@ -92,6 +92,7 @@ struct gc {
	struct timer_list timer;
	int pad_count[GC_MAX];
	int used;
	int parportno;
	struct mutex mutex;
};

@@ -304,7 +305,7 @@ static int gc_n64_play_effect(struct input_dev *dev, void *data,
	return 0;
}

static int __init gc_n64_init_ff(struct input_dev *dev, int i)
static int gc_n64_init_ff(struct input_dev *dev, int i)
{
	struct gc_subdev *sdev;
	int err;
@@ -811,7 +812,7 @@ static void gc_close(struct input_dev *dev)
	mutex_unlock(&gc->mutex);
}

static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
static int gc_setup_pad(struct gc *gc, int idx, int pad_type)
{
	struct gc_pad *pad = &gc->pads[idx];
	struct input_dev *input_dev;
@@ -926,46 +927,54 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
	return err;
}

static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
static void gc_attach(struct parport *pp)
{
	struct gc *gc;
	struct parport *pp;
	struct pardevice *pd;
	int i;
	int count = 0;
	int err;
	int *pads, n_pads;
	struct pardev_cb gc_parport_cb;

	for (i = 0; i < GC_MAX_PORTS; i++) {
		if (gc_cfg[i].nargs == 0 || gc_cfg[i].args[0] < 0)
			continue;

		if (gc_cfg[i].args[0] == pp->number)
			break;
	}

	pp = parport_find_number(parport);
	if (!pp) {
		pr_err("no such parport %d\n", parport);
		err = -EINVAL;
		goto err_out;
	if (i == GC_MAX_PORTS) {
		pr_debug("Not using parport%d.\n", pp->number);
		return;
	}
	pads = gc_cfg[i].args + 1;
	n_pads = gc_cfg[i].nargs - 1;

	pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
	gc_parport_cb.flags = PARPORT_FLAG_EXCL;

	pd = parport_register_dev_model(pp, "gamecon", &gc_parport_cb, i);
	if (!pd) {
		pr_err("parport busy already - lp.o loaded?\n");
		err = -EBUSY;
		goto err_put_pp;
		return;
	}

	gc = kzalloc(sizeof(struct gc), GFP_KERNEL);
	if (!gc) {
		pr_err("Not enough memory\n");
		err = -ENOMEM;
		goto err_unreg_pardev;
	}

	mutex_init(&gc->mutex);
	gc->pd = pd;
	gc->parportno = pp->number;
	setup_timer(&gc->timer, gc_timer, (long) gc);

	for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) {
		if (!pads[i])
			continue;

		err = gc_setup_pad(gc, i, pads[i]);
		if (err)
		if (gc_setup_pad(gc, i, pads[i]))
			goto err_unreg_devs;

		count++;
@@ -973,12 +982,11 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads)

	if (count == 0) {
		pr_err("No valid devices specified\n");
		err = -EINVAL;
		goto err_free_gc;
	}

	parport_put_port(pp);
	return gc;
	gc_base[i] = gc;
	return;

 err_unreg_devs:
	while (--i >= 0)
@@ -988,15 +996,23 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
	kfree(gc);
 err_unreg_pardev:
	parport_unregister_device(pd);
 err_put_pp:
	parport_put_port(pp);
 err_out:
	return ERR_PTR(err);
}

static void gc_remove(struct gc *gc)
static void gc_detach(struct parport *port)
{
	int i;
	struct gc *gc;

	for (i = 0; i < GC_MAX_PORTS; i++) {
		if (gc_base[i] && gc_base[i]->parportno == port->number)
			break;
	}

	if (i == GC_MAX_PORTS)
		return;

	gc = gc_base[i];
	gc_base[i] = NULL;

	for (i = 0; i < GC_MAX_DEVICES; i++)
		if (gc->pads[i].dev)
@@ -1005,11 +1021,17 @@ static void gc_remove(struct gc *gc)
	kfree(gc);
}

static struct parport_driver gc_parport_driver = {
	.name = "gamecon",
	.match_port = gc_attach,
	.detach = gc_detach,
	.devmodel = true,
};

static int __init gc_init(void)
{
	int i;
	int have_dev = 0;
	int err = 0;

	for (i = 0; i < GC_MAX_PORTS; i++) {
		if (gc_cfg[i].nargs == 0 || gc_cfg[i].args[0] < 0)
@@ -1017,37 +1039,21 @@ static int __init gc_init(void)

		if (gc_cfg[i].nargs < 2) {
			pr_err("at least one device must be specified\n");
			err = -EINVAL;
			break;
		}

		gc_base[i] = gc_probe(gc_cfg[i].args[0],
				      gc_cfg[i].args + 1, gc_cfg[i].nargs - 1);
		if (IS_ERR(gc_base[i])) {
			err = PTR_ERR(gc_base[i]);
			break;
			return -EINVAL;
		}

		have_dev = 1;
	}

	if (err) {
		while (--i >= 0)
			if (gc_base[i])
				gc_remove(gc_base[i]);
		return err;
	}
	if (!have_dev)
		return -ENODEV;

	return have_dev ? 0 : -ENODEV;
	return parport_register_driver(&gc_parport_driver);
}

static void __exit gc_exit(void)
{
	int i;

	for (i = 0; i < GC_MAX_PORTS; i++)
		if (gc_base[i])
			gc_remove(gc_base[i]);
	parport_unregister_driver(&gc_parport_driver);
}

module_init(gc_init);