Re: [PATCH] matrix_keypad: convert to threaded IRQs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Apr 03, 2012 at 10:10:00AM +0200, Peter Rusko wrote:
> Tested on Ka-Ro TX28 SOC

Needs justification; plus this is not how debounce works - you need to
postpone scan until IRQ line settles, not simply wait so many
milliseconds.

I think what you really need is request_any_context_irq().

Thanks.

> 
> Signed-off-by: Peter Rusko <rusko.peter@xxxxxxxxx>
> ---
>  drivers/input/keyboard/matrix_keypad.c |   58 +++++++++----------------------
>  1 files changed, 17 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
> index e2ae657..c3d3532 100644
> --- a/drivers/input/keyboard/matrix_keypad.c
> +++ b/drivers/input/keyboard/matrix_keypad.c
> @@ -33,7 +33,6 @@ struct matrix_keypad {
>  	DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
>  
>  	uint32_t last_key_state[MATRIX_MAX_COLS];
> -	struct delayed_work work;
>  	spinlock_t lock;
>  	bool scan_pending;
>  	bool stopped;
> @@ -112,15 +111,16 @@ static void disable_row_irqs(struct matrix_keypad *keypad)
>  /*
>   * This gets the keys from keyboard and reports it to input subsystem
>   */
> -static void matrix_keypad_scan(struct work_struct *work)
> +static irqreturn_t matrix_keypad_scan(int irq, void *id)
>  {
> -	struct matrix_keypad *keypad =
> -		container_of(work, struct matrix_keypad, work.work);
> +	struct matrix_keypad *keypad = id;
>  	struct input_dev *input_dev = keypad->input_dev;
>  	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
>  	uint32_t new_state[MATRIX_MAX_COLS];
>  	int row, col, code;
>  
> +	msleep(keypad->pdata->debounce_ms);
> +
>  	/* de-activate all columns for scanning */
>  	activate_all_cols(pdata, false);
>  
> @@ -165,32 +165,8 @@ static void matrix_keypad_scan(struct work_struct *work)
>  	/* Enable IRQs again */
>  	spin_lock_irq(&keypad->lock);
>  	keypad->scan_pending = false;
> -	enable_row_irqs(keypad);
>  	spin_unlock_irq(&keypad->lock);
> -}
> -
> -static irqreturn_t matrix_keypad_interrupt(int irq, void *id)
> -{
> -	struct matrix_keypad *keypad = id;
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&keypad->lock, flags);
>  
> -	/*
> -	 * See if another IRQ beaten us to it and scheduled the
> -	 * scan already. In that case we should not try to
> -	 * disable IRQs again.
> -	 */
> -	if (unlikely(keypad->scan_pending || keypad->stopped))
> -		goto out;
> -
> -	disable_row_irqs(keypad);
> -	keypad->scan_pending = true;
> -	schedule_delayed_work(&keypad->work,
> -		msecs_to_jiffies(keypad->pdata->debounce_ms));
> -
> -out:
> -	spin_unlock_irqrestore(&keypad->lock, flags);
>  	return IRQ_HANDLED;
>  }
>  
> @@ -201,11 +177,8 @@ static int matrix_keypad_start(struct input_dev *dev)
>  	keypad->stopped = false;
>  	mb();
>  
> -	/*
> -	 * Schedule an immediate key scan to capture current key state;
> -	 * columns will be activated and IRQs be enabled after the scan.
> -	 */
> -	schedule_delayed_work(&keypad->work, 0);
> +	matrix_keypad_scan(0, keypad);
> +	enable_row_irqs(keypad);
>  
>  	return 0;
>  }
> @@ -216,7 +189,6 @@ static void matrix_keypad_stop(struct input_dev *dev)
>  
>  	keypad->stopped = true;
>  	mb();
> -	flush_work(&keypad->work.work);
>  	/*
>  	 * matrix_keypad_scan() will leave IRQs enabled;
>  	 * we should disable them now.
> @@ -330,9 +302,11 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev,
>  	}
>  
>  	if (pdata->clustered_irq > 0) {
> -		err = request_irq(pdata->clustered_irq,
> -				matrix_keypad_interrupt,
> -				pdata->clustered_irq_flags,
> +		err = request_threaded_irq(pdata->clustered_irq,
> +				NULL,
> +				matrix_keypad_scan,
> +				pdata->clustered_irq_flags |
> +				IRQF_ONESHOT,
>  				"matrix-keypad", keypad);
>  		if (err) {
>  			dev_err(&pdev->dev,
> @@ -341,10 +315,13 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev,
>  		}
>  	} else {
>  		for (i = 0; i < pdata->num_row_gpios; i++) {
> -			err = request_irq(gpio_to_irq(pdata->row_gpios[i]),
> -					matrix_keypad_interrupt,
> +			err = request_threaded_irq(
> +					gpio_to_irq(pdata->row_gpios[i]),
> +					NULL,
> +					matrix_keypad_scan,
>  					IRQF_TRIGGER_RISING |
> -					IRQF_TRIGGER_FALLING,
> +					IRQF_TRIGGER_FALLING |
> +					IRQF_ONESHOT,
>  					"matrix-keypad", keypad);
>  			if (err) {
>  				dev_err(&pdev->dev,
> @@ -414,7 +391,6 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
>  	keypad->keycodes = keycodes;
>  	keypad->row_shift = row_shift;
>  	keypad->stopped = true;
> -	INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan);
>  	spin_lock_init(&keypad->lock);
>  
>  	input_dev->name		= pdev->name;
> -- 
> 1.7.5.4
> 

-- 
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux