Re: [PATCH 4/4] input/nomadik-ske: cleanup of probe and some more code style

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

 



Hi Linus,

On Sun, Jun 17, 2012 at 04:18:05PM +0200, Linus Walleij wrote:
> From: Naveen Kumar Gaddipati <naveen.gaddipati@xxxxxxxxxxxxxx>
> 
> This fixes some kerneldoc, and clean up the probe function so we
> split it in two parts: first allocate all resources and then start
> the clock and begin initializing the hardware. We exit quickly
> with negative error if the probe is unsucessful when getting
> resources. We add a pointer to the device's struct device to be
> used for dev_* prints and similar.
> 
> Signed-off-by: Naveen Kumar Gaddipati <naveen.gaddipati@xxxxxxxxxxxxxx>
> Signed-off-by: Naga Radesh Y <naga.radheshy@xxxxxxxxxxxxxx>
> Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx>
> ---
>  drivers/input/keyboard/nomadik-ske-keypad.c |  152 +++++++++++++++------------
>  1 file changed, 83 insertions(+), 69 deletions(-)
> 
> diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c
> index ca802fe..a2f2479 100644
> --- a/drivers/input/keyboard/nomadik-ske-keypad.c
> +++ b/drivers/input/keyboard/nomadik-ske-keypad.c
> @@ -53,14 +53,17 @@
>  
>  /**
>   * struct ske_keypad  - data structure used by keypad driver
> - * @irq:	irq no
> - * @reg_base:	ske regsiters base address
> - * @input:	pointer to input device object
> - * @board:	keypad platform device
> - * @keymap:	matrix scan code table for keycodes
> - * @clk:	clock structure pointer
> + * @dev:		Pointer to the structure device
> + * @irq:		irq no
> + * @reg_base:		ske regsiters base address
> + * @input:		pointer to input device object
> + * @board:		keypad platform device
> + * @keymap:		matrix scan code table for keycodes
> + * @clk:		clock structure pointer
> + * @ske_keypad_lock:    lock used while writting into registers
>   */
>  struct ske_keypad {
> +	struct device *dev;
>  	int irq;
>  	void __iomem *reg_base;
>  	struct input_dev *input;
> @@ -85,9 +88,9 @@ static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr,
>  	spin_unlock(&keypad->ske_keypad_lock);
>  }
>  
> -/*
> - * ske_keypad_chip_init: init keypad controller configuration
> - *
> +/**
> + * ske_keypad_chip_init() - init keypad controller configuration
> + * @keypad: pointer to device structure
>   * Enable Multi key press detection, auto scan mode
>   */
>  static int __init ske_keypad_chip_init(struct ske_keypad *keypad)
> @@ -225,6 +228,9 @@ static int __init ske_keypad_probe(struct platform_device *pdev)
>  	struct ske_keypad *keypad;
>  	struct input_dev *input;
>  	struct resource *res;
> +	struct clk *clk;
> +	void __iomem *reg_base;
> +	int ret = 0;

Now you have some error paths using 'error' and some using your new
'ret' with main exit using 'ret'. If 'error' cause fail you'll end up
returning 0 which is bad. Also, I'd prefer if you've kept using 'error'
everywhere.

Also I do not see benefits of the new probe sequence, old on works just
as well, right?

>  	int irq;
>  	int error;
>  
> @@ -242,40 +248,42 @@ static int __init ske_keypad_probe(struct platform_device *pdev)
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	if (!res) {
>  		dev_err(&pdev->dev, "missing platform resources\n");
> -		return -EINVAL;
> +		return -ENXIO;
>  	}
>  
> -	keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL);
> -	input = input_allocate_device();
> -	if (!keypad || !input) {
> -		dev_err(&pdev->dev, "failed to allocate keypad memory\n");
> -		error = -ENOMEM;
> -		goto err_free_mem;
> +	res = request_mem_region(res->start, resource_size(res), pdev->name);
> +	if (!res) {
> +		dev_err(&pdev->dev, "failed to request I/O memory\n");
> +		return -EBUSY;
>  	}
>  
> -	keypad->irq = irq;
> -	keypad->board = plat;
> -	keypad->input = input;
> -	spin_lock_init(&keypad->ske_keypad_lock);
> +	reg_base = ioremap(res->start, resource_size(res));
> +	if (!reg_base) {
> +		dev_err(&pdev->dev, "failed to remap I/O memory\n");
> +		ret = -ENXIO;
> +		goto out_freerequest_memregions;
> +	}
>  
> -	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
> -		dev_err(&pdev->dev, "failed to request I/O memory\n");
> -		error = -EBUSY;
> -		goto err_free_mem;
> +	clk = clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(clk)) {
> +		dev_err(&pdev->dev, "failed to clk_get\n");
> +		ret = PTR_ERR(clk);
> +		goto out_freeioremap;
>  	}
>  
> -	keypad->reg_base = ioremap(res->start, resource_size(res));
> -	if (!keypad->reg_base) {
> -		dev_err(&pdev->dev, "failed to remap I/O memory\n");
> -		error = -ENXIO;
> -		goto err_free_mem_region;
> +	/* resources are sane; we begin allocation */
> +	keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL);
> +	if (!keypad) {
> +		dev_err(&pdev->dev, "failed to allocate keypad memory\n");
> +		goto out_freeclk;
>  	}
> +	keypad->dev = &pdev->dev;
>  
> -	keypad->clk = clk_get(&pdev->dev, NULL);
> -	if (IS_ERR(keypad->clk)) {
> -		dev_err(&pdev->dev, "failed to get clk\n");
> -		error = PTR_ERR(keypad->clk);
> -		goto err_iounmap;
> +	input = input_allocate_device();
> +	if (!input) {
> +		dev_err(&pdev->dev, "failed to input_allocate_device\n");
> +		ret = -ENOMEM;
> +		goto out_freekeypad;
>  	}
>  
>  	input->id.bustype = BUS_HOST;
> @@ -287,37 +295,43 @@ static int __init ske_keypad_probe(struct platform_device *pdev)
>  					   keypad->keymap, input);
>  	if (error) {
>  		dev_err(&pdev->dev, "Failed to build keymap\n");
> -		goto err_iounmap;
> +		goto out_freekeypad;
>  	}
>  
>  	input_set_capability(input, EV_MSC, MSC_SCAN);
> +	input_set_drvdata(input, keypad);
> +
> +	__set_bit(EV_KEY, input->evbit);
>  	if (!plat->no_autorepeat)
>  		__set_bit(EV_REP, input->evbit);
>  
> -	clk_enable(keypad->clk);
> +	ret = input_register_device(input);
> +	if (ret) {
> +		dev_err(&pdev->dev,
> +			"unable to register input device: %d\n", ret);
> +		goto out_freeinput;
> +	}
>  
> -	/* go through board initialization helpers */
> -	if (keypad->board->init)
> -		keypad->board->init();
> +	keypad->irq	= irq;
> +	keypad->board	= plat;
> +	keypad->input	= input;
> +	keypad->reg_base = reg_base;
> +	keypad->clk	= clk;
>  
> -	error = ske_keypad_chip_init(keypad);
> -	if (error) {
> -		dev_err(&pdev->dev, "unable to init keypad hardware\n");
> -		goto err_clk_disable;
> -	}
> +	/* allocations are sane, we begin HW initialization */
> +	clk_enable(keypad->clk);
>  
> -	error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq,
> -				     IRQF_ONESHOT, "ske-keypad", keypad);
> -	if (error) {
> -		dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq);
> -		goto err_clk_disable;
> +	if (keypad->board->init && keypad->board->init() < 0) {
> +		dev_err(&pdev->dev, "keyboard init config failed\n");
> +		ret = -EINVAL;
> +		goto out_unregisterinput;
>  	}
>  
> -	error = input_register_device(input);
> -	if (error) {
> -		dev_err(&pdev->dev,
> -				"unable to register input device: %d\n", error);
> -		goto err_free_irq;
> +	ret =  request_threaded_irq(keypad->irq, NULL, ske_keypad_irq,
> +				IRQF_ONESHOT, "ske-keypad", keypad);
> +	if (ret) {
> +		dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq);
> +		goto out_unregisterinput;
>  	}
>  
>  	if (plat->wakeup_enable)
> @@ -327,19 +341,21 @@ static int __init ske_keypad_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> -err_free_irq:
> -	free_irq(keypad->irq, keypad);
> -err_clk_disable:
> +out_unregisterinput:
> +	input_unregister_device(input);
> +	input = NULL;
>  	clk_disable(keypad->clk);
> -	clk_put(keypad->clk);
> -err_iounmap:
> -	iounmap(keypad->reg_base);
> -err_free_mem_region:
> -	release_mem_region(res->start, resource_size(res));
> -err_free_mem:
> +out_freeinput:
>  	input_free_device(input);
> +out_freekeypad:
>  	kfree(keypad);
> -	return error;
> +out_freeclk:
> +	clk_put(clk);
> +out_freeioremap:
> +	iounmap(reg_base);
> +out_freerequest_memregions:
> +	release_mem_region(res->start, resource_size(res));
> +	return ret;
>  }
>  
>  static int __devexit ske_keypad_remove(struct platform_device *pdev)
> @@ -347,8 +363,6 @@ static int __devexit ske_keypad_remove(struct platform_device *pdev)
>  	struct ske_keypad *keypad = platform_get_drvdata(pdev);
>  	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  
> -	free_irq(keypad->irq, keypad);
> -

This change is broken: you unregister input device but still have IRQ
registered. What stops that IRQ to be delivered and access freed memory?

>  	input_unregister_device(keypad->input);
>  

Thanks.

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