Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1640851 > unrolled thread

[PATCH 2/8] gpio: exar: Fix passing in of parent PCI device

Started byJan Kiszka <jan.kiszka@siemens.com>
First post2017-05-13 09:30 +0200
Last post2017-05-14 10:20 +0200
Articles 3 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH 2/8] gpio: exar: Fix passing in of parent PCI device Jan Kiszka <jan.kiszka@siemens.com> - 2017-05-13 09:30 +0200
    Re: [PATCH 2/8] gpio: exar: Fix passing in of parent PCI device Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-05-13 15:30 +0200
      Re: [PATCH 2/8] gpio: exar: Fix passing in of parent PCI device Jan Kiszka <jan.kiszka@web.de> - 2017-05-14 10:20 +0200

#1640851 — [PATCH 2/8] gpio: exar: Fix passing in of parent PCI device

FromJan Kiszka <jan.kiszka@siemens.com>
Date2017-05-13 09:30 +0200
Subject[PATCH 2/8] gpio: exar: Fix passing in of parent PCI device
Message-ID<tGzF0-rm-11@gated-at.bofh.it>
This fixes reloading of the driver for the same device: First of all,
the driver sets drvdata to its own value during probing and does not
restore the original value on exit. But this won't help anyway as the
core clears drvdata after the driver left.

Use stable platform_data instead.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 drivers/gpio/gpio-exar.c            | 2 +-
 drivers/tty/serial/8250/8250_exar.c | 8 ++++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpio-exar.c b/drivers/gpio/gpio-exar.c
index 081076771217..0a2085faf271 100644
--- a/drivers/gpio/gpio-exar.c
+++ b/drivers/gpio/gpio-exar.c
@@ -119,7 +119,7 @@ static int exar_direction_input(struct gpio_chip *chip, unsigned int offset)
 
 static int gpio_exar_probe(struct platform_device *pdev)
 {
-	struct pci_dev *pcidev = platform_get_drvdata(pdev);
+	struct pci_dev *pcidev = *(struct pci_dev **)pdev->dev.platform_data;
 	struct exar_gpio_chip *exar_gpio;
 	void __iomem *p;
 	int index, ret;
diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
index b4fa585156c7..2d056d1eeca3 100644
--- a/drivers/tty/serial/8250/8250_exar.c
+++ b/drivers/tty/serial/8250/8250_exar.c
@@ -196,8 +196,12 @@ xr17v35x_register_gpio(struct pci_dev *pcidev)
 	if (!pdev)
 		return NULL;
 
-	platform_set_drvdata(pdev, pcidev);
-	if (platform_device_add(pdev) < 0) {
+	/*
+	 * platform_device_add_data kmemdups the data, therefore we can safely
+	 * pass a stack reference.
+	 */
+	if (platform_device_add_data(pdev, &pcidev, sizeof(pcidev)) < 0 ||
+	    platform_device_add(pdev) < 0) {
 		platform_device_put(pdev);
 		return NULL;
 	}
-- 
2.12.0

[toc] | [next] | [standalone]


#1640913

FromAndy Shevchenko <andy.shevchenko@gmail.com>
Date2017-05-13 15:30 +0200
Message-ID<tGFhn-4d4-3@gated-at.bofh.it>
In reply to#1640851
On Sat, May 13, 2017 at 10:29 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
> This fixes reloading of the driver for the same device: First of all,
> the driver sets drvdata to its own value during probing and does not
> restore the original value on exit. But this won't help anyway as the
> core clears drvdata after the driver left.
>
> Use stable platform_data instead.

From the above I didn't clearly get what device you are talking about.
GPIO?

Can you provide step by step what you did and what bug you got?

Regarding below it looks to me a bit hackish.

>  static int gpio_exar_probe(struct platform_device *pdev)
>  {
> -       struct pci_dev *pcidev = platform_get_drvdata(pdev);
> +       struct pci_dev *pcidev = *(struct pci_dev **)pdev->dev.platform_data;
>         struct exar_gpio_chip *exar_gpio;
>         void __iomem *p;
>         int index, ret;
> diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
> index b4fa585156c7..2d056d1eeca3 100644
> --- a/drivers/tty/serial/8250/8250_exar.c
> +++ b/drivers/tty/serial/8250/8250_exar.c
> @@ -196,8 +196,12 @@ xr17v35x_register_gpio(struct pci_dev *pcidev)
>         if (!pdev)
>                 return NULL;
>
> -       platform_set_drvdata(pdev, pcidev);
> -       if (platform_device_add(pdev) < 0) {
> +       /*
> +        * platform_device_add_data kmemdups the data, therefore we can safely
> +        * pass a stack reference.
> +        */
> +       if (platform_device_add_data(pdev, &pcidev, sizeof(pcidev)) < 0 ||
> +           platform_device_add(pdev) < 0) {
>                 platform_device_put(pdev);
>                 return NULL;

-- 
With Best Regards,
Andy Shevchenko

[toc] | [prev] | [next] | [standalone]


#1641062

FromJan Kiszka <jan.kiszka@web.de>
Date2017-05-14 10:20 +0200
Message-ID<tGWUV-7xq-3@gated-at.bofh.it>
In reply to#1640913

[Multipart message — attachments visible in raw view] — view raw

On 2017-05-13 15:25, Andy Shevchenko wrote:
> On Sat, May 13, 2017 at 10:29 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>> This fixes reloading of the driver for the same device: First of all,
>> the driver sets drvdata to its own value during probing and does not
>> restore the original value on exit. But this won't help anyway as the
>> core clears drvdata after the driver left.
>>
>> Use stable platform_data instead.
> 
>>From the above I didn't clearly get what device you are talking about.
> GPIO?

"This fixes reloading of the GPIO driver for the same platform device
instance as created by the exar UART driver: [...]"

Clearer?

> 
> Can you provide step by step what you did and what bug you got?

Obviously a NULL pointer: Just rmmod gpio-exar and reload it while there
is the same platform device present.

> 
> Regarding below it looks to me a bit hackish.

The alternative is a classic platform data structure, then also carrying
the properties of patch 7 - which are, BTW, not DT-related, thus shall
not form an external interface. Probably another reason to switch
everything to some struct exar_gpio_platform_data.

Jan

> 
>>  static int gpio_exar_probe(struct platform_device *pdev)
>>  {
>> -       struct pci_dev *pcidev = platform_get_drvdata(pdev);
>> +       struct pci_dev *pcidev = *(struct pci_dev **)pdev->dev.platform_data;
>>         struct exar_gpio_chip *exar_gpio;
>>         void __iomem *p;
>>         int index, ret;
>> diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
>> index b4fa585156c7..2d056d1eeca3 100644
>> --- a/drivers/tty/serial/8250/8250_exar.c
>> +++ b/drivers/tty/serial/8250/8250_exar.c
>> @@ -196,8 +196,12 @@ xr17v35x_register_gpio(struct pci_dev *pcidev)
>>         if (!pdev)
>>                 return NULL;
>>
>> -       platform_set_drvdata(pdev, pcidev);
>> -       if (platform_device_add(pdev) < 0) {
>> +       /*
>> +        * platform_device_add_data kmemdups the data, therefore we can safely
>> +        * pass a stack reference.
>> +        */
>> +       if (platform_device_add_data(pdev, &pcidev, sizeof(pcidev)) < 0 ||
>> +           platform_device_add(pdev) < 0) {
>>                 platform_device_put(pdev);
>>                 return NULL;
> 


[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web