public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
From: Sean Young <sean@mess.org>
To: "David Härdeman" <david@hardeman.nu>
Cc: linux-media@vger.kernel.org, mchehab@s-opensource.com
Subject: Re: [PATCH 2/6] rc-core: cleanup rc_register_device
Date: Mon, 1 May 2017 17:49:53 +0100	[thread overview]
Message-ID: <20170501164953.GA14836@gofer.mess.org> (raw)
In-Reply-To: <149332524306.32431.8964878481747905258.stgit@zeus.hardeman.nu>

On Thu, Apr 27, 2017 at 10:34:03PM +0200, David Härdeman wrote:
> The device core infrastructure is based on the presumption that
> once a driver calls device_add(), it must be ready to accept
> userspace interaction.
> 
> This requires splitting rc_setup_rx_device() into two functions
> and reorganizing rc_register_device() so that as much work
> as possible is performed before calling device_add().
> 

With this patch applied, I'm no longer getting any scancodes from
my rc devices.

David, please can you test your patches before submitting. I have to go
over them meticulously because I cannot assume you've tested them.

Thanks
Sean

> Signed-off-by: David Härdeman <david@hardeman.nu>
> ---
>  drivers/media/rc/rc-core-priv.h |    2 +
>  drivers/media/rc/rc-ir-raw.c    |   34 ++++++++++++------
>  drivers/media/rc/rc-main.c      |   75 +++++++++++++++++++++++++--------------
>  3 files changed, 73 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
> index 0455b273c2fc..b3e7cac2c3ee 100644
> --- a/drivers/media/rc/rc-core-priv.h
> +++ b/drivers/media/rc/rc-core-priv.h
> @@ -263,7 +263,9 @@ int ir_raw_gen_pl(struct ir_raw_event **ev, unsigned int max,
>   * Routines from rc-raw.c to be used internally and by decoders
>   */
>  u64 ir_raw_get_allowed_protocols(void);
> +int ir_raw_event_prepare(struct rc_dev *dev);
>  int ir_raw_event_register(struct rc_dev *dev);
> +void ir_raw_event_free(struct rc_dev *dev);
>  void ir_raw_event_unregister(struct rc_dev *dev);
>  int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
>  void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
> diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
> index 90f66dc7c0d7..ae7785c4fbe7 100644
> --- a/drivers/media/rc/rc-ir-raw.c
> +++ b/drivers/media/rc/rc-ir-raw.c
> @@ -486,14 +486,18 @@ EXPORT_SYMBOL(ir_raw_encode_scancode);
>  /*
>   * Used to (un)register raw event clients
>   */
> -int ir_raw_event_register(struct rc_dev *dev)
> +int ir_raw_event_prepare(struct rc_dev *dev)
>  {
> -	int rc;
> -	struct ir_raw_handler *handler;
> +	static bool raw_init; /* 'false' default value, raw decoders loaded? */
>  
>  	if (!dev)
>  		return -EINVAL;
>  
> +	if (!raw_init) {
> +		request_module("ir-lirc-codec");
> +		raw_init = true;
> +	}
> +
>  	dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL);
>  	if (!dev->raw)
>  		return -ENOMEM;
> @@ -502,6 +506,13 @@ int ir_raw_event_register(struct rc_dev *dev)
>  	dev->change_protocol = change_protocol;
>  	INIT_KFIFO(dev->raw->kfifo);
>  
> +	return 0;
> +}
> +
> +int ir_raw_event_register(struct rc_dev *dev)
> +{
> +	struct ir_raw_handler *handler;
> +
>  	/*
>  	 * raw transmitters do not need any event registration
>  	 * because the event is coming from userspace
> @@ -510,10 +521,8 @@ int ir_raw_event_register(struct rc_dev *dev)
>  		dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
>  					       "rc%u", dev->minor);
>  
> -		if (IS_ERR(dev->raw->thread)) {
> -			rc = PTR_ERR(dev->raw->thread);
> -			goto out;
> -		}
> +		if (IS_ERR(dev->raw->thread))
> +			return PTR_ERR(dev->raw->thread);
>  	}
>  
>  	mutex_lock(&ir_raw_handler_lock);
> @@ -524,11 +533,15 @@ int ir_raw_event_register(struct rc_dev *dev)
>  	mutex_unlock(&ir_raw_handler_lock);
>  
>  	return 0;
> +}
> +
> +void ir_raw_event_free(struct rc_dev *dev)
> +{
> +	if (!dev)
> +		return;
>  
> -out:
>  	kfree(dev->raw);
>  	dev->raw = NULL;
> -	return rc;
>  }
>  
>  void ir_raw_event_unregister(struct rc_dev *dev)
> @@ -547,8 +560,7 @@ void ir_raw_event_unregister(struct rc_dev *dev)
>  			handler->raw_unregister(dev);
>  	mutex_unlock(&ir_raw_handler_lock);
>  
> -	kfree(dev->raw);
> -	dev->raw = NULL;
> +	ir_raw_event_free(dev);
>  }
>  
>  /*
> diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
> index 802e559cc30e..44189366f232 100644
> --- a/drivers/media/rc/rc-main.c
> +++ b/drivers/media/rc/rc-main.c
> @@ -1663,7 +1663,7 @@ struct rc_dev *devm_rc_allocate_device(struct device *dev,
>  }
>  EXPORT_SYMBOL_GPL(devm_rc_allocate_device);
>  
> -static int rc_setup_rx_device(struct rc_dev *dev)
> +static int rc_prepare_rx_device(struct rc_dev *dev)
>  {
>  	int rc;
>  	struct rc_map *rc_map;
> @@ -1708,10 +1708,22 @@ static int rc_setup_rx_device(struct rc_dev *dev)
>  	dev->input_dev->phys = dev->input_phys;
>  	dev->input_dev->name = dev->input_name;
>  
> +	return 0;
> +
> +out_table:
> +	ir_free_table(&dev->rc_map);
> +
> +	return rc;
> +}
> +
> +static int rc_setup_rx_device(struct rc_dev *dev)
> +{
> +	int rc;
> +
>  	/* rc_open will be called here */
>  	rc = input_register_device(dev->input_dev);
>  	if (rc)
> -		goto out_table;
> +		return rc;
>  
>  	/*
>  	 * Default delay of 250ms is too short for some protocols, especially
> @@ -1729,27 +1741,23 @@ static int rc_setup_rx_device(struct rc_dev *dev)
>  	dev->input_dev->rep[REP_PERIOD] = 125;
>  
>  	return 0;
> -
> -out_table:
> -	ir_free_table(&dev->rc_map);
> -
> -	return rc;
>  }
>  
>  static void rc_free_rx_device(struct rc_dev *dev)
>  {
> -	if (!dev || dev->driver_type == RC_DRIVER_IR_RAW_TX)
> +	if (!dev)
>  		return;
>  
> -	ir_free_table(&dev->rc_map);
> +	if (dev->input_dev) {
> +		input_unregister_device(dev->input_dev);
> +		dev->input_dev = NULL;
> +	}
>  
> -	input_unregister_device(dev->input_dev);
> -	dev->input_dev = NULL;
> +	ir_free_table(&dev->rc_map);
>  }
>  
>  int rc_register_device(struct rc_dev *dev)
>  {
> -	static bool raw_init; /* 'false' default value, raw decoders loaded? */
>  	const char *path;
>  	int attr = 0;
>  	int minor;
> @@ -1776,30 +1784,39 @@ int rc_register_device(struct rc_dev *dev)
>  		dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp;
>  	dev->sysfs_groups[attr++] = NULL;
>  
> +	if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
> +		rc = rc_prepare_rx_device(dev);
> +		if (rc)
> +			goto out_minor;
> +	}
> +
> +	if (dev->driver_type == RC_DRIVER_IR_RAW ||
> +	    dev->driver_type == RC_DRIVER_IR_RAW_TX) {
> +		rc = ir_raw_event_prepare(dev);
> +		if (rc < 0)
> +			goto out_rx_free;
> +	}
> +
>  	rc = device_add(&dev->dev);
>  	if (rc)
> -		goto out_unlock;
> +		goto out_raw;
>  
>  	path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
>  	dev_info(&dev->dev, "%s as %s\n",
>  		dev->input_name ?: "Unspecified device", path ?: "N/A");
>  	kfree(path);
>  
> +	if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
> +		rc = rc_setup_rx_device(dev);
> +		if (rc)
> +			goto out_dev;
> +	}
> +
>  	if (dev->driver_type == RC_DRIVER_IR_RAW ||
>  	    dev->driver_type == RC_DRIVER_IR_RAW_TX) {
> -		if (!raw_init) {
> -			request_module_nowait("ir-lirc-codec");
> -			raw_init = true;
> -		}
>  		rc = ir_raw_event_register(dev);
>  		if (rc < 0)
> -			goto out_dev;
> -	}
> -
> -	if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
> -		rc = rc_setup_rx_device(dev);
> -		if (rc)
> -			goto out_raw;
> +			goto out_rx;
>  	}
>  
>  	/* Allow the RC sysfs nodes to be accessible */
> @@ -1811,11 +1828,15 @@ int rc_register_device(struct rc_dev *dev)
>  
>  	return 0;
>  
> -out_raw:
> -	ir_raw_event_unregister(dev);
> +out_rx:
> +	rc_free_rx_device(dev);
>  out_dev:
>  	device_del(&dev->dev);
> -out_unlock:
> +out_raw:
> +	ir_raw_event_free(dev);
> +out_rx_free:
> +	ir_free_table(&dev->rc_map);
> +out_minor:
>  	ida_simple_remove(&rc_ida, minor);
>  	return rc;
>  }

  reply	other threads:[~2017-05-01 16:49 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-27 20:33 [PATCH 0/6] rc-core - protocol in keytables David Härdeman
2017-04-27 20:33 ` [PATCH 1/6] rc-core: fix input repeat handling David Härdeman
2017-04-27 20:34 ` [PATCH 2/6] rc-core: cleanup rc_register_device David Härdeman
2017-05-01 16:49   ` Sean Young [this message]
2017-05-01 17:47     ` David Härdeman
2017-05-02 18:53       ` David Härdeman
2017-05-02 20:48         ` Sean Young
2017-05-03  9:49           ` David Härdeman
2017-04-27 20:34 ` [PATCH 3/6] rc-core: cleanup rc_register_device pt2 David Härdeman
2017-04-27 20:34 ` [PATCH 4/6] rc-core: use the full 32 bits for NEC scancodes in wakefilters David Härdeman
2017-04-27 20:34 ` [PATCH 5/6] rc-core: use the full 32 bits for NEC scancodes David Härdeman
2017-04-28 11:58   ` Sean Young
2017-04-28 16:42     ` David Härdeman
2017-04-27 20:34 ` [PATCH 6/6] rc-core: add protocol to EVIOC[GS]KEYCODE_V2 ioctl David Härdeman
2017-04-28 11:31   ` Mauro Carvalho Chehab
2017-04-28 16:59     ` David Härdeman
2017-04-28 19:42       ` Sean Young
2017-04-29  8:44         ` David Härdeman
2017-06-11 16:17           ` Sean Young
2017-06-17 11:20             ` David Härdeman
2017-04-28 11:40   ` Sean Young
2017-04-28 16:46     ` David Härdeman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170501164953.GA14836@gofer.mess.org \
    --to=sean@mess.org \
    --cc=david@hardeman.nu \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@s-opensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox