Re: [PATCH 06/23] gpio: sysfs: clean up chip class-device handling

2015-04-27 Thread Johan Hovold
On Mon, Apr 27, 2015 at 12:54:41PM +0900, Alexandre Courbot wrote:
> On Wed, Apr 22, 2015 at 12:42 AM, Johan Hovold  wrote:
> > Clean gpio-chip class device registration and deregistration.
> >
> > The class device is registered when a gpio-chip is added (or from
> > gpiolib_sysfs_init post-core init call), and deregistered when the chip
> > is removed.
> >
> > Store the class device in struct gpio_chip directly rather than do a
> > class-device lookup on deregistration. This also removes the need for
> > the exported flag.
> >
> > Signed-off-by: Johan Hovold 

> > diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
> > index f1b36593ec9f..8c26855fc6ec 100644
> > --- a/include/linux/gpio/driver.h
> > +++ b/include/linux/gpio/driver.h
> > @@ -20,6 +20,7 @@ struct seq_file;
> >   * struct gpio_chip - abstract a GPIO controller
> >   * @label: for diagnostics
> >   * @dev: optional device providing the GPIOs
> > + * @cdev: class device (may be NULL)
> 
> Maybe a comment explaining that this field is non-NULL when a chip is
> exported would be useful to understand how it is used in the code?

I've added comments where the field is used. I didn't want to get into
explaining sysfs implementation details in the header file, but the "may
be NULL" is there as a hint to actually look at the code.

And a gpio chip will always be registered with driver core (rather than
"exported" ;) ) until it is removed. [ Currently we also allow for
"late" registration, though. ]

This is related to the issue discussed in my last mail, and again the
plan is to let chip registration be used for more than the sysfs
interface.

Johan
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 06/23] gpio: sysfs: clean up chip class-device handling

2015-04-26 Thread Alexandre Courbot
On Wed, Apr 22, 2015 at 12:42 AM, Johan Hovold  wrote:
> Clean gpio-chip class device registration and deregistration.
>
> The class device is registered when a gpio-chip is added (or from
> gpiolib_sysfs_init post-core init call), and deregistered when the chip
> is removed.
>
> Store the class device in struct gpio_chip directly rather than do a
> class-device lookup on deregistration. This also removes the need for
> the exported flag.
>
> Signed-off-by: Johan Hovold 
> ---
>  drivers/gpio/gpiolib-sysfs.c | 39 +--
>  include/linux/gpio/driver.h  |  4 ++--
>  2 files changed, 15 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
> index c433f075f349..2f8bdce792f6 100644
> --- a/drivers/gpio/gpiolib-sysfs.c
> +++ b/drivers/gpio/gpiolib-sysfs.c
> @@ -567,7 +567,7 @@ int gpiod_export(struct gpio_desc *desc, bool 
> direction_may_change)
> mutex_lock(&sysfs_lock);
>
> /* check if chip is being removed */
> -   if (!chip || !chip->exported) {
> +   if (!chip || !chip->cdev) {
> status = -ENODEV;
> goto fail_unlock;
> }
> @@ -752,7 +752,6 @@ EXPORT_SYMBOL_GPL(gpiod_unexport);
>
>  int gpiochip_export(struct gpio_chip *chip)
>  {
> -   int status;
> struct device   *dev;
>
> /* Many systems register gpio chips for SOC support very early,
> @@ -768,41 +767,29 @@ int gpiochip_export(struct gpio_chip *chip)
> chip, gpiochip_groups,
> "gpiochip%d", chip->base);
> if (IS_ERR(dev))
> -   status = PTR_ERR(dev);
> -   else
> -   status = 0;
> +   return PTR_ERR(dev);
>
> mutex_lock(&sysfs_lock);
> -   chip->exported = (status == 0);
> +   chip->cdev = dev;
> mutex_unlock(&sysfs_lock);
>
> -   if (status)
> -   chip_dbg(chip, "%s: status %d\n", __func__, status);
> -
> -   return status;
> +   return 0;
>  }
>
>  void gpiochip_unexport(struct gpio_chip *chip)
>  {
> -   int status;
> -   struct device   *dev;
> struct gpio_desc *desc;
> unsigned int i;
>
> -   dev = class_find_device(&gpio_class, NULL, chip, match_export);
> -   if (dev) {
> -   put_device(dev);
> -   device_unregister(dev);
> -   /* prevent further gpiod exports */
> -   mutex_lock(&sysfs_lock);
> -   chip->exported = false;
> -   mutex_unlock(&sysfs_lock);
> -   status = 0;
> -   } else
> -   status = -ENODEV;
> +   if (!chip->cdev)
> +   return;
>
> -   if (status)
> -   chip_dbg(chip, "%s: status %d\n", __func__, status);
> +   device_unregister(chip->cdev);
> +
> +   /* prevent further gpiod exports */
> +   mutex_lock(&sysfs_lock);
> +   chip->cdev = NULL;
> +   mutex_unlock(&sysfs_lock);
>
> /* unregister gpiod class devices owned by sysfs */
> for (i = 0; i < chip->ngpio; i++) {
> @@ -830,7 +817,7 @@ static int __init gpiolib_sysfs_init(void)
>  */
> spin_lock_irqsave(&gpio_lock, flags);
> list_for_each_entry(chip, &gpio_chips, list) {
> -   if (chip->exported)
> +   if (chip->cdev)
> continue;
>
> /*
> diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
> index f1b36593ec9f..8c26855fc6ec 100644
> --- a/include/linux/gpio/driver.h
> +++ b/include/linux/gpio/driver.h
> @@ -20,6 +20,7 @@ struct seq_file;
>   * struct gpio_chip - abstract a GPIO controller
>   * @label: for diagnostics
>   * @dev: optional device providing the GPIOs
> + * @cdev: class device (may be NULL)

Maybe a comment explaining that this field is non-NULL when a chip is
exported would be useful to understand how it is used in the code?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 06/23] gpio: sysfs: clean up chip class-device handling

2015-04-21 Thread Johan Hovold
Clean gpio-chip class device registration and deregistration.

The class device is registered when a gpio-chip is added (or from
gpiolib_sysfs_init post-core init call), and deregistered when the chip
is removed.

Store the class device in struct gpio_chip directly rather than do a
class-device lookup on deregistration. This also removes the need for
the exported flag.

Signed-off-by: Johan Hovold 
---
 drivers/gpio/gpiolib-sysfs.c | 39 +--
 include/linux/gpio/driver.h  |  4 ++--
 2 files changed, 15 insertions(+), 28 deletions(-)

diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index c433f075f349..2f8bdce792f6 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -567,7 +567,7 @@ int gpiod_export(struct gpio_desc *desc, bool 
direction_may_change)
mutex_lock(&sysfs_lock);
 
/* check if chip is being removed */
-   if (!chip || !chip->exported) {
+   if (!chip || !chip->cdev) {
status = -ENODEV;
goto fail_unlock;
}
@@ -752,7 +752,6 @@ EXPORT_SYMBOL_GPL(gpiod_unexport);
 
 int gpiochip_export(struct gpio_chip *chip)
 {
-   int status;
struct device   *dev;
 
/* Many systems register gpio chips for SOC support very early,
@@ -768,41 +767,29 @@ int gpiochip_export(struct gpio_chip *chip)
chip, gpiochip_groups,
"gpiochip%d", chip->base);
if (IS_ERR(dev))
-   status = PTR_ERR(dev);
-   else
-   status = 0;
+   return PTR_ERR(dev);
 
mutex_lock(&sysfs_lock);
-   chip->exported = (status == 0);
+   chip->cdev = dev;
mutex_unlock(&sysfs_lock);
 
-   if (status)
-   chip_dbg(chip, "%s: status %d\n", __func__, status);
-
-   return status;
+   return 0;
 }
 
 void gpiochip_unexport(struct gpio_chip *chip)
 {
-   int status;
-   struct device   *dev;
struct gpio_desc *desc;
unsigned int i;
 
-   dev = class_find_device(&gpio_class, NULL, chip, match_export);
-   if (dev) {
-   put_device(dev);
-   device_unregister(dev);
-   /* prevent further gpiod exports */
-   mutex_lock(&sysfs_lock);
-   chip->exported = false;
-   mutex_unlock(&sysfs_lock);
-   status = 0;
-   } else
-   status = -ENODEV;
+   if (!chip->cdev)
+   return;
 
-   if (status)
-   chip_dbg(chip, "%s: status %d\n", __func__, status);
+   device_unregister(chip->cdev);
+
+   /* prevent further gpiod exports */
+   mutex_lock(&sysfs_lock);
+   chip->cdev = NULL;
+   mutex_unlock(&sysfs_lock);
 
/* unregister gpiod class devices owned by sysfs */
for (i = 0; i < chip->ngpio; i++) {
@@ -830,7 +817,7 @@ static int __init gpiolib_sysfs_init(void)
 */
spin_lock_irqsave(&gpio_lock, flags);
list_for_each_entry(chip, &gpio_chips, list) {
-   if (chip->exported)
+   if (chip->cdev)
continue;
 
/*
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index f1b36593ec9f..8c26855fc6ec 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -20,6 +20,7 @@ struct seq_file;
  * struct gpio_chip - abstract a GPIO controller
  * @label: for diagnostics
  * @dev: optional device providing the GPIOs
+ * @cdev: class device (may be NULL)
  * @owner: helps prevent removal of modules exporting active GPIOs
  * @list: links gpio_chips together for traversal
  * @request: optional hook for chip-specific activation, such as
@@ -57,7 +58,6 @@ struct seq_file;
  * implies that if the chip supports IRQs, these IRQs need to be threaded
  * as the chip access may sleep when e.g. reading out the IRQ status
  * registers.
- * @exported: flags if the gpiochip is exported for use from sysfs. Private.
  * @irq_not_threaded: flag must be set if @can_sleep is set but the
  * IRQs don't need to be threaded
  *
@@ -74,6 +74,7 @@ struct seq_file;
 struct gpio_chip {
const char  *label;
struct device   *dev;
+   struct device   *cdev;
struct module   *owner;
struct list_headlist;
 
@@ -109,7 +110,6 @@ struct gpio_chip {
const char  *const *names;
boolcan_sleep;
boolirq_not_threaded;
-   boolexported;
 
 #ifdef CONFIG_GPIOLIB_IRQCHIP
/*
-- 
2.0.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/