All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 00/16] Add ACPI _DSD and unified device properties support
@ 2014-09-16 11:52 ` Mika Westerberg
  0 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

This is a second revision of the patches first submitted here [1].

The recent publication of the ACPI 5.1 specification [2] adds a reserved name
for Device Specific Data (_DSD, Section 6.2.5). This mechanism allows for
passing arbitrary hardware description data to the OS. The exact format of the
_DSD data is specific to the UUID paired with it [3].   

An ACPI Device Properties UUID has been defined [4] to provide a format
compatible with existing device tree schemas. The purpose for this was to
allow for the reuse of the existing schemas and encourage the development
of firmware agnostic device drivers.

This series accomplishes the following (as well as some other dependencies):

 * Add _DSD support to the ACPI core
   This simply reads the UUID and the accompanying Package

 * Add ACPI Device Properties _DSD format support
   This understands the hierarchical key:value pair structure
   defined by the Device Properties UUID

 * Add a unified device properties API with ACPI and OF backends
   This provides for the firmware agnostic device properties
   Interface to be used by drivers

 * Provides 3 example drivers that were previously Device Tree aware that
   can now be used with either Device Tree or ACPI Device Properties. The
   drivers use "PRP0001" as their _HID which means that the match should be
   done using driver's .of_match_table instead.

The patch series has been tested on Minnoboard and Minnowboard MAX and the
relevant part of DSDTs are at the end of this cover letter.

This series does not provide for a means to append to a system DSDT. That
will ultimately be required to make the most effective use of the _DSD
mechanism. Work is underway on that as a separate effort.

Most important changes to the previous RFC version:

  * Added wrapper functions for most used property types
  * Return -EOVERFLOW in case integer would not fit to a type
  * Dropped dev_prop_ops
  * We now have dev_node_xxx() functions to access firmware node
    properties without dev pointer
  * The accessor function names try to be close to their corresponding of_*
    counterpart
  * Tried to have a bit better examples in the documentation patch
  * gpiolib got support for _DSD and also it now understand firmware node
    properties with dev_node_get_named_gpiod() that requests the GPIO
    properly.
  * Support for "PRP0001" _HID/_CID. This means that the match should be
    done using driver .of_match_table instead.
  * Add unified property support for at25 SPI eeprom driver as well.

[1] https://lkml.org/lkml/2014/8/17/10
[2] http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf
[3] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
[4] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf

Aaron Lu (2):
  input: gpio_keys_polled - Add support for GPIO descriptors
  input: gpio_keys_polled - Make use of device property API

Max Eliaser (2):
  leds: leds-gpio: Make use of device property API
  leds: leds-gpio: Add ACPI probing support

Mika Westerberg (11):
  ACPI: Add support for device specific properties
  ACPI: Allow drivers to match using Device Tree compatible property
  ACPI: Document ACPI device specific properties
  mfd: Add ACPI support
  gpio / ACPI: Add support for _DSD device properties
  gpio: Add support for unified device properties interface
  gpio: sch: Consolidate core and resume banks
  leds: leds-gpio: Add support for GPIO descriptors
  input: gpio_keys_polled - Add ACPI probing support
  misc: at25: Make use of device property API
  misc: at25: Add ACPI probing support

Rafael J. Wysocki (1):
  Driver core: Unified device properties interface for platform firmware

 Documentation/acpi/enumeration.txt        |  27 ++
 Documentation/acpi/properties.txt         | 410 +++++++++++++++++++++
 drivers/acpi/Makefile                     |   1 +
 drivers/acpi/internal.h                   |   6 +
 drivers/acpi/property.c                   | 584 ++++++++++++++++++++++++++++++
 drivers/acpi/scan.c                       |  93 ++++-
 drivers/base/Makefile                     |   2 +-
 drivers/base/property.c                   | 196 ++++++++++
 drivers/gpio/devres.c                     |  35 ++
 drivers/gpio/gpio-sch.c                   | 293 ++++++---------
 drivers/gpio/gpiolib-acpi.c               |  78 +++-
 drivers/gpio/gpiolib.c                    |  85 ++++-
 drivers/gpio/gpiolib.h                    |   7 +-
 drivers/input/keyboard/gpio_keys_polled.c | 169 +++++----
 drivers/leds/leds-gpio.c                  | 188 +++++-----
 drivers/mfd/mfd-core.c                    |  40 ++
 drivers/misc/eeprom/at25.c                |  41 +--
 drivers/of/base.c                         | 188 ++++++++++
 include/acpi/acpi_bus.h                   |   8 +
 include/linux/acpi.h                      |  90 ++++-
 include/linux/gpio/consumer.h             |   7 +
 include/linux/gpio_keys.h                 |   3 +
 include/linux/leds.h                      |   1 +
 include/linux/mfd/core.h                  |   3 +
 include/linux/of.h                        |  37 ++
 include/linux/property.h                  | 193 ++++++++++
 26 files changed, 2377 insertions(+), 408 deletions(-)
 create mode 100644 Documentation/acpi/properties.txt
 create mode 100644 drivers/acpi/property.c
 create mode 100644 drivers/base/property.c
 create mode 100644 include/linux/property.h

DSDT modifications for Minnowboard (for leds-gpio.c and gpio_keys_polled.c)
---------------------------------------------------------------------------

    Scope (\_SB.PCI0.LPC)
    {
        Device (LEDS)
        {
            Name (_HID, "PRP0001")

            Name (_CRS, ResourceTemplate () {
                GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
                        "\\_SB.PCI0.LPC", 0, ResourceConsumer) {10}
                GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
                        "\\_SB.PCI0.LPC", 0, ResourceConsumer) {11}
            })

            Name (_DSD, Package () {
                  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                  Package () {
                      Package () {"compatible", Package () {"gpio-leds"}},
                  }
            })

            Device (LEDH)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"label", "Heartbeat"},
                        Package () {"gpios", Package () {^^LEDS, 0, 0, 0}},
                        Package () {"linux,default-trigger", "heartbeat"},
                        Package () {"linux,default-state", "off"},
                        Package () {"linux,retain-state-suspended", 1},
                    }
                })
            }

            Device (LEDM)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"label", "MMC0 Activity"},
                        Package () {"gpios", Package () {^^LEDS, 1, 0, 0}},
                        Package () {"linux,default-trigger", "mmc0"},
                        Package () {"linux,default-state", "off"},
                        Package () {"linux,retain-state-suspended", 1},
                    }
                })
            }
        }
        
        Device (BTNS)
        {
            Name (_HID, "PRP0001")

            Name (_CRS, ResourceTemplate () {
                GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
                        "\\_SB.PCI0.LPC", 0, ResourceConsumer) {0, 1, 2, 3}
            })

            Name (_DSD, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () {"compatible", Package () {"gpio-keys-polled"}},
                    Package () {"poll-interval", 100},
                    Package () {"autorepeat", 1}
                }
            })

            Device (BTN0)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"linux,code", 105},
                        Package () {"linux,input-type", 1},
                        Package () {"gpios", Package () {^^BTNS, 0, 0, 1}},
                    }
                })
            }

            Device (BTN1)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"linux,code", 108},
                        Package () {"linux,input-type", 1},
                        Package () {"gpios", Package (4) {^^BTNS, 0, 1, 1}},
                    }
                })
            }
            
            Device (BTN2)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"linux,code", 103},
                        Package () {"linux,input-type", 1},
                        Package () {"gpios", Package () {^^BTNS, 0, 2, 1}},
                    }
                })
            }
            
            Device (BTN3)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () {"linux,code", 106},
                        Package () {"linux,input-type", 1},
                        Package () {"gpios", Package (4) {^^BTNS, 0, 3, 1}},
                    }
                })
            }
        }
    }

DSDT modifications for Minnowboard MAX (for at25.c)
---------------------------------------------------

    Scope (\_SB.SPI1)
    {
        Device (AT25)
        {
            Name (_HID, "PRP0001")
            Method (_CRS, 0, Serialized) {
                Name (UBUF, ResourceTemplate () {
                    SpiSerialBus (0x0000, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x007A1200, ClockPolarityLow,
                        ClockPhaseSecond, "\\_SB.SPI1",
                        0x00, ResourceConsumer)
                })
                Return (UBUF)
            }

            Name (_DSD, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () {"compatible", Package () {"atmel,at25"}},
		    Package () {"size", 1024},
		    Package () {"pagesize", 32},
		    Package () {"address-width", 16},
                }
            })

            Method (_STA, 0, NotSerialized)
            {
                Return (0xF)
            }
        }
    }
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 00/16] Add ACPI _DSD and unified device properties support
@ 2014-09-16 11:52 ` Mika Westerberg
  0 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

This is a second revision of the patches first submitted here [1].

The recent publication of the ACPI 5.1 specification [2] adds a reserved name
for Device Specific Data (_DSD, Section 6.2.5). This mechanism allows for
passing arbitrary hardware description data to the OS. The exact format of the
_DSD data is specific to the UUID paired with it [3].   

An ACPI Device Properties UUID has been defined [4] to provide a format
compatible with existing device tree schemas. The purpose for this was to
allow for the reuse of the existing schemas and encourage the development
of firmware agnostic device drivers.

This series accomplishes the following (as well as some other dependencies):

 * Add _DSD support to the ACPI core
   This simply reads the UUID and the accompanying Package

 * Add ACPI Device Properties _DSD format support
   This understands the hierarchical key:value pair structure
   defined by the Device Properties UUID

 * Add a unified device properties API with ACPI and OF backends
   This provides for the firmware agnostic device properties
   Interface to be used by drivers

 * Provides 3 example drivers that were previously Device Tree aware that
   can now be used with either Device Tree or ACPI Device Properties. The
   drivers use "PRP0001" as their _HID which means that the match should be
   done using driver's .of_match_table instead.

The patch series has been tested on Minnoboard and Minnowboard MAX and the
relevant part of DSDTs are at the end of this cover letter.

This series does not provide for a means to append to a system DSDT. That
will ultimately be required to make the most effective use of the _DSD
mechanism. Work is underway on that as a separate effort.

Most important changes to the previous RFC version:

  * Added wrapper functions for most used property types
  * Return -EOVERFLOW in case integer would not fit to a type
  * Dropped dev_prop_ops
  * We now have dev_node_xxx() functions to access firmware node
    properties without dev pointer
  * The accessor function names try to be close to their corresponding of_*
    counterpart
  * Tried to have a bit better examples in the documentation patch
  * gpiolib got support for _DSD and also it now understand firmware node
    properties with dev_node_get_named_gpiod() that requests the GPIO
    properly.
  * Support for "PRP0001" _HID/_CID. This means that the match should be
    done using driver .of_match_table instead.
  * Add unified property support for at25 SPI eeprom driver as well.

[1] https://lkml.org/lkml/2014/8/17/10
[2] http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf
[3] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
[4] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf

Aaron Lu (2):
  input: gpio_keys_polled - Add support for GPIO descriptors
  input: gpio_keys_polled - Make use of device property API

Max Eliaser (2):
  leds: leds-gpio: Make use of device property API
  leds: leds-gpio: Add ACPI probing support

Mika Westerberg (11):
  ACPI: Add support for device specific properties
  ACPI: Allow drivers to match using Device Tree compatible property
  ACPI: Document ACPI device specific properties
  mfd: Add ACPI support
  gpio / ACPI: Add support for _DSD device properties
  gpio: Add support for unified device properties interface
  gpio: sch: Consolidate core and resume banks
  leds: leds-gpio: Add support for GPIO descriptors
  input: gpio_keys_polled - Add ACPI probing support
  misc: at25: Make use of device property API
  misc: at25: Add ACPI probing support

Rafael J. Wysocki (1):
  Driver core: Unified device properties interface for platform firmware

 Documentation/acpi/enumeration.txt        |  27 ++
 Documentation/acpi/properties.txt         | 410 +++++++++++++++++++++
 drivers/acpi/Makefile                     |   1 +
 drivers/acpi/internal.h                   |   6 +
 drivers/acpi/property.c                   | 584 ++++++++++++++++++++++++++++++
 drivers/acpi/scan.c                       |  93 ++++-
 drivers/base/Makefile                     |   2 +-
 drivers/base/property.c                   | 196 ++++++++++
 drivers/gpio/devres.c                     |  35 ++
 drivers/gpio/gpio-sch.c                   | 293 ++++++---------
 drivers/gpio/gpiolib-acpi.c               |  78 +++-
 drivers/gpio/gpiolib.c                    |  85 ++++-
 drivers/gpio/gpiolib.h                    |   7 +-
 drivers/input/keyboard/gpio_keys_polled.c | 169 +++++----
 drivers/leds/leds-gpio.c                  | 188 +++++-----
 drivers/mfd/mfd-core.c                    |  40 ++
 drivers/misc/eeprom/at25.c                |  41 +--
 drivers/of/base.c                         | 188 ++++++++++
 include/acpi/acpi_bus.h                   |   8 +
 include/linux/acpi.h                      |  90 ++++-
 include/linux/gpio/consumer.h             |   7 +
 include/linux/gpio_keys.h                 |   3 +
 include/linux/leds.h                      |   1 +
 include/linux/mfd/core.h                  |   3 +
 include/linux/of.h                        |  37 ++
 include/linux/property.h                  | 193 ++++++++++
 26 files changed, 2377 insertions(+), 408 deletions(-)
 create mode 100644 Documentation/acpi/properties.txt
 create mode 100644 drivers/acpi/property.c
 create mode 100644 drivers/base/property.c
 create mode 100644 include/linux/property.h

DSDT modifications for Minnowboard (for leds-gpio.c and gpio_keys_polled.c)
---------------------------------------------------------------------------

    Scope (\_SB.PCI0.LPC)
    {
        Device (LEDS)
        {
            Name (_HID, "PRP0001")

            Name (_CRS, ResourceTemplate () {
                GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
                        "\\_SB.PCI0.LPC", 0, ResourceConsumer) {10}
                GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
                        "\\_SB.PCI0.LPC", 0, ResourceConsumer) {11}
            })

            Name (_DSD, Package () {
                  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                  Package () {
                      Package () {"compatible", Package () {"gpio-leds"}},
                  }
            })

            Device (LEDH)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"label", "Heartbeat"},
                        Package () {"gpios", Package () {^^LEDS, 0, 0, 0}},
                        Package () {"linux,default-trigger", "heartbeat"},
                        Package () {"linux,default-state", "off"},
                        Package () {"linux,retain-state-suspended", 1},
                    }
                })
            }

            Device (LEDM)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"label", "MMC0 Activity"},
                        Package () {"gpios", Package () {^^LEDS, 1, 0, 0}},
                        Package () {"linux,default-trigger", "mmc0"},
                        Package () {"linux,default-state", "off"},
                        Package () {"linux,retain-state-suspended", 1},
                    }
                })
            }
        }
        
        Device (BTNS)
        {
            Name (_HID, "PRP0001")

            Name (_CRS, ResourceTemplate () {
                GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
                        "\\_SB.PCI0.LPC", 0, ResourceConsumer) {0, 1, 2, 3}
            })

            Name (_DSD, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () {"compatible", Package () {"gpio-keys-polled"}},
                    Package () {"poll-interval", 100},
                    Package () {"autorepeat", 1}
                }
            })

            Device (BTN0)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"linux,code", 105},
                        Package () {"linux,input-type", 1},
                        Package () {"gpios", Package () {^^BTNS, 0, 0, 1}},
                    }
                })
            }

            Device (BTN1)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"linux,code", 108},
                        Package () {"linux,input-type", 1},
                        Package () {"gpios", Package (4) {^^BTNS, 0, 1, 1}},
                    }
                })
            }
            
            Device (BTN2)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
                        Package () {"linux,code", 103},
                        Package () {"linux,input-type", 1},
                        Package () {"gpios", Package () {^^BTNS, 0, 2, 1}},
                    }
                })
            }
            
            Device (BTN3)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () {"linux,code", 106},
                        Package () {"linux,input-type", 1},
                        Package () {"gpios", Package (4) {^^BTNS, 0, 3, 1}},
                    }
                })
            }
        }
    }

DSDT modifications for Minnowboard MAX (for at25.c)
---------------------------------------------------

    Scope (\_SB.SPI1)
    {
        Device (AT25)
        {
            Name (_HID, "PRP0001")
            Method (_CRS, 0, Serialized) {
                Name (UBUF, ResourceTemplate () {
                    SpiSerialBus (0x0000, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x007A1200, ClockPolarityLow,
                        ClockPhaseSecond, "\\_SB.SPI1",
                        0x00, ResourceConsumer)
                })
                Return (UBUF)
            }

            Name (_DSD, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () {"compatible", Package () {"atmel,at25"}},
		    Package () {"size", 1024},
		    Package () {"pagesize", 32},
		    Package () {"address-width", 16},
                }
            })

            Method (_STA, 0, NotSerialized)
            {
                Return (0xF)
            }
        }
    }
-- 
2.1.0


^ permalink raw reply	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 01/16] ACPI: Add support for device specific properties
  2014-09-16 11:52 ` Mika Westerberg
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  2014-10-06 13:50     ` Grant Likely
  -1 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

Device Tree is used in many embedded systems to describe the system
configuration to the OS. It supports attaching properties or name-value
pairs to the devices it describe. With these properties one can pass
additional information to the drivers that would not be available
otherwise.

ACPI is another configuration mechanism (among other things) typically
seen, but not limited to, x86 machines. ACPI allows passing arbitrary
data from methods but there has not been mechanism equivalent to Device
Tree until the introduction of _DSD in the recent publication of the
ACPI 5.1 specification.

In order to facilitate ACPI usage in systems where Device Tree is
typically used, it would be beneficial to standardize a way to retrieve
Device Tree style properties from ACPI devices, which is what we do in
this patch.

If a given device described in ACPI namespace wants to export properties it
must implement _DSD method (Device Specific Data, introduced with ACPI 5.1)
that returns the properties in a package of packages. For example:

	Name (_DSD, Package () {
		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
		Package () {
			Package () {"name1", <VALUE1>},
			Package () {"name2", <VALUE2>},
			...
		}
	})

The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301
and is documented in the ACPI 5.1 companion document called "_DSD
Implementation Guide" [1], [2].

We add several helper functions that can be used to extract these
properties and convert them to different Linux data types.

The ultimate goal is that we only have one device property API that
retrieves the requested properties from Device Tree or from ACPI
transparent to the caller.

[1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
[2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf

Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/acpi/Makefile   |   1 +
 drivers/acpi/internal.h |   6 +
 drivers/acpi/property.c | 364 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/scan.c     |   2 +
 include/acpi/acpi_bus.h |   7 +
 include/linux/acpi.h    |  40 ++++++
 6 files changed, 420 insertions(+)
 create mode 100644 drivers/acpi/property.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 505d4d79fe3e..ba2cafe18fe4 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -46,6 +46,7 @@ acpi-y				+= acpi_pnp.o
 acpi-y				+= power.o
 acpi-y				+= event.o
 acpi-y				+= sysfs.o
+acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 4c5cf77e7576..e34290c7af9f 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -181,4 +181,10 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev);
 bool acpi_osi_is_win8(void);
 #endif
 
+/*--------------------------------------------------------------------------
+				Device properties
+  -------------------------------------------------------------------------- */
+void acpi_init_properties(struct acpi_device *adev);
+void acpi_free_properties(struct acpi_device *adev);
+
 #endif /* _ACPI_INTERNAL_H_ */
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
new file mode 100644
index 000000000000..c4a3e800e82c
--- /dev/null
+++ b/drivers/acpi/property.c
@@ -0,0 +1,364 @@
+/*
+ * ACPI device specific properties support.
+ *
+ * Copyright (C) 2014, Intel Corporation
+ * All rights reserved.
+ *
+ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *          Darren Hart <dvhart@linux.intel.com>
+ *          Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/export.h>
+
+#include "internal.h"
+
+/* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
+static const u8 prp_uuid[16] = {
+	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
+	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
+};
+
+static bool acpi_property_value_ok(const union acpi_object *value)
+{
+	int j;
+
+	/*
+	 * The value must be an integer, a string, a reference, or a package
+	 * whose every element must be an integer, a string, or a reference.
+	 */
+	switch (value->type) {
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_LOCAL_REFERENCE:
+		return true;
+
+	case ACPI_TYPE_PACKAGE:
+		for (j = 0; j < value->package.count; j++)
+			switch (value->package.elements[j].type) {
+			case ACPI_TYPE_INTEGER:
+			case ACPI_TYPE_STRING:
+			case ACPI_TYPE_LOCAL_REFERENCE:
+				continue;
+
+			default:
+				return false;
+			}
+
+		return true;
+	}
+	return false;
+}
+
+static bool acpi_properties_format_valid(const union acpi_object *properties)
+{
+	int i;
+
+	for (i = 0; i < properties->package.count; i++) {
+		const union acpi_object *property;
+
+		property = &properties->package.elements[i];
+		/*
+		 * Only two elements allowed, the first one must be a string and
+		 * the second one has to satisfy certain conditions.
+		 */
+		if (property->package.count != 2
+		    || property->package.elements[0].type != ACPI_TYPE_STRING
+		    || !acpi_property_value_ok(&property->package.elements[1]))
+			return false;
+	}
+	return true;
+}
+
+void acpi_init_properties(struct acpi_device *adev)
+{
+	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+	const union acpi_object *desc;
+	acpi_status status;
+	int i;
+
+	status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
+					    ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(status))
+		return;
+
+	desc = buf.pointer;
+	if (desc->package.count % 2)
+		goto fail;
+
+	/* Look for the device properties UUID. */
+	for (i = 0; i < desc->package.count; i += 2) {
+		const union acpi_object *uuid, *properties;
+
+		uuid = &desc->package.elements[i];
+		properties = &desc->package.elements[i + 1];
+
+		/*
+		 * The first element must be a UUID and the second one must be
+		 * a package.
+		 */
+		if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
+		    || properties->type != ACPI_TYPE_PACKAGE)
+			break;
+
+		if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid)))
+			continue;
+
+		/*
+		 * We found the matching UUID. Now validate the format of the
+		 * package immediately following it.
+		 */
+		if (!acpi_properties_format_valid(properties))
+			break;
+
+		adev->data.pointer = buf.pointer;
+		adev->data.properties = properties;
+		return;
+	}
+
+ fail:
+	dev_warn(&adev->dev, "Returned _DSD data is not valid, skipping\n");
+	ACPI_FREE(buf.pointer);
+}
+
+void acpi_free_properties(struct acpi_device *adev)
+{
+	ACPI_FREE((void *)adev->data.pointer);
+	adev->data.pointer = NULL;
+	adev->data.properties = NULL;
+}
+
+/**
+ * acpi_dev_get_property - return an ACPI property with given name
+ * @adev: ACPI device to get property
+ * @name: Name of the property
+ * @type: Expected property type
+ * @obj: Location to store the property value (if not %NULL)
+ *
+ * Look up a property with @name and store a pointer to the resulting ACPI
+ * object at the location pointed to by @obj if found.
+ *
+ * Callers must not attempt to free the returned objects.  These objects will be
+ * freed by the ACPI core automatically during the removal of @adev.
+ *
+ * Return: %0 if property with @name has been found (success),
+ *         %-EINVAL if the arguments are invalid,
+ *         %-ENODATA if the property doesn't exist,
+ *         %-EPROTO if the property value type doesn't match @type.
+ */
+int acpi_dev_get_property(struct acpi_device *adev, const char *name,
+			  acpi_object_type type, const union acpi_object **obj)
+{
+	const union acpi_object *properties;
+	int i;
+
+	if (!adev || !name)
+		return -EINVAL;
+
+	if (!adev->data.pointer || !adev->data.properties)
+		return -ENODATA;
+
+	properties = adev->data.properties;
+	for (i = 0; i < properties->package.count; i++) {
+		const union acpi_object *propname, *propvalue;
+		const union acpi_object *property;
+
+		property = &properties->package.elements[i];
+
+		propname = &property->package.elements[0];
+		propvalue = &property->package.elements[1];
+
+		if (!strcmp(name, propname->string.pointer)) {
+			if (type != ACPI_TYPE_ANY && propvalue->type != type)
+				return -EPROTO;
+			else if (obj)
+				*obj = propvalue;
+
+			return 0;
+		}
+	}
+	return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_property);
+
+/**
+ * acpi_dev_get_property_array - return an ACPI array property with given name
+ * @adev: ACPI device to get property
+ * @name: Name of the property
+ * @type: Expected type of array elements
+ * @obj: Location to store a pointer to the property value (if not NULL)
+ *
+ * Look up an array property with @name and store a pointer to the resulting
+ * ACPI object at the location pointed to by @obj if found.
+ *
+ * Callers must not attempt to free the returned objects.  Those objects will be
+ * freed by the ACPI core automatically during the removal of @adev.
+ *
+ * Return: %0 if array property (package) with @name has been found (success),
+ *         %-EINVAL if the arguments are invalid,
+ *         %-ENODATA if the property doesn't exist,
+ *         %-EPROTO if the property is not a package or the type of its elements
+ *           doesn't match @type.
+ */
+int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
+				acpi_object_type type,
+				const union acpi_object **obj)
+{
+	const union acpi_object *prop;
+	int ret, i;
+
+	ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop);
+	if (ret)
+		return ret;
+
+	if (type != ACPI_TYPE_ANY) {
+		/* Check that all elements are of correct type. */
+		for (i = 0; i < prop->package.count; i++)
+			if (prop->package.elements[i].type != type)
+				return -EPROTO;
+	}
+	if (obj)
+		*obj = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_property_array);
+
+/**
+ * acpi_dev_get_property_reference - returns handle to the referenced object
+ * @adev: ACPI device to get property
+ * @name: Name of the property
+ * @size_prop: Name of the "size" property in referenced object
+ * @index: Index of the reference to return
+ * @args: Location to store the returned reference with optional arguments
+ *
+ * Find property with @name, verifify that it is a package containing at least
+ * one object reference and if so, store the ACPI device object pointer to the
+ * target object in @args->adev.
+ *
+ * If the reference includes arguments (@size_prop is not %NULL) follow the
+ * reference and check whether or not there is an integer property @size_prop
+ * under the target object and if so, whether or not its value matches the
+ * number of arguments that follow the reference.  If there's more than one
+ * reference in the property value package, @index is used to select the one to
+ * return.
+ *
+ * Return: %0 on success, negative error code on failure.
+ */
+int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
+				    const char *size_prop, size_t index,
+				    struct acpi_reference_args *args)
+{
+	const union acpi_object *element, *end;
+	const union acpi_object *obj;
+	struct acpi_device *device;
+	int ret, idx = 0;
+
+	ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj);
+	if (ret)
+		return ret;
+
+	/*
+	 * The simplest case is when the value is a single reference.  Just
+	 * return that reference then.
+	 */
+	if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
+		if (size_prop || index)
+			return -EINVAL;
+
+		ret = acpi_bus_get_device(obj->reference.handle, &device);
+		if (ret)
+			return ret;
+
+		args->adev = device;
+		args->nargs = 0;
+		return 0;
+	}
+
+	/*
+	 * If it is not a single reference, then it is a package of
+	 * references followed by number of ints as follows:
+	 *
+	 *  Package () { REF, INT, REF, INT, INT }
+	 *
+	 * The index argument is then used to determine which reference
+	 * the caller wants (along with the arguments).
+	 */
+	if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count)
+		return -EPROTO;
+
+	element = obj->package.elements;
+	end = element + obj->package.count;
+
+	while (element < end) {
+		u32 nargs, i;
+
+		if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
+			return -EPROTO;
+
+		ret = acpi_bus_get_device(element->reference.handle, &device);
+		if (ret)
+			return -ENODEV;
+
+		element++;
+		nargs = 0;
+
+		if (size_prop) {
+			const union acpi_object *prop;
+
+			/*
+			 * Find out how many arguments the refenced object
+			 * expects by reading its size_prop property.
+			 */
+			ret = acpi_dev_get_property(device, size_prop,
+						    ACPI_TYPE_INTEGER, &prop);
+			if (ret)
+				return ret;
+
+			nargs = prop->integer.value;
+			if (nargs > MAX_ACPI_REFERENCE_ARGS
+			    || element + nargs > end)
+				return -EPROTO;
+
+			/*
+			 * Skip to the start of the arguments and verify
+			 * that they all are in fact integers.
+			 */
+			for (i = 0; i < nargs; i++)
+				if (element[i].type != ACPI_TYPE_INTEGER)
+					return -EPROTO;
+		} else {
+			/* assume following integer elements are all args */
+			for (i = 0; element + i < end; i++) {
+				int type = element[i].type;
+
+				if (type == ACPI_TYPE_INTEGER)
+					nargs++;
+				else if (type == ACPI_TYPE_LOCAL_REFERENCE)
+					break;
+				else
+					return -EPROTO;
+			}
+		}
+
+		if (idx++ == index) {
+			args->adev = device;
+			args->nargs = nargs;
+			for (i = 0; i < nargs; i++)
+				args->args[i] = element[i].integer.value;
+
+			return 0;
+		}
+
+		element += nargs;
+	}
+
+	return -EPROTO;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d5e6ac5042d8..f4aabf9c0aad 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -884,6 +884,7 @@ static void acpi_device_release(struct device *dev)
 {
 	struct acpi_device *acpi_dev = to_acpi_device(dev);
 
+	acpi_free_properties(acpi_dev);
 	acpi_free_pnp_ids(&acpi_dev->pnp);
 	acpi_free_power_resources_lists(acpi_dev);
 	kfree(acpi_dev);
@@ -1888,6 +1889,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
 	acpi_set_device_status(device, sta);
 	acpi_device_get_busid(device);
 	acpi_set_pnp_ids(handle, &device->pnp, type);
+	acpi_init_properties(device);
 	acpi_bus_get_flags(device);
 	device->flags.match_driver = false;
 	device->flags.initialized = true;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c1c9de19edbe..620b4f89c87b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -337,6 +337,12 @@ struct acpi_device_physical_node {
 	bool put_online:1;
 };
 
+/* ACPI Device Specific Data (_DSD) */
+struct acpi_device_data {
+	const union acpi_object *pointer;
+	const union acpi_object *properties;
+};
+
 /* Device */
 struct acpi_device {
 	int device_type;
@@ -353,6 +359,7 @@ struct acpi_device {
 	struct acpi_device_wakeup wakeup;
 	struct acpi_device_perf performance;
 	struct acpi_device_dir dir;
+	struct acpi_device_data data;
 	struct acpi_scan_handler *handler;
 	struct acpi_hotplug_context *hp;
 	struct acpi_driver *driver;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 807cbc46d73e..104321d994f5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -660,4 +660,44 @@ do {									\
 #endif
 #endif
 
+/* Device properties */
+
+#define MAX_ACPI_REFERENCE_ARGS	8
+struct acpi_reference_args {
+	struct acpi_device *adev;
+	size_t nargs;
+	u64 args[MAX_ACPI_REFERENCE_ARGS];
+};
+
+#ifdef CONFIG_ACPI
+int acpi_dev_get_property(struct acpi_device *adev, const char *name,
+			  acpi_object_type type, const union acpi_object **obj);
+int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
+				acpi_object_type type,
+				const union acpi_object **obj);
+int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
+				    const char *cells_name, size_t index,
+				    struct acpi_reference_args *args);
+#else
+static inline int acpi_dev_get_property(struct acpi_device *adev,
+					const char *name, acpi_object_type type,
+					const union acpi_object **obj)
+{
+	return -ENXIO;
+}
+static inline int acpi_dev_get_property_array(struct acpi_device *adev,
+					      const char *name,
+					      acpi_object_type type,
+					      const union acpi_object **obj)
+{
+	return -ENXIO;
+}
+static inline int acpi_dev_get_property_reference(struct acpi_device *adev,
+				const char *name, const char *cells_name,
+				size_t index, struct acpi_reference_args *args)
+{
+	return -ENXIO;
+}
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 02/16] Driver core: Unified device properties interface for platform firmware
  2014-09-16 11:52 ` Mika Westerberg
  (?)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  2014-09-17 18:28   ` Greg Kroah-Hartman
  -1 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

Add a uniform interface by which device drivers can request device
properties from the platform firmware by providing a property name
and the corresponding data type.  The purpose of it is to help to
write portable code that won't depend on any particular platform
firmware interface.

Three general helper functions, device_get_property(),
device_read_property() and device_read_property_array() are provided.
The first one allows the raw value of a given device property to be
accessed by the driver.  The remaining two allow the value of a numeric
or string property and multiple numeric or string values of one array
property to be acquired, respectively.  Static inline wrappers are also
provided for the various property data types that can be passed to
device_read_property() or device_read_property_array() for extra type
checking.

In addition to that new generic routines are provided for retrieving
properties from device description objects in the platform firmware
in case there are no struct device objects for them (either those
objects have not been created yet or they do not exist at all).
Again, three functions are provided, dev_node_get_property(),
dev_node_read_property(), dev_node_read_property_array(), in analogy
with device_get_property(), device_read_property() and
device_read_property_array() described above, respectively, along
with static inline wrappers for all of the propery data types that
can be used.  For all of them, the first argument is a pointer to
struct fw_dev_node (new type) that in turn contains exactly one
valid pointer to a device description object (depending on what
platform firmware interface is in use).

Finally, device_for_each_child_node() is added for iterating over
the children of the device description object associated with the
given device.

The interface covers both ACPI and Device Trees.

This change set includes material from Mika Westerberg and Aaron Lu.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/property.c  | 186 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/base/Makefile    |   2 +-
 drivers/base/property.c  | 196 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/of/base.c        | 188 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h     |  42 ++++++++++
 include/linux/of.h       |  37 +++++++++
 include/linux/property.h | 193 ++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 843 insertions(+), 1 deletion(-)
 create mode 100644 drivers/base/property.c
 create mode 100644 include/linux/property.h

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index c4a3e800e82c..e50964012da8 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -362,3 +362,189 @@ int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
 	return -EPROTO;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference);
+
+int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
+		      void **valptr)
+{
+	return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY,
+				     (const union acpi_object **)valptr);
+}
+
+int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
+		       enum dev_prop_type proptype, void *val)
+{
+	const union acpi_object *obj;
+	int ret = -EINVAL;
+
+	if (!val)
+		return -EINVAL;
+
+	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
+		ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj);
+		if (ret)
+			return ret;
+
+		switch (proptype) {
+		case DEV_PROP_U8:
+			if (obj->integer.value > U8_MAX)
+				return -EOVERFLOW;
+			*(u8 *)val = obj->integer.value;
+			break;
+		case DEV_PROP_U16:
+			if (obj->integer.value > U16_MAX)
+				return -EOVERFLOW;
+			*(u16 *)val = obj->integer.value;
+			break;
+		case DEV_PROP_U32:
+			if (obj->integer.value > U32_MAX)
+				return -EOVERFLOW;
+			*(u32 *)val = obj->integer.value;
+			break;
+		default:
+			*(u64 *)val = obj->integer.value;
+			break;
+		}
+	} else if (proptype == DEV_PROP_STRING) {
+		ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj);
+		if (ret)
+			return ret;
+
+		*(char **)val = obj->string.pointer;
+	}
+	return ret;
+}
+
+static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
+				       size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_INTEGER)
+			return -EPROTO;
+		if (items[i].integer.value > U8_MAX)
+			return -EOVERFLOW;
+
+		val[i] = items[i].integer.value;
+	}
+	return 0;
+}
+
+static int acpi_copy_property_array_u16(const union acpi_object *items,
+					u16 *val, size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_INTEGER)
+			return -EPROTO;
+		if (items[i].integer.value > U16_MAX)
+			return -EOVERFLOW;
+
+		val[i] = items[i].integer.value;
+	}
+	return 0;
+}
+
+static int acpi_copy_property_array_u32(const union acpi_object *items,
+					u32 *val, size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_INTEGER)
+			return -EPROTO;
+		if (items[i].integer.value > U32_MAX)
+			return -EOVERFLOW;
+
+		val[i] = items[i].integer.value;
+	}
+	return 0;
+}
+
+static int acpi_copy_property_array_u64(const union acpi_object *items,
+					u64 *val, size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_INTEGER)
+			return -EPROTO;
+
+		val[i] = items[i].integer.value;
+	}
+	return 0;
+}
+
+static int acpi_copy_property_array_string(const union acpi_object *items,
+					   char **val, size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_STRING)
+			return -EPROTO;
+
+		val[i] = items[i].string.pointer;
+	}
+	return 0;
+}
+
+int acpi_dev_prop_read_array(struct acpi_device *adev, const char *propname,
+			     enum dev_prop_type proptype, void *val,
+			     size_t nval)
+{
+	const union acpi_object *obj;
+	const union acpi_object *items;
+	int ret;
+
+	ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj);
+	if (ret)
+		return ret;
+
+	if (!val)
+		return obj->package.count;
+
+	if (nval > obj->package.count)
+		nval = obj->package.count;
+
+	items = obj->package.elements;
+	switch (proptype) {
+	case DEV_PROP_U8:
+		ret = acpi_copy_property_array_u8(items, (u8 *)val, nval);
+		break;
+	case DEV_PROP_U16:
+		ret = acpi_copy_property_array_u16(items, (u16 *)val, nval);
+		break;
+	case DEV_PROP_U32:
+		ret = acpi_copy_property_array_u32(items, (u32 *)val, nval);
+		break;
+	case DEV_PROP_U64:
+		ret = acpi_copy_property_array_u64(items, (u64 *)val, nval);
+		break;
+	case DEV_PROP_STRING:
+		ret = acpi_copy_property_array_string(items, (char **)val, nval);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+int acpi_for_each_child_node(struct acpi_device *adev,
+			      int (*fn)(struct fw_dev_node *fdn, void *data),
+			      void *data)
+{
+	struct acpi_device *child;
+	int ret = 0;
+
+	list_for_each_entry(child, &adev->children, node) {
+		struct fw_dev_node fdn = { .acpi_node = child, };
+
+		ret = fn(&fdn, data);
+		if (ret)
+			break;
+	}
+	return ret;
+}
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 4aab26ec0292..0d801cfb7390 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -4,7 +4,7 @@ obj-y			:= component.o core.o bus.o dd.o syscore.o \
 			   driver.o class.o platform.o \
 			   cpu.o firmware.o init.o map.o devres.o \
 			   attribute_container.o transport_class.o \
-			   topology.o container.o
+			   topology.o container.o property.o
 obj-$(CONFIG_DEVTMPFS)	+= devtmpfs.o
 obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
 obj-y			+= power/
diff --git a/drivers/base/property.c b/drivers/base/property.c
new file mode 100644
index 000000000000..8348176e5498
--- /dev/null
+++ b/drivers/base/property.c
@@ -0,0 +1,196 @@
+/*
+ * property.c - Unified device property interface.
+ *
+ * Copyright (C) 2014, Intel Corporation
+ * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *          Mika Westerberg <mika.westerberg@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/property.h>
+#include <linux/export.h>
+#include <linux/acpi.h>
+#include <linux/of.h>
+
+/**
+ * dev_node_get_property - return a raw property from device description
+ * @fdn: Device node to get the property from
+ * @propname: Name of the property
+ * @valptr: The raw property value is stored here
+ *
+ * Function reads property @propname from the device firmware description and
+ * stores the raw value into @valptr if found.  Otherwise returns a negative
+ * errno as specified below.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not exist.
+ */
+int dev_node_get_property(struct fw_dev_node *fdn, const char *propname,
+			  void **valptr)
+{
+	if (IS_ENABLED(CONFIG_OF) && fdn->of_node)
+		return of_dev_prop_get(fdn->of_node, propname, valptr);
+	else if (IS_ENABLED(CONFIG_ACPI) && fdn->acpi_node)
+		return acpi_dev_prop_get(fdn->acpi_node, propname, valptr);
+
+	return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(dev_node_get_property);
+
+/**
+ * device_get_property - return a raw property of a device
+ * @dev: Device get the property of
+ * @propname: Name of the property
+ * @valptr: The raw property value is stored here
+ */
+int device_get_property(struct device *dev, const char *propname, void **valptr)
+{
+	struct fw_dev_node fdn = {
+		.of_node = dev->of_node,
+		.acpi_node = ACPI_COMPANION(dev),
+	};
+	return dev_node_get_property(&fdn, propname, valptr);
+}
+EXPORT_SYMBOL_GPL(device_get_property);
+
+/**
+ * dev_node_read_property - return a typed property from device description
+ * @fdn: Device node to get the property from
+ * @propname: Name of the property
+ * @proptype: Type of the property
+ * @val: The value is stored here
+ *
+ * Function reads property @propname from the device firmware description and
+ * stores the value into @val if found. The value is checked to be of type
+ * @proptype.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not exist,
+ *	   %-EPROTO if the property type does not match @proptype,
+ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
+ */
+int dev_node_read_property(struct fw_dev_node *fdn, const char *propname,
+			   enum dev_prop_type proptype, void *val)
+{
+	if (IS_ENABLED(CONFIG_OF) && fdn->of_node)
+		return of_dev_prop_read(fdn->of_node, propname, proptype, val);
+	else if (IS_ENABLED(CONFIG_ACPI) && fdn->acpi_node)
+		return acpi_dev_prop_read(fdn->acpi_node, propname, proptype, val);
+
+	return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(dev_node_read_property);
+
+/**
+ * device_read_property - return a typed property of a device
+ * @dev: Device to get the property of
+ * @propname: Name of the property
+ * @proptype: Type of the property
+ * @val: The value is stored here
+ */
+int device_read_property(struct device *dev, const char *propname,
+			 enum dev_prop_type proptype, void *val)
+{
+	struct fw_dev_node fdn = {
+		.of_node = dev->of_node,
+		.acpi_node = ACPI_COMPANION(dev),
+	};
+	return dev_node_read_property(&fdn, propname, proptype, val);
+}
+EXPORT_SYMBOL_GPL(device_read_property);
+
+/**
+ * dev_node_read_property_array - return an array property from a device
+ * @fdn: Device node to get the property from
+ * @propname: Name of the property
+ * @proptype: Type of the property
+ * @val: The values are stored here
+ * @nval: Size of the @val array
+ *
+ * Function reads an array of properties with @propname from the device
+ * firmware description and stores them to @val if found. All the values
+ * in the array must be of type @proptype.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not exist,
+ *	   %-EPROTO if the property type does not match @proptype,
+ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
+ */
+int dev_node_read_property_array(struct fw_dev_node *fdn, const char *propname,
+				 enum dev_prop_type proptype, void *val,
+				 size_t nval)
+{
+	if (IS_ENABLED(CONFIG_OF) && fdn->of_node)
+		return of_dev_prop_read_array(fdn->of_node, propname, proptype,
+					      val, nval);
+	else if (IS_ENABLED(CONFIG_ACPI) && fdn->acpi_node)
+		return acpi_dev_prop_read_array(fdn->acpi_node, propname,
+						proptype, val, nval);
+
+	return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(dev_node_read_property_array);
+
+/**
+ * device_read_property_array - return an array property of a device
+ * @dev: Device to get the property of
+ * @propname: Name of the property
+ * @proptype: Type of the property
+ * @val: The values are stored here
+ * @nval: Size of the @val array
+ */
+int device_read_property_array(struct device *dev, const char *propname,
+			       enum dev_prop_type proptype, void *val,
+			       size_t nval)
+{
+	struct fw_dev_node fdn = {
+		.of_node = dev->of_node,
+		.acpi_node = ACPI_COMPANION(dev),
+	};
+	return dev_node_read_property_array(&fdn, propname, proptype, val, nval);
+}
+EXPORT_SYMBOL_GPL(device_read_property_array);
+
+/**
+ * device_for_each_child_node - execute function for each child node of device
+ * @dev: Device to run the function for
+ * @fn: Function to run
+ * @data: Additional data to pass to the function
+ */
+int device_for_each_child_node(struct device *dev,
+			       int (*fn)(struct fw_dev_node *fdn, void *data),
+			       void *data)
+{
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+		return of_for_each_child_node(dev->of_node, fn, data);
+	else if (ACPI_COMPANION(dev))
+		return acpi_for_each_child_node(ACPI_COMPANION(dev), fn, data);
+
+	return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(device_for_each_child_node);
+
+static int dev_node_count(struct fw_dev_node *fdn, void *data)
+{
+	*((int *)data) += 1;
+	return 0;
+}
+
+/**
+ * device_get_child_node_count - return number of child nodes for this device
+ * @dev: Device to get the child node count from
+ */
+int device_get_child_node_count(struct device *dev)
+{
+	int count = 0;
+
+	device_for_each_child_node(dev, dev_node_count, &count);
+	return count;
+}
+EXPORT_SYMBOL_GPL(device_get_child_node_count);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d8574adf0d62..84d436aeac51 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1241,6 +1241,39 @@ int of_property_read_u64(const struct device_node *np, const char *propname,
 EXPORT_SYMBOL_GPL(of_property_read_u64);
 
 /**
+ * of_property_read_u64_array - Find and read an array of 64 bit integers
+ * from a property.
+ *
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @out_values:	pointer to return value, modified only if return value is 0.
+ * @sz:		number of array elements to read
+ *
+ * Search for a property in a device node and read 64-bit value(s) from
+ * it. Returns 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+ * The out_values is modified only if a valid u64 value can be decoded.
+ */
+int of_property_read_u64_array(const struct device_node *np,
+			       const char *propname, u64 *out_values,
+			       size_t sz)
+{
+	const __be32 *val = of_find_property_value_of_size(np, propname,
+						(sz * sizeof(*out_values)));
+
+	if (IS_ERR(val))
+		return PTR_ERR(val);
+
+	while (sz--) {
+		*out_values++ = of_read_number(val, 2);
+		val += 2;
+	};
+	return 0;
+}
+
+/**
  * of_property_read_string - Find and read a string from a property
  * @np:		device node from which the property value is to be read.
  * @propname:	name of the property to be searched.
@@ -1388,6 +1421,49 @@ int of_property_count_strings(struct device_node *np, const char *propname)
 }
 EXPORT_SYMBOL_GPL(of_property_count_strings);
 
+/**
+ * of_property_read_string_array - Find and read an array of strings
+ * from a multiple strings property.
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @out_string:	pointer to null terminated return string, modified only if
+ *		return value is 0.
+ * @sz:		number of array elements to read
+ *
+ * Search for a property in a device tree node and retrieve a list of
+ * terminated string value (pointer to data, not a copy) in that property.
+ * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
+ * property does not have a value, and -EOVERFLOW if the string is not
+ * null-terminated within the length of the property data.
+ *
+ * The out_string pointer is modified only if a valid string can be decoded.
+ */
+int of_property_read_string_array(struct device_node *np, const char *propname,
+				  char **output, size_t sz)
+{
+	struct property *prop = of_find_property(np, propname, NULL);
+	int i = 0;
+	size_t l = 0, total = 0;
+	char *p;
+
+	if (!prop)
+		return -EINVAL;
+
+	if (!prop->value)
+		return -ENODATA;
+
+	if (strnlen(prop->value, prop->length) >= prop->length)
+		return -EOVERFLOW;
+
+	p = prop->value;
+
+	for (i = 0; total < prop->length; total += l, p += l) {
+		output[i++] = p;
+		l = strlen(p) + 1;
+	}
+	return 0;
+}
+
 void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
 {
 	int i;
@@ -2171,3 +2247,115 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
 	return of_get_next_parent(np);
 }
 EXPORT_SYMBOL(of_graph_get_remote_port);
+
+int of_dev_prop_get(struct device_node *dn, const char *propname, void **valptr)
+{
+	struct property *pp = of_find_property(dn, propname, NULL);
+
+	if (!pp)
+		return -ENODATA;
+
+	if (valptr)
+		*valptr = pp->value;
+	return 0;
+}
+
+int of_dev_prop_read(struct device_node *dn, const char *propname,
+		     enum dev_prop_type proptype, void *val)
+{
+	void *value;
+	int ret = of_dev_prop_get(dn, propname, &value);
+
+	if (ret)
+		return ret;
+
+	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
+		switch (proptype) {
+		case DEV_PROP_U8: {
+			*(u8 *)val = *(u8 *)value;
+			break;
+		}
+		case DEV_PROP_U16:
+			*(u16 *)val = *(u16 *)value;
+			break;
+		case DEV_PROP_U32:
+			*(u32 *)val = *(u32 *)value;
+			break;
+		default:
+			*(u64 *)val = *(u64 *)value;
+			break;
+		}
+	} else if (proptype == DEV_PROP_STRING) {
+		*(char **)val = value;
+	}
+	return ret;
+
+}
+
+int of_dev_prop_read_array(struct device_node *dn, const char *propname,
+			   enum dev_prop_type proptype, void *val, size_t nval)
+{
+	int ret, elem_size;
+
+	if (!val) {
+		switch (proptype) {
+		case DEV_PROP_U8:
+			elem_size = sizeof(u8);
+			break;
+		case DEV_PROP_U16:
+			elem_size = sizeof(u16);
+			break;
+		case DEV_PROP_U32:
+			elem_size = sizeof(u32);
+			break;
+		case DEV_PROP_U64:
+			elem_size = sizeof(u64);
+			break;
+		case DEV_PROP_STRING:
+			return of_property_count_strings(dn, propname);
+		default:
+			return -EINVAL;
+		}
+		return of_property_count_elems_of_size(dn, propname, elem_size);
+	}
+
+	switch (proptype) {
+	case DEV_PROP_U8:
+		ret = of_property_read_u8_array(dn, propname, (u8 *)val, nval);
+		break;
+	case DEV_PROP_U16:
+		ret = of_property_read_u16_array(dn, propname, (u16 *)val, nval);
+		break;
+	case DEV_PROP_U32:
+		ret = of_property_read_u32_array(dn, propname, (u32 *)val, nval);
+		break;
+	case DEV_PROP_U64:
+		ret = of_property_read_u64_array(dn, propname, (u64 *)val, nval);
+		break;
+	case DEV_PROP_STRING:
+		ret = of_property_read_string_array(dn, propname,
+						    (char **)val, nval);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+int of_for_each_child_node(struct device_node *dn,
+			    int (*fn)(struct fw_dev_node *fdn, void *data),
+			    void *data)
+{
+	struct device_node *child;
+	int ret = 0;
+
+	for_each_child_of_node(dn, child) {
+		struct fw_dev_node fdn = { .of_node = child, };
+
+		ret = fn(&fdn, data);
+		if (ret)
+			break;
+	}
+	return ret;
+}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 104321d994f5..288abbdf2fb4 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -28,6 +28,7 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>	/* for struct resource */
 #include <linux/device.h>
+#include <linux/property.h>
 
 #ifndef _LINUX
 #define _LINUX
@@ -678,6 +679,17 @@ int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
 int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
 				    const char *cells_name, size_t index,
 				    struct acpi_reference_args *args);
+
+int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
+		      void **valptr);
+int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
+		       enum dev_prop_type proptype, void *val);
+int acpi_dev_prop_read_array(struct acpi_device *adev, const char *propname,
+			     enum dev_prop_type proptype, void *val,
+			     size_t nval);
+int acpi_for_each_child_node(struct acpi_device *adev,
+			      int (*fn)(struct fw_dev_node *fdn, void *data),
+			      void *data);
 #else
 static inline int acpi_dev_get_property(struct acpi_device *adev,
 					const char *name, acpi_object_type type,
@@ -698,6 +710,36 @@ static inline int acpi_dev_get_property_reference(struct acpi_device *adev,
 {
 	return -ENXIO;
 }
+
+static inline int acpi_dev_prop_get(struct acpi_device *adev,
+				    const char *propname,
+				    void **valptr)
+{
+	return -ENXIO;
+}
+
+static inline int acpi_dev_prop_read(struct acpi_device *adev,
+				     const char *propname,
+				     enum dev_prop_type proptype, void *val)
+{
+	return -ENXIO;
+}
+
+static inline int acpi_dev_prop_read_array(struct acpi_device *adev,
+					   const char *propname,
+					   enum dev_prop_type proptype,
+					   void *val, size_t nval)
+{
+	return -ENXIO;
+}
+
+static inline int acpi_for_each_child_node(struct acpi_device *adev,
+				int (*fn)(struct fw_dev_node *fdn, void *data),
+				void *data)
+{
+	return -ENXIO;
+}
+
 #endif
 
 #endif	/*_LINUX_ACPI_H*/
diff --git a/include/linux/of.h b/include/linux/of.h
index 6c4363b8ddc3..8121cc920bb4 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/topology.h>
 #include <linux/notifier.h>
+#include <linux/property.h>
 
 #include <asm/byteorder.h>
 #include <asm/errno.h>
@@ -355,6 +356,15 @@ const char *of_prop_next_string(struct property *prop, const char *cur);
 
 bool of_console_check(struct device_node *dn, char *name, int index);
 
+int of_dev_prop_get(struct device_node *dn, const char *propname, void **valptr);
+int of_dev_prop_read(struct device_node *dn, const char *propname,
+		     enum dev_prop_type proptype, void *val);
+int of_dev_prop_read_array(struct device_node *dn, const char *propname,
+			   enum dev_prop_type proptype, void *val, size_t nval);
+int of_for_each_child_node(struct device_node *dn,
+			    int (*fn)(struct fw_dev_node *fdn, void *data),
+			    void *data);
+
 #else /* CONFIG_OF */
 
 static inline const char* of_node_full_name(const struct device_node *np)
@@ -582,6 +592,33 @@ static inline const char *of_prop_next_string(struct property *prop,
 	return NULL;
 }
 
+static inline int of_dev_prop_get(struct device_node *dn, const char *propname,
+				 void **valptr)
+{
+	return -ENXIO;
+}
+
+static inline int of_dev_prop_read(struct device_node *dn, const char *propname,
+				   enum dev_prop_type proptype, void *val)
+{
+	return -ENXIO;
+}
+
+static inline int of_dev_prop_read_array(struct device_node *dn,
+					 const char *propname,
+					 enum dev_prop_type proptype,
+					 void *val, size_t nval)
+{
+	return -ENXIO;
+}
+
+static inline int of_for_each_child_node(struct device_node *dn,
+				int (*fn)(struct fw_dev_node *fdn, void *data),
+				void *data)
+{
+	return -ENXIO;
+}
+
 #define of_match_ptr(_ptr)	NULL
 #define of_match_node(_matches, _node)	NULL
 #endif /* CONFIG_OF */
diff --git a/include/linux/property.h b/include/linux/property.h
new file mode 100644
index 000000000000..6a9f76007ca9
--- /dev/null
+++ b/include/linux/property.h
@@ -0,0 +1,193 @@
+/*
+ * property.h - Unified device property interface.
+ *
+ * Copyright (C) 2014, Intel Corporation
+ * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *          Mika Westerberg <mika.westerberg@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_PROPERTY_H_
+#define _LINUX_PROPERTY_H_
+
+#include <linux/device.h>
+
+enum dev_prop_type {
+	DEV_PROP_U8,
+	DEV_PROP_U16,
+	DEV_PROP_U32,
+	DEV_PROP_U64,
+	DEV_PROP_STRING,
+	DEV_PROP_MAX,
+};
+
+struct fw_dev_node {
+	struct device_node *of_node;
+	struct acpi_device *acpi_node;
+};
+
+int dev_node_get_property(struct fw_dev_node *fdn, const char *propname,
+			  void **valptr);
+int dev_node_read_property(struct fw_dev_node *fdn, const char *propname,
+			   enum dev_prop_type proptype, void *val);
+int dev_node_read_property_array(struct fw_dev_node *fdn, const char *propname,
+				 enum dev_prop_type proptype, void *val,
+				 size_t nval);
+int device_get_property(struct device *dev, const char *propname,
+			void **valptr);
+int device_read_property(struct device *dev, const char *propname,
+			 enum dev_prop_type proptype, void *val);
+int device_read_property_array(struct device *dev, const char *propname,
+			       enum dev_prop_type proptype, void *val,
+			       size_t nval);
+int device_for_each_child_node(struct device *dev,
+			       int (*fn)(struct fw_dev_node *fdn, void *data),
+			       void *data);
+int device_get_child_node_count(struct device *dev);
+
+static inline int dev_node_property_read_u8(struct fw_dev_node *fdn,
+					    const char *propname, u8 *out_value)
+{
+	return dev_node_read_property(fdn, propname, DEV_PROP_U8, out_value);
+}
+
+static inline int dev_node_property_read_u16(struct fw_dev_node *fdn,
+					     const char *propname,
+					     u16 *out_value)
+{
+	return dev_node_read_property(fdn, propname, DEV_PROP_U16, out_value);
+}
+
+static inline int dev_node_property_read_u32(struct fw_dev_node *fdn,
+					     const char *propname,
+					     u32 *out_value)
+{
+	return dev_node_read_property(fdn, propname, DEV_PROP_U32, out_value);
+}
+
+static inline int dev_node_property_read_u64(struct fw_dev_node *fdn,
+					     const char *propname,
+					     u64 *out_value)
+{
+	return dev_node_read_property(fdn, propname, DEV_PROP_U64, out_value);
+}
+
+static inline int dev_node_property_read_u8_array(struct fw_dev_node *fdn,
+						  const char *propname,
+						  u8 *val, size_t nval)
+{
+	return dev_node_read_property_array(fdn, propname, DEV_PROP_U8, val, nval);
+}
+
+static inline int dev_node_property_read_u16_array(struct fw_dev_node *fdn,
+						   const char *propname,
+						   u16 *val, size_t nval)
+{
+	return dev_node_read_property_array(fdn, propname, DEV_PROP_U16, val, nval);
+}
+
+static inline int dev_node_property_read_u32_array(struct fw_dev_node *fdn,
+						   const char *propname,
+						   u32 *val, size_t nval)
+{
+	return dev_node_read_property_array(fdn, propname, DEV_PROP_U32, val, nval);
+}
+
+static inline int dev_node_property_read_u64_array(struct fw_dev_node *fdn,
+						   const char *propname,
+						   u64 *val, size_t nval)
+{
+	return dev_node_read_property_array(fdn, propname, DEV_PROP_U64, val, nval);
+}
+
+static inline int dev_node_property_read_string(struct fw_dev_node *fdn,
+						const char *propname,
+						const char **out_string)
+{
+	return dev_node_read_property(fdn, propname, DEV_PROP_STRING, out_string);
+}
+
+static inline int dev_node_property_read_string_array(struct fw_dev_node *fdn,
+						      const char *propname,
+						      const char **out_strings,
+						      size_t nstrings)
+{
+	return dev_node_read_property_array(fdn, propname, DEV_PROP_STRING,
+					    out_strings, nstrings);
+}
+
+static inline int device_property_read_u8(struct device *dev,
+					  const char *propname, u8 *out_value)
+{
+	return device_read_property(dev, propname, DEV_PROP_U8, out_value);
+}
+
+static inline int device_property_read_u16(struct device *dev,
+					  const char *propname, u16 *out_value)
+{
+	return device_read_property(dev, propname, DEV_PROP_U16, out_value);
+}
+
+static inline int device_property_read_u32(struct device *dev,
+					  const char *propname, u32 *out_value)
+{
+	return device_read_property(dev, propname, DEV_PROP_U32, out_value);
+}
+
+static inline int device_property_read_u64(struct device *dev,
+					  const char *propname, u64 *out_value)
+{
+	return device_read_property(dev, propname, DEV_PROP_U64, out_value);
+}
+
+static inline int device_property_read_u8_array(struct device *dev,
+						const char *propname,
+						u8 *val, size_t nval)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_U8, val,
+					  nval);
+}
+
+static inline int device_property_read_u16_array(struct device *dev,
+						 const char *propname,
+						 u16 *val, size_t nval)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_U16, val,
+					  nval);
+}
+
+static inline int device_property_read_u32_array(struct device *dev,
+						 const char *propname,
+						 u32 *val, size_t nval)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_U32, val,
+					  nval);
+}
+
+static inline int device_property_read_u64_array(struct device *dev,
+						 const char *propname,
+						 u64 *val, size_t nval)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_U64, val,
+					  nval);
+}
+
+static inline int device_property_read_string(struct device *dev,
+					      const char *propname,
+					      const char **out_string)
+{
+	return device_read_property(dev, propname, DEV_PROP_STRING, out_string);
+}
+
+static inline int device_property_read_string_array(struct device *dev,
+						    const char *propname,
+						    const char **out_strings,
+						    size_t nstrings)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_STRING,
+					  out_strings, nstrings);
+}
+#endif /* _LINUX_PROPERTY_H_ */
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 03/16] ACPI: Allow drivers to match using Device Tree compatible property
  2014-09-16 11:52 ` Mika Westerberg
                   ` (2 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

We have lots of existing Device Tree enabled drivers and allocating
separate _HID for each is not feasible. Instead we allocate special _HID
"PRP0001" that means that the match should be done using Device Tree
compatible property using driver's .of_match_table instead.

If there is a need to distinguish from where the device is enumerated
(DT/ACPI) driver can check dev->of_node or ACPI_COMPATION(dev).

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/acpi/property.c | 34 ++++++++++++++++++
 drivers/acpi/scan.c     | 91 +++++++++++++++++++++++++++++++++++++++++++------
 include/acpi/acpi_bus.h |  1 +
 include/linux/acpi.h    |  8 ++---
 4 files changed, 118 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index e50964012da8..c6c3ab6f68c3 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -76,6 +76,37 @@ static bool acpi_properties_format_valid(const union acpi_object *properties)
 	return true;
 }
 
+static void acpi_init_of_compatible(struct acpi_device *adev)
+{
+	const union acpi_object *of_compatible;
+	struct acpi_hardware_id *hwid;
+	bool acpi_of = false;
+
+	/*
+	 * Check if the special PRP0001 ACPI ID is present and in that
+	 * case we fill in Device Tree compatible properties for this
+	 * device.
+	 */
+	list_for_each_entry(hwid, &adev->pnp.ids, list) {
+		if (!strcmp(hwid->id, "PRP0001")) {
+			acpi_of = true;
+			break;
+		}
+	}
+
+	if (!acpi_of)
+		return;
+
+	if (acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
+					&of_compatible)) {
+		acpi_handle_warn(adev->handle,
+				 "PRP0001 requires compatible property\n");
+		return;
+	}
+
+	adev->data.of_compatible = of_compatible;
+}
+
 void acpi_init_properties(struct acpi_device *adev)
 {
 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
@@ -119,6 +150,8 @@ void acpi_init_properties(struct acpi_device *adev)
 
 		adev->data.pointer = buf.pointer;
 		adev->data.properties = properties;
+
+		acpi_init_of_compatible(adev);
 		return;
 	}
 
@@ -130,6 +163,7 @@ void acpi_init_properties(struct acpi_device *adev)
 void acpi_free_properties(struct acpi_device *adev)
 {
 	ACPI_FREE((void *)adev->data.pointer);
+	adev->data.of_compatible = NULL;
 	adev->data.pointer = NULL;
 	adev->data.properties = NULL;
 }
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index f4aabf9c0aad..0c8e751cbe6b 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -124,17 +124,43 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
 	if (list_empty(&acpi_dev->pnp.ids))
 		return 0;
 
-	len = snprintf(modalias, size, "acpi:");
-	size -= len;
+	/*
+	 * If the device has PRP0001 we expose DT compatible modalias
+	 * instead.
+	 */
+	if (acpi_dev->data.of_compatible) {
+		const union acpi_object *of_compatible, *obj;
+		int i;
+
+		len = snprintf(modalias, size, "of:Nprp0001Tacpi");
+
+		of_compatible = acpi_dev->data.of_compatible;
+		for (i = 0; i < of_compatible->package.count; i++) {
+			obj = &of_compatible->package.elements[i];
 
-	list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
-		count = snprintf(&modalias[len], size, "%s:", id->id);
-		if (count < 0)
-			return -EINVAL;
-		if (count >= size)
-			return -ENOMEM;
-		len += count;
-		size -= count;
+			count = snprintf(&modalias[len], size, "C%s",
+					 obj->string.pointer);
+			if (count < 0)
+				return -EINVAL;
+			if (count >= size)
+				return -ENOMEM;
+
+			len += count;
+			size -= count;
+		}
+	} else {
+		len = snprintf(modalias, size, "acpi:");
+		size -= len;
+
+		list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
+			count = snprintf(&modalias[len], size, "%s:", id->id);
+			if (count < 0)
+				return -EINVAL;
+			if (count >= size)
+				return -ENOMEM;
+			len += count;
+			size -= count;
+		}
 	}
 
 	modalias[len] = '\0';
@@ -864,6 +890,51 @@ int acpi_match_device_ids(struct acpi_device *device,
 }
 EXPORT_SYMBOL(acpi_match_device_ids);
 
+/* Performs match for special "PRP0001" shoehorn ACPI ID */
+static bool acpi_of_driver_match_device(struct device *dev,
+					const struct device_driver *drv)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	const union acpi_object *of_compatible;
+	int i;
+
+	/*
+	 * If the ACPI device does not have corresponding compatible
+	 * property or the driver in question does not have DT matching
+	 * table we consider the match succesful (matches the ACPI ID).
+	 */
+	of_compatible = adev->data.of_compatible;
+	if (!drv->of_match_table || !of_compatible)
+		return true;
+
+	/* Now we can look for the driver DT compatible strings */
+	for (i = 0; i < of_compatible->package.count; i++) {
+		const struct of_device_id *id;
+		const union acpi_object *obj;
+
+		obj = &of_compatible->package.elements[i];
+
+		for (id = drv->of_match_table; id->compatible[0]; id++)
+			if (!strcasecmp(obj->string.pointer, id->compatible))
+				return true;
+	}
+
+	return false;
+}
+
+bool acpi_driver_match_device(struct device *dev,
+			      const struct device_driver *drv)
+{
+	const struct acpi_device_id *id;
+
+	id = acpi_match_device(drv->acpi_match_table, dev);
+	if (!id)
+		return false;
+
+	return acpi_of_driver_match_device(dev, drv);
+}
+EXPORT_SYMBOL_GPL(acpi_driver_match_device);
+
 static void acpi_free_power_resources_lists(struct acpi_device *device)
 {
 	int i;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 620b4f89c87b..65866e23e3e9 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -341,6 +341,7 @@ struct acpi_device_physical_node {
 struct acpi_device_data {
 	const union acpi_object *pointer;
 	const union acpi_object *properties;
+	const union acpi_object *of_compatible;
 };
 
 /* Device */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288abbdf2fb4..37a5280a64a5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -424,12 +424,8 @@ extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
 const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
 					       const struct device *dev);
 
-static inline bool acpi_driver_match_device(struct device *dev,
-					    const struct device_driver *drv)
-{
-	return !!acpi_match_device(drv->acpi_match_table, dev);
-}
-
+extern bool acpi_driver_match_device(struct device *dev,
+				     const struct device_driver *drv);
 int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
 int acpi_device_modalias(struct device *, char *, int);
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 04/16] ACPI: Document ACPI device specific properties
  2014-09-16 11:52 ` Mika Westerberg
                   ` (3 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

This document describes the data format and interfaces of ACPI device
specific properties.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
 Documentation/acpi/properties.txt | 410 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 410 insertions(+)
 create mode 100644 Documentation/acpi/properties.txt

diff --git a/Documentation/acpi/properties.txt b/Documentation/acpi/properties.txt
new file mode 100644
index 000000000000..43404523e282
--- /dev/null
+++ b/Documentation/acpi/properties.txt
@@ -0,0 +1,410 @@
+ACPI device properties
+======================
+This document describes the format and interfaces of ACPI device
+properties as specified in "Device Properties UUID For _DSD" available
+here:
+
+http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
+
+1. Introduction
+---------------
+In systems that use ACPI and want to take advantage of device specific
+properties, there needs to be a standard way to return and extract
+name-value pairs for a given ACPI device.
+
+An ACPI device that wants to export its properties must implement a
+static name called _DSD that takes no arguments and returns a package of
+packages:
+
+	Name (_DSD, Package () {
+		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+		Package () {
+			Package () {"name1", <VALUE1>},
+			Package () {"name2", <VALUE2>}
+		}
+	})
+
+The UUID identifies contents of the following package. In case of ACPI
+device properties it is daffd814-6eba-4d8c-8a91-bc9bbf4aa301.
+
+In each returned package, the first item is the name and must be a string.
+The corresponding value can be a string, integer, reference, or package. If
+a package it may only contain strings, integers, and references.
+
+An example device where we might need properties is a device that uses
+GPIOs. In addition to the GpioIo/GpioInt resources the driver needs to
+know which GPIO is used for which purpose.
+
+To solve this we add the following ACPI device properties to the device:
+
+	Device (DEV0)
+	{
+		Name (_CRS, ResourceTemplate () {
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
+			...
+		})
+
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {"reset-gpio", {^DEV0, 0, 0, 0}},
+				Package () {"shutdown-gpio", {^DEV0, 1, 0, 0}},
+			}
+		})
+	}
+
+Now the device driver can reference the GPIOs using names instead of
+using indexes.
+
+If there is an existing Device Tree binding for a device, it is expected
+that the same bindings are used with ACPI properties, so that the driver
+dealing with the device needs only minor modifications if any.
+
+2. Formal definition of properties
+----------------------------------
+The following chapters define the currently supported properties. For
+these there exists a helper function that can be used to extract the
+property value.
+
+2.1 Integer types
+-----------------
+ACPI integers are always 64-bit. However, for drivers the full range is
+typically not needed so we provide a set of functions which convert the
+64-bit integer to a smaller Linux integer type.
+
+An integer property looks like this:
+
+	Package () {"i2c-sda-hold-time-ns", 300},
+	Package () {"clock-frequency", 400000},
+
+To read a property value, use a unified property accessor as shown
+below:
+
+	u32 val;
+	int ret;
+
+	ret = device_property_read_u32(dev, "clock-frequency", &val);
+	if (ret)
+		/* Handle error */
+
+The function returns 0 if the property is copied to 'val' or negative
+errno if something went wrong (or the property does not exist).
+
+2.2 Integer arrays
+------------------
+An integer array is a package holding only integers. Arrays can be used to
+represent different things like Linux input key codes to GPIO mappings, pin
+control settings, dma request lines, etc.
+
+An integer array looks like this:
+
+	Package () {
+		"max8952,dvs-mode-microvolt",
+		Package () {
+			1250000,
+			1200000,
+			1050000,
+			950000,
+		}
+	}
+
+The above array property can be accessed like:
+
+	u32 voltages[4];
+	int ret;
+
+	ret = device_property_read_u32_array(dev, "max8952,dvs-mode-microvolt",
+					     voltages, ARRAY_SIZE(voltages));
+	if (ret)
+		/* Handle error */
+
+
+All functions copy the resulting values cast to a requested type to the
+caller supplied array. If you pass NULL in the value pointer ('voltages' in
+this case), the function returns number of items in the array. This can be
+useful if caller does not know size of the array beforehand.
+
+2.3 Strings
+-----------
+String properties can be used to describe many things like labels for GPIO
+buttons, compability ids, etc.
+
+A string property looks like this:
+
+	Package () {"pwm-names", "backlight"},
+	Package () {"label", "Status-LED"},
+
+You can use device_property_read_string() to extract strings:
+
+	const char *val;
+	int ret;
+
+	ret = device_property_read_string(dev, "label", &val);
+	if (ret)
+		/* Handle error */
+
+Note that the function does not copy the returned string but instead the
+value is modified to point to the string property itself.
+
+The memory is owned by the associated ACPI device object and released
+when it is removed. The user need not free the associated memory.
+
+2.4 String arrays
+-----------------
+String arrays can be useful in describing a list of labels, names for
+DMA channels, etc.
+
+A string array property looks like this:
+
+	Package () {"dma-names", Package () {"tx", "rx", "rx-tx"}},
+	Package () {"clock-output-names", Package () {"pll", "pll-switched"}},
+
+And these can be read in similar way that the integer arrrays:
+
+	const char *dma_names[3];
+	int ret;
+
+	ret = device_property_read_string_array(dev, "dma-names", dma_names,
+						ARRAY_SIZE(dma_names));
+	if (ret)
+		/* Handle error */
+
+The memory management rules follow what is specified for single strings.
+Specifically the returned pointers should be treated as constant and not to
+be freed. That is done automatically when the correspondig ACPI device
+object is released.
+
+2.5 Object references
+---------------------
+An ACPI object reference is used to refer to some object in the
+namespace. For example, if a device has dependencies with some other
+object, an object reference can be used.
+
+An object reference looks like this:
+
+	Package () {"dev0", \_SB.DEV0},
+
+At the time of writing this, there is no unified device_property_* accessor
+for references so one needs to use the following ACPI helper function:
+
+	int acpi_dev_get_property_reference(struct acpi_device *adev,
+					    const char *name,
+					    const char *size_prop, int index,
+					    struct acpi_reference_args *args);
+
+The referenced ACPI device is returned in args->adev if found.
+
+In addition to simple object references it is also possible to have object
+references with arguments. These are represented in ASL as follows:
+
+	Device (\_SB.PCI0.PWM)
+	{
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {"#pwm-cells", 2}
+			}
+		})
+	}
+
+	Device (\_SB.PCI0.BL)
+	{
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {
+					"pwms",
+					Package () {
+						\_SB.PCI0.PWM, 0, 5000000,
+						\_SB.PCI0.PWM, 1, 4500000,
+					}
+				}
+			}
+		})
+	}
+
+In the above example, the referenced device declares a property that
+returns the number of expected arguments (here it is "#pwm-cells"). If
+no such property is given we assume that all the integers following the
+reference are arguments.
+
+In the above example PWM device expects 2 additional arguments. This
+will be validated by the ACPI property core.
+
+The additional arguments must be integers. Nothing else is supported.
+
+It is possible, as in the above example, to have multiple references
+with varying number of integer arguments. It is up to the referenced
+device to declare how many arguments it expects. The 'index' parameter
+selects which reference is returned.
+
+One can use acpi_dev_get_property_reference() as well to extract the
+information in additional parameters:
+
+	struct acpi_reference_args args;
+	struct acpi_device *adev = /* this will point to the BL device */
+	int ret;
+
+	/* extract the first reference */
+	acpi_dev_get_property_reference(adev, "pwms", "#pwm-cells", 0, &args);
+
+	BUG_ON(args.nargs != 2);
+	BUG_ON(args.args[0] != 0);
+	BUG_ON(args.args[1] != 5000000);
+
+	/* extract the second reference */
+	acpi_dev_get_property_reference(adev, "pwms", "#pwm-cells", 1, &args);
+
+	BUG_ON(args.nargs != 2);
+	BUG_ON(args.args[0] != 1);
+	BUG_ON(args.args[1] != 4500000);
+
+In addition to arguments, args.adev now points to the ACPI device that
+corresponds to \_SB.PCI0.PWM.
+
+It is intended that this function is not used directly but instead
+subsystems like pwm implement their ACPI support on top of this function
+in such way that it is hidden from the client drivers, such as via
+pwm_get().
+
+3. Device property hierarchies
+------------------------------
+Devices are organized in a tree within the Linux kernel. It follows that
+the configuration data would also be hierarchical. In order to reach
+equivalence with Device Tree, the ACPI mechanism must also provide some
+sort of tree-like representation. Fortunately, the ACPI namespace is
+already such a structure.
+
+For example, we could have the following device in ACPI namespace. The
+KEYS device is much like gpio_keys_polled.c in that it includes "pseudo"
+devices for each GPIO:
+
+	Device (KEYS)
+	{
+		Name (_CRS, ResourceTemplate () {
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
+			...
+		})
+
+		// "pseudo" devices declared under the parent device
+		Device (BTN0) {
+			Name (_DSD, Package () {
+				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+				Package () {
+					Package () {"label", "minnow_btn0"}
+					Package () {"gpios", Package () {^KEYS, 0, 0, 1}}
+				}
+			})
+		}
+
+		Device (BTN1) {
+			Name (_DSD, Package () {
+				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+				Package () {
+					Package () {"label", "minnow_btn1"}
+					Package () {"gpios", Package () {^KEYS, 1, 0, 1}}
+				}
+			})
+		}
+	}
+
+We can extract the above in gpio_keys_polled.c like:
+
+	static int gpio_keys_polled_create_button(struct fw_dev_node *fdn,
+						  void *data)
+	{
+		struct button_data *bdata = data;
+		const char *label = NULL;
+
+		/*
+		 * We need to use dev_node_ variant here to access the
+		 * firmware properties.
+		 */
+		dev_node_property_read_string(fdn, "label", &label);
+		/* and so on */
+	}
+
+	static void gpio_keys_polled_probe(struct device *dev)
+	{
+		/* Properties for the KEYS device itself */
+		device_property_read(dev, ...);
+
+		/*
+		 * Iterate over button devices and extract their
+		 * firmware configuration.
+		 */
+		ret = device_for_each_child_node(dev, gpio_keys_polled_create_button,
+						 &bdata);
+		if (ret)
+			/* Handle error */
+	}
+
+Note that you still need proper error handling which is omitted in the
+above example.
+
+4. Existing Device Tree enabled drivers
+---------------------------------------
+At the time of writing this, there are ~250 existing DT enabled drivers.
+Allocating _HID/_CID for each would not be feasible. To make sure that
+those drivers can still be used on ACPI systems, we provide an
+alternative way to get these matched.
+
+There is a special _HID "PRP0001" which means that use the DT bindings
+for matching this device to a driver. The driver needs to have
+.of_match_table filled in even when !CONFIG_OF.
+
+An example device would be leds that can be controlled via GPIOs. This
+is represented as "leds-gpio" device and looks like this in the ACPI
+namespace:
+
+	Device (LEDS)
+	{
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {"compatible", Package () {"gpio-leds"}},
+			}
+		})
+		...
+	}
+
+In order to get the existing drivers/leds/leds-gpio.c bound to this
+device, we take advantage of "PRP0001":
+
+	/* Following already exists in the driver */
+	static const struct of_device_id of_gpio_leds_match[] = {
+		{ .compatible = "gpio-leds", },
+		{},
+	};
+	MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
+
+	/* This we add to the driver to get it probed */
+	static const struct acpi_device_id acpi_gpio_leds_match[] = {
+		{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
+		{},
+	};
+	MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
+
+	static struct platform_driver gpio_led_driver = {
+		.driver = {
+			/*
+			 * No of_match_ptr() here because we want this
+			 * table to be visible even when !CONFIG_OF to
+			 * match against "compatible" in _DSD.
+			 */
+			.of_match_table = of_gpio_leds_match,
+			.acpi_match_table = acpi_gpio_leds_match,
+		},
+	};
+
+Once ACPI core sees "PRP0001" and that the device has "compatible"
+property it will do the match using .of_match_table instead.
+
+It is preferred that new devices get a proper _HID allocated for them
+instead of inventing new DT "compatible" devices.
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 05/16] mfd: Add ACPI support
  2014-09-16 11:52 ` Mika Westerberg
                   ` (4 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  2014-09-16 21:54     ` Lee Jones
  2014-09-24 12:00     ` Lee Jones
  -1 siblings, 2 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

If an MFD device is backed by ACPI namespace, we should allow subdevice
drivers to access their corresponding ACPI companion devices through normal
means (e.g using ACPI_COMPANION()).

This patch adds such support to the MFD core. If the MFD parent device
does not specify any ACPI _HID/_CID for the child device, the child
device will share the parent ACPI companion device. Otherwise the child
device will be assigned with the corresponding ACPI companion, if found
in the namespace below the parent.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Darren Hart <dvhart@linux.intel.com>
---
Lee, I tried to get rid of #ifdefs in the below patch but it wasn't
possible because we are using functions that are not available when
!CONFIG_ACPI.

 Documentation/acpi/enumeration.txt | 27 +++++++++++++++++++++++++
 drivers/mfd/mfd-core.c             | 40 ++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/core.h           |  3 +++
 3 files changed, 70 insertions(+)

diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt
index e182be5e3c83..b60d2ab69497 100644
--- a/Documentation/acpi/enumeration.txt
+++ b/Documentation/acpi/enumeration.txt
@@ -312,3 +312,30 @@ a code like this:
 
 There are also devm_* versions of these functions which release the
 descriptors once the device is released.
+
+MFD devices
+~~~~~~~~~~~
+The MFD devices register their children as platform devices. For the child
+devices there needs to be an ACPI handle that they can use to reference
+parts of the ACPI namespace that relate to them. In the Linux MFD subsystem
+we provide two ways:
+
+	o The children share the parent ACPI handle.
+	o The MFD cell can specify the ACPI id of the device.
+
+For the first case, the MFD drivers do not need to do anything. The
+resulting child platform device will have its ACPI_COMPANION() set to point
+to the parent device.
+
+If the ACPI namespace has a device that we can match using an ACPI id,
+the id should be set like:
+
+	static struct mfd_cell my_subdevice_cell = {
+		.name = "my_subdevice",
+		/* set the resources relative to the parent */
+		.acpi_pnpid = "XYZ0001",
+	};
+
+The ACPI id "XYZ0001" is then used to lookup an ACPI device directly under
+the MFD device and if found, that ACPI companion device is bound to the
+resulting child platform device.
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 892d343193ad..e25f584be55b 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -78,6 +78,44 @@ static int mfd_platform_add_cell(struct platform_device *pdev,
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_ACPI)
+static void mfd_acpi_add_device(const struct mfd_cell *cell,
+				struct platform_device *pdev)
+{
+	struct acpi_device *parent_adev;
+	struct acpi_device *adev;
+
+	parent_adev = ACPI_COMPANION(pdev->dev.parent);
+	if (!parent_adev)
+		return;
+
+	/*
+	 * MFD child device gets its ACPI handle either from the ACPI
+	 * device directly under the parent that matches the acpi_pnpid or
+	 * it will use the parent handle if is no acpi_pnpid is given.
+	 */
+	adev = parent_adev;
+	if (cell->acpi_pnpid) {
+		struct acpi_device_id ids[2] = {};
+		struct acpi_device *child_adev;
+
+		strlcpy(ids[0].id, cell->acpi_pnpid, sizeof(ids[0].id));
+		list_for_each_entry(child_adev, &parent_adev->children, node)
+			if (acpi_match_device_ids(child_adev, ids)) {
+				adev = child_adev;
+				break;
+			}
+	}
+
+	ACPI_COMPANION_SET(&pdev->dev, adev);
+}
+#else
+static inline void mfd_acpi_add_device(const struct mfd_cell *cell,
+				       struct platform_device *pdev)
+{
+}
+#endif
+
 static int mfd_add_device(struct device *parent, int id,
 			  const struct mfd_cell *cell, atomic_t *usage_count,
 			  struct resource *mem_base,
@@ -118,6 +156,8 @@ static int mfd_add_device(struct device *parent, int id,
 		}
 	}
 
+	mfd_acpi_add_device(cell, pdev);
+
 	if (cell->pdata_size) {
 		ret = platform_device_add_data(pdev,
 					cell->platform_data, cell->pdata_size);
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index f543de91ce19..73e1709d4c09 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -44,6 +44,9 @@ struct mfd_cell {
 	 */
 	const char		*of_compatible;
 
+	/* Matches ACPI PNP id, either _HID or _CID */
+	const char		*acpi_pnpid;
+
 	/*
 	 * These resources can be specified relative to the parent device.
 	 * For accessing hardware you should use resources from the platform dev
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 06/16] gpio / ACPI: Add support for _DSD device properties
  2014-09-16 11:52 ` Mika Westerberg
                   ` (5 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  2014-09-23 15:27   ` Linus Walleij
  -1 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

With release of ACPI 5.1 and _DSD method we can finally name GPIOs (and
other things as well) returned by _CRS. Previously we were only able to
use integer index to find the corresponding GPIO, which is pretty error
prone if the order changes.

With _DSD we can now query GPIOs using name instead of an integer index,
like the below example shows:

  // Bluetooth device with reset and shutdown GPIOs
  Device (BTH)
  {
      Name (_HID, ...)

      Name (_CRS, ResourceTemplate ()
      {
          GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
                  "\\_SB.GPO0", 0, ResourceConsumer) {15}
          GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
                  "\\_SB.GPO0", 0, ResourceConsumer) {27, 31}
      })

      Name (_DSD, Package ()
      {
          ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
          Package ()
	  {
              Package () {"reset-gpio", Package() {^BTH, 1, 1, 0 }},
              Package () {"shutdown-gpio", Package() {^BTH, 0, 0, 0 }},
          }
      })
  }

The format of the supported GPIO property is:

  Package () { "name", Package () { ref, index, pin, active_low }}

  ref - The device that has _CRS containing GpioIo()/GpioInt() resources,
        typically this is the device itself (BTH in our case).
  index - Index of the GpioIo()/GpioInt() resource in _CRS starting from zero.
  pin - Pin in the GpioIo()/GpioInt() resource. Typically this is zero.
  active_low - If 1 the GPIO is marked as active_low.

Since ACPI GpioIo() resource does not have field saying whether it is
active low or high, the "active_low" argument can be used here. Setting
it to 1 marks the GPIO as active low.

In our Bluetooth example the "reset-gpio" refers to the second GpioIo()
resource, second pin in that resource with the GPIO number of 31.

This patch implements necessary support to gpiolib for extracting GPIOs
using _DSD device properties.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/gpio/gpiolib-acpi.c | 78 +++++++++++++++++++++++++++++++++++++--------
 drivers/gpio/gpiolib.c      | 30 ++++++++++++++---
 drivers/gpio/gpiolib.h      |  7 ++--
 3 files changed, 94 insertions(+), 21 deletions(-)

diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index d62eaaa75397..9212cde087b0 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -293,6 +293,7 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
 struct acpi_gpio_lookup {
 	struct acpi_gpio_info info;
 	int index;
+	int pin_index;
 	struct gpio_desc *desc;
 	int n;
 };
@@ -306,13 +307,24 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
 
 	if (lookup->n++ == lookup->index && !lookup->desc) {
 		const struct acpi_resource_gpio *agpio = &ares->data.gpio;
+		int pin_index = lookup->pin_index;
+
+		if (pin_index >= agpio->pin_table_length)
+			return 1;
 
 		lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
-					      agpio->pin_table[0]);
+					      agpio->pin_table[pin_index]);
 		lookup->info.gpioint =
 			agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
-		lookup->info.active_low =
-			agpio->polarity == ACPI_ACTIVE_LOW;
+
+		/*
+		 * ActiveLow is only specified for GpioInt resource. If
+		 * GpioIo is used then the only way to set the flag is
+		 * to use _DSD "gpios" property.
+		 */
+		if (lookup->info.gpioint)
+			lookup->info.active_low =
+				agpio->polarity == ACPI_ACTIVE_LOW;
 	}
 
 	return 1;
@@ -320,40 +332,75 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
 
 /**
  * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
- * @dev: pointer to a device to get GPIO from
+ * @adev: pointer to a ACPI device to get GPIO from
+ * @propname: Property name of the GPIO (optional)
  * @index: index of GpioIo/GpioInt resource (starting from %0)
  * @info: info pointer to fill in (optional)
  *
- * Function goes through ACPI resources for @dev and based on @index looks
+ * Function goes through ACPI resources for @adev and based on @index looks
  * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor,
  * and returns it. @index matches GpioIo/GpioInt resources only so if there
  * are total %3 GPIO resources, the index goes from %0 to %2.
  *
+ * If @propname is specified the GPIO is looked using device property. In
+ * that case @index is used to select the GPIO entry in the property value
+ * (in case of multiple).
+ *
  * If the GPIO cannot be translated or there is an error an ERR_PTR is
  * returned.
  *
  * Note: if the GPIO resource has multiple entries in the pin list, this
  * function only returns the first.
  */
-struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
+struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
+					  const char *propname, int index,
 					  struct acpi_gpio_info *info)
 {
 	struct acpi_gpio_lookup lookup;
 	struct list_head resource_list;
-	struct acpi_device *adev;
-	acpi_handle handle;
+	bool active_low = false;
 	int ret;
 
-	if (!dev)
-		return ERR_PTR(-EINVAL);
-
-	handle = ACPI_HANDLE(dev);
-	if (!handle || acpi_bus_get_device(handle, &adev))
+	if (!adev)
 		return ERR_PTR(-ENODEV);
 
 	memset(&lookup, 0, sizeof(lookup));
 	lookup.index = index;
 
+	if (propname) {
+		struct acpi_reference_args args;
+
+		dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
+
+		memset(&args, 0, sizeof(args));
+		ret = acpi_dev_get_property_reference(adev, propname, NULL,
+						      index, &args);
+		if (ret)
+			return ERR_PTR(ret);
+
+		/*
+		 * The property was found and resolved so need to
+		 * lookup the GPIO based on returned args instead.
+		 */
+		adev = args.adev;
+		if (args.nargs >= 2) {
+			lookup.index = args.args[0];
+			lookup.pin_index = args.args[1];
+			/*
+			 * 3rd argument, if present is used to
+			 * specify active_low.
+			 */
+			if (args.nargs >= 3)
+				active_low = !!args.args[2];
+		}
+
+		dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n",
+			dev_name(&adev->dev), args.nargs,
+			args.args[0], args.args[1], args.args[2]);
+	} else {
+		dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index);
+	}
+
 	INIT_LIST_HEAD(&resource_list);
 	ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
 				     &lookup);
@@ -362,8 +409,11 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
 
 	acpi_dev_free_resource_list(&resource_list);
 
-	if (lookup.desc && info)
+	if (lookup.desc && info) {
 		*info = lookup.info;
+		if (active_low)
+			info->active_low = active_low;
+	}
 
 	return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
 }
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 15cc0bb65dda..444d43c9fd3e 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1487,14 +1487,36 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
 					unsigned int idx,
 					enum gpio_lookup_flags *flags)
 {
+	static const char * const suffixes[] = { "gpios", "gpio" };
+	struct acpi_device *adev = ACPI_COMPANION(dev);
 	struct acpi_gpio_info info;
 	struct gpio_desc *desc;
+	char propname[32];
+	int i;
 
-	desc = acpi_get_gpiod_by_index(dev, idx, &info);
-	if (IS_ERR(desc))
-		return desc;
+	/* Try first from _DSD */
+	for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
+		if (con_id && strcmp(con_id, "gpios")) {
+			snprintf(propname, sizeof(propname), "%s-%s",
+				 con_id, suffixes[i]);
+		} else {
+			snprintf(propname, sizeof(propname), "%s",
+				 suffixes[i]);
+		}
+
+		desc = acpi_get_gpiod_by_index(adev, propname, 0, &info);
+		if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
+			break;
+	}
+
+	/* Then from plain _CRS GPIOs */
+	if (IS_ERR(desc)) {
+		desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
+		if (IS_ERR(desc))
+			return desc;
+	}
 
-	if (info.gpioint && info.active_low)
+	if (info.active_low)
 		*flags |= GPIO_ACTIVE_LOW;
 
 	return desc;
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 9db2b6a71c5d..e3a52113a541 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -34,7 +34,8 @@ void acpi_gpiochip_remove(struct gpio_chip *chip);
 void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
 void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
 
-struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
+struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
+					  const char *propname, int index,
 					  struct acpi_gpio_info *info);
 #else
 static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
@@ -47,8 +48,8 @@ static inline void
 acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
 
 static inline struct gpio_desc *
-acpi_get_gpiod_by_index(struct device *dev, int index,
-			struct acpi_gpio_info *info)
+acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname,
+			int index, struct acpi_gpio_info *info)
 {
 	return ERR_PTR(-ENOSYS);
 }
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-16 11:52 ` Mika Westerberg
                   ` (6 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
       [not found]   ` <1410868367-11056-8-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  -1 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

Some drivers need to deal with only firmware representation of its
GPIOs. An example would be a GPIO button array driver where each button
is described as a separate firmware node in device tree. Typically these
child nodes do not have physical representation in the Linux device
model.

In order to help device drivers to handle such firmware child nodes we
add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
parameter, finds the GPIO using whatever is the underlying firmware
method, and requests the GPIO properly.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/gpio/devres.c         | 35 +++++++++++++++++++++++++++
 drivers/gpio/gpiolib.c        | 55 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/gpio/consumer.h |  7 ++++++
 3 files changed, 97 insertions(+)

diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c
index 954b9f6b0ef8..1556a251fc8e 100644
--- a/drivers/gpio/devres.c
+++ b/drivers/gpio/devres.c
@@ -109,6 +109,41 @@ struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev,
 EXPORT_SYMBOL(__devm_gpiod_get_index);
 
 /**
+ * devm_node_get_named_gpiod - resource-managed dev_node_get_named_gpiod()
+ * @dev:	GPIO consumer
+ * @fdn:	firmware device node
+ * @propname:	name of the firmware property
+ * @idx:	index of the GPIO in the property value in case of many
+ *
+ * Managed dev_node_get_named_gpiod(). GPIO descriptors returned from
+ * this function are automatically disposed on driver detach.
+ */
+struct gpio_desc *devm_node_get_named_gpiod(struct device *dev,
+					    struct fw_dev_node *fdn,
+					    const char *propname, int index)
+{
+	struct gpio_desc **dr;
+	struct gpio_desc *desc;
+
+	dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
+			  GFP_KERNEL);
+	if (!dr)
+		return ERR_PTR(-ENOMEM);
+
+	desc = dev_node_get_named_gpiod(fdn, propname, index);
+	if (IS_ERR(desc)) {
+		devres_free(dr);
+		return desc;
+	}
+
+	*dr = desc;
+	devres_add(dev, dr);
+
+	return desc;
+}
+EXPORT_SYMBOL(devm_node_get_named_gpiod);
+
+/**
  * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
  * @dev: GPIO consumer
  * @con_id: function within the GPIO consumer
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 444d43c9fd3e..d364214d2946 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1717,6 +1717,61 @@ struct gpio_desc *__must_check __gpiod_get_index(struct device *dev,
 EXPORT_SYMBOL_GPL(__gpiod_get_index);
 
 /**
+ * dev_node_get_named_gpiod - obtain a GPIO from firmware device node
+ * @fdn:	firmware device node
+ * @propname:	name of the firmware property
+ * @idx:	index of the GPIO in the property value in case of many
+ *
+ * This function can be used for drivers that get their configuration
+ * from firmware in such way that there is not always corresponding
+ * physical device pointer available. For example some properties are
+ * described as a child nodes for the parent device in DT or ACPI.
+ *
+ * Function properly finds the corresponding GPIO using whatever is the
+ * underlying firmware interface and then makes sure that the GPIO
+ * descriptor is requested before it is returned to the caller.
+ *
+ * In case of error an ERR_PTR() is returned.
+ */
+struct gpio_desc *dev_node_get_named_gpiod(struct fw_dev_node *fdn,
+					   const char *propname, int index)
+{
+	struct gpio_desc *desc = ERR_PTR(-ENODEV);
+	struct acpi_device *adev = fdn->acpi_node;
+	struct device_node *np = fdn->of_node;
+	bool active_low = false;
+	int ret;
+
+	if (IS_ENABLED(CONFIG_OF) && np) {
+		enum of_gpio_flags flags;
+
+		desc = of_get_named_gpiod_flags(np, propname, index, &flags);
+		if (!IS_ERR(desc))
+			active_low = flags & OF_GPIO_ACTIVE_LOW;
+	} else if (IS_ENABLED(CONFIG_ACPI) && adev) {
+		struct acpi_gpio_info info;
+
+		desc = acpi_get_gpiod_by_index(adev, propname, index, &info);
+		if (!IS_ERR(desc))
+			active_low = info.active_low;
+	}
+
+	if (IS_ERR(desc))
+		return desc;
+
+	ret = gpiod_request(desc, NULL);
+	if (ret)
+		return ERR_PTR(ret);
+
+	/* Only value flag can be set from both DT and ACPI is active_low */
+	if (active_low)
+		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+
+	return desc;
+}
+EXPORT_SYMBOL_GPL(dev_node_get_named_gpiod);
+
+/**
  * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
  *                            function
  * @dev: GPIO consumer, can be NULL for system-global GPIOs
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 12f146fa6604..aa1b273f0e38 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -6,6 +6,7 @@
 #include <linux/kernel.h>
 
 struct device;
+struct fw_dev_node;
 
 /**
  * Opaque descriptor for a GPIO. These are obtained using gpiod_get() and are
@@ -94,6 +95,12 @@ int gpiod_to_irq(const struct gpio_desc *desc);
 struct gpio_desc *gpio_to_desc(unsigned gpio);
 int desc_to_gpio(const struct gpio_desc *desc);
 
+/* Firmware node interface */
+struct gpio_desc *dev_node_get_named_gpiod(struct fw_dev_node *fdn,
+					   const char *propname, int index);
+struct gpio_desc *devm_node_get_named_gpiod(struct device *dev,
+					    struct fw_dev_node *fdn,
+					    const char *propname, int index);
 #else /* CONFIG_GPIOLIB */
 
 static inline struct gpio_desc *__must_check __gpiod_get(struct device *dev,
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 08/16] gpio: sch: Consolidate core and resume banks
  2014-09-16 11:52 ` Mika Westerberg
                   ` (7 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

This is actually a single device with two sets of identical registers,
which just happen to start from a different offset. Instead of having
separate GPIO chips created we consolidate them to be single GPIO chip.

In addition having a single GPIO chip allows us to handle ACPI GPIO
translation in the core in a more generic way, since the two GPIO chips
share the same parent ACPI device.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-sch.c | 293 ++++++++++++++++++------------------------------
 1 file changed, 112 insertions(+), 181 deletions(-)

diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
index 41e91d70301e..99720c8bc8ed 100644
--- a/drivers/gpio/gpio-sch.c
+++ b/drivers/gpio/gpio-sch.c
@@ -29,290 +29,221 @@
 
 #include <linux/gpio.h>
 
-static DEFINE_SPINLOCK(gpio_lock);
-
-#define CGEN	(0x00)
-#define CGIO	(0x04)
-#define CGLV	(0x08)
-
-#define RGEN	(0x20)
-#define RGIO	(0x24)
-#define RGLV	(0x28)
-
-static unsigned short gpio_ba;
-
-static int sch_gpio_core_direction_in(struct gpio_chip *gc, unsigned  gpio_num)
-{
-	u8 curr_dirs;
-	unsigned short offset, bit;
-
-	spin_lock(&gpio_lock);
-
-	offset = CGIO + gpio_num / 8;
-	bit = gpio_num % 8;
-
-	curr_dirs = inb(gpio_ba + offset);
-
-	if (!(curr_dirs & (1 << bit)))
-		outb(curr_dirs | (1 << bit), gpio_ba + offset);
+#define GEN	0x00
+#define GIO	0x04
+#define GLV	0x08
+
+struct sch_gpio {
+	struct gpio_chip chip;
+	spinlock_t lock;
+	unsigned short iobase;
+	unsigned short core_base;
+	unsigned short resume_base;
+};
 
-	spin_unlock(&gpio_lock);
-	return 0;
-}
+#define to_sch_gpio(c)	container_of(c, struct sch_gpio, chip)
 
-static int sch_gpio_core_get(struct gpio_chip *gc, unsigned gpio_num)
+static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
+				unsigned reg)
 {
-	int res;
-	unsigned short offset, bit;
+	unsigned base = 0;
 
-	offset = CGLV + gpio_num / 8;
-	bit = gpio_num % 8;
+	if (gpio >= sch->resume_base) {
+		gpio -= sch->resume_base;
+		base += 0x20;
+	}
 
-	res = !!(inb(gpio_ba + offset) & (1 << bit));
-	return res;
+	return base + reg + gpio / 8;
 }
 
-static void sch_gpio_core_set(struct gpio_chip *gc, unsigned gpio_num, int val)
+static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
 {
-	u8 curr_vals;
-	unsigned short offset, bit;
-
-	spin_lock(&gpio_lock);
-
-	offset = CGLV + gpio_num / 8;
-	bit = gpio_num % 8;
-
-	curr_vals = inb(gpio_ba + offset);
-
-	if (val)
-		outb(curr_vals | (1 << bit), gpio_ba + offset);
-	else
-		outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
-	spin_unlock(&gpio_lock);
+	if (gpio >= sch->resume_base)
+		gpio -= sch->resume_base;
+	return gpio % 8;
 }
 
-static int sch_gpio_core_direction_out(struct gpio_chip *gc,
-					unsigned gpio_num, int val)
+static void sch_gpio_enable(struct sch_gpio *sch, unsigned gpio)
 {
-	u8 curr_dirs;
 	unsigned short offset, bit;
+	u8 enable;
 
-	spin_lock(&gpio_lock);
+	spin_lock(&sch->lock);
 
-	offset = CGIO + gpio_num / 8;
-	bit = gpio_num % 8;
-
-	curr_dirs = inb(gpio_ba + offset);
-	if (curr_dirs & (1 << bit))
-		outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
+	offset = sch_gpio_offset(sch, gpio, GEN);
+	bit = sch_gpio_bit(sch, gpio);
 
-	spin_unlock(&gpio_lock);
+	enable = inb(sch->iobase + offset);
+	if (!(enable & (1 << bit)))
+		outb(enable | (1 << bit), sch->iobase + offset);
 
-	/*
-	 * according to the datasheet, writing to the level register has no
-	 * effect when GPIO is programmed as input.
-	 * Actually the the level register is read-only when configured as input.
-	 * Thus presetting the output level before switching to output is _NOT_ possible.
-	 * Hence we set the level after configuring the GPIO as output.
-	 * But we cannot prevent a short low pulse if direction is set to high
-	 * and an external pull-up is connected.
-	 */
-	sch_gpio_core_set(gc, gpio_num, val);
-	return 0;
+	spin_unlock(&sch->lock);
 }
 
-static struct gpio_chip sch_gpio_core = {
-	.label			= "sch_gpio_core",
-	.owner			= THIS_MODULE,
-	.direction_input	= sch_gpio_core_direction_in,
-	.get			= sch_gpio_core_get,
-	.direction_output	= sch_gpio_core_direction_out,
-	.set			= sch_gpio_core_set,
-};
-
-static int sch_gpio_resume_direction_in(struct gpio_chip *gc,
-					unsigned gpio_num)
+static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned  gpio_num)
 {
+	struct sch_gpio *sch = to_sch_gpio(gc);
 	u8 curr_dirs;
 	unsigned short offset, bit;
 
-	spin_lock(&gpio_lock);
+	spin_lock(&sch->lock);
 
-	offset = RGIO + gpio_num / 8;
-	bit = gpio_num % 8;
+	offset = sch_gpio_offset(sch, gpio_num, GIO);
+	bit = sch_gpio_bit(sch, gpio_num);
 
-	curr_dirs = inb(gpio_ba + offset);
+	curr_dirs = inb(sch->iobase + offset);
 
 	if (!(curr_dirs & (1 << bit)))
-		outb(curr_dirs | (1 << bit), gpio_ba + offset);
+		outb(curr_dirs | (1 << bit), sch->iobase + offset);
 
-	spin_unlock(&gpio_lock);
+	spin_unlock(&sch->lock);
 	return 0;
 }
 
-static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num)
+static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
 {
+	struct sch_gpio *sch = to_sch_gpio(gc);
+	int res;
 	unsigned short offset, bit;
 
-	offset = RGLV + gpio_num / 8;
-	bit = gpio_num % 8;
+	offset = sch_gpio_offset(sch, gpio_num, GLV);
+	bit = sch_gpio_bit(sch, gpio_num);
+
+	res = !!(inb(sch->iobase + offset) & (1 << bit));
 
-	return !!(inb(gpio_ba + offset) & (1 << bit));
+	return res;
 }
 
-static void sch_gpio_resume_set(struct gpio_chip *gc,
-				unsigned gpio_num, int val)
+static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
 {
+	struct sch_gpio *sch = to_sch_gpio(gc);
 	u8 curr_vals;
 	unsigned short offset, bit;
 
-	spin_lock(&gpio_lock);
+	spin_lock(&sch->lock);
 
-	offset = RGLV + gpio_num / 8;
-	bit = gpio_num % 8;
+	offset = sch_gpio_offset(sch, gpio_num, GLV);
+	bit = sch_gpio_bit(sch, gpio_num);
 
-	curr_vals = inb(gpio_ba + offset);
+	curr_vals = inb(sch->iobase + offset);
 
 	if (val)
-		outb(curr_vals | (1 << bit), gpio_ba + offset);
+		outb(curr_vals | (1 << bit), sch->iobase + offset);
 	else
-		outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
+		outb((curr_vals & ~(1 << bit)), sch->iobase + offset);
 
-	spin_unlock(&gpio_lock);
+	spin_unlock(&sch->lock);
 }
 
-static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
-					unsigned gpio_num, int val)
+static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
+				  int val)
 {
+	struct sch_gpio *sch = to_sch_gpio(gc);
 	u8 curr_dirs;
 	unsigned short offset, bit;
 
-	offset = RGIO + gpio_num / 8;
-	bit = gpio_num % 8;
+	spin_lock(&sch->lock);
 
-	spin_lock(&gpio_lock);
+	offset = sch_gpio_offset(sch, gpio_num, GIO);
+	bit = sch_gpio_bit(sch, gpio_num);
 
-	curr_dirs = inb(gpio_ba + offset);
+	curr_dirs = inb(sch->iobase + offset);
 	if (curr_dirs & (1 << bit))
-		outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
+		outb(curr_dirs & ~(1 << bit), sch->iobase + offset);
 
-	spin_unlock(&gpio_lock);
+	spin_unlock(&sch->lock);
 
 	/*
-	* according to the datasheet, writing to the level register has no
-	* effect when GPIO is programmed as input.
-	* Actually the the level register is read-only when configured as input.
-	* Thus presetting the output level before switching to output is _NOT_ possible.
-	* Hence we set the level after configuring the GPIO as output.
-	* But we cannot prevent a short low pulse if direction is set to high
-	* and an external pull-up is connected.
-	*/
-	sch_gpio_resume_set(gc, gpio_num, val);
+	 * according to the datasheet, writing to the level register has no
+	 * effect when GPIO is programmed as input.
+	 * Actually the the level register is read-only when configured as input.
+	 * Thus presetting the output level before switching to output is _NOT_ possible.
+	 * Hence we set the level after configuring the GPIO as output.
+	 * But we cannot prevent a short low pulse if direction is set to high
+	 * and an external pull-up is connected.
+	 */
+	sch_gpio_set(gc, gpio_num, val);
 	return 0;
 }
 
-static struct gpio_chip sch_gpio_resume = {
-	.label			= "sch_gpio_resume",
+static struct gpio_chip sch_gpio_chip = {
+	.label			= "sch_gpio",
 	.owner			= THIS_MODULE,
-	.direction_input	= sch_gpio_resume_direction_in,
-	.get			= sch_gpio_resume_get,
-	.direction_output	= sch_gpio_resume_direction_out,
-	.set			= sch_gpio_resume_set,
+	.direction_input	= sch_gpio_direction_in,
+	.get			= sch_gpio_get,
+	.direction_output	= sch_gpio_direction_out,
+	.set			= sch_gpio_set,
 };
 
 static int sch_gpio_probe(struct platform_device *pdev)
 {
+	struct sch_gpio *sch;
 	struct resource *res;
-	int err, id;
 
-	id = pdev->id;
-	if (!id)
-		return -ENODEV;
+	sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL);
+	if (!sch)
+		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 	if (!res)
 		return -EBUSY;
 
-	if (!request_region(res->start, resource_size(res), pdev->name))
+	if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
+				 pdev->name))
 		return -EBUSY;
 
-	gpio_ba = res->start;
+	spin_lock_init(&sch->lock);
+	sch->iobase = res->start;
+	sch->chip = sch_gpio_chip;
+	sch->chip.label = dev_name(&pdev->dev);
+	sch->chip.dev = &pdev->dev;
 
-	switch (id) {
+	switch (pdev->id) {
 	case PCI_DEVICE_ID_INTEL_SCH_LPC:
-		sch_gpio_core.base = 0;
-		sch_gpio_core.ngpio = 10;
-		sch_gpio_resume.base = 10;
-		sch_gpio_resume.ngpio = 4;
+		sch->core_base = 0;
+		sch->resume_base = 10;
+		sch->chip.ngpio = 14;
+
 		/*
 		 * GPIO[6:0] enabled by default
 		 * GPIO7 is configured by the CMC as SLPIOVR
 		 * Enable GPIO[9:8] core powered gpios explicitly
 		 */
-		outb(0x3, gpio_ba + CGEN + 1);
+		sch_gpio_enable(sch, 8);
+		sch_gpio_enable(sch, 9);
 		/*
 		 * SUS_GPIO[2:0] enabled by default
 		 * Enable SUS_GPIO3 resume powered gpio explicitly
 		 */
-		outb(0x8, gpio_ba + RGEN);
+		sch_gpio_enable(sch, 13);
 		break;
 
 	case PCI_DEVICE_ID_INTEL_ITC_LPC:
-		sch_gpio_core.base = 0;
-		sch_gpio_core.ngpio = 5;
-		sch_gpio_resume.base = 5;
-		sch_gpio_resume.ngpio = 9;
+		sch->core_base = 0;
+		sch->resume_base = 5;
+		sch->chip.ngpio = 14;
 		break;
 
 	case PCI_DEVICE_ID_INTEL_CENTERTON_ILB:
-		sch_gpio_core.base = 0;
-		sch_gpio_core.ngpio = 21;
-		sch_gpio_resume.base = 21;
-		sch_gpio_resume.ngpio = 9;
+		sch->core_base = 0;
+		sch->resume_base = 21;
+		sch->chip.ngpio = 30;
 		break;
 
 	default:
-		err = -ENODEV;
-		goto err_sch_gpio_core;
+		return -ENODEV;
 	}
 
-	sch_gpio_core.dev = &pdev->dev;
-	sch_gpio_resume.dev = &pdev->dev;
-
-	err = gpiochip_add(&sch_gpio_core);
-	if (err < 0)
-		goto err_sch_gpio_core;
+	platform_set_drvdata(pdev, sch);
 
-	err = gpiochip_add(&sch_gpio_resume);
-	if (err < 0)
-		goto err_sch_gpio_resume;
-
-	return 0;
-
-err_sch_gpio_resume:
-	gpiochip_remove(&sch_gpio_core);
-
-err_sch_gpio_core:
-	release_region(res->start, resource_size(res));
-	gpio_ba = 0;
-
-	return err;
+	return gpiochip_add(&sch->chip);
 }
 
 static int sch_gpio_remove(struct platform_device *pdev)
 {
-	struct resource *res;
-	if (gpio_ba) {
-
-		gpiochip_remove(&sch_gpio_core);
-		gpiochip_remove(&sch_gpio_resume);
-
-		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-
-		release_region(res->start, resource_size(res));
-		gpio_ba = 0;
-	}
+	struct sch_gpio *sch = platform_get_drvdata(pdev);
 
+	gpiochip_remove(&sch->chip);
 	return 0;
 }
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 09/16] leds: leds-gpio: Add support for GPIO descriptors
  2014-09-16 11:52 ` Mika Westerberg
                   ` (8 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  2014-09-19  8:18   ` Alexandre Courbot
  2014-09-24  7:55   ` Linus Walleij
  -1 siblings, 2 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

GPIO descriptors are the preferred way over legacy GPIO numbers
nowadays. Convert the driver to use GPIO descriptors internally but
still allow passing legacy GPIO numbers from platform data to support
existing platforms.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/leds/leds-gpio.c | 80 +++++++++++++++++++++++++++---------------------
 include/linux/leds.h     |  1 +
 2 files changed, 46 insertions(+), 35 deletions(-)

diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 57ff20fecf57..c84e913527f0 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/leds.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -24,11 +25,10 @@
 
 struct gpio_led_data {
 	struct led_classdev cdev;
-	unsigned gpio;
+	struct gpio_desc *gpiod;
 	struct work_struct work;
 	u8 new_level;
 	u8 can_sleep;
-	u8 active_low;
 	u8 blinking;
 	int (*platform_gpio_blink_set)(unsigned gpio, int state,
 			unsigned long *delay_on, unsigned long *delay_off);
@@ -40,12 +40,16 @@ static void gpio_led_work(struct work_struct *work)
 		container_of(work, struct gpio_led_data, work);
 
 	if (led_dat->blinking) {
-		led_dat->platform_gpio_blink_set(led_dat->gpio,
-						 led_dat->new_level,
-						 NULL, NULL);
+		int gpio = desc_to_gpio(led_dat->gpiod);
+		int level = led_dat->new_level;
+
+		if (gpiod_is_active_low(led_dat->gpiod))
+			level = !level;
+
+		led_dat->platform_gpio_blink_set(gpio, level, NULL, NULL);
 		led_dat->blinking = 0;
 	} else
-		gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level);
+		gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level);
 }
 
 static void gpio_led_set(struct led_classdev *led_cdev,
@@ -60,9 +64,6 @@ static void gpio_led_set(struct led_classdev *led_cdev,
 	else
 		level = 1;
 
-	if (led_dat->active_low)
-		level = !level;
-
 	/* Setting GPIOs with I2C/etc requires a task context, and we don't
 	 * seem to have a reliable way to know if we're already in one; so
 	 * let's just assume the worst.
@@ -72,11 +73,16 @@ static void gpio_led_set(struct led_classdev *led_cdev,
 		schedule_work(&led_dat->work);
 	} else {
 		if (led_dat->blinking) {
-			led_dat->platform_gpio_blink_set(led_dat->gpio, level,
-							 NULL, NULL);
+			int gpio = desc_to_gpio(led_dat->gpiod);
+
+			if (gpiod_is_active_low(led_dat->gpiod))
+				level = !level;
+
+			led_dat->platform_gpio_blink_set(gpio, level, NULL,
+							 NULL);
 			led_dat->blinking = 0;
 		} else
-			gpio_set_value(led_dat->gpio, level);
+			gpiod_set_value(led_dat->gpiod, level);
 	}
 }
 
@@ -85,9 +91,10 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
 {
 	struct gpio_led_data *led_dat =
 		container_of(led_cdev, struct gpio_led_data, cdev);
+	int gpio = desc_to_gpio(led_dat->gpiod);
 
 	led_dat->blinking = 1;
-	return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK,
+	return led_dat->platform_gpio_blink_set(gpio, GPIO_LED_BLINK,
 						delay_on, delay_off);
 }
 
@@ -97,24 +104,33 @@ static int create_gpio_led(const struct gpio_led *template,
 {
 	int ret, state;
 
-	led_dat->gpio = -1;
+	if (!template->gpiod) {
+		unsigned long flags = 0;
 
-	/* skip leds that aren't available */
-	if (!gpio_is_valid(template->gpio)) {
-		dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n",
-				template->gpio, template->name);
-		return 0;
-	}
+		/* skip leds that aren't available */
+		if (!gpio_is_valid(template->gpio)) {
+			dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n",
+					template->gpio, template->name);
+			return 0;
+		}
 
-	ret = devm_gpio_request(parent, template->gpio, template->name);
-	if (ret < 0)
-		return ret;
+		if (template->active_low)
+			flags |= GPIOF_ACTIVE_LOW;
+
+		ret = devm_gpio_request_one(parent, template->gpio, flags,
+					    template->name);
+		if (ret < 0)
+			return ret;
+
+		led_dat->gpiod = gpio_to_desc(template->gpio);
+		if (IS_ERR(led_dat->gpiod))
+			return PTR_ERR(led_dat->gpiod);
+	}
 
 	led_dat->cdev.name = template->name;
 	led_dat->cdev.default_trigger = template->default_trigger;
-	led_dat->gpio = template->gpio;
-	led_dat->can_sleep = gpio_cansleep(template->gpio);
-	led_dat->active_low = template->active_low;
+	led_dat->gpiod = template->gpiod;
+	led_dat->can_sleep = gpiod_cansleep(template->gpiod);
 	led_dat->blinking = 0;
 	if (blink_set) {
 		led_dat->platform_gpio_blink_set = blink_set;
@@ -122,30 +138,24 @@ static int create_gpio_led(const struct gpio_led *template,
 	}
 	led_dat->cdev.brightness_set = gpio_led_set;
 	if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP)
-		state = !!gpio_get_value_cansleep(led_dat->gpio) ^ led_dat->active_low;
+		state = !!gpiod_get_value_cansleep(led_dat->gpiod);
 	else
 		state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
 	led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
 	if (!template->retain_state_suspended)
 		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
 
-	ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
+	ret = gpiod_direction_output(led_dat->gpiod, state);
 	if (ret < 0)
 		return ret;
 
 	INIT_WORK(&led_dat->work, gpio_led_work);
 
-	ret = led_classdev_register(parent, &led_dat->cdev);
-	if (ret < 0)
-		return ret;
-
-	return 0;
+	return led_classdev_register(parent, &led_dat->cdev);
 }
 
 static void delete_gpio_led(struct gpio_led_data *led)
 {
-	if (!gpio_is_valid(led->gpio))
-		return;
 	led_classdev_unregister(&led->cdev);
 	cancel_work_sync(&led->work);
 }
diff --git a/include/linux/leds.h b/include/linux/leds.h
index e43686472197..879a113b3d57 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -246,6 +246,7 @@ struct led_platform_data {
 struct gpio_led {
 	const char *name;
 	const char *default_trigger;
+	struct gpio_desc *gpiod;
 	unsigned 	gpio;
 	unsigned	active_low : 1;
 	unsigned	retain_state_suspended : 1;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 10/16] leds: leds-gpio: Make use of device property API
  2014-09-16 11:52 ` Mika Westerberg
                   ` (9 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

From: Max Eliaser <max.eliaser@intel.com>

Make use of device property API in this driver so that both OF and ACPI
based system can use the same driver.

Signed-off-by: Max Eliaser <max.eliaser@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/leds/leds-gpio.c | 102 +++++++++++++++++++++--------------------------
 1 file changed, 45 insertions(+), 57 deletions(-)

diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index c84e913527f0..5dbf7485da66 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -15,13 +15,11 @@
 #include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/leds.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/of_gpio.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/property.h>
 
 struct gpio_led_data {
 	struct led_classdev cdev;
@@ -161,6 +159,7 @@ static void delete_gpio_led(struct gpio_led_data *led)
 }
 
 struct gpio_leds_priv {
+	struct device *dev;
 	int num_leds;
 	struct gpio_led_data leds[];
 };
@@ -171,65 +170,61 @@ static inline int sizeof_gpio_leds_priv(int num_leds)
 		(sizeof(struct gpio_led_data) * num_leds);
 }
 
-/* Code to create from OpenFirmware platform devices */
-#ifdef CONFIG_OF_GPIO
-static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
+static int gpio_leds_create_led(struct fw_dev_node *fdn, void *data)
+{
+	struct gpio_leds_priv *priv = data;
+	struct gpio_led led = {};
+	const char *state = NULL;
+
+	led.gpiod = devm_node_get_named_gpiod(priv->dev, fdn, "gpios", 0);
+	if (IS_ERR(led.gpiod))
+		return PTR_ERR(led.gpiod);
+
+	dev_node_property_read_string(fdn, "label", &led.name);
+	dev_node_property_read_string(fdn, "linux,default-trigger",
+				      &led.default_trigger);
+
+	dev_node_property_read_string(fdn, "linux,default_state", &state);
+	if (state) {
+		if (!strcmp(state, "keep"))
+			led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
+		else if (!strcmp(state, "on"))
+			led.default_state = LEDS_GPIO_DEFSTATE_ON;
+		else
+			led.default_state = LEDS_GPIO_DEFSTATE_OFF;
+	}
+
+	if (!dev_node_get_property(fdn, "retain-state-suspended", NULL))
+		led.retain_state_suspended = 1;
+
+	return create_gpio_led(&led, &priv->leds[priv->num_leds++], priv->dev,
+			       NULL);
+}
+
+static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node, *child;
 	struct gpio_leds_priv *priv;
-	int count, ret;
+	int ret, count;
 
-	/* count LEDs in this device, so we know how much to allocate */
-	count = of_get_available_child_count(np);
+	count = device_get_child_node_count(&pdev->dev);
 	if (!count)
 		return ERR_PTR(-ENODEV);
 
-	for_each_available_child_of_node(np, child)
-		if (of_get_gpio(child, 0) == -EPROBE_DEFER)
-			return ERR_PTR(-EPROBE_DEFER);
-
 	priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count),
 			GFP_KERNEL);
 	if (!priv)
 		return ERR_PTR(-ENOMEM);
 
-	for_each_available_child_of_node(np, child) {
-		struct gpio_led led = {};
-		enum of_gpio_flags flags;
-		const char *state;
-
-		led.gpio = of_get_gpio_flags(child, 0, &flags);
-		led.active_low = flags & OF_GPIO_ACTIVE_LOW;
-		led.name = of_get_property(child, "label", NULL) ? : child->name;
-		led.default_trigger =
-			of_get_property(child, "linux,default-trigger", NULL);
-		state = of_get_property(child, "default-state", NULL);
-		if (state) {
-			if (!strcmp(state, "keep"))
-				led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
-			else if (!strcmp(state, "on"))
-				led.default_state = LEDS_GPIO_DEFSTATE_ON;
-			else
-				led.default_state = LEDS_GPIO_DEFSTATE_OFF;
-		}
-
-		if (of_get_property(child, "retain-state-suspended", NULL))
-			led.retain_state_suspended = 1;
-
-		ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
-				      &pdev->dev, NULL);
-		if (ret < 0) {
-			of_node_put(child);
-			goto err;
-		}
+	priv->dev = &pdev->dev;
+	ret = device_for_each_child_node(&pdev->dev, gpio_leds_create_led,
+					 priv);
+	if (ret) {
+		for (count = priv->num_leds - 2; count >= 0; count--)
+			delete_gpio_led(&priv->leds[count]);
+		return ERR_PTR(ret);
 	}
 
 	return priv;
-
-err:
-	for (count = priv->num_leds - 2; count >= 0; count--)
-		delete_gpio_led(&priv->leds[count]);
-	return ERR_PTR(-ENODEV);
 }
 
 static const struct of_device_id of_gpio_leds_match[] = {
@@ -238,13 +233,6 @@ static const struct of_device_id of_gpio_leds_match[] = {
 };
 
 MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
-#else /* CONFIG_OF_GPIO */
-static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
-{
-	return ERR_PTR(-ENODEV);
-}
-#endif /* CONFIG_OF_GPIO */
-
 
 static int gpio_led_probe(struct platform_device *pdev)
 {
@@ -273,7 +261,7 @@ static int gpio_led_probe(struct platform_device *pdev)
 			}
 		}
 	} else {
-		priv = gpio_leds_create_of(pdev);
+		priv = gpio_leds_create(pdev);
 		if (IS_ERR(priv))
 			return PTR_ERR(priv);
 	}
@@ -300,7 +288,7 @@ static struct platform_driver gpio_led_driver = {
 	.driver		= {
 		.name	= "leds-gpio",
 		.owner	= THIS_MODULE,
-		.of_match_table = of_match_ptr(of_gpio_leds_match),
+		.of_match_table = of_gpio_leds_match,
 	},
 };
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 11/16] leds: leds-gpio: Add ACPI probing support
  2014-09-16 11:52 ` Mika Westerberg
                   ` (10 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

From: Max Eliaser <max.eliaser@intel.com>

This allows the driver to probe from ACPI namespace.

Signed-off-by: Max Eliaser <max.eliaser@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/leds/leds-gpio.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 5dbf7485da66..24e05adbbaf8 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -234,6 +234,13 @@ static const struct of_device_id of_gpio_leds_match[] = {
 
 MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
 
+static const struct acpi_device_id acpi_gpio_leds_match[] = {
+	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
+	{},
+};
+
+MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
+
 static int gpio_led_probe(struct platform_device *pdev)
 {
 	struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -289,6 +296,7 @@ static struct platform_driver gpio_led_driver = {
 		.name	= "leds-gpio",
 		.owner	= THIS_MODULE,
 		.of_match_table = of_gpio_leds_match,
+		.acpi_match_table = acpi_gpio_leds_match,
 	},
 };
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 12/16] input: gpio_keys_polled - Add support for GPIO descriptors
  2014-09-16 11:52 ` Mika Westerberg
                   ` (11 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  2014-09-19  8:22   ` Alexandre Courbot
  2014-09-24  8:02   ` Linus Walleij
  -1 siblings, 2 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

From: Aaron Lu <aaron.lu@intel.com>

GPIO descriptors are the preferred way over legacy GPIO numbers
nowadays. Convert the driver to use GPIO descriptors internally but
still allow passing legacy GPIO numbers from platform data to support
existing platforms.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/input/keyboard/gpio_keys_polled.c | 39 +++++++++++++++++++++----------
 include/linux/gpio_keys.h                 |  3 +++
 2 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
index 432d36395f35..b7a514ced509 100644
--- a/drivers/input/keyboard/gpio_keys_polled.c
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -23,6 +23,7 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/gpio_keys.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -51,15 +52,14 @@ static void gpio_keys_polled_check_state(struct input_dev *input,
 	int state;
 
 	if (bdata->can_sleep)
-		state = !!gpio_get_value_cansleep(button->gpio);
+		state = !!gpiod_get_value_cansleep(button->gpiod);
 	else
-		state = !!gpio_get_value(button->gpio);
+		state = !!gpiod_get_value(button->gpiod);
 
 	if (state != bdata->last_state) {
 		unsigned int type = button->type ?: EV_KEY;
 
-		input_event(input, type, button->code,
-			    !!(state ^ button->active_low));
+		input_event(input, type, button->code, state);
 		input_sync(input);
 		bdata->count = 0;
 		bdata->last_state = state;
@@ -259,7 +259,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
 	for (i = 0; i < pdata->nbuttons; i++) {
 		struct gpio_keys_button *button = &pdata->buttons[i];
 		struct gpio_keys_button_data *bdata = &bdev->data[i];
-		unsigned int gpio = button->gpio;
 		unsigned int type = button->type ?: EV_KEY;
 
 		if (button->wakeup) {
@@ -267,15 +266,31 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
 			return -EINVAL;
 		}
 
-		error = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_IN,
-					      button->desc ? : DRV_NAME);
-		if (error) {
-			dev_err(dev, "unable to claim gpio %u, err=%d\n",
-				gpio, error);
-			return error;
+		/*
+		 * Legacy GPIO number so request the GPIO here and
+		 * convert it to descriptor.
+		 */
+		if (!button->gpiod && gpio_is_valid(button->gpio)) {
+			unsigned flags = 0;
+
+			if (button->active_low)
+				flags |= GPIOF_ACTIVE_LOW;
+
+			error = devm_gpio_request_one(&pdev->dev, button->gpio,
+					flags, button->desc ? : DRV_NAME);
+			if (error) {
+				dev_err(dev, "unable to claim gpio %u, err=%d\n",
+					button->gpio, error);
+				return error;
+			}
+
+			button->gpiod = gpio_to_desc(button->gpio);
 		}
 
-		bdata->can_sleep = gpio_cansleep(gpio);
+		if (IS_ERR(button->gpiod))
+			return PTR_ERR(button->gpiod);
+
+		bdata->can_sleep = gpiod_cansleep(button->gpiod);
 		bdata->last_state = -1;
 		bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
 						pdata->poll_interval);
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
index 8b622468952c..ee2d8c6f9130 100644
--- a/include/linux/gpio_keys.h
+++ b/include/linux/gpio_keys.h
@@ -2,6 +2,7 @@
 #define _GPIO_KEYS_H
 
 struct device;
+struct gpio_desc;
 
 /**
  * struct gpio_keys_button - configuration parameters
@@ -17,6 +18,7 @@ struct device;
  *			disable button via sysfs
  * @value:		axis value for %EV_ABS
  * @irq:		Irq number in case of interrupt keys
+ * @gpiod:		GPIO descriptor
  */
 struct gpio_keys_button {
 	unsigned int code;
@@ -29,6 +31,7 @@ struct gpio_keys_button {
 	bool can_disable;
 	int value;
 	unsigned int irq;
+	struct gpio_desc *gpiod;
 };
 
 /**
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 13/16] input: gpio_keys_polled - Make use of device property API
  2014-09-16 11:52 ` Mika Westerberg
                   ` (12 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

From: Aaron Lu <aaron.lu@intel.com>

Make use of device property API in this driver so that both OF based
system and ACPI based system can use this driver.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/input/keyboard/gpio_keys_polled.c | 125 ++++++++++++++----------------
 1 file changed, 59 insertions(+), 66 deletions(-)

diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
index b7a514ced509..9afd9a6c43f4 100644
--- a/drivers/input/keyboard/gpio_keys_polled.c
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -25,9 +25,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio_keys.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/of_gpio.h>
+#include <linux/property.h>
 
 #define DRV_NAME	"gpio-keys-polled"
 
@@ -45,6 +43,11 @@ struct gpio_keys_polled_dev {
 	struct gpio_keys_button_data data[0];
 };
 
+struct gpio_keys_devtree_data {
+	struct device *dev;
+	struct gpio_keys_platform_data *pdata;
+};
+
 static void gpio_keys_polled_check_state(struct input_dev *input,
 					 struct gpio_keys_button *button,
 					 struct gpio_keys_button_data *bdata)
@@ -102,21 +105,56 @@ static void gpio_keys_polled_close(struct input_polled_dev *dev)
 		pdata->disable(bdev->dev);
 }
 
-#ifdef CONFIG_OF
+static int gpio_keys_polled_get_button(struct fw_dev_node *fdn, void *data)
+{
+	struct gpio_keys_devtree_data *dtdata = data;
+	struct gpio_keys_platform_data *pdata = dtdata->pdata;
+	struct device *dev = dtdata->dev;
+	struct gpio_keys_button *button;
+	struct gpio_desc *desc;
+
+	desc = devm_node_get_named_gpiod(dev, fdn, "gpios", 0);
+	if (IS_ERR(desc)) {
+		int err = PTR_ERR(desc);
+
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get gpio flags, error: %d\n",
+				err);
+		return err;
+	}
+
+	button = &pdata->buttons[pdata->nbuttons++];
+	button->gpiod = desc;
+
+	if (dev_node_property_read_u32(fdn, "linux,code", &button->code)) {
+		dev_err(dev, "Button without keycode: %d\n",
+			pdata->nbuttons - 1);
+		return -EINVAL;
+	}
+
+	dev_node_property_read_string(fdn, "label", &button->desc);
+
+	if (dev_node_property_read_u32(fdn, "linux,input-type", &button->type))
+		button->type = EV_KEY;
+
+	button->wakeup = !dev_node_get_property(fdn, "gpio-key,wakeup", NULL);
+
+	if (dev_node_property_read_u32(fdn, "debounce-interval",
+				       &button->debounce_interval))
+		button->debounce_interval = 5;
+
+	return 0;
+}
+
 static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev)
 {
-	struct device_node *node, *pp;
+	struct gpio_keys_devtree_data dtdata;
 	struct gpio_keys_platform_data *pdata;
 	struct gpio_keys_button *button;
 	int error;
 	int nbuttons;
-	int i;
 
-	node = dev->of_node;
-	if (!node)
-		return NULL;
-
-	nbuttons = of_get_child_count(node);
+	nbuttons = device_get_child_node_count(dev);
 	if (nbuttons == 0)
 		return NULL;
 
@@ -126,54 +164,18 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct
 		return ERR_PTR(-ENOMEM);
 
 	pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
-	pdata->nbuttons = nbuttons;
-
-	pdata->rep = !!of_get_property(node, "autorepeat", NULL);
-	of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
-
-	i = 0;
-	for_each_child_of_node(node, pp) {
-		int gpio;
-		enum of_gpio_flags flags;
-
-		if (!of_find_property(pp, "gpios", NULL)) {
-			pdata->nbuttons--;
-			dev_warn(dev, "Found button without gpios\n");
-			continue;
-		}
-
-		gpio = of_get_gpio_flags(pp, 0, &flags);
-		if (gpio < 0) {
-			error = gpio;
-			if (error != -EPROBE_DEFER)
-				dev_err(dev,
-					"Failed to get gpio flags, error: %d\n",
-					error);
-			return ERR_PTR(error);
-		}
 
-		button = &pdata->buttons[i++];
+	pdata->rep = !device_get_property(dev, "autorepeat", NULL);
+	device_property_read_u32(dev, "poll-interval", &pdata->poll_interval);
 
-		button->gpio = gpio;
-		button->active_low = flags & OF_GPIO_ACTIVE_LOW;
+	memset(&dtdata, 0, sizeof(dtdata));
+	dtdata.pdata = pdata;
+	dtdata.dev = dev;
 
-		if (of_property_read_u32(pp, "linux,code", &button->code)) {
-			dev_err(dev, "Button without keycode: 0x%x\n",
-				button->gpio);
-			return ERR_PTR(-EINVAL);
-		}
-
-		button->desc = of_get_property(pp, "label", NULL);
-
-		if (of_property_read_u32(pp, "linux,input-type", &button->type))
-			button->type = EV_KEY;
-
-		button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
-
-		if (of_property_read_u32(pp, "debounce-interval",
-					 &button->debounce_interval))
-			button->debounce_interval = 5;
-	}
+	error = device_for_each_child_node(dev, gpio_keys_polled_get_button,
+					   &dtdata);
+	if (error)
+		return ERR_PTR(error);
 
 	if (pdata->nbuttons == 0)
 		return ERR_PTR(-EINVAL);
@@ -187,15 +189,6 @@ static const struct of_device_id gpio_keys_polled_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
 
-#else
-
-static inline struct gpio_keys_platform_data *
-gpio_keys_polled_get_devtree_pdata(struct device *dev)
-{
-	return NULL;
-}
-#endif
-
 static int gpio_keys_polled_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -323,7 +316,7 @@ static struct platform_driver gpio_keys_polled_driver = {
 	.driver	= {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
-		.of_match_table = of_match_ptr(gpio_keys_polled_of_match),
+		.of_match_table = gpio_keys_polled_of_match,
 	},
 };
 module_platform_driver(gpio_keys_polled_driver);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 14/16] input: gpio_keys_polled - Add ACPI probing support
  2014-09-16 11:52 ` Mika Westerberg
                   ` (13 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

Allow the driver to probe from ACPI namespace.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/input/keyboard/gpio_keys_polled.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
index 9afd9a6c43f4..89bf5732d200 100644
--- a/drivers/input/keyboard/gpio_keys_polled.c
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -189,6 +189,12 @@ static const struct of_device_id gpio_keys_polled_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
 
+static const struct acpi_device_id gpio_keys_polled_acpi_match[] = {
+	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, gpio_keys_polled_acpi_match);
+
 static int gpio_keys_polled_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -317,6 +323,7 @@ static struct platform_driver gpio_keys_polled_driver = {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
 		.of_match_table = gpio_keys_polled_of_match,
+		.acpi_match_table = gpio_keys_polled_acpi_match,
 	},
 };
 module_platform_driver(gpio_keys_polled_driver);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 15/16] misc: at25: Make use of device property API
  2014-09-16 11:52 ` Mika Westerberg
                   ` (14 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

Make use of device property API in this driver so that both DT and ACPI
based systems can use this driver.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/misc/eeprom/at25.c | 34 +++++++++++++---------------------
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 634f72929e12..58f6cdd2551c 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -18,7 +18,7 @@
 
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
-#include <linux/of.h>
+#include <linux/property.h>
 
 /*
  * NOTE: this is an *EEPROM* driver.  The vagaries of product naming
@@ -301,35 +301,33 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
 
 /*-------------------------------------------------------------------------*/
 
-static int at25_np_to_chip(struct device *dev,
-			   struct device_node *np,
-			   struct spi_eeprom *chip)
+static int at25_fw_to_chip(struct device *dev, struct spi_eeprom *chip)
 {
 	u32 val;
 
 	memset(chip, 0, sizeof(*chip));
-	strncpy(chip->name, np->name, sizeof(chip->name));
+	strncpy(chip->name, "at25", sizeof(chip->name));
 
-	if (of_property_read_u32(np, "size", &val) == 0 ||
-	    of_property_read_u32(np, "at25,byte-len", &val) == 0) {
+	if (device_property_read_u32(dev, "size", &val) == 0 ||
+	    device_property_read_u32(dev, "at25,byte-len", &val) == 0) {
 		chip->byte_len = val;
 	} else {
 		dev_err(dev, "Error: missing \"size\" property\n");
 		return -ENODEV;
 	}
 
-	if (of_property_read_u32(np, "pagesize", &val) == 0 ||
-	    of_property_read_u32(np, "at25,page-size", &val) == 0) {
+	if (device_property_read_u32(dev, "pagesize", &val) == 0 ||
+	    device_property_read_u32(dev, "at25,page-size", &val) == 0) {
 		chip->page_size = (u16)val;
 	} else {
 		dev_err(dev, "Error: missing \"pagesize\" property\n");
 		return -ENODEV;
 	}
 
-	if (of_property_read_u32(np, "at25,addr-mode", &val) == 0) {
+	if (device_property_read_u32(dev, "at25,addr-mode", &val) == 0) {
 		chip->flags = (u16)val;
 	} else {
-		if (of_property_read_u32(np, "address-width", &val)) {
+		if (device_property_read_u32(dev, "address-width", &val)) {
 			dev_err(dev,
 				"Error: missing \"address-width\" property\n");
 			return -ENODEV;
@@ -350,7 +348,7 @@ static int at25_np_to_chip(struct device *dev,
 				val);
 			return -ENODEV;
 		}
-		if (of_find_property(np, "read-only", NULL))
+		if (!device_get_property(dev, "read-only", NULL))
 			chip->flags |= EE_READONLY;
 	}
 	return 0;
@@ -360,21 +358,15 @@ static int at25_probe(struct spi_device *spi)
 {
 	struct at25_data	*at25 = NULL;
 	struct spi_eeprom	chip;
-	struct device_node	*np = spi->dev.of_node;
 	int			err;
 	int			sr;
 	int			addrlen;
 
 	/* Chip description */
 	if (!spi->dev.platform_data) {
-		if (np) {
-			err = at25_np_to_chip(&spi->dev, np, &chip);
-			if (err)
-				return err;
-		} else {
-			dev_err(&spi->dev, "Error: no chip description\n");
-			return -ENODEV;
-		}
+		err = at25_fw_to_chip(&spi->dev, &chip);
+		if (err)
+			return err;
 	} else
 		chip = *(struct spi_eeprom *)spi->dev.platform_data;
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC PATCH v2 16/16] misc: at25: Add ACPI probing support
  2014-09-16 11:52 ` Mika Westerberg
                   ` (15 preceding siblings ...)
  (?)
@ 2014-09-16 11:52 ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-16 11:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart,
	Mika Westerberg

Add support for matching using DT compatible string from ACPI _DSD.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/misc/eeprom/at25.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 58f6cdd2551c..1a760cd966bd 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -459,11 +459,18 @@ static const struct of_device_id at25_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, at25_of_match);
 
+static const struct acpi_device_id at25_acpi_match[] = {
+	{ "PRP0001" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, at25_acpi_match);
+
 static struct spi_driver at25_driver = {
 	.driver = {
 		.name		= "at25",
 		.owner		= THIS_MODULE,
 		.of_match_table = at25_of_match,
+		.acpi_match_table = at25_acpi_match,
 	},
 	.probe		= at25_probe,
 	.remove		= at25_remove,
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 05/16] mfd: Add ACPI support
  2014-09-16 11:52 ` [RFC PATCH v2 05/16] mfd: Add ACPI support Mika Westerberg
@ 2014-09-16 21:54     ` Lee Jones
  2014-09-24 12:00     ` Lee Jones
  1 sibling, 0 replies; 152+ messages in thread
From: Lee Jones @ 2014-09-16 21:54 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, linux-kernel,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Grant Likely, Arnd Bergmann, Aaron Lu,
	Darren Hart

On Tue, 16 Sep 2014, Mika Westerberg wrote:

> If an MFD device is backed by ACPI namespace, we should allow subdevice
> drivers to access their corresponding ACPI companion devices through normal
> means (e.g using ACPI_COMPANION()).
> 
> This patch adds such support to the MFD core. If the MFD parent device
> does not specify any ACPI _HID/_CID for the child device, the child
> device will share the parent ACPI companion device. Otherwise the child
> device will be assigned with the corresponding ACPI companion, if found
> in the namespace below the parent.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Reviewed-by: Darren Hart <dvhart@linux.intel.com>
> ---
> Lee, I tried to get rid of #ifdefs in the below patch but it wasn't
> possible because we are using functions that are not available when
> !CONFIG_ACPI.
> 
>  Documentation/acpi/enumeration.txt | 27 +++++++++++++++++++++++++
>  drivers/mfd/mfd-core.c             | 40 ++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/core.h           |  3 +++
>  3 files changed, 70 insertions(+)

Acked-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 05/16] mfd: Add ACPI support
@ 2014-09-16 21:54     ` Lee Jones
  0 siblings, 0 replies; 152+ messages in thread
From: Lee Jones @ 2014-09-16 21:54 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, linux-kernel,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Grant Likely, Arnd Bergmann, Aaron Lu,
	Darren Hart

On Tue, 16 Sep 2014, Mika Westerberg wrote:

> If an MFD device is backed by ACPI namespace, we should allow subdevice
> drivers to access their corresponding ACPI companion devices through normal
> means (e.g using ACPI_COMPANION()).
> 
> This patch adds such support to the MFD core. If the MFD parent device
> does not specify any ACPI _HID/_CID for the child device, the child
> device will share the parent ACPI companion device. Otherwise the child
> device will be assigned with the corresponding ACPI companion, if found
> in the namespace below the parent.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Reviewed-by: Darren Hart <dvhart@linux.intel.com>
> ---
> Lee, I tried to get rid of #ifdefs in the below patch but it wasn't
> possible because we are using functions that are not available when
> !CONFIG_ACPI.
> 
>  Documentation/acpi/enumeration.txt | 27 +++++++++++++++++++++++++
>  drivers/mfd/mfd-core.c             | 40 ++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/core.h           |  3 +++
>  3 files changed, 70 insertions(+)

Acked-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 02/16] Driver core: Unified device properties interface for platform firmware
  2014-09-16 11:52 ` [RFC PATCH v2 02/16] Driver core: Unified device properties interface for platform firmware Mika Westerberg
@ 2014-09-17 18:28   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 152+ messages in thread
From: Greg Kroah-Hartman @ 2014-09-17 18:28 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, linux-kernel,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

On Tue, Sep 16, 2014 at 02:52:33PM +0300, Mika Westerberg wrote:
> From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> 
> Add a uniform interface by which device drivers can request device
> properties from the platform firmware by providing a property name
> and the corresponding data type.  The purpose of it is to help to
> write portable code that won't depend on any particular platform
> firmware interface.
> 
> Three general helper functions, device_get_property(),
> device_read_property() and device_read_property_array() are provided.
> The first one allows the raw value of a given device property to be
> accessed by the driver.  The remaining two allow the value of a numeric
> or string property and multiple numeric or string values of one array
> property to be acquired, respectively.  Static inline wrappers are also
> provided for the various property data types that can be passed to
> device_read_property() or device_read_property_array() for extra type
> checking.
> 
> In addition to that new generic routines are provided for retrieving
> properties from device description objects in the platform firmware
> in case there are no struct device objects for them (either those
> objects have not been created yet or they do not exist at all).
> Again, three functions are provided, dev_node_get_property(),
> dev_node_read_property(), dev_node_read_property_array(), in analogy
> with device_get_property(), device_read_property() and
> device_read_property_array() described above, respectively, along
> with static inline wrappers for all of the propery data types that
> can be used.  For all of them, the first argument is a pointer to
> struct fw_dev_node (new type) that in turn contains exactly one
> valid pointer to a device description object (depending on what
> platform firmware interface is in use).
> 
> Finally, device_for_each_child_node() is added for iterating over
> the children of the device description object associated with the
> given device.
> 
> The interface covers both ACPI and Device Trees.
> 
> This change set includes material from Mika Westerberg and Aaron Lu.
> 
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Looks good to me, feel free to take this through your tree with my:

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 09/16] leds: leds-gpio: Add support for GPIO descriptors
  2014-09-16 11:52 ` [RFC PATCH v2 09/16] leds: leds-gpio: Add support for GPIO descriptors Mika Westerberg
@ 2014-09-19  8:18   ` Alexandre Courbot
  2014-09-24  7:55   ` Linus Walleij
  1 sibling, 0 replies; 152+ messages in thread
From: Alexandre Courbot @ 2014-09-19  8:18 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, devicetree,
	Linux Kernel Mailing List, Greg Kroah-Hartman, Linus Walleij,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely,
	Arnd Bergmann, Aaron Lu, Darren Hart

On Tue, Sep 16, 2014 at 8:52 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> GPIO descriptors are the preferred way over legacy GPIO numbers
> nowadays. Convert the driver to use GPIO descriptors internally but
> still allow passing legacy GPIO numbers from platform data to support
> existing platforms.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Obviously a good thing to do.

Acked-by: Alexandre Courbot <acourbot@nvidia.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 12/16] input: gpio_keys_polled - Add support for GPIO descriptors
  2014-09-16 11:52 ` [RFC PATCH v2 12/16] input: gpio_keys_polled - Add support for GPIO descriptors Mika Westerberg
@ 2014-09-19  8:22   ` Alexandre Courbot
  2014-09-24  8:02   ` Linus Walleij
  1 sibling, 0 replies; 152+ messages in thread
From: Alexandre Courbot @ 2014-09-19  8:22 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, devicetree,
	Linux Kernel Mailing List, Greg Kroah-Hartman, Linus Walleij,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely,
	Arnd Bergmann, Aaron Lu, Darren Hart

On Tue, Sep 16, 2014 at 8:52 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> From: Aaron Lu <aaron.lu@intel.com>
>
> GPIO descriptors are the preferred way over legacy GPIO numbers
> nowadays. Convert the driver to use GPIO descriptors internally but
> still allow passing legacy GPIO numbers from platform data to support
> existing platforms.
>
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Acked-by: Alexandre Courbot <acourbot@nvidia.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 00/16] Add ACPI _DSD and unified device properties support
  2014-09-16 11:52 ` Mika Westerberg
                   ` (16 preceding siblings ...)
  (?)
@ 2014-09-21  0:26 ` Rafael J. Wysocki
  2014-09-24  8:34   ` Lee Jones
  -1 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-09-21  0:26 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

On Tuesday, September 16, 2014 02:52:31 PM Mika Westerberg wrote:
> This is a second revision of the patches first submitted here [1].
> 
> The recent publication of the ACPI 5.1 specification [2] adds a reserved name
> for Device Specific Data (_DSD, Section 6.2.5). This mechanism allows for
> passing arbitrary hardware description data to the OS. The exact format of the
> _DSD data is specific to the UUID paired with it [3].   
> 
> An ACPI Device Properties UUID has been defined [4] to provide a format
> compatible with existing device tree schemas. The purpose for this was to
> allow for the reuse of the existing schemas and encourage the development
> of firmware agnostic device drivers.
> 
> This series accomplishes the following (as well as some other dependencies):
> 
>  * Add _DSD support to the ACPI core
>    This simply reads the UUID and the accompanying Package
> 
>  * Add ACPI Device Properties _DSD format support
>    This understands the hierarchical key:value pair structure
>    defined by the Device Properties UUID
> 
>  * Add a unified device properties API with ACPI and OF backends
>    This provides for the firmware agnostic device properties
>    Interface to be used by drivers
> 
>  * Provides 3 example drivers that were previously Device Tree aware that
>    can now be used with either Device Tree or ACPI Device Properties. The
>    drivers use "PRP0001" as their _HID which means that the match should be
>    done using driver's .of_match_table instead.
> 
> The patch series has been tested on Minnoboard and Minnowboard MAX and the
> relevant part of DSDTs are at the end of this cover letter.
> 
> This series does not provide for a means to append to a system DSDT. That
> will ultimately be required to make the most effective use of the _DSD
> mechanism. Work is underway on that as a separate effort.
> 
> Most important changes to the previous RFC version:
> 
>   * Added wrapper functions for most used property types
>   * Return -EOVERFLOW in case integer would not fit to a type
>   * Dropped dev_prop_ops
>   * We now have dev_node_xxx() functions to access firmware node
>     properties without dev pointer
>   * The accessor function names try to be close to their corresponding of_*
>     counterpart
>   * Tried to have a bit better examples in the documentation patch
>   * gpiolib got support for _DSD and also it now understand firmware node
>     properties with dev_node_get_named_gpiod() that requests the GPIO
>     properly.
>   * Support for "PRP0001" _HID/_CID. This means that the match should be
>     done using driver .of_match_table instead.
>   * Add unified property support for at25 SPI eeprom driver as well.
> 
> [1] https://lkml.org/lkml/2014/8/17/10
> [2] http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf
> [3] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
> [4] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> 
> Aaron Lu (2):
>   input: gpio_keys_polled - Add support for GPIO descriptors
>   input: gpio_keys_polled - Make use of device property API
> 
> Max Eliaser (2):
>   leds: leds-gpio: Make use of device property API
>   leds: leds-gpio: Add ACPI probing support
> 
> Mika Westerberg (11):
>   ACPI: Add support for device specific properties
>   ACPI: Allow drivers to match using Device Tree compatible property
>   ACPI: Document ACPI device specific properties
>   mfd: Add ACPI support
>   gpio / ACPI: Add support for _DSD device properties
>   gpio: Add support for unified device properties interface
>   gpio: sch: Consolidate core and resume banks
>   leds: leds-gpio: Add support for GPIO descriptors
>   input: gpio_keys_polled - Add ACPI probing support
>   misc: at25: Make use of device property API
>   misc: at25: Add ACPI probing support

Given the ACKs that we've got already (the Greg's one in particular) and
the apparent lack of objections (or indeed any comments at all), I'm about
to queue this up for 3.18 next week.

Rafael


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 00/16] Add ACPI _DSD and unified device properties support
  2014-09-16 11:52 ` Mika Westerberg
                   ` (17 preceding siblings ...)
  (?)
@ 2014-09-22 23:29 ` Bryan Wu
  -1 siblings, 0 replies; 152+ messages in thread
From: Bryan Wu @ 2014-09-22 23:29 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, lkml,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Lee Jones, Grant Likely, Arnd Bergmann,
	Aaron Lu, Darren Hart

On Tue, Sep 16, 2014 at 4:52 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> This is a second revision of the patches first submitted here [1].
>
> The recent publication of the ACPI 5.1 specification [2] adds a reserved name
> for Device Specific Data (_DSD, Section 6.2.5). This mechanism allows for
> passing arbitrary hardware description data to the OS. The exact format of the
> _DSD data is specific to the UUID paired with it [3].
>
> An ACPI Device Properties UUID has been defined [4] to provide a format
> compatible with existing device tree schemas. The purpose for this was to
> allow for the reuse of the existing schemas and encourage the development
> of firmware agnostic device drivers.
>
> This series accomplishes the following (as well as some other dependencies):
>
>  * Add _DSD support to the ACPI core
>    This simply reads the UUID and the accompanying Package
>
>  * Add ACPI Device Properties _DSD format support
>    This understands the hierarchical key:value pair structure
>    defined by the Device Properties UUID
>
>  * Add a unified device properties API with ACPI and OF backends
>    This provides for the firmware agnostic device properties
>    Interface to be used by drivers
>
>  * Provides 3 example drivers that were previously Device Tree aware that
>    can now be used with either Device Tree or ACPI Device Properties. The
>    drivers use "PRP0001" as their _HID which means that the match should be
>    done using driver's .of_match_table instead.
>
> The patch series has been tested on Minnoboard and Minnowboard MAX and the
> relevant part of DSDTs are at the end of this cover letter.
>
> This series does not provide for a means to append to a system DSDT. That
> will ultimately be required to make the most effective use of the _DSD
> mechanism. Work is underway on that as a separate effort.
>
> Most important changes to the previous RFC version:
>
>   * Added wrapper functions for most used property types
>   * Return -EOVERFLOW in case integer would not fit to a type
>   * Dropped dev_prop_ops
>   * We now have dev_node_xxx() functions to access firmware node
>     properties without dev pointer
>   * The accessor function names try to be close to their corresponding of_*
>     counterpart
>   * Tried to have a bit better examples in the documentation patch
>   * gpiolib got support for _DSD and also it now understand firmware node
>     properties with dev_node_get_named_gpiod() that requests the GPIO
>     properly.
>   * Support for "PRP0001" _HID/_CID. This means that the match should be
>     done using driver .of_match_table instead.
>   * Add unified property support for at25 SPI eeprom driver as well.
>
> [1] https://lkml.org/lkml/2014/8/17/10
> [2] http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf
> [3] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
> [4] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
>
> Aaron Lu (2):
>   input: gpio_keys_polled - Add support for GPIO descriptors
>   input: gpio_keys_polled - Make use of device property API
>
> Max Eliaser (2):
>   leds: leds-gpio: Make use of device property API
>   leds: leds-gpio: Add ACPI probing support
>
> Mika Westerberg (11):
>   ACPI: Add support for device specific properties
>   ACPI: Allow drivers to match using Device Tree compatible property
>   ACPI: Document ACPI device specific properties
>   mfd: Add ACPI support
>   gpio / ACPI: Add support for _DSD device properties
>   gpio: Add support for unified device properties interface
>   gpio: sch: Consolidate core and resume banks
>   leds: leds-gpio: Add support for GPIO descriptors
>   input: gpio_keys_polled - Add ACPI probing support
>   misc: at25: Make use of device property API
>   misc: at25: Add ACPI probing support
>
> Rafael J. Wysocki (1):
>   Driver core: Unified device properties interface for platform firmware
>

I'm good with the LEDs change, please go ahead with my Ack
Acked-by: Bryan Wu <cooloney@gmail.com>

Thanks,
-Bryan


>  Documentation/acpi/enumeration.txt        |  27 ++
>  Documentation/acpi/properties.txt         | 410 +++++++++++++++++++++
>  drivers/acpi/Makefile                     |   1 +
>  drivers/acpi/internal.h                   |   6 +
>  drivers/acpi/property.c                   | 584 ++++++++++++++++++++++++++++++
>  drivers/acpi/scan.c                       |  93 ++++-
>  drivers/base/Makefile                     |   2 +-
>  drivers/base/property.c                   | 196 ++++++++++
>  drivers/gpio/devres.c                     |  35 ++
>  drivers/gpio/gpio-sch.c                   | 293 ++++++---------
>  drivers/gpio/gpiolib-acpi.c               |  78 +++-
>  drivers/gpio/gpiolib.c                    |  85 ++++-
>  drivers/gpio/gpiolib.h                    |   7 +-
>  drivers/input/keyboard/gpio_keys_polled.c | 169 +++++----
>  drivers/leds/leds-gpio.c                  | 188 +++++-----
>  drivers/mfd/mfd-core.c                    |  40 ++
>  drivers/misc/eeprom/at25.c                |  41 +--
>  drivers/of/base.c                         | 188 ++++++++++
>  include/acpi/acpi_bus.h                   |   8 +
>  include/linux/acpi.h                      |  90 ++++-
>  include/linux/gpio/consumer.h             |   7 +
>  include/linux/gpio_keys.h                 |   3 +
>  include/linux/leds.h                      |   1 +
>  include/linux/mfd/core.h                  |   3 +
>  include/linux/of.h                        |  37 ++
>  include/linux/property.h                  | 193 ++++++++++
>  26 files changed, 2377 insertions(+), 408 deletions(-)
>  create mode 100644 Documentation/acpi/properties.txt
>  create mode 100644 drivers/acpi/property.c
>  create mode 100644 drivers/base/property.c
>  create mode 100644 include/linux/property.h
>
> DSDT modifications for Minnowboard (for leds-gpio.c and gpio_keys_polled.c)
> ---------------------------------------------------------------------------
>
>     Scope (\_SB.PCI0.LPC)
>     {
>         Device (LEDS)
>         {
>             Name (_HID, "PRP0001")
>
>             Name (_CRS, ResourceTemplate () {
>                 GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
>                         "\\_SB.PCI0.LPC", 0, ResourceConsumer) {10}
>                 GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
>                         "\\_SB.PCI0.LPC", 0, ResourceConsumer) {11}
>             })
>
>             Name (_DSD, Package () {
>                   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                   Package () {
>                       Package () {"compatible", Package () {"gpio-leds"}},
>                   }
>             })
>
>             Device (LEDH)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"label", "Heartbeat"},
>                         Package () {"gpios", Package () {^^LEDS, 0, 0, 0}},
>                         Package () {"linux,default-trigger", "heartbeat"},
>                         Package () {"linux,default-state", "off"},
>                         Package () {"linux,retain-state-suspended", 1},
>                     }
>                 })
>             }
>
>             Device (LEDM)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"label", "MMC0 Activity"},
>                         Package () {"gpios", Package () {^^LEDS, 1, 0, 0}},
>                         Package () {"linux,default-trigger", "mmc0"},
>                         Package () {"linux,default-state", "off"},
>                         Package () {"linux,retain-state-suspended", 1},
>                     }
>                 })
>             }
>         }
>
>         Device (BTNS)
>         {
>             Name (_HID, "PRP0001")
>
>             Name (_CRS, ResourceTemplate () {
>                 GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
>                         "\\_SB.PCI0.LPC", 0, ResourceConsumer) {0, 1, 2, 3}
>             })
>
>             Name (_DSD, Package () {
>                 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                 Package () {
>                     Package () {"compatible", Package () {"gpio-keys-polled"}},
>                     Package () {"poll-interval", 100},
>                     Package () {"autorepeat", 1}
>                 }
>             })
>
>             Device (BTN0)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"linux,code", 105},
>                         Package () {"linux,input-type", 1},
>                         Package () {"gpios", Package () {^^BTNS, 0, 0, 1}},
>                     }
>                 })
>             }
>
>             Device (BTN1)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"linux,code", 108},
>                         Package () {"linux,input-type", 1},
>                         Package () {"gpios", Package (4) {^^BTNS, 0, 1, 1}},
>                     }
>                 })
>             }
>
>             Device (BTN2)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"linux,code", 103},
>                         Package () {"linux,input-type", 1},
>                         Package () {"gpios", Package () {^^BTNS, 0, 2, 1}},
>                     }
>                 })
>             }
>
>             Device (BTN3)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package ()
>                     {
>                         Package () {"linux,code", 106},
>                         Package () {"linux,input-type", 1},
>                         Package () {"gpios", Package (4) {^^BTNS, 0, 3, 1}},
>                     }
>                 })
>             }
>         }
>     }
>
> DSDT modifications for Minnowboard MAX (for at25.c)
> ---------------------------------------------------
>
>     Scope (\_SB.SPI1)
>     {
>         Device (AT25)
>         {
>             Name (_HID, "PRP0001")
>             Method (_CRS, 0, Serialized) {
>                 Name (UBUF, ResourceTemplate () {
>                     SpiSerialBus (0x0000, PolarityLow, FourWireMode, 0x08,
>                         ControllerInitiated, 0x007A1200, ClockPolarityLow,
>                         ClockPhaseSecond, "\\_SB.SPI1",
>                         0x00, ResourceConsumer)
>                 })
>                 Return (UBUF)
>             }
>
>             Name (_DSD, Package () {
>                 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                 Package () {
>                     Package () {"compatible", Package () {"atmel,at25"}},
>                     Package () {"size", 1024},
>                     Package () {"pagesize", 32},
>                     Package () {"address-width", 16},
>                 }
>             })
>
>             Method (_STA, 0, NotSerialized)
>             {
>                 Return (0xF)
>             }
>         }
>     }
> --
> 2.1.0
>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-16 11:52 ` [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface Mika Westerberg
@ 2014-09-23 15:25       ` Linus Walleij
  0 siblings, 0 replies; 152+ messages in thread
From: Linus Walleij @ 2014-09-23 15:25 UTC (permalink / raw)
  To: Mika Westerberg, Grant Likely, Arnd Bergmann, Darren Hart, Mark Rutland
  Cc: Rafael J. Wysocki, ACPI Devel Maling List,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Aaron Lu

On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
<mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote:

> Some drivers need to deal with only firmware representation of its
> GPIOs. An example would be a GPIO button array driver where each button
> is described as a separate firmware node in device tree. Typically these
> child nodes do not have physical representation in the Linux device
> model.
>
> In order to help device drivers to handle such firmware child nodes we
> add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> parameter, finds the GPIO using whatever is the underlying firmware
> method, and requests the GPIO properly.
>
> Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

I have a hard time figuring out if this is what we want for common
accessors between DT and ACPI.

Can I get some input from Grant, Arnd, Mark, Darren...?

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
@ 2014-09-23 15:25       ` Linus Walleij
  0 siblings, 0 replies; 152+ messages in thread
From: Linus Walleij @ 2014-09-23 15:25 UTC (permalink / raw)
  To: Mika Westerberg, Grant Likely, Arnd Bergmann, Darren Hart, Mark Rutland
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Aaron Lu

On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:

> Some drivers need to deal with only firmware representation of its
> GPIOs. An example would be a GPIO button array driver where each button
> is described as a separate firmware node in device tree. Typically these
> child nodes do not have physical representation in the Linux device
> model.
>
> In order to help device drivers to handle such firmware child nodes we
> add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> parameter, finds the GPIO using whatever is the underlying firmware
> method, and requests the GPIO properly.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

I have a hard time figuring out if this is what we want for common
accessors between DT and ACPI.

Can I get some input from Grant, Arnd, Mark, Darren...?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 06/16] gpio / ACPI: Add support for _DSD device properties
  2014-09-16 11:52 ` [RFC PATCH v2 06/16] gpio / ACPI: Add support for _DSD device properties Mika Westerberg
@ 2014-09-23 15:27   ` Linus Walleij
  0 siblings, 0 replies; 152+ messages in thread
From: Linus Walleij @ 2014-09-23 15:27 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely,
	Arnd Bergmann, Aaron Lu, Darren Hart

On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:

> With release of ACPI 5.1 and _DSD method we can finally name GPIOs (and
> other things as well) returned by _CRS. Previously we were only able to
> use integer index to find the corresponding GPIO, which is pretty error
> prone if the order changes.
>
> With _DSD we can now query GPIOs using name instead of an integer index,
> like the below example shows:
>
>   // Bluetooth device with reset and shutdown GPIOs
>   Device (BTH)
>   {
>       Name (_HID, ...)
>
>       Name (_CRS, ResourceTemplate ()
>       {
>           GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
>                   "\\_SB.GPO0", 0, ResourceConsumer) {15}
>           GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
>                   "\\_SB.GPO0", 0, ResourceConsumer) {27, 31}
>       })
>
>       Name (_DSD, Package ()
>       {
>           ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>           Package ()
>           {
>               Package () {"reset-gpio", Package() {^BTH, 1, 1, 0 }},
>               Package () {"shutdown-gpio", Package() {^BTH, 0, 0, 0 }},
>           }
>       })
>   }
>
> The format of the supported GPIO property is:
>
>   Package () { "name", Package () { ref, index, pin, active_low }}
>
>   ref - The device that has _CRS containing GpioIo()/GpioInt() resources,
>         typically this is the device itself (BTH in our case).
>   index - Index of the GpioIo()/GpioInt() resource in _CRS starting from zero.
>   pin - Pin in the GpioIo()/GpioInt() resource. Typically this is zero.
>   active_low - If 1 the GPIO is marked as active_low.
>
> Since ACPI GpioIo() resource does not have field saying whether it is
> active low or high, the "active_low" argument can be used here. Setting
> it to 1 marks the GPIO as active low.
>
> In our Bluetooth example the "reset-gpio" refers to the second GpioIo()
> resource, second pin in that resource with the GPIO number of 31.
>
> This patch implements necessary support to gpiolib for extracting GPIOs
> using _DSD device properties.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

If Rafael is happy with this approach, and you decide to take it
through the ACPI tree.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 15:25       ` Linus Walleij
  (?)
@ 2014-09-23 15:45       ` Arnd Bergmann
  2014-09-23 15:52           ` Mika Westerberg
  2014-09-23 16:25           ` Rafael J. Wysocki
  -1 siblings, 2 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-09-23 15:45 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mika Westerberg, Grant Likely, Darren Hart, Mark Rutland,
	Rafael J. Wysocki, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Aaron Lu

On Tuesday 23 September 2014 17:25:50 Linus Walleij wrote:
> On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> 
> > Some drivers need to deal with only firmware representation of its
> > GPIOs. An example would be a GPIO button array driver where each button
> > is described as a separate firmware node in device tree. Typically these
> > child nodes do not have physical representation in the Linux device
> > model.
> >
> > In order to help device drivers to handle such firmware child nodes we
> > add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> > parameter, finds the GPIO using whatever is the underlying firmware
> > method, and requests the GPIO properly.
> >
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> I have a hard time figuring out if this is what we want for common
> accessors between DT and ACPI.
> 
> Can I get some input from Grant, Arnd, Mark, Darren...?

I just took a brief look at this. My first impression is that the
fw_dev_node structure is weird when all callers just do (in patch 2)

+	struct fw_dev_node fdn = {
+		.of_node = dev->of_node,
+		.acpi_node = ACPI_COMPANION(dev),
+	};

I'd much rather see an interface that passes the 'struct device'
pointer down to dev_get_named_gpiod() and all other exported
functions, and then internally does the conversion at the point
where the access is done.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 15:45       ` Arnd Bergmann
@ 2014-09-23 15:52           ` Mika Westerberg
  2014-09-23 16:25           ` Rafael J. Wysocki
  1 sibling, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-23 15:52 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linus Walleij, Grant Likely, Darren Hart, Mark Rutland,
	Rafael J. Wysocki, ACPI Devel Maling List,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Aaron Lu

On Tue, Sep 23, 2014 at 05:45:57PM +0200, Arnd Bergmann wrote:
> On Tuesday 23 September 2014 17:25:50 Linus Walleij wrote:
> > On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
> > <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote:
> > 
> > > Some drivers need to deal with only firmware representation of its
> > > GPIOs. An example would be a GPIO button array driver where each button
> > > is described as a separate firmware node in device tree. Typically these
> > > child nodes do not have physical representation in the Linux device
> > > model.
> > >
> > > In order to help device drivers to handle such firmware child nodes we
> > > add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> > > parameter, finds the GPIO using whatever is the underlying firmware
> > > method, and requests the GPIO properly.
> > >
> > > Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> > 
> > I have a hard time figuring out if this is what we want for common
> > accessors between DT and ACPI.
> > 
> > Can I get some input from Grant, Arnd, Mark, Darren...?
> 
> I just took a brief look at this. My first impression is that the
> fw_dev_node structure is weird when all callers just do (in patch 2)
> 
> +	struct fw_dev_node fdn = {
> +		.of_node = dev->of_node,
> +		.acpi_node = ACPI_COMPANION(dev),
> +	};
> 
> I'd much rather see an interface that passes the 'struct device'
> pointer down to dev_get_named_gpiod() and all other exported
> functions, and then internally does the conversion at the point
> where the access is done.

Problem is that if you don't have the dev pointer in the first place.
Please look how leds-gpio.c or gpio_keys_polled.c are using this.

Of course you have the first level device but when you need to iterate
"leds" or "buttons" below where there is no Linux device available we
need something like this.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
@ 2014-09-23 15:52           ` Mika Westerberg
  0 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-23 15:52 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linus Walleij, Grant Likely, Darren Hart, Mark Rutland,
	Rafael J. Wysocki, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Aaron Lu

On Tue, Sep 23, 2014 at 05:45:57PM +0200, Arnd Bergmann wrote:
> On Tuesday 23 September 2014 17:25:50 Linus Walleij wrote:
> > On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
> > <mika.westerberg@linux.intel.com> wrote:
> > 
> > > Some drivers need to deal with only firmware representation of its
> > > GPIOs. An example would be a GPIO button array driver where each button
> > > is described as a separate firmware node in device tree. Typically these
> > > child nodes do not have physical representation in the Linux device
> > > model.
> > >
> > > In order to help device drivers to handle such firmware child nodes we
> > > add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> > > parameter, finds the GPIO using whatever is the underlying firmware
> > > method, and requests the GPIO properly.
> > >
> > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > 
> > I have a hard time figuring out if this is what we want for common
> > accessors between DT and ACPI.
> > 
> > Can I get some input from Grant, Arnd, Mark, Darren...?
> 
> I just took a brief look at this. My first impression is that the
> fw_dev_node structure is weird when all callers just do (in patch 2)
> 
> +	struct fw_dev_node fdn = {
> +		.of_node = dev->of_node,
> +		.acpi_node = ACPI_COMPANION(dev),
> +	};
> 
> I'd much rather see an interface that passes the 'struct device'
> pointer down to dev_get_named_gpiod() and all other exported
> functions, and then internally does the conversion at the point
> where the access is done.

Problem is that if you don't have the dev pointer in the first place.
Please look how leds-gpio.c or gpio_keys_polled.c are using this.

Of course you have the first level device but when you need to iterate
"leds" or "buttons" below where there is no Linux device available we
need something like this.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 15:52           ` Mika Westerberg
  (?)
@ 2014-09-23 16:17           ` Dmitry Torokhov
       [not found]             ` <20140923161724.GA40700-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org>
  -1 siblings, 1 reply; 152+ messages in thread
From: Dmitry Torokhov @ 2014-09-23 16:17 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Arnd Bergmann, Linus Walleij, Grant Likely, Darren Hart,
	Mark Rutland, Rafael J. Wysocki, ACPI Devel Maling List,
	devicetree, linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Bryan Wu, Lee Jones, Aaron Lu

On Tue, Sep 23, 2014 at 06:52:02PM +0300, Mika Westerberg wrote:
> On Tue, Sep 23, 2014 at 05:45:57PM +0200, Arnd Bergmann wrote:
> > On Tuesday 23 September 2014 17:25:50 Linus Walleij wrote:
> > > On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
> > > <mika.westerberg@linux.intel.com> wrote:
> > > 
> > > > Some drivers need to deal with only firmware representation of its
> > > > GPIOs. An example would be a GPIO button array driver where each button
> > > > is described as a separate firmware node in device tree. Typically these
> > > > child nodes do not have physical representation in the Linux device
> > > > model.
> > > >
> > > > In order to help device drivers to handle such firmware child nodes we
> > > > add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> > > > parameter, finds the GPIO using whatever is the underlying firmware
> > > > method, and requests the GPIO properly.
> > > >
> > > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > 
> > > I have a hard time figuring out if this is what we want for common
> > > accessors between DT and ACPI.
> > > 
> > > Can I get some input from Grant, Arnd, Mark, Darren...?
> > 
> > I just took a brief look at this. My first impression is that the
> > fw_dev_node structure is weird when all callers just do (in patch 2)
> > 
> > +	struct fw_dev_node fdn = {
> > +		.of_node = dev->of_node,
> > +		.acpi_node = ACPI_COMPANION(dev),
> > +	};
> > 
> > I'd much rather see an interface that passes the 'struct device'
> > pointer down to dev_get_named_gpiod() and all other exported
> > functions, and then internally does the conversion at the point
> > where the access is done.
> 
> Problem is that if you don't have the dev pointer in the first place.
> Please look how leds-gpio.c or gpio_keys_polled.c are using this.
> 
> Of course you have the first level device but when you need to iterate
> "leds" or "buttons" below where there is no Linux device available we
> need something like this.

Maybe we should be passing the parent/owner device to the iterator
functions?

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 15:45       ` Arnd Bergmann
@ 2014-09-23 16:25           ` Rafael J. Wysocki
  2014-09-23 16:25           ` Rafael J. Wysocki
  1 sibling, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-09-23 16:25 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linus Walleij, Mika Westerberg, Grant Likely, Darren Hart,
	Mark Rutland, ACPI Devel Maling List,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Aaron Lu

On Tuesday, September 23, 2014 05:45:57 PM Arnd Bergmann wrote:
> On Tuesday 23 September 2014 17:25:50 Linus Walleij wrote:
> > On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
> > <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote:
> > 
> > > Some drivers need to deal with only firmware representation of its
> > > GPIOs. An example would be a GPIO button array driver where each button
> > > is described as a separate firmware node in device tree. Typically these
> > > child nodes do not have physical representation in the Linux device
> > > model.
> > >
> > > In order to help device drivers to handle such firmware child nodes we
> > > add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> > > parameter, finds the GPIO using whatever is the underlying firmware
> > > method, and requests the GPIO properly.
> > >
> > > Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> > 
> > I have a hard time figuring out if this is what we want for common
> > accessors between DT and ACPI.
> > 
> > Can I get some input from Grant, Arnd, Mark, Darren...?
> 
> I just took a brief look at this. My first impression is that the
> fw_dev_node structure is weird when all callers just do (in patch 2)
> 
> +	struct fw_dev_node fdn = {
> +		.of_node = dev->of_node,
> +		.acpi_node = ACPI_COMPANION(dev),
> +	};
> 
> I'd much rather see an interface that passes the 'struct device'
> pointer down to dev_get_named_gpiod() and all other exported
> functions, and then internally does the conversion at the point
> where the access is done.

The problem is iteration over child nodes of a given one where there
may not be struct device objects.

For example (from patch [2/16]):

+int acpi_for_each_child_node(struct acpi_device *adev,
+                             int (*fn)(struct fw_dev_node *fdn, void *data),
+                             void *data)
+{
+       struct acpi_device *child;
+       int ret = 0;
+
+       list_for_each_entry(child, &adev->children, node) {
+               struct fw_dev_node fdn = { .acpi_node = child, };
+
+               ret = fn(&fdn, data);
+               if (ret)
+                       break;
+       }
+       return ret;
+}

and then fn() can be made work for both DTs and ACPI.  Without this we'd
need to have two versions of fn(), one for DTs and one for ACPI (and possibly
more for some other FW protocols), which isn't necessary in general (and
duplicates code etc.). 

That actually is used by some patches down in the series (eg. [10/16]).

Rafael

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
@ 2014-09-23 16:25           ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-09-23 16:25 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linus Walleij, Mika Westerberg, Grant Likely, Darren Hart,
	Mark Rutland, ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Tuesday, September 23, 2014 05:45:57 PM Arnd Bergmann wrote:
> On Tuesday 23 September 2014 17:25:50 Linus Walleij wrote:
> > On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
> > <mika.westerberg@linux.intel.com> wrote:
> > 
> > > Some drivers need to deal with only firmware representation of its
> > > GPIOs. An example would be a GPIO button array driver where each button
> > > is described as a separate firmware node in device tree. Typically these
> > > child nodes do not have physical representation in the Linux device
> > > model.
> > >
> > > In order to help device drivers to handle such firmware child nodes we
> > > add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> > > parameter, finds the GPIO using whatever is the underlying firmware
> > > method, and requests the GPIO properly.
> > >
> > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > 
> > I have a hard time figuring out if this is what we want for common
> > accessors between DT and ACPI.
> > 
> > Can I get some input from Grant, Arnd, Mark, Darren...?
> 
> I just took a brief look at this. My first impression is that the
> fw_dev_node structure is weird when all callers just do (in patch 2)
> 
> +	struct fw_dev_node fdn = {
> +		.of_node = dev->of_node,
> +		.acpi_node = ACPI_COMPANION(dev),
> +	};
> 
> I'd much rather see an interface that passes the 'struct device'
> pointer down to dev_get_named_gpiod() and all other exported
> functions, and then internally does the conversion at the point
> where the access is done.

The problem is iteration over child nodes of a given one where there
may not be struct device objects.

For example (from patch [2/16]):

+int acpi_for_each_child_node(struct acpi_device *adev,
+                             int (*fn)(struct fw_dev_node *fdn, void *data),
+                             void *data)
+{
+       struct acpi_device *child;
+       int ret = 0;
+
+       list_for_each_entry(child, &adev->children, node) {
+               struct fw_dev_node fdn = { .acpi_node = child, };
+
+               ret = fn(&fdn, data);
+               if (ret)
+                       break;
+       }
+       return ret;
+}

and then fn() can be made work for both DTs and ACPI.  Without this we'd
need to have two versions of fn(), one for DTs and one for ACPI (and possibly
more for some other FW protocols), which isn't necessary in general (and
duplicates code etc.). 

That actually is used by some patches down in the series (eg. [10/16]).

Rafael


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 16:25           ` Rafael J. Wysocki
@ 2014-09-23 16:26               ` Arnd Bergmann
  -1 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-09-23 16:26 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linus Walleij, Mika Westerberg, Grant Likely, Darren Hart,
	Mark Rutland, ACPI Devel Maling List,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Aaron Lu

On Tuesday 23 September 2014 18:25:01 Rafael J. Wysocki wrote:
> The problem is iteration over child nodes of a given one where there
> may not be struct device objects.
> 
> For example (from patch [2/16]):
> 
> +int acpi_for_each_child_node(struct acpi_device *adev,
> +                             int (*fn)(struct fw_dev_node *fdn, void *data),
> +                             void *data)
> +{
> +       struct acpi_device *child;
> +       int ret = 0;
> +
> +       list_for_each_entry(child, &adev->children, node) {
> +               struct fw_dev_node fdn = { .acpi_node = child, };
> +
> +               ret = fn(&fdn, data);
> +               if (ret)
> +                       break;
> +       }
> +       return ret;
> +}
> 
> and then fn() can be made work for both DTs and ACPI.  Without this we'd
> need to have two versions of fn(), one for DTs and one for ACPI (and possibly
> more for some other FW protocols), which isn't necessary in general (and
> duplicates code etc.). 
> 
> That actually is used by some patches down in the series (eg. [10/16]).
> 

Ok, I understand what you are doing now.

Looking at the example you point to (http://www.spinics.net/lists/devicetree/msg49502.html), I still feel
that this is adding more abstraction than what is good for us, and
I'd be happier with an implementation of gpio_leds_create() that
has a bit more duplication and less abstraction.

The important part should be that the driver-side interface is
sensible, other than that an implementation like

static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
{
	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
		return gpio_leds_create_of(pdev);
	else if (IS_ENABLED(CONFIG_ACPI))
		return gpio_leds_create_of(acpi);
	return ERR_PTR(-ENXIO);
}

would keep either side of it relatively simple, by leaving out the
indirect function calls and new for_each_available_child_of_node()
macro.

How many other users of fw_dev_node do you have at the moment?

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
@ 2014-09-23 16:26               ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-09-23 16:26 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linus Walleij, Mika Westerberg, Grant Likely, Darren Hart,
	Mark Rutland, ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Tuesday 23 September 2014 18:25:01 Rafael J. Wysocki wrote:
> The problem is iteration over child nodes of a given one where there
> may not be struct device objects.
> 
> For example (from patch [2/16]):
> 
> +int acpi_for_each_child_node(struct acpi_device *adev,
> +                             int (*fn)(struct fw_dev_node *fdn, void *data),
> +                             void *data)
> +{
> +       struct acpi_device *child;
> +       int ret = 0;
> +
> +       list_for_each_entry(child, &adev->children, node) {
> +               struct fw_dev_node fdn = { .acpi_node = child, };
> +
> +               ret = fn(&fdn, data);
> +               if (ret)
> +                       break;
> +       }
> +       return ret;
> +}
> 
> and then fn() can be made work for both DTs and ACPI.  Without this we'd
> need to have two versions of fn(), one for DTs and one for ACPI (and possibly
> more for some other FW protocols), which isn't necessary in general (and
> duplicates code etc.). 
> 
> That actually is used by some patches down in the series (eg. [10/16]).
> 

Ok, I understand what you are doing now.

Looking at the example you point to (http://www.spinics.net/lists/devicetree/msg49502.html), I still feel
that this is adding more abstraction than what is good for us, and
I'd be happier with an implementation of gpio_leds_create() that
has a bit more duplication and less abstraction.

The important part should be that the driver-side interface is
sensible, other than that an implementation like

static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
{
	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
		return gpio_leds_create_of(pdev);
	else if (IS_ENABLED(CONFIG_ACPI))
		return gpio_leds_create_of(acpi);
	return ERR_PTR(-ENXIO);
}

would keep either side of it relatively simple, by leaving out the
indirect function calls and new for_each_available_child_of_node()
macro.

How many other users of fw_dev_node do you have at the moment?

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 16:17           ` Dmitry Torokhov
@ 2014-09-23 20:31                 ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-09-23 20:31 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Mika Westerberg, Arnd Bergmann, Linus Walleij, Grant Likely,
	Darren Hart, Mark Rutland, ACPI Devel Maling List,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Alexandre Courbot, Bryan Wu, Lee Jones, Aaron Lu

On Tuesday, September 23, 2014 09:17:24 AM Dmitry Torokhov wrote:
> On Tue, Sep 23, 2014 at 06:52:02PM +0300, Mika Westerberg wrote:
> > On Tue, Sep 23, 2014 at 05:45:57PM +0200, Arnd Bergmann wrote:
> > > On Tuesday 23 September 2014 17:25:50 Linus Walleij wrote:
> > > > On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
> > > > <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote:
> > > > 
> > > > > Some drivers need to deal with only firmware representation of its
> > > > > GPIOs. An example would be a GPIO button array driver where each button
> > > > > is described as a separate firmware node in device tree. Typically these
> > > > > child nodes do not have physical representation in the Linux device
> > > > > model.
> > > > >
> > > > > In order to help device drivers to handle such firmware child nodes we
> > > > > add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> > > > > parameter, finds the GPIO using whatever is the underlying firmware
> > > > > method, and requests the GPIO properly.
> > > > >
> > > > > Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> > > > 
> > > > I have a hard time figuring out if this is what we want for common
> > > > accessors between DT and ACPI.
> > > > 
> > > > Can I get some input from Grant, Arnd, Mark, Darren...?
> > > 
> > > I just took a brief look at this. My first impression is that the
> > > fw_dev_node structure is weird when all callers just do (in patch 2)
> > > 
> > > +	struct fw_dev_node fdn = {
> > > +		.of_node = dev->of_node,
> > > +		.acpi_node = ACPI_COMPANION(dev),
> > > +	};
> > > 
> > > I'd much rather see an interface that passes the 'struct device'
> > > pointer down to dev_get_named_gpiod() and all other exported
> > > functions, and then internally does the conversion at the point
> > > where the access is done.
> > 
> > Problem is that if you don't have the dev pointer in the first place.
> > Please look how leds-gpio.c or gpio_keys_polled.c are using this.
> > 
> > Of course you have the first level device but when you need to iterate
> > "leds" or "buttons" below where there is no Linux device available we
> > need something like this.
> 
> Maybe we should be passing the parent/owner device to the iterator
> functions?

Yes, we can do that.  That's one alternative for what we have in the current
set.

Rafael

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
@ 2014-09-23 20:31                 ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-09-23 20:31 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Mika Westerberg, Arnd Bergmann, Linus Walleij, Grant Likely,
	Darren Hart, Mark Rutland, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot, Bryan Wu,
	Lee Jones, Aaron Lu

On Tuesday, September 23, 2014 09:17:24 AM Dmitry Torokhov wrote:
> On Tue, Sep 23, 2014 at 06:52:02PM +0300, Mika Westerberg wrote:
> > On Tue, Sep 23, 2014 at 05:45:57PM +0200, Arnd Bergmann wrote:
> > > On Tuesday 23 September 2014 17:25:50 Linus Walleij wrote:
> > > > On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
> > > > <mika.westerberg@linux.intel.com> wrote:
> > > > 
> > > > > Some drivers need to deal with only firmware representation of its
> > > > > GPIOs. An example would be a GPIO button array driver where each button
> > > > > is described as a separate firmware node in device tree. Typically these
> > > > > child nodes do not have physical representation in the Linux device
> > > > > model.
> > > > >
> > > > > In order to help device drivers to handle such firmware child nodes we
> > > > > add dev[m]_node_get_named_gpiod() that takes a firmware node pointer as
> > > > > parameter, finds the GPIO using whatever is the underlying firmware
> > > > > method, and requests the GPIO properly.
> > > > >
> > > > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > > 
> > > > I have a hard time figuring out if this is what we want for common
> > > > accessors between DT and ACPI.
> > > > 
> > > > Can I get some input from Grant, Arnd, Mark, Darren...?
> > > 
> > > I just took a brief look at this. My first impression is that the
> > > fw_dev_node structure is weird when all callers just do (in patch 2)
> > > 
> > > +	struct fw_dev_node fdn = {
> > > +		.of_node = dev->of_node,
> > > +		.acpi_node = ACPI_COMPANION(dev),
> > > +	};
> > > 
> > > I'd much rather see an interface that passes the 'struct device'
> > > pointer down to dev_get_named_gpiod() and all other exported
> > > functions, and then internally does the conversion at the point
> > > where the access is done.
> > 
> > Problem is that if you don't have the dev pointer in the first place.
> > Please look how leds-gpio.c or gpio_keys_polled.c are using this.
> > 
> > Of course you have the first level device but when you need to iterate
> > "leds" or "buttons" below where there is no Linux device available we
> > need something like this.
> 
> Maybe we should be passing the parent/owner device to the iterator
> functions?

Yes, we can do that.  That's one alternative for what we have in the current
set.

Rafael


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 16:26               ` Arnd Bergmann
  (?)
@ 2014-09-23 20:47               ` Rafael J. Wysocki
       [not found]                 ` <1579761.oeYleOAY1N-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
  -1 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-09-23 20:47 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linus Walleij, Mika Westerberg, Grant Likely, Darren Hart,
	Mark Rutland, ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Tuesday, September 23, 2014 06:26:07 PM Arnd Bergmann wrote:
> On Tuesday 23 September 2014 18:25:01 Rafael J. Wysocki wrote:
> > The problem is iteration over child nodes of a given one where there
> > may not be struct device objects.
> > 
> > For example (from patch [2/16]):
> > 
> > +int acpi_for_each_child_node(struct acpi_device *adev,
> > +                             int (*fn)(struct fw_dev_node *fdn, void *data),
> > +                             void *data)
> > +{
> > +       struct acpi_device *child;
> > +       int ret = 0;
> > +
> > +       list_for_each_entry(child, &adev->children, node) {
> > +               struct fw_dev_node fdn = { .acpi_node = child, };
> > +
> > +               ret = fn(&fdn, data);
> > +               if (ret)
> > +                       break;
> > +       }
> > +       return ret;
> > +}
> > 
> > and then fn() can be made work for both DTs and ACPI.  Without this we'd
> > need to have two versions of fn(), one for DTs and one for ACPI (and possibly
> > more for some other FW protocols), which isn't necessary in general (and
> > duplicates code etc.). 
> > 
> > That actually is used by some patches down in the series (eg. [10/16]).
> > 
> 
> Ok, I understand what you are doing now.
> 
> Looking at the example you point to (http://www.spinics.net/lists/devicetree/msg49502.html), I still feel
> that this is adding more abstraction than what is good for us, and
> I'd be happier with an implementation of gpio_leds_create() that
> has a bit more duplication and less abstraction.
> 
> The important part should be that the driver-side interface is
> sensible, other than that an implementation like
> 
> static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
> {
> 	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
> 		return gpio_leds_create_of(pdev);
> 	else if (IS_ENABLED(CONFIG_ACPI))
> 		return gpio_leds_create_of(acpi);
> 	return ERR_PTR(-ENXIO);
> }
> 
> would keep either side of it relatively simple, by leaving out the
> indirect function calls and new for_each_available_child_of_node()
> macro.

Quite frankly, I'm not sure what you're asking for.

It seems to mean "I kind of don't like the current implementation", but
then the last part is quite unclear to me.  Are you suggesting to add more
"if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) etc" type of checks to
device drivers?  That I'd like to avoid to be honest.

Instead of the current proposal we can introduce something like

int device_get_child_property(struct device *dev, void *child_node,
                              const char *propname, void **valptr);

(and analogously for device_read_property*) and use that in the drivers that
need to iterate over child nodes of a device.  Quite along the lines of what
Dmitry is suggesting.

Then, fn() in acpi_for_each_child_node() (and the of_ counterpart of it)
would become

int (*fn)(struct device *dev, void *child_node, void *data)

and so on.

Would you prefer that?


> How many other users of fw_dev_node do you have at the moment?

One more, gpio_keys_polled in patch [13/16] (https://patchwork.kernel.org/patch/4917311/).

Rafael


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 16:26               ` Arnd Bergmann
  (?)
  (?)
@ 2014-09-23 21:15               ` Darren Hart
  2014-09-24  9:12                 ` Arnd Bergmann
  -1 siblings, 1 reply; 152+ messages in thread
From: Darren Hart @ 2014-09-23 21:15 UTC (permalink / raw)
  To: Arnd Bergmann, Rafael J. Wysocki, David Woodhouse
  Cc: Linus Walleij, Mika Westerberg, Grant Likely, Mark Rutland,
	ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On 9/23/14, 9:26, "Arnd Bergmann" <arnd@arndb.de> wrote:

>On Tuesday 23 September 2014 18:25:01 Rafael J. Wysocki wrote:
>> The problem is iteration over child nodes of a given one where there
>> may not be struct device objects.
>> 
>> For example (from patch [2/16]):
>> 
>> +int acpi_for_each_child_node(struct acpi_device *adev,
>> +                             int (*fn)(struct fw_dev_node *fdn, void
>>*data),
>> +                             void *data)
>> +{
>> +       struct acpi_device *child;
>> +       int ret = 0;
>> +
>> +       list_for_each_entry(child, &adev->children, node) {
>> +               struct fw_dev_node fdn = { .acpi_node = child, };
>> +
>> +               ret = fn(&fdn, data);
>> +               if (ret)
>> +                       break;
>> +       }
>> +       return ret;
>> +}
>> 
>> and then fn() can be made work for both DTs and ACPI.  Without this we'd
>> need to have two versions of fn(), one for DTs and one for ACPI (and
>>possibly
>> more for some other FW protocols), which isn't necessary in general (and
>> duplicates code etc.).
>> 
>> That actually is used by some patches down in the series (eg. [10/16]).
>> 
>
>Ok, I understand what you are doing now.
>
>Looking at the example you point to
>(http://www.spinics.net/lists/devicetree/msg49502.html), I still feel
>that this is adding more abstraction than what is good for us, and
>I'd be happier with an implementation of gpio_leds_create() that
>has a bit more duplication and less abstraction.
>
>The important part should be that the driver-side interface is
>sensible, other than that an implementation like
>
>static struct gpio_leds_priv *gpio_leds_create(struct platform_device
>*pdev)
>{
>	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
>		return gpio_leds_create_of(pdev);
>	else if (IS_ENABLED(CONFIG_ACPI))
>		return gpio_leds_create_of(acpi);

Arnd, I think you meant:

	Return gpio_leds_create_acpi(pdev) ?

This is what we did early on to prototype this concept, but the problem
with this approach we duplicate all of the creation code, which leads to
maintenance errors, and is inconsistent with the goals of the _DSD which
is to reuse the same schemas for ACPI and FDT. If we have separate pdata
creation functions anyway, we are leaving much of the advantage of the
common schema on the table. Namely the ability to reuse drivers relatively
easily across firmware implementations. We don't want driver authors to
have to care if it's ACPI or FDT.

We would have preferred to have deprecated the of property interface in
favor of the new generic device_property interface, but Grant specifically
requested that we update drivers individually rather than all at once,
which means we can't just kill the OF interface.

We agreed to that, somewhat reluctantly as it adds more work in updating
the drivers over time which will slow adoption, but I understand the
desire not to make large sweeping changes due to the risk of breaking
things inadvertently as we cannot expect to be able to test all of them.
That said, I don't want to forget that the goal is to use the common
interface over time as we convert individual drivers, and using the common
interface means we need a common iterator function and that we not have fw
implementation specific pdata create functions.

--
Darren Hart
Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 20:47               ` Rafael J. Wysocki
@ 2014-09-24  7:55                     ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-09-24  7:55 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linus Walleij, Mika Westerberg, Grant Likely, Darren Hart,
	Mark Rutland, ACPI Devel Maling List,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Aaron Lu

On Tuesday 23 September 2014 22:47:36 Rafael J. Wysocki wrote:
> Quite frankly, I'm not sure what you're asking for.
> 
> It seems to mean "I kind of don't like the current implementation", but
> then the last part is quite unclear to me.  Are you suggesting to add more
> "if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) etc" type of checks to
> device drivers?  That I'd like to avoid to be honest.

No, that is not what I want. Device drivers should ideally call interfaces
that just take a 'struct device' or 'struct platform_device' pointer,
and those should be implemented in an appropriate way.

> Instead of the current proposal we can introduce something like
> 
> int device_get_child_property(struct device *dev, void *child_node,
>                               const char *propname, void **valptr);
> 
> (and analogously for device_read_property*) and use that in the drivers that
> need to iterate over child nodes of a device.  Quite along the lines of what
> Dmitry is suggesting.
> 
> Then, fn() in acpi_for_each_child_node() (and the of_ counterpart of it)
> would become
> 
> int (*fn)(struct device *dev, void *child_node, void *data)
> 
> and so on.
> 
> Would you prefer that?

I must still be missing part of what you are trying to achieve above.
We definitely need an interface to get properties from the device itself,
like

int device_get_property(struct device *dev, const char *propname, void **valptr);

(whatever valptr ends up being, that would be a separate discussion).

As soon as it comes to devices that have child nodes, I don't see a
necessity to have a generic abstraction for them, as this is typically
only done for some of the more obscure bindings, or for child nodes that
are defined in a subsystem-wide binding rather than a device private
binding.

For the former case, I think they are indeed better left in drivers that
actively know the difference between DT and ACPI, and that don't necessarily
use the same binding for both. In the latter case, I'd leave the
implementation up to subsystem code, which again would know what
interface it is using.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
@ 2014-09-24  7:55                     ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-09-24  7:55 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linus Walleij, Mika Westerberg, Grant Likely, Darren Hart,
	Mark Rutland, ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Tuesday 23 September 2014 22:47:36 Rafael J. Wysocki wrote:
> Quite frankly, I'm not sure what you're asking for.
> 
> It seems to mean "I kind of don't like the current implementation", but
> then the last part is quite unclear to me.  Are you suggesting to add more
> "if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) etc" type of checks to
> device drivers?  That I'd like to avoid to be honest.

No, that is not what I want. Device drivers should ideally call interfaces
that just take a 'struct device' or 'struct platform_device' pointer,
and those should be implemented in an appropriate way.

> Instead of the current proposal we can introduce something like
> 
> int device_get_child_property(struct device *dev, void *child_node,
>                               const char *propname, void **valptr);
> 
> (and analogously for device_read_property*) and use that in the drivers that
> need to iterate over child nodes of a device.  Quite along the lines of what
> Dmitry is suggesting.
> 
> Then, fn() in acpi_for_each_child_node() (and the of_ counterpart of it)
> would become
> 
> int (*fn)(struct device *dev, void *child_node, void *data)
> 
> and so on.
> 
> Would you prefer that?

I must still be missing part of what you are trying to achieve above.
We definitely need an interface to get properties from the device itself,
like

int device_get_property(struct device *dev, const char *propname, void **valptr);

(whatever valptr ends up being, that would be a separate discussion).

As soon as it comes to devices that have child nodes, I don't see a
necessity to have a generic abstraction for them, as this is typically
only done for some of the more obscure bindings, or for child nodes that
are defined in a subsystem-wide binding rather than a device private
binding.

For the former case, I think they are indeed better left in drivers that
actively know the difference between DT and ACPI, and that don't necessarily
use the same binding for both. In the latter case, I'd leave the
implementation up to subsystem code, which again would know what
interface it is using.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 09/16] leds: leds-gpio: Add support for GPIO descriptors
  2014-09-16 11:52 ` [RFC PATCH v2 09/16] leds: leds-gpio: Add support for GPIO descriptors Mika Westerberg
  2014-09-19  8:18   ` Alexandre Courbot
@ 2014-09-24  7:55   ` Linus Walleij
  2014-09-24  9:42     ` Mika Westerberg
  1 sibling, 1 reply; 152+ messages in thread
From: Linus Walleij @ 2014-09-24  7:55 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely,
	Arnd Bergmann, Aaron Lu, Darren Hart

On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:

> GPIO descriptors are the preferred way over legacy GPIO numbers
> nowadays. Convert the driver to use GPIO descriptors internally but
> still allow passing legacy GPIO numbers from platform data to support
> existing platforms.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Great!

>  #include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>

You should not need to include <linux/gpio.h> at all after this change.

> @@ -85,9 +91,10 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
>  {
>         struct gpio_led_data *led_dat =
>                 container_of(led_cdev, struct gpio_led_data, cdev);
> +       int gpio = desc_to_gpio(led_dat->gpiod);
>
>         led_dat->blinking = 1;
> -       return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK,
> +       return led_dat->platform_gpio_blink_set(gpio, GPIO_LED_BLINK,
>                                                 delay_on, delay_off);
>  }

While this is a nice first step, it must be possible to patch all in-kernel
users of this callback to take a gpiod too...

It's actually just:

$ git grep gpio_blink_set
arch/arm/mach-orion5x/dns323-setup.c:   .gpio_blink_set =
orion_gpio_led_blink_set,
arch/arm/mach-orion5x/dns323-setup.c:   .gpio_blink_set =
orion_gpio_led_blink_set,
arch/arm/mach-s3c24xx/mach-h1940.c:     .gpio_blink_set = h1940_led_blink_set,
arch/arm/mach-s3c24xx/mach-rx1950.c:    .gpio_blink_set = rx1950_led_blink_set,

However we can do that as a follow-up patch. (Add to TODO...)

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 12/16] input: gpio_keys_polled - Add support for GPIO descriptors
  2014-09-16 11:52 ` [RFC PATCH v2 12/16] input: gpio_keys_polled - Add support for GPIO descriptors Mika Westerberg
  2014-09-19  8:22   ` Alexandre Courbot
@ 2014-09-24  8:02   ` Linus Walleij
  1 sibling, 0 replies; 152+ messages in thread
From: Linus Walleij @ 2014-09-24  8:02 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely,
	Arnd Bergmann, Aaron Lu, Darren Hart

On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:

> From: Aaron Lu <aaron.lu@intel.com>
>
> GPIO descriptors are the preferred way over legacy GPIO numbers
> nowadays. Convert the driver to use GPIO descriptors internally but
> still allow passing legacy GPIO numbers from platform data to support
> existing platforms.
>
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Great!

>  #include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>

Again <linux/gpio.h> should not be needed anymore.

> +               /*
> +                * Legacy GPIO number so request the GPIO here and
> +                * convert it to descriptor.
> +                */
> +               if (!button->gpiod && gpio_is_valid(button->gpio)) {
> +                       unsigned flags = 0;
> +
> +                       if (button->active_low)
> +                               flags |= GPIOF_ACTIVE_LOW;
> +
> +                       error = devm_gpio_request_one(&pdev->dev, button->gpio,
> +                                       flags, button->desc ? : DRV_NAME);
> +                       if (error) {
> +                               dev_err(dev, "unable to claim gpio %u, err=%d\n",
> +                                       button->gpio, error);
> +                               return error;
> +                       }
> +
> +                       button->gpiod = gpio_to_desc(button->gpio);

So the field button->gpio is still there, this is a bit disturbing, but when
I grep for it I see there is a multitude of users :-/

OK I guess these users have to be fixed one by one.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 00/16] Add ACPI _DSD and unified device properties support
  2014-09-21  0:26 ` [RFC PATCH v2 00/16] Add ACPI _DSD and unified device properties support Rafael J. Wysocki
@ 2014-09-24  8:34   ` Lee Jones
  2014-09-24  9:45     ` Mika Westerberg
  0 siblings, 1 reply; 152+ messages in thread
From: Lee Jones @ 2014-09-24  8:34 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, linux-acpi, devicetree, linux-kernel,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Grant Likely, Arnd Bergmann, Aaron Lu,
	Darren Hart

On Sun, 21 Sep 2014, Rafael J. Wysocki wrote:

> On Tuesday, September 16, 2014 02:52:31 PM Mika Westerberg wrote:
> > This is a second revision of the patches first submitted here [1].
> > 
> > The recent publication of the ACPI 5.1 specification [2] adds a reserved name
> > for Device Specific Data (_DSD, Section 6.2.5). This mechanism allows for
> > passing arbitrary hardware description data to the OS. The exact format of the
> > _DSD data is specific to the UUID paired with it [3].   
> > 
> > An ACPI Device Properties UUID has been defined [4] to provide a format
> > compatible with existing device tree schemas. The purpose for this was to
> > allow for the reuse of the existing schemas and encourage the development
> > of firmware agnostic device drivers.
> > 
> > This series accomplishes the following (as well as some other dependencies):
> > 
> >  * Add _DSD support to the ACPI core
> >    This simply reads the UUID and the accompanying Package
> > 
> >  * Add ACPI Device Properties _DSD format support
> >    This understands the hierarchical key:value pair structure
> >    defined by the Device Properties UUID
> > 
> >  * Add a unified device properties API with ACPI and OF backends
> >    This provides for the firmware agnostic device properties
> >    Interface to be used by drivers
> > 
> >  * Provides 3 example drivers that were previously Device Tree aware that
> >    can now be used with either Device Tree or ACPI Device Properties. The
> >    drivers use "PRP0001" as their _HID which means that the match should be
> >    done using driver's .of_match_table instead.
> > 
> > The patch series has been tested on Minnoboard and Minnowboard MAX and the
> > relevant part of DSDTs are at the end of this cover letter.
> > 
> > This series does not provide for a means to append to a system DSDT. That
> > will ultimately be required to make the most effective use of the _DSD
> > mechanism. Work is underway on that as a separate effort.
> > 
> > Most important changes to the previous RFC version:
> > 
> >   * Added wrapper functions for most used property types
> >   * Return -EOVERFLOW in case integer would not fit to a type
> >   * Dropped dev_prop_ops
> >   * We now have dev_node_xxx() functions to access firmware node
> >     properties without dev pointer
> >   * The accessor function names try to be close to their corresponding of_*
> >     counterpart
> >   * Tried to have a bit better examples in the documentation patch
> >   * gpiolib got support for _DSD and also it now understand firmware node
> >     properties with dev_node_get_named_gpiod() that requests the GPIO
> >     properly.
> >   * Support for "PRP0001" _HID/_CID. This means that the match should be
> >     done using driver .of_match_table instead.
> >   * Add unified property support for at25 SPI eeprom driver as well.
> > 
> > [1] https://lkml.org/lkml/2014/8/17/10
> > [2] http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf
> > [3] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
> > [4] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> > 
> > Aaron Lu (2):
> >   input: gpio_keys_polled - Add support for GPIO descriptors
> >   input: gpio_keys_polled - Make use of device property API
> > 
> > Max Eliaser (2):
> >   leds: leds-gpio: Make use of device property API
> >   leds: leds-gpio: Add ACPI probing support
> > 
> > Mika Westerberg (11):
> >   ACPI: Add support for device specific properties
> >   ACPI: Allow drivers to match using Device Tree compatible property
> >   ACPI: Document ACPI device specific properties
> >   mfd: Add ACPI support
> >   gpio / ACPI: Add support for _DSD device properties
> >   gpio: Add support for unified device properties interface
> >   gpio: sch: Consolidate core and resume banks
> >   leds: leds-gpio: Add support for GPIO descriptors
> >   input: gpio_keys_polled - Add ACPI probing support
> >   misc: at25: Make use of device property API
> >   misc: at25: Add ACPI probing support
> 
> Given the ACKs that we've got already (the Greg's one in particular) and
> the apparent lack of objections (or indeed any comments at all), I'm about
> to queue this up for 3.18 next week.

I'd prefer to take the MFD patch through the MFD tree if that's
possible.  Are there any technical reasons why this would prove
difficult?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-23 21:15               ` Darren Hart
@ 2014-09-24  9:12                 ` Arnd Bergmann
  2014-09-24  9:38                   ` Mika Westerberg
  2014-09-26  3:21                   ` Darren Hart
  0 siblings, 2 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-09-24  9:12 UTC (permalink / raw)
  To: Darren Hart
  Cc: Rafael J. Wysocki, David Woodhouse, Linus Walleij,
	Mika Westerberg, Grant Likely, Mark Rutland,
	ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Tuesday 23 September 2014 14:15:47 Darren Hart wrote:
> Arnd, I think you meant:
> 
>         Return gpio_leds_create_acpi(pdev) ?

Yes, sorry for the confusion on my part.

> This is what we did early on to prototype this concept, but the problem
> with this approach we duplicate all of the creation code, which leads to
> maintenance errors, and is inconsistent with the goals of the _DSD which
> is to reuse the same schemas for ACPI and FDT. If we have separate pdata
> creation functions anyway, we are leaving much of the advantage of the
> common schema on the table. Namely the ability to reuse drivers relatively
> easily across firmware implementations. We don't want driver authors to
> have to care if it's ACPI or FDT.

I think we are absolutely in agreement about the basic principle here,
but disagree on how far we'd want to take the abstraction.

I got a little confused by the leds-gpio example, as I initially saw
that as generic infrastructure rather than a specific driver. As I just
wrote in my reply to Rafael, I generally believe we should strive to
have generic driver-side interfaces so drivers don't have to care,
but keep the differences in subsystem specific code.

> We would have preferred to have deprecated the of property interface in
> favor of the new generic device_property interface, but Grant specifically
> requested that we update drivers individually rather than all at once,
> which means we can't just kill the OF interface.

I don't actually have a strong opinion on that matter, having only the
device property interface does have some advantages as well, but I also
agree that we are somewhat better off not having to change all the drivers.

> We agreed to that, somewhat reluctantly as it adds more work in updating
> the drivers over time which will slow adoption, but I understand the
> desire not to make large sweeping changes due to the risk of breaking
> things inadvertently as we cannot expect to be able to test all of them.
> That said, I don't want to forget that the goal is to use the common
> interface over time as we convert individual drivers, and using the common
> interface means we need a common iterator function and that we not have fw
> implementation specific pdata create functions.

I've looked a bit closer at how the LED subsystem handles sub-nodes
in DT at the moment. It seems that there is some duplication between
the drivers already, as they all implement a variation of the sub-node
parsing code.

There are other non-LED drivers with similar loops, but they seem to be
either very specialized, or explicitly for DT abstractions, so I'm still
not convinced we need a generic loop-through-child-nodes-and-parse-properties
interface.

How would you feel about a more general way of probing LED, using
a new helper in the leds-core that iterates over the child nodes
and parses the standard properties but calls into a driver specific
callback to parse the specific properties?
It's probably much more work than your current approach, but it seems
to me that there is more to gain by solving the problem for LED
drivers in particular to cut down the per-driver duplication
at the same time as the per-firmware-interface duplication.

As a start, we could probably take the proposed device_for_each_child_node
and move that into the leds-core, changing the fw_dev_node argument
for an led_classdev with the addition of the of_node and acpi_object
members. It would still leave it up to the gpio-leds driver to do

	if (led_cdev->of_node)
		gpiod = devm_of_get_gpiod(led_cdev->of_node, ...);
	else
		gpiod = devm_acpi_get_gpiod(led_cdev->acpi_object, ...);

but there seems little benefit in abstracting this because there is
only one driver that needs it.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-24  9:12                 ` Arnd Bergmann
@ 2014-09-24  9:38                   ` Mika Westerberg
  2014-09-24 14:11                     ` Rafael J. Wysocki
  2014-09-26  3:21                   ` Darren Hart
  1 sibling, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-09-24  9:38 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Darren Hart, Rafael J. Wysocki, David Woodhouse, Linus Walleij,
	Grant Likely, Mark Rutland, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Aaron Lu

On Wed, Sep 24, 2014 at 11:12:36AM +0200, Arnd Bergmann wrote:
> As a start, we could probably take the proposed device_for_each_child_node
> and move that into the leds-core, changing the fw_dev_node argument
> for an led_classdev with the addition of the of_node and acpi_object
> members. It would still leave it up to the gpio-leds driver to do
> 
> 	if (led_cdev->of_node)
> 		gpiod = devm_of_get_gpiod(led_cdev->of_node, ...);
> 	else
> 		gpiod = devm_acpi_get_gpiod(led_cdev->acpi_object, ...);
> 
> but there seems little benefit in abstracting this because there is
> only one driver that needs it.

The same interface is used also in gpio_keys_polled.c driver so if we
want to avoid duplicating code this needs to be abstracted away from the
drivers.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 09/16] leds: leds-gpio: Add support for GPIO descriptors
  2014-09-24  7:55   ` Linus Walleij
@ 2014-09-24  9:42     ` Mika Westerberg
  0 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-24  9:42 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely,
	Arnd Bergmann, Aaron Lu, Darren Hart

On Wed, Sep 24, 2014 at 09:55:48AM +0200, Linus Walleij wrote:
> On Tue, Sep 16, 2014 at 1:52 PM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> 
> > GPIO descriptors are the preferred way over legacy GPIO numbers
> > nowadays. Convert the driver to use GPIO descriptors internally but
> > still allow passing legacy GPIO numbers from platform data to support
> > existing platforms.
> >
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> Great!
> 
> >  #include <linux/gpio.h>
> > +#include <linux/gpio/consumer.h>
> 
> You should not need to include <linux/gpio.h> at all after this change.

It is still needed because we call devm_gpio_request_one() if we find
legacy numbers from platform data.

> > @@ -85,9 +91,10 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
> >  {
> >         struct gpio_led_data *led_dat =
> >                 container_of(led_cdev, struct gpio_led_data, cdev);
> > +       int gpio = desc_to_gpio(led_dat->gpiod);
> >
> >         led_dat->blinking = 1;
> > -       return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK,
> > +       return led_dat->platform_gpio_blink_set(gpio, GPIO_LED_BLINK,
> >                                                 delay_on, delay_off);
> >  }
> 
> While this is a nice first step, it must be possible to patch all in-kernel
> users of this callback to take a gpiod too...
> 
> It's actually just:
> 
> $ git grep gpio_blink_set
> arch/arm/mach-orion5x/dns323-setup.c:   .gpio_blink_set =
> orion_gpio_led_blink_set,
> arch/arm/mach-orion5x/dns323-setup.c:   .gpio_blink_set =
> orion_gpio_led_blink_set,
> arch/arm/mach-s3c24xx/mach-h1940.c:     .gpio_blink_set = h1940_led_blink_set,
> arch/arm/mach-s3c24xx/mach-rx1950.c:    .gpio_blink_set = rx1950_led_blink_set,
> 
> However we can do that as a follow-up patch. (Add to TODO...)

OK, I'll add that to my TODO list :)

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 00/16] Add ACPI _DSD and unified device properties support
  2014-09-24  8:34   ` Lee Jones
@ 2014-09-24  9:45     ` Mika Westerberg
  0 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-09-24  9:45 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, linux-kernel,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Grant Likely, Arnd Bergmann, Aaron Lu,
	Darren Hart

On Wed, Sep 24, 2014 at 09:34:18AM +0100, Lee Jones wrote:
> I'd prefer to take the MFD patch through the MFD tree if that's
> possible.  Are there any technical reasons why this would prove
> difficult?

I don't see any reasons why it cannot be taken via MFD tree.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 05/16] mfd: Add ACPI support
  2014-09-16 11:52 ` [RFC PATCH v2 05/16] mfd: Add ACPI support Mika Westerberg
@ 2014-09-24 12:00     ` Lee Jones
  2014-09-24 12:00     ` Lee Jones
  1 sibling, 0 replies; 152+ messages in thread
From: Lee Jones @ 2014-09-24 12:00 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, linux-kernel,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Grant Likely, Arnd Bergmann, Aaron Lu,
	Darren Hart

On Tue, 16 Sep 2014, Mika Westerberg wrote:
> If an MFD device is backed by ACPI namespace, we should allow subdevice
> drivers to access their corresponding ACPI companion devices through normal
> means (e.g using ACPI_COMPANION()).
> 
> This patch adds such support to the MFD core. If the MFD parent device
> does not specify any ACPI _HID/_CID for the child device, the child
> device will share the parent ACPI companion device. Otherwise the child
> device will be assigned with the corresponding ACPI companion, if found
> in the namespace below the parent.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Reviewed-by: Darren Hart <dvhart@linux.intel.com>
> ---
> Lee, I tried to get rid of #ifdefs in the below patch but it wasn't
> possible because we are using functions that are not available when
> !CONFIG_ACPI.
> 
>  Documentation/acpi/enumeration.txt | 27 +++++++++++++++++++++++++
>  drivers/mfd/mfd-core.c             | 40 ++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/core.h           |  3 +++
>  3 files changed, 70 insertions(+)

Applied, thanks.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 05/16] mfd: Add ACPI support
@ 2014-09-24 12:00     ` Lee Jones
  0 siblings, 0 replies; 152+ messages in thread
From: Lee Jones @ 2014-09-24 12:00 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, linux-kernel,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Grant Likely, Arnd Bergmann, Aaron Lu,
	Darren Hart

On Tue, 16 Sep 2014, Mika Westerberg wrote:
> If an MFD device is backed by ACPI namespace, we should allow subdevice
> drivers to access their corresponding ACPI companion devices through normal
> means (e.g using ACPI_COMPANION()).
> 
> This patch adds such support to the MFD core. If the MFD parent device
> does not specify any ACPI _HID/_CID for the child device, the child
> device will share the parent ACPI companion device. Otherwise the child
> device will be assigned with the corresponding ACPI companion, if found
> in the namespace below the parent.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Reviewed-by: Darren Hart <dvhart@linux.intel.com>
> ---
> Lee, I tried to get rid of #ifdefs in the below patch but it wasn't
> possible because we are using functions that are not available when
> !CONFIG_ACPI.
> 
>  Documentation/acpi/enumeration.txt | 27 +++++++++++++++++++++++++
>  drivers/mfd/mfd-core.c             | 40 ++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/core.h           |  3 +++
>  3 files changed, 70 insertions(+)

Applied, thanks.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-24  7:55                     ` Arnd Bergmann
  (?)
@ 2014-09-24 14:08                     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-09-24 14:08 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linus Walleij, Mika Westerberg, Grant Likely, Darren Hart,
	Mark Rutland, ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Wednesday, September 24, 2014 09:55:12 AM Arnd Bergmann wrote:
> On Tuesday 23 September 2014 22:47:36 Rafael J. Wysocki wrote:
> > Quite frankly, I'm not sure what you're asking for.
> > 
> > It seems to mean "I kind of don't like the current implementation", but
> > then the last part is quite unclear to me.  Are you suggesting to add more
> > "if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) etc" type of checks to
> > device drivers?  That I'd like to avoid to be honest.
> 
> No, that is not what I want. Device drivers should ideally call interfaces
> that just take a 'struct device' or 'struct platform_device' pointer,
> and those should be implemented in an appropriate way.

But then you have drivers that access properties of their child nodes which
have no corresponding struct device(s).

> > Instead of the current proposal we can introduce something like
> > 
> > int device_get_child_property(struct device *dev, void *child_node,
> >                               const char *propname, void **valptr);
> > 
> > (and analogously for device_read_property*) and use that in the drivers that
> > need to iterate over child nodes of a device.  Quite along the lines of what
> > Dmitry is suggesting.
> > 
> > Then, fn() in acpi_for_each_child_node() (and the of_ counterpart of it)
> > would become
> > 
> > int (*fn)(struct device *dev, void *child_node, void *data)
> > 
> > and so on.
> > 
> > Would you prefer that?
> 
> I must still be missing part of what you are trying to achieve above.
> We definitely need an interface to get properties from the device itself,
> like
> 
> int device_get_property(struct device *dev, const char *propname, void **valptr);
> 
> (whatever valptr ends up being, that would be a separate discussion).
> 
> As soon as it comes to devices that have child nodes, I don't see a
> necessity to have a generic abstraction for them, as this is typically
> only done for some of the more obscure bindings, or for child nodes that
> are defined in a subsystem-wide binding rather than a device private
> binding.

Well, I don't really agree here.

We can demonstrably reduce code duplication (and therefore complexity too) in
at least two drivers by doing that at a reasonably low cost, which is
simply exposing the API for child nodes and adding helpers for iterating
over them.

We don't have to use struct fw_dev_node (or similar) for that if that's what
bothers you, but in my opinion something like "get me a property of this thing
which may be either a device tree node or an ACPI object" (ie. what the current
dev_node_get_property() does) is more straightforwad than "get me a property
of that child of this device which may be either a device tree node or an ACPI
object" (ie. what device_get_child_property() as described above would do).

> For the former case, I think they are indeed better left in drivers that
> actively know the difference between DT and ACPI, and that don't necessarily
> use the same binding for both. In the latter case, I'd leave the
> implementation up to subsystem code, which again would know what
> interface it is using.

The case in question is drivers that need not know the difference between DT and
ACPI and do use the same binding for both.  It seems quite clear what needs to
be done in the other cases.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-24  9:38                   ` Mika Westerberg
@ 2014-09-24 14:11                     ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-09-24 14:11 UTC (permalink / raw)
  To: Mika Westerberg, Arnd Bergmann
  Cc: Darren Hart, David Woodhouse, Linus Walleij, Grant Likely,
	Mark Rutland, ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Wednesday, September 24, 2014 12:38:23 PM Mika Westerberg wrote:
> On Wed, Sep 24, 2014 at 11:12:36AM +0200, Arnd Bergmann wrote:
> > As a start, we could probably take the proposed device_for_each_child_node
> > and move that into the leds-core, changing the fw_dev_node argument
> > for an led_classdev with the addition of the of_node and acpi_object
> > members. It would still leave it up to the gpio-leds driver to do
> > 
> > 	if (led_cdev->of_node)
> > 		gpiod = devm_of_get_gpiod(led_cdev->of_node, ...);
> > 	else
> > 		gpiod = devm_acpi_get_gpiod(led_cdev->acpi_object, ...);
> > 
> > but there seems little benefit in abstracting this because there is
> > only one driver that needs it.
> 
> The same interface is used also in gpio_keys_polled.c driver so if we
> want to avoid duplicating code this needs to be abstracted away from the
> drivers.

Well, precisely.

Moving it to the leds-core doesn't buy us anything.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-24  9:12                 ` Arnd Bergmann
  2014-09-24  9:38                   ` Mika Westerberg
@ 2014-09-26  3:21                   ` Darren Hart
  2014-09-26  8:36                     ` Arnd Bergmann
  2014-10-07 13:37                     ` Linus Walleij
  1 sibling, 2 replies; 152+ messages in thread
From: Darren Hart @ 2014-09-26  3:21 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, David Woodhouse, Linus Walleij,
	Mika Westerberg, Grant Likely, Mark Rutland,
	ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Wed, Sep 24, 2014 at 11:12:36AM +0200, Arnd Bergmann wrote:
> On Tuesday 23 September 2014 14:15:47 Darren Hart wrote:
> > Arnd, I think you meant:
> > 
> >         Return gpio_leds_create_acpi(pdev) ?
> 
> Yes, sorry for the confusion on my part.

Hi Arnd,

No problem, just wanted to make sure I knew what you meant.

> 
> > This is what we did early on to prototype this concept, but the problem
> > with this approach we duplicate all of the creation code, which leads to
> > maintenance errors, and is inconsistent with the goals of the _DSD which
> > is to reuse the same schemas for ACPI and FDT. If we have separate pdata
> > creation functions anyway, we are leaving much of the advantage of the
> > common schema on the table. Namely the ability to reuse drivers relatively
> > easily across firmware implementations. We don't want driver authors to
> > have to care if it's ACPI or FDT.
> 
> I think we are absolutely in agreement about the basic principle here,
> but disagree on how far we'd want to take the abstraction.
> 
> I got a little confused by the leds-gpio example, as I initially saw
> that as generic infrastructure rather than a specific driver. As I just
> wrote in my reply to Rafael, I generally believe we should strive to
> have generic driver-side interfaces so drivers don't have to care,
> but keep the differences in subsystem specific code.
> 
> > We would have preferred to have deprecated the of property interface in
> > favor of the new generic device_property interface, but Grant specifically
> > requested that we update drivers individually rather than all at once,
> > which means we can't just kill the OF interface.
> 
> I don't actually have a strong opinion on that matter, having only the
> device property interface does have some advantages as well, but I also
> agree that we are somewhat better off not having to change all the drivers.
> 
> > We agreed to that, somewhat reluctantly as it adds more work in updating
> > the drivers over time which will slow adoption, but I understand the
> > desire not to make large sweeping changes due to the risk of breaking
> > things inadvertently as we cannot expect to be able to test all of them.
> > That said, I don't want to forget that the goal is to use the common
> > interface over time as we convert individual drivers, and using the common
> > interface means we need a common iterator function and that we not have fw
> > implementation specific pdata create functions.
> 
> I've looked a bit closer at how the LED subsystem handles sub-nodes
> in DT at the moment. It seems that there is some duplication between
> the drivers already, as they all implement a variation of the sub-node
> parsing code.
> 
> There are other non-LED drivers with similar loops, but they seem to be
> either very specialized, or explicitly for DT abstractions, so I'm still
> not convinced we need a generic loop-through-child-nodes-and-parse-properties
> interface.
> 
> How would you feel about a more general way of probing LED, using
> a new helper in the leds-core that iterates over the child nodes
> and parses the standard properties but calls into a driver specific
> callback to parse the specific properties?
> It's probably much more work than your current approach, but it seems
> to me that there is more to gain by solving the problem for LED
> drivers in particular to cut down the per-driver duplication
> at the same time as the per-firmware-interface duplication.
> 
> As a start, we could probably take the proposed device_for_each_child_node
> and move that into the leds-core, changing the fw_dev_node argument
> for an led_classdev with the addition of the of_node and acpi_object
> members. It would still leave it up to the gpio-leds driver to do
> 
> 	if (led_cdev->of_node)
> 		gpiod = devm_of_get_gpiod(led_cdev->of_node, ...);
> 	else
> 		gpiod = devm_acpi_get_gpiod(led_cdev->acpi_object, ...);

So as Mika has pointed out, LEDs aren't the only ones affected. Several drivers
will need to walk through non-device child nodes, and it seems to me that having
a firmware-independent mechanism to do so benefits the drivers by both making
them smaller and by increasing the reusability of new drivers and drivers
updated to use the new API across platforms.

I fear we might be entering bike shed territory as we seem to be repeating
points now. Can you restate your concern with the interface and why this level
of abstraction is worse for the kernel? I'm not seeing this point, so I'm not
sure what to address in my response.

Grant, Linus W? Thoughts?

> 
> but there seems little benefit in abstracting this because there is
> only one driver that needs it.
> 
> 	Arnd
> 

-- 
Darren Hart
Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-26  3:21                   ` Darren Hart
@ 2014-09-26  8:36                     ` Arnd Bergmann
  2014-09-26 14:42                       ` Rafael J. Wysocki
  2014-10-07 13:37                     ` Linus Walleij
  1 sibling, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-09-26  8:36 UTC (permalink / raw)
  To: Darren Hart
  Cc: Rafael J. Wysocki, David Woodhouse, Linus Walleij,
	Mika Westerberg, Grant Likely, Mark Rutland,
	ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Thursday 25 September 2014 20:21:32 Darren Hart wrote:
> On Wed, Sep 24, 2014 at 11:12:36AM +0200, Arnd Bergmann wrote:
> > How would you feel about a more general way of probing LED, using
> > a new helper in the leds-core that iterates over the child nodes
> > and parses the standard properties but calls into a driver specific
> > callback to parse the specific properties?
> > It's probably much more work than your current approach, but it seems
> > to me that there is more to gain by solving the problem for LED
> > drivers in particular to cut down the per-driver duplication
> > at the same time as the per-firmware-interface duplication.
> > 
> > As a start, we could probably take the proposed device_for_each_child_node
> > and move that into the leds-core, changing the fw_dev_node argument
> > for an led_classdev with the addition of the of_node and acpi_object
> > members. It would still leave it up to the gpio-leds driver to do
> > 
> > 	if (led_cdev->of_node)
> > 		gpiod = devm_of_get_gpiod(led_cdev->of_node, ...);
> > 	else
> > 		gpiod = devm_acpi_get_gpiod(led_cdev->acpi_object, ...);
> 
> So as Mika has pointed out, LEDs aren't the only ones affected. Several drivers
> will need to walk through non-device child nodes, and it seems to me that having
> a firmware-independent mechanism to do so benefits the drivers by both making
> them smaller and by increasing the reusability of new drivers and drivers
> updated to use the new API across platforms.
> 
> I fear we might be entering bike shed territory as we seem to be repeating
> points now. Can you restate your concern with the interface and why this level
> of abstraction is worse for the kernel? I'm not seeing this point, so I'm not
> sure what to address in my response.

I think we should have abstractions for all common interfaces but make
them as simple as possible. In the discussions at the kernel summit,
everyone agreed that we should have common accessors for simple properties
(bool, int, string, ...) based on device pointers, as well as subsystem
specific accessors to handle the high-level abstractions (registers,
interrupts, gpio, regulator, pinctrl, dma, reset, pwm, ...).

Having generalized accessors for the same properties in child nodes of
the device goes beyond that, and I think this is the wrong trade-off
between interface simplicity and generality since only few drivers will
be able to use those. I think we will always have to live with a leaky
abstraction because some drivers need to do things beyond what we can
do with a common API.

> Grant, Linus W? Thoughts?

I definitely want to hear other voices on this too. This is really not
a fundamental debate I think, but more a question of how far the abstraction
should go.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-26  8:36                     ` Arnd Bergmann
@ 2014-09-26 14:42                       ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-09-26 14:42 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Darren Hart, David Woodhouse, Linus Walleij, Mika Westerberg,
	Grant Likely, Mark Rutland, ACPI Devel Maling List, devicetree,
	linux-kernel, Greg Kroah-Hartman, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Aaron Lu

On Friday, September 26, 2014 10:36:06 AM Arnd Bergmann wrote:
> On Thursday 25 September 2014 20:21:32 Darren Hart wrote:
> > On Wed, Sep 24, 2014 at 11:12:36AM +0200, Arnd Bergmann wrote:
> > > How would you feel about a more general way of probing LED, using
> > > a new helper in the leds-core that iterates over the child nodes
> > > and parses the standard properties but calls into a driver specific
> > > callback to parse the specific properties?
> > > It's probably much more work than your current approach, but it seems
> > > to me that there is more to gain by solving the problem for LED
> > > drivers in particular to cut down the per-driver duplication
> > > at the same time as the per-firmware-interface duplication.
> > > 
> > > As a start, we could probably take the proposed device_for_each_child_node
> > > and move that into the leds-core, changing the fw_dev_node argument
> > > for an led_classdev with the addition of the of_node and acpi_object
> > > members. It would still leave it up to the gpio-leds driver to do
> > > 
> > > 	if (led_cdev->of_node)
> > > 		gpiod = devm_of_get_gpiod(led_cdev->of_node, ...);
> > > 	else
> > > 		gpiod = devm_acpi_get_gpiod(led_cdev->acpi_object, ...);
> > 
> > So as Mika has pointed out, LEDs aren't the only ones affected. Several drivers
> > will need to walk through non-device child nodes, and it seems to me that having
> > a firmware-independent mechanism to do so benefits the drivers by both making
> > them smaller and by increasing the reusability of new drivers and drivers
> > updated to use the new API across platforms.
> > 
> > I fear we might be entering bike shed territory as we seem to be repeating
> > points now. Can you restate your concern with the interface and why this level
> > of abstraction is worse for the kernel? I'm not seeing this point, so I'm not
> > sure what to address in my response.
> 
> I think we should have abstractions for all common interfaces but make
> them as simple as possible. In the discussions at the kernel summit,
> everyone agreed that we should have common accessors for simple properties
> (bool, int, string, ...) based on device pointers, as well as subsystem
> specific accessors to handle the high-level abstractions (registers,
> interrupts, gpio, regulator, pinctrl, dma, reset, pwm, ...).
> 
> Having generalized accessors for the same properties in child nodes of
> the device goes beyond that, and I think this is the wrong trade-off
> between interface simplicity and generality since only few drivers will
> be able to use those. I think we will always have to live with a leaky
> abstraction because some drivers need to do things beyond what we can
> do with a common API.

Some drivers do, but then we can avoid adding DT/ACPI knowledge to some
drivers by adding general accessors for properties in child nodes.  In my
opinion, drivers should not do things specific to DT/ACPI unless that is
unavoidable.

> 
> > Grant, Linus W? Thoughts?
> 
> I definitely want to hear other voices on this too. This is really not
> a fundamental debate I think, but more a question of how far the abstraction
> should go.

Right.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 00/15] Add ACPI _DSD and unified device properties support
  2014-09-16 11:52 ` Mika Westerberg
                   ` (18 preceding siblings ...)
  (?)
@ 2014-10-01  2:08 ` Rafael J. Wysocki
  2014-10-01  2:08   ` [PATCH v3 01/15] ACPI: Add support for device specific properties Rafael J. Wysocki
                     ` (13 more replies)
  -1 siblings, 14 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

Hi Everyone,

Since Dmitry was suggesting that instead of using struct fw_dev_node pointers,
as we did in the previous version, we could pass the parent device along with
the child pointer to iterator functions while walking the children of a given
device node, the following patches do just that.  Some things look better this
way, but some look worse.  Please tell me what you think.

Mika has tested them on Minnowboard and Minnowboard MAX using the MFD patch
(number 5 previously) that is not included as it has been already applied.

The cover letter below is still applicable mostly, so I'm leaving it as is.

The only patches that changed are [2, 4, 6, 9, 12/15], so I didn't add any
ACKs to them to be prudent.

On Tuesday, September 16, 2014 02:52:31 PM Mika Westerberg wrote:
> This is a second revision of the patches first submitted here [1].
> 
> The recent publication of the ACPI 5.1 specification [2] adds a reserved name
> for Device Specific Data (_DSD, Section 6.2.5). This mechanism allows for
> passing arbitrary hardware description data to the OS. The exact format of the
> _DSD data is specific to the UUID paired with it [3].   
> 
> An ACPI Device Properties UUID has been defined [4] to provide a format
> compatible with existing device tree schemas. The purpose for this was to
> allow for the reuse of the existing schemas and encourage the development
> of firmware agnostic device drivers.
> 
> This series accomplishes the following (as well as some other dependencies):
> 
>  * Add _DSD support to the ACPI core
>    This simply reads the UUID and the accompanying Package
> 
>  * Add ACPI Device Properties _DSD format support
>    This understands the hierarchical key:value pair structure
>    defined by the Device Properties UUID
> 
>  * Add a unified device properties API with ACPI and OF backends
>    This provides for the firmware agnostic device properties
>    Interface to be used by drivers
> 
>  * Provides 3 example drivers that were previously Device Tree aware that
>    can now be used with either Device Tree or ACPI Device Properties. The
>    drivers use "PRP0001" as their _HID which means that the match should be
>    done using driver's .of_match_table instead.
> 
> The patch series has been tested on Minnoboard and Minnowboard MAX and the
> relevant part of DSDTs are at the end of this cover letter.
> 
> This series does not provide for a means to append to a system DSDT. That
> will ultimately be required to make the most effective use of the _DSD
> mechanism. Work is underway on that as a separate effort.
> 
> Most important changes to the previous RFC version:
> 
>   * Added wrapper functions for most used property types
>   * Return -EOVERFLOW in case integer would not fit to a type
>   * Dropped dev_prop_ops
>   * We now have dev_node_xxx() functions to access firmware node
>     properties without dev pointer
>   * The accessor function names try to be close to their corresponding of_*
>     counterpart
>   * Tried to have a bit better examples in the documentation patch
>   * gpiolib got support for _DSD and also it now understand firmware node
>     properties with dev_node_get_named_gpiod() that requests the GPIO
>     properly.
>   * Support for "PRP0001" _HID/_CID. This means that the match should be
>     done using driver .of_match_table instead.
>   * Add unified property support for at25 SPI eeprom driver as well.
> 
> [1] https://lkml.org/lkml/2014/8/17/10
> [2] http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf
> [3] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
> [4] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> 
> Aaron Lu (2):
>   input: gpio_keys_polled - Add support for GPIO descriptors
>   input: gpio_keys_polled - Make use of device property API
> 
> Max Eliaser (2):
>   leds: leds-gpio: Make use of device property API
>   leds: leds-gpio: Add ACPI probing support
> 
> Mika Westerberg (11):
>   ACPI: Add support for device specific properties
>   ACPI: Allow drivers to match using Device Tree compatible property
>   ACPI: Document ACPI device specific properties
>   mfd: Add ACPI support
>   gpio / ACPI: Add support for _DSD device properties
>   gpio: Add support for unified device properties interface
>   gpio: sch: Consolidate core and resume banks
>   leds: leds-gpio: Add support for GPIO descriptors
>   input: gpio_keys_polled - Add ACPI probing support
>   misc: at25: Make use of device property API
>   misc: at25: Add ACPI probing support
> 
> Rafael J. Wysocki (1):
>   Driver core: Unified device properties interface for platform firmware
> 
>  Documentation/acpi/enumeration.txt        |  27 ++
>  Documentation/acpi/properties.txt         | 410 +++++++++++++++++++++
>  drivers/acpi/Makefile                     |   1 +
>  drivers/acpi/internal.h                   |   6 +
>  drivers/acpi/property.c                   | 584 ++++++++++++++++++++++++++++++
>  drivers/acpi/scan.c                       |  93 ++++-
>  drivers/base/Makefile                     |   2 +-
>  drivers/base/property.c                   | 196 ++++++++++
>  drivers/gpio/devres.c                     |  35 ++
>  drivers/gpio/gpio-sch.c                   | 293 ++++++---------
>  drivers/gpio/gpiolib-acpi.c               |  78 +++-
>  drivers/gpio/gpiolib.c                    |  85 ++++-
>  drivers/gpio/gpiolib.h                    |   7 +-
>  drivers/input/keyboard/gpio_keys_polled.c | 169 +++++----
>  drivers/leds/leds-gpio.c                  | 188 +++++-----
>  drivers/mfd/mfd-core.c                    |  40 ++
>  drivers/misc/eeprom/at25.c                |  41 +--
>  drivers/of/base.c                         | 188 ++++++++++
>  include/acpi/acpi_bus.h                   |   8 +
>  include/linux/acpi.h                      |  90 ++++-
>  include/linux/gpio/consumer.h             |   7 +
>  include/linux/gpio_keys.h                 |   3 +
>  include/linux/leds.h                      |   1 +
>  include/linux/mfd/core.h                  |   3 +
>  include/linux/of.h                        |  37 ++
>  include/linux/property.h                  | 193 ++++++++++
>  26 files changed, 2377 insertions(+), 408 deletions(-)
>  create mode 100644 Documentation/acpi/properties.txt
>  create mode 100644 drivers/acpi/property.c
>  create mode 100644 drivers/base/property.c
>  create mode 100644 include/linux/property.h
> 
> DSDT modifications for Minnowboard (for leds-gpio.c and gpio_keys_polled.c)
> ---------------------------------------------------------------------------
> 
>     Scope (\_SB.PCI0.LPC)
>     {
>         Device (LEDS)
>         {
>             Name (_HID, "PRP0001")
> 
>             Name (_CRS, ResourceTemplate () {
>                 GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
>                         "\\_SB.PCI0.LPC", 0, ResourceConsumer) {10}
>                 GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
>                         "\\_SB.PCI0.LPC", 0, ResourceConsumer) {11}
>             })
> 
>             Name (_DSD, Package () {
>                   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                   Package () {
>                       Package () {"compatible", Package () {"gpio-leds"}},
>                   }
>             })
> 
>             Device (LEDH)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"label", "Heartbeat"},
>                         Package () {"gpios", Package () {^^LEDS, 0, 0, 0}},
>                         Package () {"linux,default-trigger", "heartbeat"},
>                         Package () {"linux,default-state", "off"},
>                         Package () {"linux,retain-state-suspended", 1},
>                     }
>                 })
>             }
> 
>             Device (LEDM)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"label", "MMC0 Activity"},
>                         Package () {"gpios", Package () {^^LEDS, 1, 0, 0}},
>                         Package () {"linux,default-trigger", "mmc0"},
>                         Package () {"linux,default-state", "off"},
>                         Package () {"linux,retain-state-suspended", 1},
>                     }
>                 })
>             }
>         }
>         
>         Device (BTNS)
>         {
>             Name (_HID, "PRP0001")
> 
>             Name (_CRS, ResourceTemplate () {
>                 GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
>                         "\\_SB.PCI0.LPC", 0, ResourceConsumer) {0, 1, 2, 3}
>             })
> 
>             Name (_DSD, Package () {
>                 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                 Package () {
>                     Package () {"compatible", Package () {"gpio-keys-polled"}},
>                     Package () {"poll-interval", 100},
>                     Package () {"autorepeat", 1}
>                 }
>             })
> 
>             Device (BTN0)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"linux,code", 105},
>                         Package () {"linux,input-type", 1},
>                         Package () {"gpios", Package () {^^BTNS, 0, 0, 1}},
>                     }
>                 })
>             }
> 
>             Device (BTN1)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"linux,code", 108},
>                         Package () {"linux,input-type", 1},
>                         Package () {"gpios", Package (4) {^^BTNS, 0, 1, 1}},
>                     }
>                 })
>             }
>             
>             Device (BTN2)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package () {
>                         Package () {"linux,code", 103},
>                         Package () {"linux,input-type", 1},
>                         Package () {"gpios", Package () {^^BTNS, 0, 2, 1}},
>                     }
>                 })
>             }
>             
>             Device (BTN3)
>             {
>                 Name (_DSD, Package () {
>                     ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                     Package ()
>                     {
>                         Package () {"linux,code", 106},
>                         Package () {"linux,input-type", 1},
>                         Package () {"gpios", Package (4) {^^BTNS, 0, 3, 1}},
>                     }
>                 })
>             }
>         }
>     }
> 
> DSDT modifications for Minnowboard MAX (for at25.c)
> ---------------------------------------------------
> 
>     Scope (\_SB.SPI1)
>     {
>         Device (AT25)
>         {
>             Name (_HID, "PRP0001")
>             Method (_CRS, 0, Serialized) {
>                 Name (UBUF, ResourceTemplate () {
>                     SpiSerialBus (0x0000, PolarityLow, FourWireMode, 0x08,
>                         ControllerInitiated, 0x007A1200, ClockPolarityLow,
>                         ClockPhaseSecond, "\\_SB.SPI1",
>                         0x00, ResourceConsumer)
>                 })
>                 Return (UBUF)
>             }
> 
>             Name (_DSD, Package () {
>                 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                 Package () {
>                     Package () {"compatible", Package () {"atmel,at25"}},
> 		    Package () {"size", 1024},
> 		    Package () {"pagesize", 32},
> 		    Package () {"address-width", 16},
>                 }
>             })
> 
>             Method (_STA, 0, NotSerialized)
>             {
>                 Return (0xF)
>             }
>         }
>     }
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 01/15] ACPI: Add support for device specific properties
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
@ 2014-10-01  2:08   ` Rafael J. Wysocki
  2014-10-01  7:38     ` Arnd Bergmann
  2014-10-01  2:10   ` [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware Rafael J. Wysocki
                     ` (12 subsequent siblings)
  13 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

Device Tree is used in many embedded systems to describe the system
configuration to the OS. It supports attaching properties or name-value
pairs to the devices it describe. With these properties one can pass
additional information to the drivers that would not be available
otherwise.

ACPI is another configuration mechanism (among other things) typically
seen, but not limited to, x86 machines. ACPI allows passing arbitrary
data from methods but there has not been mechanism equivalent to Device
Tree until the introduction of _DSD in the recent publication of the
ACPI 5.1 specification.

In order to facilitate ACPI usage in systems where Device Tree is
typically used, it would be beneficial to standardize a way to retrieve
Device Tree style properties from ACPI devices, which is what we do in
this patch.

If a given device described in ACPI namespace wants to export properties it
must implement _DSD method (Device Specific Data, introduced with ACPI 5.1)
that returns the properties in a package of packages. For example:

	Name (_DSD, Package () {
		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
		Package () {
			Package () {"name1", <VALUE1>},
			Package () {"name2", <VALUE2>},
			...
		}
	})

The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301
and is documented in the ACPI 5.1 companion document called "_DSD
Implementation Guide" [1], [2].

We add several helper functions that can be used to extract these
properties and convert them to different Linux data types.

The ultimate goal is that we only have one device property API that
retrieves the requested properties from Device Tree or from ACPI
transparent to the caller.

[1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
[2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf

Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/Makefile   |    1 
 drivers/acpi/internal.h |    6 
 drivers/acpi/property.c |  364 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/scan.c     |    2 
 include/acpi/acpi_bus.h |    7 
 include/linux/acpi.h    |   40 +++++
 6 files changed, 420 insertions(+)
 create mode 100644 drivers/acpi/property.c

Index: linux-pm/drivers/acpi/Makefile
===================================================================
--- linux-pm.orig/drivers/acpi/Makefile
+++ linux-pm/drivers/acpi/Makefile
@@ -46,6 +46,7 @@ acpi-y				+= acpi_pnp.o
 acpi-y				+= power.o
 acpi-y				+= event.o
 acpi-y				+= sysfs.o
+acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
Index: linux-pm/drivers/acpi/internal.h
===================================================================
--- linux-pm.orig/drivers/acpi/internal.h
+++ linux-pm/drivers/acpi/internal.h
@@ -181,4 +181,10 @@ struct platform_device *acpi_create_plat
 bool acpi_osi_is_win8(void);
 #endif
 
+/*--------------------------------------------------------------------------
+				Device properties
+  -------------------------------------------------------------------------- */
+void acpi_init_properties(struct acpi_device *adev);
+void acpi_free_properties(struct acpi_device *adev);
+
 #endif /* _ACPI_INTERNAL_H_ */
Index: linux-pm/drivers/acpi/property.c
===================================================================
--- /dev/null
+++ linux-pm/drivers/acpi/property.c
@@ -0,0 +1,364 @@
+/*
+ * ACPI device specific properties support.
+ *
+ * Copyright (C) 2014, Intel Corporation
+ * All rights reserved.
+ *
+ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *          Darren Hart <dvhart@linux.intel.com>
+ *          Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/export.h>
+
+#include "internal.h"
+
+/* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
+static const u8 prp_uuid[16] = {
+	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
+	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
+};
+
+static bool acpi_property_value_ok(const union acpi_object *value)
+{
+	int j;
+
+	/*
+	 * The value must be an integer, a string, a reference, or a package
+	 * whose every element must be an integer, a string, or a reference.
+	 */
+	switch (value->type) {
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_LOCAL_REFERENCE:
+		return true;
+
+	case ACPI_TYPE_PACKAGE:
+		for (j = 0; j < value->package.count; j++)
+			switch (value->package.elements[j].type) {
+			case ACPI_TYPE_INTEGER:
+			case ACPI_TYPE_STRING:
+			case ACPI_TYPE_LOCAL_REFERENCE:
+				continue;
+
+			default:
+				return false;
+			}
+
+		return true;
+	}
+	return false;
+}
+
+static bool acpi_properties_format_valid(const union acpi_object *properties)
+{
+	int i;
+
+	for (i = 0; i < properties->package.count; i++) {
+		const union acpi_object *property;
+
+		property = &properties->package.elements[i];
+		/*
+		 * Only two elements allowed, the first one must be a string and
+		 * the second one has to satisfy certain conditions.
+		 */
+		if (property->package.count != 2
+		    || property->package.elements[0].type != ACPI_TYPE_STRING
+		    || !acpi_property_value_ok(&property->package.elements[1]))
+			return false;
+	}
+	return true;
+}
+
+void acpi_init_properties(struct acpi_device *adev)
+{
+	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+	const union acpi_object *desc;
+	acpi_status status;
+	int i;
+
+	status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
+					    ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(status))
+		return;
+
+	desc = buf.pointer;
+	if (desc->package.count % 2)
+		goto fail;
+
+	/* Look for the device properties UUID. */
+	for (i = 0; i < desc->package.count; i += 2) {
+		const union acpi_object *uuid, *properties;
+
+		uuid = &desc->package.elements[i];
+		properties = &desc->package.elements[i + 1];
+
+		/*
+		 * The first element must be a UUID and the second one must be
+		 * a package.
+		 */
+		if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
+		    || properties->type != ACPI_TYPE_PACKAGE)
+			break;
+
+		if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid)))
+			continue;
+
+		/*
+		 * We found the matching UUID. Now validate the format of the
+		 * package immediately following it.
+		 */
+		if (!acpi_properties_format_valid(properties))
+			break;
+
+		adev->data.pointer = buf.pointer;
+		adev->data.properties = properties;
+		return;
+	}
+
+ fail:
+	dev_warn(&adev->dev, "Returned _DSD data is not valid, skipping\n");
+	ACPI_FREE(buf.pointer);
+}
+
+void acpi_free_properties(struct acpi_device *adev)
+{
+	ACPI_FREE((void *)adev->data.pointer);
+	adev->data.pointer = NULL;
+	adev->data.properties = NULL;
+}
+
+/**
+ * acpi_dev_get_property - return an ACPI property with given name
+ * @adev: ACPI device to get property
+ * @name: Name of the property
+ * @type: Expected property type
+ * @obj: Location to store the property value (if not %NULL)
+ *
+ * Look up a property with @name and store a pointer to the resulting ACPI
+ * object at the location pointed to by @obj if found.
+ *
+ * Callers must not attempt to free the returned objects.  These objects will be
+ * freed by the ACPI core automatically during the removal of @adev.
+ *
+ * Return: %0 if property with @name has been found (success),
+ *         %-EINVAL if the arguments are invalid,
+ *         %-ENODATA if the property doesn't exist,
+ *         %-EPROTO if the property value type doesn't match @type.
+ */
+int acpi_dev_get_property(struct acpi_device *adev, const char *name,
+			  acpi_object_type type, const union acpi_object **obj)
+{
+	const union acpi_object *properties;
+	int i;
+
+	if (!adev || !name)
+		return -EINVAL;
+
+	if (!adev->data.pointer || !adev->data.properties)
+		return -ENODATA;
+
+	properties = adev->data.properties;
+	for (i = 0; i < properties->package.count; i++) {
+		const union acpi_object *propname, *propvalue;
+		const union acpi_object *property;
+
+		property = &properties->package.elements[i];
+
+		propname = &property->package.elements[0];
+		propvalue = &property->package.elements[1];
+
+		if (!strcmp(name, propname->string.pointer)) {
+			if (type != ACPI_TYPE_ANY && propvalue->type != type)
+				return -EPROTO;
+			else if (obj)
+				*obj = propvalue;
+
+			return 0;
+		}
+	}
+	return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_property);
+
+/**
+ * acpi_dev_get_property_array - return an ACPI array property with given name
+ * @adev: ACPI device to get property
+ * @name: Name of the property
+ * @type: Expected type of array elements
+ * @obj: Location to store a pointer to the property value (if not NULL)
+ *
+ * Look up an array property with @name and store a pointer to the resulting
+ * ACPI object at the location pointed to by @obj if found.
+ *
+ * Callers must not attempt to free the returned objects.  Those objects will be
+ * freed by the ACPI core automatically during the removal of @adev.
+ *
+ * Return: %0 if array property (package) with @name has been found (success),
+ *         %-EINVAL if the arguments are invalid,
+ *         %-ENODATA if the property doesn't exist,
+ *         %-EPROTO if the property is not a package or the type of its elements
+ *           doesn't match @type.
+ */
+int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
+				acpi_object_type type,
+				const union acpi_object **obj)
+{
+	const union acpi_object *prop;
+	int ret, i;
+
+	ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop);
+	if (ret)
+		return ret;
+
+	if (type != ACPI_TYPE_ANY) {
+		/* Check that all elements are of correct type. */
+		for (i = 0; i < prop->package.count; i++)
+			if (prop->package.elements[i].type != type)
+				return -EPROTO;
+	}
+	if (obj)
+		*obj = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_property_array);
+
+/**
+ * acpi_dev_get_property_reference - returns handle to the referenced object
+ * @adev: ACPI device to get property
+ * @name: Name of the property
+ * @size_prop: Name of the "size" property in referenced object
+ * @index: Index of the reference to return
+ * @args: Location to store the returned reference with optional arguments
+ *
+ * Find property with @name, verifify that it is a package containing at least
+ * one object reference and if so, store the ACPI device object pointer to the
+ * target object in @args->adev.
+ *
+ * If the reference includes arguments (@size_prop is not %NULL) follow the
+ * reference and check whether or not there is an integer property @size_prop
+ * under the target object and if so, whether or not its value matches the
+ * number of arguments that follow the reference.  If there's more than one
+ * reference in the property value package, @index is used to select the one to
+ * return.
+ *
+ * Return: %0 on success, negative error code on failure.
+ */
+int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
+				    const char *size_prop, size_t index,
+				    struct acpi_reference_args *args)
+{
+	const union acpi_object *element, *end;
+	const union acpi_object *obj;
+	struct acpi_device *device;
+	int ret, idx = 0;
+
+	ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj);
+	if (ret)
+		return ret;
+
+	/*
+	 * The simplest case is when the value is a single reference.  Just
+	 * return that reference then.
+	 */
+	if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
+		if (size_prop || index)
+			return -EINVAL;
+
+		ret = acpi_bus_get_device(obj->reference.handle, &device);
+		if (ret)
+			return ret;
+
+		args->adev = device;
+		args->nargs = 0;
+		return 0;
+	}
+
+	/*
+	 * If it is not a single reference, then it is a package of
+	 * references followed by number of ints as follows:
+	 *
+	 *  Package () { REF, INT, REF, INT, INT }
+	 *
+	 * The index argument is then used to determine which reference
+	 * the caller wants (along with the arguments).
+	 */
+	if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count)
+		return -EPROTO;
+
+	element = obj->package.elements;
+	end = element + obj->package.count;
+
+	while (element < end) {
+		u32 nargs, i;
+
+		if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
+			return -EPROTO;
+
+		ret = acpi_bus_get_device(element->reference.handle, &device);
+		if (ret)
+			return -ENODEV;
+
+		element++;
+		nargs = 0;
+
+		if (size_prop) {
+			const union acpi_object *prop;
+
+			/*
+			 * Find out how many arguments the refenced object
+			 * expects by reading its size_prop property.
+			 */
+			ret = acpi_dev_get_property(device, size_prop,
+						    ACPI_TYPE_INTEGER, &prop);
+			if (ret)
+				return ret;
+
+			nargs = prop->integer.value;
+			if (nargs > MAX_ACPI_REFERENCE_ARGS
+			    || element + nargs > end)
+				return -EPROTO;
+
+			/*
+			 * Skip to the start of the arguments and verify
+			 * that they all are in fact integers.
+			 */
+			for (i = 0; i < nargs; i++)
+				if (element[i].type != ACPI_TYPE_INTEGER)
+					return -EPROTO;
+		} else {
+			/* assume following integer elements are all args */
+			for (i = 0; element + i < end; i++) {
+				int type = element[i].type;
+
+				if (type == ACPI_TYPE_INTEGER)
+					nargs++;
+				else if (type == ACPI_TYPE_LOCAL_REFERENCE)
+					break;
+				else
+					return -EPROTO;
+			}
+		}
+
+		if (idx++ == index) {
+			args->adev = device;
+			args->nargs = nargs;
+			for (i = 0; i < nargs; i++)
+				args->args[i] = element[i].integer.value;
+
+			return 0;
+		}
+
+		element += nargs;
+	}
+
+	return -EPROTO;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference);
Index: linux-pm/drivers/acpi/scan.c
===================================================================
--- linux-pm.orig/drivers/acpi/scan.c
+++ linux-pm/drivers/acpi/scan.c
@@ -884,6 +884,7 @@ static void acpi_device_release(struct d
 {
 	struct acpi_device *acpi_dev = to_acpi_device(dev);
 
+	acpi_free_properties(acpi_dev);
 	acpi_free_pnp_ids(&acpi_dev->pnp);
 	acpi_free_power_resources_lists(acpi_dev);
 	kfree(acpi_dev);
@@ -1888,6 +1889,7 @@ void acpi_init_device_object(struct acpi
 	acpi_set_device_status(device, sta);
 	acpi_device_get_busid(device);
 	acpi_set_pnp_ids(handle, &device->pnp, type);
+	acpi_init_properties(device);
 	acpi_bus_get_flags(device);
 	device->flags.match_driver = false;
 	device->flags.initialized = true;
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -337,6 +337,12 @@ struct acpi_device_physical_node {
 	bool put_online:1;
 };
 
+/* ACPI Device Specific Data (_DSD) */
+struct acpi_device_data {
+	const union acpi_object *pointer;
+	const union acpi_object *properties;
+};
+
 /* Device */
 struct acpi_device {
 	int device_type;
@@ -353,6 +359,7 @@ struct acpi_device {
 	struct acpi_device_wakeup wakeup;
 	struct acpi_device_perf performance;
 	struct acpi_device_dir dir;
+	struct acpi_device_data data;
 	struct acpi_scan_handler *handler;
 	struct acpi_hotplug_context *hp;
 	struct acpi_driver *driver;
Index: linux-pm/include/linux/acpi.h
===================================================================
--- linux-pm.orig/include/linux/acpi.h
+++ linux-pm/include/linux/acpi.h
@@ -658,4 +658,44 @@ do {									\
 #endif
 #endif
 
+/* Device properties */
+
+#define MAX_ACPI_REFERENCE_ARGS	8
+struct acpi_reference_args {
+	struct acpi_device *adev;
+	size_t nargs;
+	u64 args[MAX_ACPI_REFERENCE_ARGS];
+};
+
+#ifdef CONFIG_ACPI
+int acpi_dev_get_property(struct acpi_device *adev, const char *name,
+			  acpi_object_type type, const union acpi_object **obj);
+int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
+				acpi_object_type type,
+				const union acpi_object **obj);
+int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
+				    const char *cells_name, size_t index,
+				    struct acpi_reference_args *args);
+#else
+static inline int acpi_dev_get_property(struct acpi_device *adev,
+					const char *name, acpi_object_type type,
+					const union acpi_object **obj)
+{
+	return -ENXIO;
+}
+static inline int acpi_dev_get_property_array(struct acpi_device *adev,
+					      const char *name,
+					      acpi_object_type type,
+					      const union acpi_object **obj)
+{
+	return -ENXIO;
+}
+static inline int acpi_dev_get_property_reference(struct acpi_device *adev,
+				const char *name, const char *cells_name,
+				size_t index, struct acpi_reference_args *args)
+{
+	return -ENXIO;
+}
+#endif
+
 #endif	/*_LINUX_ACPI_H*/

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
  2014-10-01  2:08   ` [PATCH v3 01/15] ACPI: Add support for device specific properties Rafael J. Wysocki
@ 2014-10-01  2:10   ` Rafael J. Wysocki
  2014-10-01  7:47     ` Arnd Bergmann
  2014-10-02  0:03     ` Greg Kroah-Hartman
  2014-10-01  2:10   ` [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property Rafael J. Wysocki
                     ` (11 subsequent siblings)
  13 siblings, 2 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:10 UTC (permalink / raw)
  To: linux-kernel, Greg Kroah-Hartman
  Cc: Mika Westerberg, linux-acpi, devicetree, Linus Walleij,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

Add a uniform interface by which device drivers can request device
properties from the platform firmware by providing a property name
and the corresponding data type.  The purpose of it is to help to
write portable code that won't depend on any particular platform
firmware interface.

Three general helper functions, device_get_property(),
device_read_property() and device_read_property_array() are provided.
The first one allows the raw value of a given device property to be
accessed.  The remaining two allow the value of a numeric or string
property and multiple numeric or string values of one array
property to be acquired, respectively.  Static inline wrappers are also
provided for the various property data types that can be passed to
device_read_property() or device_read_property_array() for extra type
checking.

In addition to that, new generic routines are provided for retrieving
properties from device description objects in the platform firmware
in case a device driver needs/wants to access properties of a child
object of a given device object.  There are cases in which there is
no struct device representation of such child objects and this
additional API is useful then.  Again, three functions are provided,
device_get_child_property(), device_read_child_property(),
device_read_child_property_array(), in analogy with device_get_property(),
device_read_property() and device_read_property_array() described above,
respectively, along with static inline wrappers for all of the propery
data types that can be used.  For all of them, the first argument is
a struct device pointer to the parent device object and the second
argument is a (void *) pointer to the child description provided by
the platform firmware (either ACPI or FDT).

Finally, device_for_each_child_node() is added for iterating over
the children of the device description object associated with a
given device.

The interface covers both ACPI and Device Trees.

This change set includes material from Mika Westerberg and Aaron Lu.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

Greg, please let me know if you're fine with this one.

---
 drivers/acpi/property.c  |  188 +++++++++++++++++++++++++++++++++++++
 drivers/base/Makefile    |    2 
 drivers/base/property.c  |  235 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/of/base.c        |  186 +++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h     |   42 ++++++++
 include/linux/of.h       |   37 +++++++
 include/linux/property.h |  207 +++++++++++++++++++++++++++++++++++++++++
 7 files changed, 896 insertions(+), 1 deletion(-)
 create mode 100644 drivers/base/property.c
 create mode 100644 include/linux/property.h

Index: linux-pm/drivers/acpi/property.c
===================================================================
--- linux-pm.orig/drivers/acpi/property.c
+++ linux-pm/drivers/acpi/property.c
@@ -362,3 +362,191 @@ int acpi_dev_get_property_reference(stru
 	return -EPROTO;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference);
+
+int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
+		      void **valptr)
+{
+	return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY,
+				     (const union acpi_object **)valptr);
+}
+
+int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
+		       enum dev_prop_type proptype, void *val)
+{
+	const union acpi_object *obj;
+	int ret = -EINVAL;
+
+	if (!val)
+		return -EINVAL;
+
+	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
+		ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj);
+		if (ret)
+			return ret;
+
+		switch (proptype) {
+		case DEV_PROP_U8:
+			if (obj->integer.value > U8_MAX)
+				return -EOVERFLOW;
+			*(u8 *)val = obj->integer.value;
+			break;
+		case DEV_PROP_U16:
+			if (obj->integer.value > U16_MAX)
+				return -EOVERFLOW;
+			*(u16 *)val = obj->integer.value;
+			break;
+		case DEV_PROP_U32:
+			if (obj->integer.value > U32_MAX)
+				return -EOVERFLOW;
+			*(u32 *)val = obj->integer.value;
+			break;
+		default:
+			*(u64 *)val = obj->integer.value;
+			break;
+		}
+	} else if (proptype == DEV_PROP_STRING) {
+		ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj);
+		if (ret)
+			return ret;
+
+		*(char **)val = obj->string.pointer;
+	}
+	return ret;
+}
+
+static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
+				       size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_INTEGER)
+			return -EPROTO;
+		if (items[i].integer.value > U8_MAX)
+			return -EOVERFLOW;
+
+		val[i] = items[i].integer.value;
+	}
+	return 0;
+}
+
+static int acpi_copy_property_array_u16(const union acpi_object *items,
+					u16 *val, size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_INTEGER)
+			return -EPROTO;
+		if (items[i].integer.value > U16_MAX)
+			return -EOVERFLOW;
+
+		val[i] = items[i].integer.value;
+	}
+	return 0;
+}
+
+static int acpi_copy_property_array_u32(const union acpi_object *items,
+					u32 *val, size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_INTEGER)
+			return -EPROTO;
+		if (items[i].integer.value > U32_MAX)
+			return -EOVERFLOW;
+
+		val[i] = items[i].integer.value;
+	}
+	return 0;
+}
+
+static int acpi_copy_property_array_u64(const union acpi_object *items,
+					u64 *val, size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_INTEGER)
+			return -EPROTO;
+
+		val[i] = items[i].integer.value;
+	}
+	return 0;
+}
+
+static int acpi_copy_property_array_string(const union acpi_object *items,
+					   char **val, size_t nval)
+{
+	int i;
+
+	for (i = 0; i < nval; i++) {
+		if (items[i].type != ACPI_TYPE_STRING)
+			return -EPROTO;
+
+		val[i] = items[i].string.pointer;
+	}
+	return 0;
+}
+
+int acpi_dev_prop_read_array(struct acpi_device *adev, const char *propname,
+			     enum dev_prop_type proptype, void *val,
+			     size_t nval)
+{
+	const union acpi_object *obj;
+	const union acpi_object *items;
+	int ret;
+
+	ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj);
+	if (ret)
+		return ret;
+
+	if (!val)
+		return obj->package.count;
+
+	if (nval > obj->package.count)
+		nval = obj->package.count;
+
+	items = obj->package.elements;
+	switch (proptype) {
+	case DEV_PROP_U8:
+		ret = acpi_copy_property_array_u8(items, (u8 *)val, nval);
+		break;
+	case DEV_PROP_U16:
+		ret = acpi_copy_property_array_u16(items, (u16 *)val, nval);
+		break;
+	case DEV_PROP_U32:
+		ret = acpi_copy_property_array_u32(items, (u32 *)val, nval);
+		break;
+	case DEV_PROP_U64:
+		ret = acpi_copy_property_array_u64(items, (u64 *)val, nval);
+		break;
+	case DEV_PROP_STRING:
+		ret = acpi_copy_property_array_string(items, (char **)val, nval);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+int acpi_for_each_child_node(struct device *dev,
+			int (*fn)(struct device *dev, void *child, void *data),
+			void *data)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	struct acpi_device *child;
+	int ret = 0;
+
+	if (!adev)
+		return -EINVAL;
+
+	list_for_each_entry(child, &adev->children, node) {
+		ret = fn(dev, child, data);
+		if (ret)
+			break;
+	}
+	return ret;
+}
Index: linux-pm/drivers/base/Makefile
===================================================================
--- linux-pm.orig/drivers/base/Makefile
+++ linux-pm/drivers/base/Makefile
@@ -4,7 +4,7 @@ obj-y			:= component.o core.o bus.o dd.o
 			   driver.o class.o platform.o \
 			   cpu.o firmware.o init.o map.o devres.o \
 			   attribute_container.o transport_class.o \
-			   topology.o container.o
+			   topology.o container.o property.o
 obj-$(CONFIG_DEVTMPFS)	+= devtmpfs.o
 obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
 obj-y			+= power/
Index: linux-pm/drivers/base/property.c
===================================================================
--- /dev/null
+++ linux-pm/drivers/base/property.c
@@ -0,0 +1,235 @@
+/*
+ * property.c - Unified device property interface.
+ *
+ * Copyright (C) 2014, Intel Corporation
+ * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *          Mika Westerberg <mika.westerberg@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/property.h>
+#include <linux/export.h>
+#include <linux/acpi.h>
+#include <linux/of.h>
+
+/**
+ * device_get_property - return a raw property of a device
+ * @dev: Device get the property of
+ * @propname: Name of the property
+ * @valptr: The raw property value is stored here
+ *
+ * Function reads property @propname from the device firmware description and
+ * stores the raw value into @valptr if found.  Otherwise returns a negative
+ * errno as specified below.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not exist.
+ */
+int device_get_property(struct device *dev, const char *propname, void **valptr)
+{
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+		return of_dev_prop_get(dev->of_node, propname, valptr);
+
+	return acpi_dev_prop_get(ACPI_COMPANION(dev), propname, valptr);
+}
+EXPORT_SYMBOL_GPL(device_get_property);
+
+/**
+ * device_get_child_property - return a raw property of a device's child
+ * @dev: Parent device
+ * @child: Child to get a property of
+ * @propname: Name of the property
+ * @valptr: The raw property value is stored here
+ *
+ * Function reads property @propname from the firmware description of @child and
+ * stores the raw value into @valptr if found.  Otherwise returns a negative
+ * errno as specified below.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not exist.
+ */
+int device_get_child_property(struct device *dev, void *child,
+			      const char *propname, void **valptr)
+{
+	if (!child)
+		return -EINVAL;
+
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+		return of_dev_prop_get(child, propname, valptr);
+	else if (ACPI_COMPANION(dev))
+		return acpi_dev_prop_get(child, propname, valptr);
+
+	return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(device_get_child_property);
+
+/**
+ * device_read_property - read a typed property of a device
+ * @dev: Device to get the property of
+ * @propname: Name of the property
+ * @proptype: Type of the property
+ * @val: The value is stored here
+ *
+ * Function reads property @propname from the device firmware description and
+ * stores the value into @val if found. The value is checked to be of type
+ * @proptype.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not exist,
+ *	   %-EPROTO if the property type does not match @proptype,
+ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
+ */
+int device_read_property(struct device *dev, const char *propname,
+			 enum dev_prop_type proptype, void *val)
+{
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+		return of_dev_prop_read(dev->of_node, propname, proptype, val);
+
+	return acpi_dev_prop_read(ACPI_COMPANION(dev), propname, proptype, val);
+}
+EXPORT_SYMBOL_GPL(device_read_property);
+
+/**
+ * device_read_child_property - read a typed property of a device's child
+ * @dev: Parent device
+ * @child: Child to read a property of
+ * @propname: Name of the property
+ * @proptype: Type of the property
+ * @val: The value is stored here
+ *
+ * Function reads property @propname from the firmware description of @child and
+ * stores the value into @val if found. The value is checked to be of type
+ * @proptype.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not exist,
+ *	   %-EPROTO if the property type does not match @proptype,
+ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
+ */
+int device_read_child_property(struct device *dev, void *child,
+			       const char *propname, enum dev_prop_type proptype,
+			       void *val)
+{
+	if (!child)
+		return -EINVAL;
+
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+		return of_dev_prop_read(child, propname, proptype, val);
+	else if (ACPI_COMPANION(dev))
+		return acpi_dev_prop_read(child, propname, proptype, val);
+
+	return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(device_read_child_property);
+
+/**
+ * device_read_property_array - read an array property of a device
+ * @dev: Device to get the property of
+ * @propname: Name of the property
+ * @proptype: Type of the property
+ * @val: The values are stored here
+ * @nval: Size of the @val array
+ *
+ * Function reads an array of properties with @propname from the device
+ * firmware description and stores them to @val if found. All the values
+ * in the array must be of type @proptype.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not exist,
+ *	   %-EPROTO if the property type does not match @proptype,
+ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
+ */
+int device_read_property_array(struct device *dev, const char *propname,
+			       enum dev_prop_type proptype, void *val,
+			       size_t nval)
+{
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+		return of_dev_prop_read_array(dev->of_node, propname, proptype,
+					      val, nval);
+
+	return acpi_dev_prop_read_array(ACPI_COMPANION(dev), propname, proptype,
+					val, nval);
+}
+EXPORT_SYMBOL_GPL(device_read_property_array);
+
+/**
+ * device_read_child_property_array - read an array property of a device's child
+ * @dev: Parent device
+ * @child: Child to get the property of
+ * @propname: Name of the property
+ * @proptype: Type of the property
+ * @val: The values are stored here
+ * @nval: Size of the @val array
+ *
+ * Function reads an array of properties with @propname from the firmware
+ * description of @child and stores them to @val if found. All the values
+ * in the array must be of type @proptype.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not exist,
+ *	   %-EPROTO if the property type does not match @proptype,
+ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
+ */
+int device_read_child_property_array(struct device *dev, void *child,
+				     const char *propname,
+				     enum dev_prop_type proptype, void *val,
+				     size_t nval)
+{
+	if (!child)
+		return -EINVAL;
+
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+		return of_dev_prop_read_array(child, propname, proptype,
+					      val, nval);
+	else if (ACPI_COMPANION(dev))
+		return acpi_dev_prop_read_array(child, propname, proptype,
+						val, nval);
+
+	return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(device_read_child_property_array);
+
+/**
+ * device_for_each_child_node - execute function for each child node of device
+ * @dev: Device to run the function for
+ * @fn: Function to run
+ * @data: Additional data to pass to the function
+ */
+int device_for_each_child_node(struct device *dev,
+			int (*fn)(struct device *dev, void *child, void *data),
+			void *data)
+{
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+		return of_for_each_child_node(dev, fn, data);
+
+	return acpi_for_each_child_node(dev, fn, data);
+}
+EXPORT_SYMBOL_GPL(device_for_each_child_node);
+
+static int increment_count(struct device *dev, void *child, void *data)
+{
+	*((unsigned int *)data) += 1;
+	return 0;
+}
+
+/**
+ * device_get_child_node_count - return the number of child nodes for device
+ * @dev: Device to cound the child nodes for
+ */
+unsigned int device_get_child_node_count(struct device *dev)
+{
+	unsigned int count = 0;
+
+	device_for_each_child_node(dev, increment_count, &count);
+	return count;
+}
+EXPORT_SYMBOL_GPL(device_get_child_node_count);
Index: linux-pm/drivers/of/base.c
===================================================================
--- linux-pm.orig/drivers/of/base.c
+++ linux-pm/drivers/of/base.c
@@ -1247,6 +1247,39 @@ int of_property_read_u64(const struct de
 EXPORT_SYMBOL_GPL(of_property_read_u64);
 
 /**
+ * of_property_read_u64_array - Find and read an array of 64 bit integers
+ * from a property.
+ *
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @out_values:	pointer to return value, modified only if return value is 0.
+ * @sz:		number of array elements to read
+ *
+ * Search for a property in a device node and read 64-bit value(s) from
+ * it. Returns 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+ * The out_values is modified only if a valid u64 value can be decoded.
+ */
+int of_property_read_u64_array(const struct device_node *np,
+			       const char *propname, u64 *out_values,
+			       size_t sz)
+{
+	const __be32 *val = of_find_property_value_of_size(np, propname,
+						(sz * sizeof(*out_values)));
+
+	if (IS_ERR(val))
+		return PTR_ERR(val);
+
+	while (sz--) {
+		*out_values++ = of_read_number(val, 2);
+		val += 2;
+	}
+	return 0;
+}
+
+/**
  * of_property_read_string - Find and read a string from a property
  * @np:		device node from which the property value is to be read.
  * @propname:	name of the property to be searched.
@@ -1394,6 +1427,49 @@ int of_property_count_strings(struct dev
 }
 EXPORT_SYMBOL_GPL(of_property_count_strings);
 
+/**
+ * of_property_read_string_array - Find and read an array of strings
+ * from a multiple strings property.
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @out_string:	pointer to null terminated return string, modified only if
+ *		return value is 0.
+ * @sz:		number of array elements to read
+ *
+ * Search for a property in a device tree node and retrieve a list of
+ * terminated string value (pointer to data, not a copy) in that property.
+ * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
+ * property does not have a value, and -EOVERFLOW if the string is not
+ * null-terminated within the length of the property data.
+ *
+ * The out_string pointer is modified only if a valid string can be decoded.
+ */
+int of_property_read_string_array(struct device_node *np, const char *propname,
+				  char **output, size_t sz)
+{
+	struct property *prop = of_find_property(np, propname, NULL);
+	int i = 0;
+	size_t l = 0, total = 0;
+	char *p;
+
+	if (!prop)
+		return -EINVAL;
+
+	if (!prop->value)
+		return -ENODATA;
+
+	if (strnlen(prop->value, prop->length) >= prop->length)
+		return -EOVERFLOW;
+
+	p = prop->value;
+
+	for (i = 0; total < prop->length; total += l, p += l) {
+		output[i++] = p;
+		l = strlen(p) + 1;
+	}
+	return 0;
+}
+
 void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
 {
 	int i;
@@ -2183,3 +2259,113 @@ struct device_node *of_graph_get_remote_
 	return of_get_next_parent(np);
 }
 EXPORT_SYMBOL(of_graph_get_remote_port);
+
+int of_dev_prop_get(struct device_node *dn, const char *propname, void **valptr)
+{
+	struct property *pp = of_find_property(dn, propname, NULL);
+
+	if (!pp)
+		return -ENODATA;
+
+	if (valptr)
+		*valptr = pp->value;
+	return 0;
+}
+
+int of_dev_prop_read(struct device_node *dn, const char *propname,
+		     enum dev_prop_type proptype, void *val)
+{
+	void *value;
+	int ret = of_dev_prop_get(dn, propname, &value);
+
+	if (ret)
+		return ret;
+
+	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
+		switch (proptype) {
+		case DEV_PROP_U8: {
+			*(u8 *)val = *(u8 *)value;
+			break;
+		}
+		case DEV_PROP_U16:
+			*(u16 *)val = *(u16 *)value;
+			break;
+		case DEV_PROP_U32:
+			*(u32 *)val = *(u32 *)value;
+			break;
+		default:
+			*(u64 *)val = *(u64 *)value;
+			break;
+		}
+	} else if (proptype == DEV_PROP_STRING) {
+		*(char **)val = value;
+	}
+	return ret;
+
+}
+
+int of_dev_prop_read_array(struct device_node *dn, const char *propname,
+			   enum dev_prop_type proptype, void *val, size_t nval)
+{
+	int ret, elem_size;
+
+	if (!val) {
+		switch (proptype) {
+		case DEV_PROP_U8:
+			elem_size = sizeof(u8);
+			break;
+		case DEV_PROP_U16:
+			elem_size = sizeof(u16);
+			break;
+		case DEV_PROP_U32:
+			elem_size = sizeof(u32);
+			break;
+		case DEV_PROP_U64:
+			elem_size = sizeof(u64);
+			break;
+		case DEV_PROP_STRING:
+			return of_property_count_strings(dn, propname);
+		default:
+			return -EINVAL;
+		}
+		return of_property_count_elems_of_size(dn, propname, elem_size);
+	}
+
+	switch (proptype) {
+	case DEV_PROP_U8:
+		ret = of_property_read_u8_array(dn, propname, (u8 *)val, nval);
+		break;
+	case DEV_PROP_U16:
+		ret = of_property_read_u16_array(dn, propname, (u16 *)val, nval);
+		break;
+	case DEV_PROP_U32:
+		ret = of_property_read_u32_array(dn, propname, (u32 *)val, nval);
+		break;
+	case DEV_PROP_U64:
+		ret = of_property_read_u64_array(dn, propname, (u64 *)val, nval);
+		break;
+	case DEV_PROP_STRING:
+		ret = of_property_read_string_array(dn, propname,
+						    (char **)val, nval);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+int of_for_each_child_node(struct device *dev,
+			int (*fn)(struct device *dev, void *child, void *data),
+			void *data)
+{
+	struct device_node *child;
+	int ret = 0;
+
+	for_each_child_of_node(dev->of_node, child) {
+		ret = fn(dev, child, data);
+		if (ret)
+			break;
+	}
+	return ret;
+}
Index: linux-pm/include/linux/acpi.h
===================================================================
--- linux-pm.orig/include/linux/acpi.h
+++ linux-pm/include/linux/acpi.h
@@ -28,6 +28,7 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>	/* for struct resource */
 #include <linux/device.h>
+#include <linux/property.h>
 
 #ifndef _LINUX
 #define _LINUX
@@ -676,6 +677,17 @@ int acpi_dev_get_property_array(struct a
 int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
 				    const char *cells_name, size_t index,
 				    struct acpi_reference_args *args);
+
+int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
+		      void **valptr);
+int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
+		       enum dev_prop_type proptype, void *val);
+int acpi_dev_prop_read_array(struct acpi_device *adev, const char *propname,
+			     enum dev_prop_type proptype, void *val,
+			     size_t nval);
+int acpi_for_each_child_node(struct device *dev,
+			int (*fn)(struct device *dev, void *child, void *data),
+			void *data);
 #else
 static inline int acpi_dev_get_property(struct acpi_device *adev,
 					const char *name, acpi_object_type type,
@@ -696,6 +708,36 @@ static inline int acpi_dev_get_property_
 {
 	return -ENXIO;
 }
+
+static inline int acpi_dev_prop_get(struct acpi_device *adev,
+				    const char *propname,
+				    void **valptr)
+{
+	return -ENXIO;
+}
+
+static inline int acpi_dev_prop_read(struct acpi_device *adev,
+				     const char *propname,
+				     enum dev_prop_type proptype, void *val)
+{
+	return -ENXIO;
+}
+
+static inline int acpi_dev_prop_read_array(struct acpi_device *adev,
+					   const char *propname,
+					   enum dev_prop_type proptype,
+					   void *val, size_t nval)
+{
+	return -ENXIO;
+}
+
+static inline int acpi_for_each_child_node(struct device *dev,
+			int (*fn)(struct device *dev, void *child, void *data),
+			void *data)
+{
+	return -ENXIO;
+}
+
 #endif
 
 #endif	/*_LINUX_ACPI_H*/
Index: linux-pm/include/linux/of.h
===================================================================
--- linux-pm.orig/include/linux/of.h
+++ linux-pm/include/linux/of.h
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/topology.h>
 #include <linux/notifier.h>
+#include <linux/property.h>
 
 #include <asm/byteorder.h>
 #include <asm/errno.h>
@@ -355,6 +356,15 @@ const char *of_prop_next_string(struct p
 
 bool of_console_check(struct device_node *dn, char *name, int index);
 
+int of_dev_prop_get(struct device_node *dn, const char *propname, void **valptr);
+int of_dev_prop_read(struct device_node *dn, const char *propname,
+		     enum dev_prop_type proptype, void *val);
+int of_dev_prop_read_array(struct device_node *dn, const char *propname,
+			   enum dev_prop_type proptype, void *val, size_t nval);
+int of_for_each_child_node(struct device *dev,
+			int (*fn)(struct device *dev, void *child, void *data),
+			void *data);
+
 #else /* CONFIG_OF */
 
 static inline const char* of_node_full_name(const struct device_node *np)
@@ -582,6 +592,33 @@ static inline const char *of_prop_next_s
 	return NULL;
 }
 
+static inline int of_dev_prop_get(struct device_node *dn, const char *propname,
+				 void **valptr)
+{
+	return -ENXIO;
+}
+
+static inline int of_dev_prop_read(struct device_node *dn, const char *propname,
+				   enum dev_prop_type proptype, void *val)
+{
+	return -ENXIO;
+}
+
+static inline int of_dev_prop_read_array(struct device_node *dn,
+					 const char *propname,
+					 enum dev_prop_type proptype,
+					 void *val, size_t nval)
+{
+	return -ENXIO;
+}
+
+static inline int of_for_each_child_node(struct device *dev,
+			int (*fn)(struct device *dev, void *child, void *data),
+			void *data)
+{
+	return -ENXIO;
+}
+
 #define of_match_ptr(_ptr)	NULL
 #define of_match_node(_matches, _node)	NULL
 #endif /* CONFIG_OF */
Index: linux-pm/include/linux/property.h
===================================================================
--- /dev/null
+++ linux-pm/include/linux/property.h
@@ -0,0 +1,207 @@
+/*
+ * property.h - Unified device property interface.
+ *
+ * Copyright (C) 2014, Intel Corporation
+ * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *          Mika Westerberg <mika.westerberg@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_PROPERTY_H_
+#define _LINUX_PROPERTY_H_
+
+#include <linux/device.h>
+
+enum dev_prop_type {
+	DEV_PROP_U8,
+	DEV_PROP_U16,
+	DEV_PROP_U32,
+	DEV_PROP_U64,
+	DEV_PROP_STRING,
+	DEV_PROP_MAX,
+};
+
+int device_get_property(struct device *dev, const char *propname,
+			void **valptr);
+int device_read_property(struct device *dev, const char *propname,
+			 enum dev_prop_type proptype, void *val);
+int device_read_property_array(struct device *dev, const char *propname,
+			       enum dev_prop_type proptype, void *val,
+			       size_t nval);
+int device_get_child_property(struct device *dev, void *child,
+			      const char *propname, void **valptr);
+int device_read_child_property(struct device *dev, void *child,
+			       const char *propname,
+			       enum dev_prop_type proptype, void *val);
+int device_read_child_property_array(struct device *dev, void *child,
+				     const char *propname,
+				     enum dev_prop_type proptype, void *val,
+				     size_t nval);
+int device_for_each_child_node(struct device *dev,
+			int (*fn)(struct device *dev, void *child, void *data),
+			void *data);
+unsigned int device_get_child_node_count(struct device *dev);
+
+static inline int device_property_read_u8(struct device *dev,
+					  const char *propname, u8 *out_value)
+{
+	return device_read_property(dev, propname, DEV_PROP_U8, out_value);
+}
+
+static inline int device_property_read_u16(struct device *dev,
+					  const char *propname, u16 *out_value)
+{
+	return device_read_property(dev, propname, DEV_PROP_U16, out_value);
+}
+
+static inline int device_property_read_u32(struct device *dev,
+					  const char *propname, u32 *out_value)
+{
+	return device_read_property(dev, propname, DEV_PROP_U32, out_value);
+}
+
+static inline int device_property_read_u64(struct device *dev,
+					  const char *propname, u64 *out_value)
+{
+	return device_read_property(dev, propname, DEV_PROP_U64, out_value);
+}
+
+static inline int device_property_read_u8_array(struct device *dev,
+						const char *propname,
+						u8 *val, size_t nval)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_U8, val,
+					  nval);
+}
+
+static inline int device_property_read_u16_array(struct device *dev,
+						 const char *propname,
+						 u16 *val, size_t nval)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_U16, val,
+					  nval);
+}
+
+static inline int device_property_read_u32_array(struct device *dev,
+						 const char *propname,
+						 u32 *val, size_t nval)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_U32, val,
+					  nval);
+}
+
+static inline int device_property_read_u64_array(struct device *dev,
+						 const char *propname,
+						 u64 *val, size_t nval)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_U64, val,
+					  nval);
+}
+
+static inline int device_property_read_string(struct device *dev,
+					      const char *propname,
+					      const char **out_string)
+{
+	return device_read_property(dev, propname, DEV_PROP_STRING, out_string);
+}
+
+static inline int device_property_read_string_array(struct device *dev,
+						    const char *propname,
+						    const char **out_strings,
+						    size_t nstrings)
+{
+	return device_read_property_array(dev, propname, DEV_PROP_STRING,
+					  out_strings, nstrings);
+}
+
+static inline int device_child_property_read_u8(struct device *dev, void *child,
+						const char *propname,
+						u8 *out_value)
+{
+	return device_read_child_property(dev, child, propname, DEV_PROP_U8,
+					  out_value);
+}
+
+static inline int device_child_property_read_u16(struct device *dev, void *child,
+						 const char *propname,
+						 u16 *out_value)
+{
+	return device_read_child_property(dev, child, propname, DEV_PROP_U16,
+					  out_value);
+}
+
+static inline int device_child_property_read_u32(struct device *dev, void *child,
+						 const char *propname,
+						 u32 *out_value)
+{
+	return device_read_child_property(dev, child, propname, DEV_PROP_U32,
+					  out_value);
+}
+
+static inline int device_child_property_read_u64(struct device *dev, void *child,
+						 const char *propname,
+						 u64 *out_value)
+{
+	return device_read_child_property(dev, child, propname, DEV_PROP_U64,
+					  out_value);
+}
+
+static inline int device_child_property_read_u8_array(struct device *dev,
+						      void *child,
+						      const char *propname,
+						      u8 *val, size_t nval)
+{
+	return device_read_child_property_array(dev, child, propname,
+						DEV_PROP_U8, val, nval);
+}
+
+static inline int device_child_property_read_u16_array(struct device *dev,
+						       void *child,
+						       const char *propname,
+						       u16 *val, size_t nval)
+{
+	return device_read_child_property_array(dev, child, propname,
+						DEV_PROP_U16, val, nval);
+}
+
+static inline int device_child_property_read_u32_array(struct device *dev,
+						       void *child,
+						       const char *propname,
+						       u32 *val, size_t nval)
+{
+	return device_read_child_property_array(dev, child, propname,
+						DEV_PROP_U32, val, nval);
+}
+
+static inline int device_child_property_read_u64_array(struct device *dev,
+						       void *child,
+						       const char *propname,
+						       u64 *val, size_t nval)
+{
+	return device_read_child_property_array(dev, child, propname,
+						DEV_PROP_U64, val, nval);
+}
+
+static inline int device_child_property_read_string(struct device *dev,
+						    void *child,
+						    const char *propname,
+						    const char **out_string)
+{
+	return device_read_child_property(dev, child, propname, DEV_PROP_STRING,
+					  out_string);
+}
+
+static inline int device_child_property_read_string_array(struct device *dev,
+						void *child,
+						const char *propname,
+						const char **out_strings,
+						size_t nstrings)
+{
+	return device_read_child_property_array(dev, child, propname,
+						DEV_PROP_STRING,
+						out_strings, nstrings);
+}
+#endif /* _LINUX_PROPERTY_H_ */


^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
  2014-10-01  2:08   ` [PATCH v3 01/15] ACPI: Add support for device specific properties Rafael J. Wysocki
  2014-10-01  2:10   ` [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware Rafael J. Wysocki
@ 2014-10-01  2:10   ` Rafael J. Wysocki
  2014-10-01  7:48     ` Arnd Bergmann
  2014-10-03 13:43     ` Mark Rutland
  2014-10-01  2:11   ` [PATCH v3 04/15] ACPI: Document ACPI device specific properties Rafael J. Wysocki
                     ` (10 subsequent siblings)
  13 siblings, 2 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

We have lots of existing Device Tree enabled drivers and allocating
separate _HID for each is not feasible. Instead we allocate special _HID
"PRP0001" that means that the match should be done using Device Tree
compatible property using driver's .of_match_table instead.

If there is a need to distinguish from where the device is enumerated
(DT/ACPI) driver can check dev->of_node or ACPI_COMPATION(dev).

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/property.c |   34 +++++++++++++++++
 drivers/acpi/scan.c     |   91 ++++++++++++++++++++++++++++++++++++++++++------
 include/acpi/acpi_bus.h |    1 
 include/linux/acpi.h    |    8 +---
 4 files changed, 118 insertions(+), 16 deletions(-)

Index: linux-pm/drivers/acpi/property.c
===================================================================
--- linux-pm.orig/drivers/acpi/property.c
+++ linux-pm/drivers/acpi/property.c
@@ -76,6 +76,37 @@ static bool acpi_properties_format_valid
 	return true;
 }
 
+static void acpi_init_of_compatible(struct acpi_device *adev)
+{
+	const union acpi_object *of_compatible;
+	struct acpi_hardware_id *hwid;
+	bool acpi_of = false;
+
+	/*
+	 * Check if the special PRP0001 ACPI ID is present and in that
+	 * case we fill in Device Tree compatible properties for this
+	 * device.
+	 */
+	list_for_each_entry(hwid, &adev->pnp.ids, list) {
+		if (!strcmp(hwid->id, "PRP0001")) {
+			acpi_of = true;
+			break;
+		}
+	}
+
+	if (!acpi_of)
+		return;
+
+	if (acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
+					&of_compatible)) {
+		acpi_handle_warn(adev->handle,
+				 "PRP0001 requires compatible property\n");
+		return;
+	}
+
+	adev->data.of_compatible = of_compatible;
+}
+
 void acpi_init_properties(struct acpi_device *adev)
 {
 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
@@ -119,6 +150,8 @@ void acpi_init_properties(struct acpi_de
 
 		adev->data.pointer = buf.pointer;
 		adev->data.properties = properties;
+
+		acpi_init_of_compatible(adev);
 		return;
 	}
 
@@ -130,6 +163,7 @@ void acpi_init_properties(struct acpi_de
 void acpi_free_properties(struct acpi_device *adev)
 {
 	ACPI_FREE((void *)adev->data.pointer);
+	adev->data.of_compatible = NULL;
 	adev->data.pointer = NULL;
 	adev->data.properties = NULL;
 }
Index: linux-pm/drivers/acpi/scan.c
===================================================================
--- linux-pm.orig/drivers/acpi/scan.c
+++ linux-pm/drivers/acpi/scan.c
@@ -124,17 +124,43 @@ static int create_modalias(struct acpi_d
 	if (list_empty(&acpi_dev->pnp.ids))
 		return 0;
 
-	len = snprintf(modalias, size, "acpi:");
-	size -= len;
+	/*
+	 * If the device has PRP0001 we expose DT compatible modalias
+	 * instead.
+	 */
+	if (acpi_dev->data.of_compatible) {
+		const union acpi_object *of_compatible, *obj;
+		int i;
+
+		len = snprintf(modalias, size, "of:Nprp0001Tacpi");
+
+		of_compatible = acpi_dev->data.of_compatible;
+		for (i = 0; i < of_compatible->package.count; i++) {
+			obj = &of_compatible->package.elements[i];
+
+			count = snprintf(&modalias[len], size, "C%s",
+					 obj->string.pointer);
+			if (count < 0)
+				return -EINVAL;
+			if (count >= size)
+				return -ENOMEM;
+
+			len += count;
+			size -= count;
+		}
+	} else {
+		len = snprintf(modalias, size, "acpi:");
+		size -= len;
 
-	list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
-		count = snprintf(&modalias[len], size, "%s:", id->id);
-		if (count < 0)
-			return -EINVAL;
-		if (count >= size)
-			return -ENOMEM;
-		len += count;
-		size -= count;
+		list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
+			count = snprintf(&modalias[len], size, "%s:", id->id);
+			if (count < 0)
+				return -EINVAL;
+			if (count >= size)
+				return -ENOMEM;
+			len += count;
+			size -= count;
+		}
 	}
 
 	modalias[len] = '\0';
@@ -864,6 +890,51 @@ int acpi_match_device_ids(struct acpi_de
 }
 EXPORT_SYMBOL(acpi_match_device_ids);
 
+/* Performs match for special "PRP0001" shoehorn ACPI ID */
+static bool acpi_of_driver_match_device(struct device *dev,
+					const struct device_driver *drv)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	const union acpi_object *of_compatible;
+	int i;
+
+	/*
+	 * If the ACPI device does not have corresponding compatible
+	 * property or the driver in question does not have DT matching
+	 * table we consider the match succesful (matches the ACPI ID).
+	 */
+	of_compatible = adev->data.of_compatible;
+	if (!drv->of_match_table || !of_compatible)
+		return true;
+
+	/* Now we can look for the driver DT compatible strings */
+	for (i = 0; i < of_compatible->package.count; i++) {
+		const struct of_device_id *id;
+		const union acpi_object *obj;
+
+		obj = &of_compatible->package.elements[i];
+
+		for (id = drv->of_match_table; id->compatible[0]; id++)
+			if (!strcasecmp(obj->string.pointer, id->compatible))
+				return true;
+	}
+
+	return false;
+}
+
+bool acpi_driver_match_device(struct device *dev,
+			      const struct device_driver *drv)
+{
+	const struct acpi_device_id *id;
+
+	id = acpi_match_device(drv->acpi_match_table, dev);
+	if (!id)
+		return false;
+
+	return acpi_of_driver_match_device(dev, drv);
+}
+EXPORT_SYMBOL_GPL(acpi_driver_match_device);
+
 static void acpi_free_power_resources_lists(struct acpi_device *device)
 {
 	int i;
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -341,6 +341,7 @@ struct acpi_device_physical_node {
 struct acpi_device_data {
 	const union acpi_object *pointer;
 	const union acpi_object *properties;
+	const union acpi_object *of_compatible;
 };
 
 /* Device */
Index: linux-pm/include/linux/acpi.h
===================================================================
--- linux-pm.orig/include/linux/acpi.h
+++ linux-pm/include/linux/acpi.h
@@ -424,12 +424,8 @@ extern int acpi_nvs_for_each_region(int
 const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
 					       const struct device *dev);
 
-static inline bool acpi_driver_match_device(struct device *dev,
-					    const struct device_driver *drv)
-{
-	return !!acpi_match_device(drv->acpi_match_table, dev);
-}
-
+extern bool acpi_driver_match_device(struct device *dev,
+				     const struct device_driver *drv);
 int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
 int acpi_device_modalias(struct device *, char *, int);
 

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (2 preceding siblings ...)
  2014-10-01  2:10   ` [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property Rafael J. Wysocki
@ 2014-10-01  2:11   ` Rafael J. Wysocki
  2014-10-01  7:59     ` Arnd Bergmann
  2014-10-01  2:12   ` [PATCH v3 05/15] gpio / ACPI: Add support for _DSD device properties Rafael J. Wysocki
                     ` (9 subsequent siblings)
  13 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:11 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

This document describes the data format and interfaces of ACPI device
specific properties.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 Documentation/acpi/properties.txt | 410 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 410 insertions(+)
 create mode 100644 Documentation/acpi/properties.txt

diff --git a/Documentation/acpi/properties.txt b/Documentation/acpi/properties.txt
new file mode 100644
index 0000000..13a93c5
--- /dev/null
+++ b/Documentation/acpi/properties.txt
@@ -0,0 +1,410 @@
+ACPI device properties
+======================
+This document describes the format and interfaces of ACPI device
+properties as specified in "Device Properties UUID For _DSD" available
+here:
+
+http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
+
+1. Introduction
+---------------
+In systems that use ACPI and want to take advantage of device specific
+properties, there needs to be a standard way to return and extract
+name-value pairs for a given ACPI device.
+
+An ACPI device that wants to export its properties must implement a
+static name called _DSD that takes no arguments and returns a package of
+packages:
+
+	Name (_DSD, Package () {
+		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+		Package () {
+			Package () {"name1", <VALUE1>},
+			Package () {"name2", <VALUE2>}
+		}
+	})
+
+The UUID identifies contents of the following package. In case of ACPI
+device properties it is daffd814-6eba-4d8c-8a91-bc9bbf4aa301.
+
+In each returned package, the first item is the name and must be a string.
+The corresponding value can be a string, integer, reference, or package. If
+a package it may only contain strings, integers, and references.
+
+An example device where we might need properties is a device that uses
+GPIOs. In addition to the GpioIo/GpioInt resources the driver needs to
+know which GPIO is used for which purpose.
+
+To solve this we add the following ACPI device properties to the device:
+
+	Device (DEV0)
+	{
+		Name (_CRS, ResourceTemplate () {
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
+			...
+		})
+
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {"reset-gpio", {^DEV0, 0, 0, 0}},
+				Package () {"shutdown-gpio", {^DEV0, 1, 0, 0}},
+			}
+		})
+	}
+
+Now the device driver can reference the GPIOs using names instead of
+using indexes.
+
+If there is an existing Device Tree binding for a device, it is expected
+that the same bindings are used with ACPI properties, so that the driver
+dealing with the device needs only minor modifications if any.
+
+2. Formal definition of properties
+----------------------------------
+The following chapters define the currently supported properties. For
+these there exists a helper function that can be used to extract the
+property value.
+
+2.1 Integer types
+-----------------
+ACPI integers are always 64-bit. However, for drivers the full range is
+typically not needed so we provide a set of functions which convert the
+64-bit integer to a smaller Linux integer type.
+
+An integer property looks like this:
+
+	Package () {"i2c-sda-hold-time-ns", 300},
+	Package () {"clock-frequency", 400000},
+
+To read a property value, use a unified property accessor as shown
+below:
+
+	u32 val;
+	int ret;
+
+	ret = device_property_read_u32(dev, "clock-frequency", &val);
+	if (ret)
+		/* Handle error */
+
+The function returns 0 if the property is copied to 'val' or negative
+errno if something went wrong (or the property does not exist).
+
+2.2 Integer arrays
+------------------
+An integer array is a package holding only integers. Arrays can be used to
+represent different things like Linux input key codes to GPIO mappings, pin
+control settings, dma request lines, etc.
+
+An integer array looks like this:
+
+	Package () {
+		"max8952,dvs-mode-microvolt",
+		Package () {
+			1250000,
+			1200000,
+			1050000,
+			950000,
+		}
+	}
+
+The above array property can be accessed like:
+
+	u32 voltages[4];
+	int ret;
+
+	ret = device_property_read_u32_array(dev, "max8952,dvs-mode-microvolt",
+					     voltages, ARRAY_SIZE(voltages));
+	if (ret)
+		/* Handle error */
+
+
+All functions copy the resulting values cast to a requested type to the
+caller supplied array. If you pass NULL in the value pointer ('voltages' in
+this case), the function returns number of items in the array. This can be
+useful if caller does not know size of the array beforehand.
+
+2.3 Strings
+-----------
+String properties can be used to describe many things like labels for GPIO
+buttons, compability ids, etc.
+
+A string property looks like this:
+
+	Package () {"pwm-names", "backlight"},
+	Package () {"label", "Status-LED"},
+
+You can use device_property_read_string() to extract strings:
+
+	const char *val;
+	int ret;
+
+	ret = device_property_read_string(dev, "label", &val);
+	if (ret)
+		/* Handle error */
+
+Note that the function does not copy the returned string but instead the
+value is modified to point to the string property itself.
+
+The memory is owned by the associated ACPI device object and released
+when it is removed. The user need not free the associated memory.
+
+2.4 String arrays
+-----------------
+String arrays can be useful in describing a list of labels, names for
+DMA channels, etc.
+
+A string array property looks like this:
+
+	Package () {"dma-names", Package () {"tx", "rx", "rx-tx"}},
+	Package () {"clock-output-names", Package () {"pll", "pll-switched"}},
+
+And these can be read in similar way that the integer arrrays:
+
+	const char *dma_names[3];
+	int ret;
+
+	ret = device_property_read_string_array(dev, "dma-names", dma_names,
+						ARRAY_SIZE(dma_names));
+	if (ret)
+		/* Handle error */
+
+The memory management rules follow what is specified for single strings.
+Specifically the returned pointers should be treated as constant and not to
+be freed. That is done automatically when the correspondig ACPI device
+object is released.
+
+2.5 Object references
+---------------------
+An ACPI object reference is used to refer to some object in the
+namespace. For example, if a device has dependencies with some other
+object, an object reference can be used.
+
+An object reference looks like this:
+
+	Package () {"dev0", \_SB.DEV0},
+
+At the time of writing this, there is no unified device_property_* accessor
+for references so one needs to use the following ACPI helper function:
+
+	int acpi_dev_get_property_reference(struct acpi_device *adev,
+					    const char *name,
+					    const char *size_prop, int index,
+					    struct acpi_reference_args *args);
+
+The referenced ACPI device is returned in args->adev if found.
+
+In addition to simple object references it is also possible to have object
+references with arguments. These are represented in ASL as follows:
+
+	Device (\_SB.PCI0.PWM)
+	{
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {"#pwm-cells", 2}
+			}
+		})
+	}
+
+	Device (\_SB.PCI0.BL)
+	{
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {
+					"pwms",
+					Package () {
+						\_SB.PCI0.PWM, 0, 5000000,
+						\_SB.PCI0.PWM, 1, 4500000,
+					}
+				}
+			}
+		})
+	}
+
+In the above example, the referenced device declares a property that
+returns the number of expected arguments (here it is "#pwm-cells"). If
+no such property is given we assume that all the integers following the
+reference are arguments.
+
+In the above example PWM device expects 2 additional arguments. This
+will be validated by the ACPI property core.
+
+The additional arguments must be integers. Nothing else is supported.
+
+It is possible, as in the above example, to have multiple references
+with varying number of integer arguments. It is up to the referenced
+device to declare how many arguments it expects. The 'index' parameter
+selects which reference is returned.
+
+One can use acpi_dev_get_property_reference() as well to extract the
+information in additional parameters:
+
+	struct acpi_reference_args args;
+	struct acpi_device *adev = /* this will point to the BL device */
+	int ret;
+
+	/* extract the first reference */
+	acpi_dev_get_property_reference(adev, "pwms", "#pwm-cells", 0, &args);
+
+	BUG_ON(args.nargs != 2);
+	BUG_ON(args.args[0] != 0);
+	BUG_ON(args.args[1] != 5000000);
+
+	/* extract the second reference */
+	acpi_dev_get_property_reference(adev, "pwms", "#pwm-cells", 1, &args);
+
+	BUG_ON(args.nargs != 2);
+	BUG_ON(args.args[0] != 1);
+	BUG_ON(args.args[1] != 4500000);
+
+In addition to arguments, args.adev now points to the ACPI device that
+corresponds to \_SB.PCI0.PWM.
+
+It is intended that this function is not used directly but instead
+subsystems like pwm implement their ACPI support on top of this function
+in such way that it is hidden from the client drivers, such as via
+pwm_get().
+
+3. Device property hierarchies
+------------------------------
+Devices are organized in a tree within the Linux kernel. It follows that
+the configuration data would also be hierarchical. In order to reach
+equivalence with Device Tree, the ACPI mechanism must also provide some
+sort of tree-like representation. Fortunately, the ACPI namespace is
+already such a structure.
+
+For example, we could have the following device in ACPI namespace. The
+KEYS device is much like gpio_keys_polled.c in that it includes "pseudo"
+devices for each GPIO:
+
+	Device (KEYS)
+	{
+		Name (_CRS, ResourceTemplate () {
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
+			...
+		})
+
+		// "pseudo" devices declared under the parent device
+		Device (BTN0) {
+			Name (_DSD, Package () {
+				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+				Package () {
+					Package () {"label", "minnow_btn0"}
+					Package () {"gpios", Package () {^KEYS, 0, 0, 1}}
+				}
+			})
+		}
+
+		Device (BTN1) {
+			Name (_DSD, Package () {
+				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+				Package () {
+					Package () {"label", "minnow_btn1"}
+					Package () {"gpios", Package () {^KEYS, 1, 0, 1}}
+				}
+			})
+		}
+	}
+
+We can extract the above in gpio_keys_polled.c like:
+
+	static int gpio_keys_polled_create_button(struct device *dev, void *child,
+						  void *data)
+	{
+		struct button_data *bdata = data;
+		const char *label = NULL;
+
+		/*
+		 * We need to use device_child_ variant here to access
+		 * properties of the child.
+		 */
+		device_child_property_read_string(dev, child, "label", &label);
+		/* and so on */
+	}
+
+	static void gpio_keys_polled_probe(struct device *dev)
+	{
+		/* Properties for the KEYS device itself */
+		device_property_read(dev, ...);
+
+		/*
+		 * Iterate over button devices and extract their
+		 * firmware configuration.
+		 */
+		ret = device_for_each_child_node(dev, gpio_keys_polled_create_button,
+						 &bdata);
+		if (ret)
+			/* Handle error */
+	}
+
+Note that you still need proper error handling which is omitted in the
+above example.
+
+4. Existing Device Tree enabled drivers
+---------------------------------------
+At the time of writing this, there are ~250 existing DT enabled drivers.
+Allocating _HID/_CID for each would not be feasible. To make sure that
+those drivers can still be used on ACPI systems, we provide an
+alternative way to get these matched.
+
+There is a special _HID "PRP0001" which means that use the DT bindings
+for matching this device to a driver. The driver needs to have
+.of_match_table filled in even when !CONFIG_OF.
+
+An example device would be leds that can be controlled via GPIOs. This
+is represented as "leds-gpio" device and looks like this in the ACPI
+namespace:
+
+	Device (LEDS)
+	{
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {"compatible", Package () {"gpio-leds"}},
+			}
+		})
+		...
+	}
+
+In order to get the existing drivers/leds/leds-gpio.c bound to this
+device, we take advantage of "PRP0001":
+
+	/* Following already exists in the driver */
+	static const struct of_device_id of_gpio_leds_match[] = {
+		{ .compatible = "gpio-leds", },
+		{},
+	};
+	MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
+
+	/* This we add to the driver to get it probed */
+	static const struct acpi_device_id acpi_gpio_leds_match[] = {
+		{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
+		{},
+	};
+	MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
+
+	static struct platform_driver gpio_led_driver = {
+		.driver = {
+			/*
+			 * No of_match_ptr() here because we want this
+			 * table to be visible even when !CONFIG_OF to
+			 * match against "compatible" in _DSD.
+			 */
+			.of_match_table = of_gpio_leds_match,
+			.acpi_match_table = acpi_gpio_leds_match,
+		},
+	};
+
+Once ACPI core sees "PRP0001" and that the device has "compatible"
+property it will do the match using .of_match_table instead.
+
+It is preferred that new devices get a proper _HID allocated for them
+instead of inventing new DT "compatible" devices.
-- 
1.9.3


--G44BJl3Aq1QbV/QL--

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [PATCH v3 05/15] gpio / ACPI: Add support for _DSD device properties
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (3 preceding siblings ...)
  2014-10-01  2:11   ` [PATCH v3 04/15] ACPI: Document ACPI device specific properties Rafael J. Wysocki
@ 2014-10-01  2:12   ` Rafael J. Wysocki
       [not found]     ` <4786851.38d7sjpzag-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
       [not found]   ` <1852462.V1jlbi8OPt-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
                     ` (8 subsequent siblings)
  13 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:12 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

With release of ACPI 5.1 and _DSD method we can finally name GPIOs (and
other things as well) returned by _CRS. Previously we were only able to
use integer index to find the corresponding GPIO, which is pretty error
prone if the order changes.

With _DSD we can now query GPIOs using name instead of an integer index,
like the below example shows:

  // Bluetooth device with reset and shutdown GPIOs
  Device (BTH)
  {
      Name (_HID, ...)

      Name (_CRS, ResourceTemplate ()
      {
          GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
                  "\\_SB.GPO0", 0, ResourceConsumer) {15}
          GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
                  "\\_SB.GPO0", 0, ResourceConsumer) {27, 31}
      })

      Name (_DSD, Package ()
      {
          ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
          Package ()
	  {
              Package () {"reset-gpio", Package() {^BTH, 1, 1, 0 }},
              Package () {"shutdown-gpio", Package() {^BTH, 0, 0, 0 }},
          }
      })
  }

The format of the supported GPIO property is:

  Package () { "name", Package () { ref, index, pin, active_low }}

  ref - The device that has _CRS containing GpioIo()/GpioInt() resources,
        typically this is the device itself (BTH in our case).
  index - Index of the GpioIo()/GpioInt() resource in _CRS starting from zero.
  pin - Pin in the GpioIo()/GpioInt() resource. Typically this is zero.
  active_low - If 1 the GPIO is marked as active_low.

Since ACPI GpioIo() resource does not have field saying whether it is
active low or high, the "active_low" argument can be used here. Setting
it to 1 marks the GPIO as active low.

In our Bluetooth example the "reset-gpio" refers to the second GpioIo()
resource, second pin in that resource with the GPIO number of 31.

This patch implements necessary support to gpiolib for extracting GPIOs
using _DSD device properties.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/gpio/gpiolib-acpi.c |   78 ++++++++++++++++++++++++++++++++++++--------
 drivers/gpio/gpiolib.c      |   30 ++++++++++++++--
 drivers/gpio/gpiolib.h      |    7 ++-
 3 files changed, 94 insertions(+), 21 deletions(-)

Index: linux-pm/drivers/gpio/gpiolib-acpi.c
===================================================================
--- linux-pm.orig/drivers/gpio/gpiolib-acpi.c
+++ linux-pm/drivers/gpio/gpiolib-acpi.c
@@ -293,6 +293,7 @@ void acpi_gpiochip_free_interrupts(struc
 struct acpi_gpio_lookup {
 	struct acpi_gpio_info info;
 	int index;
+	int pin_index;
 	struct gpio_desc *desc;
 	int n;
 };
@@ -306,13 +307,24 @@ static int acpi_find_gpio(struct acpi_re
 
 	if (lookup->n++ == lookup->index && !lookup->desc) {
 		const struct acpi_resource_gpio *agpio = &ares->data.gpio;
+		int pin_index = lookup->pin_index;
+
+		if (pin_index >= agpio->pin_table_length)
+			return 1;
 
 		lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
-					      agpio->pin_table[0]);
+					      agpio->pin_table[pin_index]);
 		lookup->info.gpioint =
 			agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
-		lookup->info.active_low =
-			agpio->polarity == ACPI_ACTIVE_LOW;
+
+		/*
+		 * ActiveLow is only specified for GpioInt resource. If
+		 * GpioIo is used then the only way to set the flag is
+		 * to use _DSD "gpios" property.
+		 */
+		if (lookup->info.gpioint)
+			lookup->info.active_low =
+				agpio->polarity == ACPI_ACTIVE_LOW;
 	}
 
 	return 1;
@@ -320,40 +332,75 @@ static int acpi_find_gpio(struct acpi_re
 
 /**
  * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
- * @dev: pointer to a device to get GPIO from
+ * @adev: pointer to a ACPI device to get GPIO from
+ * @propname: Property name of the GPIO (optional)
  * @index: index of GpioIo/GpioInt resource (starting from %0)
  * @info: info pointer to fill in (optional)
  *
- * Function goes through ACPI resources for @dev and based on @index looks
+ * Function goes through ACPI resources for @adev and based on @index looks
  * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor,
  * and returns it. @index matches GpioIo/GpioInt resources only so if there
  * are total %3 GPIO resources, the index goes from %0 to %2.
  *
+ * If @propname is specified the GPIO is looked using device property. In
+ * that case @index is used to select the GPIO entry in the property value
+ * (in case of multiple).
+ *
  * If the GPIO cannot be translated or there is an error an ERR_PTR is
  * returned.
  *
  * Note: if the GPIO resource has multiple entries in the pin list, this
  * function only returns the first.
  */
-struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
+struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
+					  const char *propname, int index,
 					  struct acpi_gpio_info *info)
 {
 	struct acpi_gpio_lookup lookup;
 	struct list_head resource_list;
-	struct acpi_device *adev;
-	acpi_handle handle;
+	bool active_low = false;
 	int ret;
 
-	if (!dev)
-		return ERR_PTR(-EINVAL);
-
-	handle = ACPI_HANDLE(dev);
-	if (!handle || acpi_bus_get_device(handle, &adev))
+	if (!adev)
 		return ERR_PTR(-ENODEV);
 
 	memset(&lookup, 0, sizeof(lookup));
 	lookup.index = index;
 
+	if (propname) {
+		struct acpi_reference_args args;
+
+		dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
+
+		memset(&args, 0, sizeof(args));
+		ret = acpi_dev_get_property_reference(adev, propname, NULL,
+						      index, &args);
+		if (ret)
+			return ERR_PTR(ret);
+
+		/*
+		 * The property was found and resolved so need to
+		 * lookup the GPIO based on returned args instead.
+		 */
+		adev = args.adev;
+		if (args.nargs >= 2) {
+			lookup.index = args.args[0];
+			lookup.pin_index = args.args[1];
+			/*
+			 * 3rd argument, if present is used to
+			 * specify active_low.
+			 */
+			if (args.nargs >= 3)
+				active_low = !!args.args[2];
+		}
+
+		dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n",
+			dev_name(&adev->dev), args.nargs,
+			args.args[0], args.args[1], args.args[2]);
+	} else {
+		dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index);
+	}
+
 	INIT_LIST_HEAD(&resource_list);
 	ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
 				     &lookup);
@@ -362,8 +409,11 @@ struct gpio_desc *acpi_get_gpiod_by_inde
 
 	acpi_dev_free_resource_list(&resource_list);
 
-	if (lookup.desc && info)
+	if (lookup.desc && info) {
 		*info = lookup.info;
+		if (active_low)
+			info->active_low = active_low;
+	}
 
 	return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
 }
Index: linux-pm/drivers/gpio/gpiolib.c
===================================================================
--- linux-pm.orig/drivers/gpio/gpiolib.c
+++ linux-pm/drivers/gpio/gpiolib.c
@@ -1487,14 +1487,36 @@ static struct gpio_desc *acpi_find_gpio(
 					unsigned int idx,
 					enum gpio_lookup_flags *flags)
 {
+	static const char * const suffixes[] = { "gpios", "gpio" };
+	struct acpi_device *adev = ACPI_COMPANION(dev);
 	struct acpi_gpio_info info;
 	struct gpio_desc *desc;
+	char propname[32];
+	int i;
 
-	desc = acpi_get_gpiod_by_index(dev, idx, &info);
-	if (IS_ERR(desc))
-		return desc;
+	/* Try first from _DSD */
+	for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
+		if (con_id && strcmp(con_id, "gpios")) {
+			snprintf(propname, sizeof(propname), "%s-%s",
+				 con_id, suffixes[i]);
+		} else {
+			snprintf(propname, sizeof(propname), "%s",
+				 suffixes[i]);
+		}
 
-	if (info.gpioint && info.active_low)
+		desc = acpi_get_gpiod_by_index(adev, propname, 0, &info);
+		if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
+			break;
+	}
+
+	/* Then from plain _CRS GPIOs */
+	if (IS_ERR(desc)) {
+		desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
+		if (IS_ERR(desc))
+			return desc;
+	}
+
+	if (info.active_low)
 		*flags |= GPIO_ACTIVE_LOW;
 
 	return desc;
Index: linux-pm/drivers/gpio/gpiolib.h
===================================================================
--- linux-pm.orig/drivers/gpio/gpiolib.h
+++ linux-pm/drivers/gpio/gpiolib.h
@@ -34,7 +34,8 @@ void acpi_gpiochip_remove(struct gpio_ch
 void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
 void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
 
-struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
+struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
+					  const char *propname, int index,
 					  struct acpi_gpio_info *info);
 #else
 static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
@@ -47,8 +48,8 @@ static inline void
 acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
 
 static inline struct gpio_desc *
-acpi_get_gpiod_by_index(struct device *dev, int index,
-			struct acpi_gpio_info *info)
+acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname,
+			int index, struct acpi_gpio_info *info)
 {
 	return ERR_PTR(-ENOSYS);
 }

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 06/15] gpio: Support for unified device properties interface
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
@ 2014-10-01  2:14       ` Rafael J. Wysocki
  2014-10-01  2:10   ` [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware Rafael J. Wysocki
                         ` (12 subsequent siblings)
  13 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:14 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Linus Walleij
  Cc: Mika Westerberg, linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

Some drivers need to deal with only firmware representation of its
GPIOs. An example would be a GPIO button array driver where each button
is described as a separate firmware node in device tree. Typically these
child nodes do not have physical representation in the Linux device
model.

In order to help device drivers to handle such firmware child nodes we
add dev[m]_get_named_gpiod_from_child() that takes a child firmware
node pointer as its second argument (the first one is the parent device
itself), finds the GPIO using whatever is the underlying firmware
method, and requests the GPIO properly.

Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---

Linus, does this look better than the previous one to you?

---
 drivers/gpio/devres.c         |   34 +++++++++++++++++++++++++
 drivers/gpio/gpiolib.c        |   56 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/gpio/consumer.h |    5 +++
 3 files changed, 95 insertions(+)

Index: linux-pm/drivers/gpio/devres.c
===================================================================
--- linux-pm.orig/drivers/gpio/devres.c
+++ linux-pm/drivers/gpio/devres.c
@@ -109,6 +109,40 @@ struct gpio_desc *__must_check __devm_gp
 EXPORT_SYMBOL(__devm_gpiod_get_index);
 
 /**
+ * devm_get_named_gpiod_from_child - managed dev_get_named_gpiod_from_child()
+ * @dev:	GPIO consumer
+ * @child:	firmware node (child of @dev)
+ * @propname:	name of the firmware property
+ * @index:	index of the GPIO in the property value in case of many
+ *
+ * GPIO descriptors returned from this function are automatically disposed on
+ * driver detach.
+ */
+struct gpio_desc *devm_get_named_gpiod_from_child(struct device *dev, void *child,
+						  const char *propname, int index)
+{
+	struct gpio_desc **dr;
+	struct gpio_desc *desc;
+
+	dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
+			  GFP_KERNEL);
+	if (!dr)
+		return ERR_PTR(-ENOMEM);
+
+	desc = dev_get_named_gpiod_from_child(dev, child, propname, index);
+	if (IS_ERR(desc)) {
+		devres_free(dr);
+		return desc;
+	}
+
+	*dr = desc;
+	devres_add(dev, dr);
+
+	return desc;
+}
+EXPORT_SYMBOL(devm_get_named_gpiod_from_child);
+
+/**
  * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
  * @dev: GPIO consumer
  * @con_id: function within the GPIO consumer
Index: linux-pm/drivers/gpio/gpiolib.c
===================================================================
--- linux-pm.orig/drivers/gpio/gpiolib.c
+++ linux-pm/drivers/gpio/gpiolib.c
@@ -1717,6 +1717,62 @@ struct gpio_desc *__must_check __gpiod_g
 EXPORT_SYMBOL_GPL(__gpiod_get_index);
 
 /**
+ * dev_get_named_gpiod_from_child - obtain a GPIO from firmware node
+ * @dev:	parent device
+ * @child:	firmware node (child of @dev)
+ * @propname:	name of the firmware property
+ * @idx:	index of the GPIO in the property value in case of many
+ *
+ * This function can be used for drivers that get their configuration
+ * from firmware in such a way that some properties are described as child
+ * nodes for the parent device in DT or ACPI.
+ *
+ * Function properly finds the corresponding GPIO using whatever is the
+ * underlying firmware interface and then makes sure that the GPIO
+ * descriptor is requested before it is returned to the caller.
+ *
+ * In case of error an ERR_PTR() is returned.
+ */
+struct gpio_desc *dev_get_named_gpiod_from_child(struct device *dev, void *child,
+						 const char *propname, int index)
+{
+	struct gpio_desc *desc = ERR_PTR(-ENODEV);
+	bool active_low = false;
+	int ret;
+
+	if (!child)
+		return ERR_PTR(-EINVAL);
+
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+		enum of_gpio_flags flags;
+
+		desc = of_get_named_gpiod_flags(child, propname, index, &flags);
+		if (!IS_ERR(desc))
+			active_low = flags & OF_GPIO_ACTIVE_LOW;
+	} else if (ACPI_COMPANION(dev)) {
+		struct acpi_gpio_info info;
+
+		desc = acpi_get_gpiod_by_index(child, propname, index, &info);
+		if (!IS_ERR(desc))
+			active_low = info.active_low;
+	}
+
+	if (IS_ERR(desc))
+		return desc;
+
+	ret = gpiod_request(desc, NULL);
+	if (ret)
+		return ERR_PTR(ret);
+
+	/* Only value flag can be set from both DT and ACPI is active_low */
+	if (active_low)
+		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+
+	return desc;
+}
+EXPORT_SYMBOL_GPL(dev_get_named_gpiod_from_child);
+
+/**
  * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
  *                            function
  * @dev: GPIO consumer, can be NULL for system-global GPIOs
Index: linux-pm/include/linux/gpio/consumer.h
===================================================================
--- linux-pm.orig/include/linux/gpio/consumer.h
+++ linux-pm/include/linux/gpio/consumer.h
@@ -94,6 +94,11 @@ int gpiod_to_irq(const struct gpio_desc
 struct gpio_desc *gpio_to_desc(unsigned gpio);
 int desc_to_gpio(const struct gpio_desc *desc);
 
+/* Child properties interface */
+struct gpio_desc *dev_get_named_gpiod_from_child(struct device *dev, void *child,
+						 const char *propname, int index);
+struct gpio_desc *devm_get_named_gpiod_from_child(struct device *dev, void *child,
+						  const char *propname, int index);
 #else /* CONFIG_GPIOLIB */
 
 static inline struct gpio_desc *__must_check __gpiod_get(struct device *dev,

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 06/15] gpio: Support for unified device properties interface
@ 2014-10-01  2:14       ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:14 UTC (permalink / raw)
  To: linux-kernel, Linus Walleij
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

Some drivers need to deal with only firmware representation of its
GPIOs. An example would be a GPIO button array driver where each button
is described as a separate firmware node in device tree. Typically these
child nodes do not have physical representation in the Linux device
model.

In order to help device drivers to handle such firmware child nodes we
add dev[m]_get_named_gpiod_from_child() that takes a child firmware
node pointer as its second argument (the first one is the parent device
itself), finds the GPIO using whatever is the underlying firmware
method, and requests the GPIO properly.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

Linus, does this look better than the previous one to you?

---
 drivers/gpio/devres.c         |   34 +++++++++++++++++++++++++
 drivers/gpio/gpiolib.c        |   56 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/gpio/consumer.h |    5 +++
 3 files changed, 95 insertions(+)

Index: linux-pm/drivers/gpio/devres.c
===================================================================
--- linux-pm.orig/drivers/gpio/devres.c
+++ linux-pm/drivers/gpio/devres.c
@@ -109,6 +109,40 @@ struct gpio_desc *__must_check __devm_gp
 EXPORT_SYMBOL(__devm_gpiod_get_index);
 
 /**
+ * devm_get_named_gpiod_from_child - managed dev_get_named_gpiod_from_child()
+ * @dev:	GPIO consumer
+ * @child:	firmware node (child of @dev)
+ * @propname:	name of the firmware property
+ * @index:	index of the GPIO in the property value in case of many
+ *
+ * GPIO descriptors returned from this function are automatically disposed on
+ * driver detach.
+ */
+struct gpio_desc *devm_get_named_gpiod_from_child(struct device *dev, void *child,
+						  const char *propname, int index)
+{
+	struct gpio_desc **dr;
+	struct gpio_desc *desc;
+
+	dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
+			  GFP_KERNEL);
+	if (!dr)
+		return ERR_PTR(-ENOMEM);
+
+	desc = dev_get_named_gpiod_from_child(dev, child, propname, index);
+	if (IS_ERR(desc)) {
+		devres_free(dr);
+		return desc;
+	}
+
+	*dr = desc;
+	devres_add(dev, dr);
+
+	return desc;
+}
+EXPORT_SYMBOL(devm_get_named_gpiod_from_child);
+
+/**
  * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
  * @dev: GPIO consumer
  * @con_id: function within the GPIO consumer
Index: linux-pm/drivers/gpio/gpiolib.c
===================================================================
--- linux-pm.orig/drivers/gpio/gpiolib.c
+++ linux-pm/drivers/gpio/gpiolib.c
@@ -1717,6 +1717,62 @@ struct gpio_desc *__must_check __gpiod_g
 EXPORT_SYMBOL_GPL(__gpiod_get_index);
 
 /**
+ * dev_get_named_gpiod_from_child - obtain a GPIO from firmware node
+ * @dev:	parent device
+ * @child:	firmware node (child of @dev)
+ * @propname:	name of the firmware property
+ * @idx:	index of the GPIO in the property value in case of many
+ *
+ * This function can be used for drivers that get their configuration
+ * from firmware in such a way that some properties are described as child
+ * nodes for the parent device in DT or ACPI.
+ *
+ * Function properly finds the corresponding GPIO using whatever is the
+ * underlying firmware interface and then makes sure that the GPIO
+ * descriptor is requested before it is returned to the caller.
+ *
+ * In case of error an ERR_PTR() is returned.
+ */
+struct gpio_desc *dev_get_named_gpiod_from_child(struct device *dev, void *child,
+						 const char *propname, int index)
+{
+	struct gpio_desc *desc = ERR_PTR(-ENODEV);
+	bool active_low = false;
+	int ret;
+
+	if (!child)
+		return ERR_PTR(-EINVAL);
+
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+		enum of_gpio_flags flags;
+
+		desc = of_get_named_gpiod_flags(child, propname, index, &flags);
+		if (!IS_ERR(desc))
+			active_low = flags & OF_GPIO_ACTIVE_LOW;
+	} else if (ACPI_COMPANION(dev)) {
+		struct acpi_gpio_info info;
+
+		desc = acpi_get_gpiod_by_index(child, propname, index, &info);
+		if (!IS_ERR(desc))
+			active_low = info.active_low;
+	}
+
+	if (IS_ERR(desc))
+		return desc;
+
+	ret = gpiod_request(desc, NULL);
+	if (ret)
+		return ERR_PTR(ret);
+
+	/* Only value flag can be set from both DT and ACPI is active_low */
+	if (active_low)
+		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+
+	return desc;
+}
+EXPORT_SYMBOL_GPL(dev_get_named_gpiod_from_child);
+
+/**
  * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
  *                            function
  * @dev: GPIO consumer, can be NULL for system-global GPIOs
Index: linux-pm/include/linux/gpio/consumer.h
===================================================================
--- linux-pm.orig/include/linux/gpio/consumer.h
+++ linux-pm/include/linux/gpio/consumer.h
@@ -94,6 +94,11 @@ int gpiod_to_irq(const struct gpio_desc
 struct gpio_desc *gpio_to_desc(unsigned gpio);
 int desc_to_gpio(const struct gpio_desc *desc);
 
+/* Child properties interface */
+struct gpio_desc *dev_get_named_gpiod_from_child(struct device *dev, void *child,
+						 const char *propname, int index);
+struct gpio_desc *devm_get_named_gpiod_from_child(struct device *dev, void *child,
+						  const char *propname, int index);
 #else /* CONFIG_GPIOLIB */
 
 static inline struct gpio_desc *__must_check __gpiod_get(struct device *dev,


^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 07/15] gpio: sch: Consolidate core and resume banks
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (5 preceding siblings ...)
       [not found]   ` <1852462.V1jlbi8OPt-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
@ 2014-10-01  2:15   ` Rafael J. Wysocki
  2014-10-01  2:15   ` [PATCH v3 08/15] leds: leds-gpio: Add support for GPIO descriptors Rafael J. Wysocki
                     ` (6 subsequent siblings)
  13 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

This is actually a single device with two sets of identical registers,
which just happen to start from a different offset. Instead of having
separate GPIO chips created we consolidate them to be single GPIO chip.

In addition having a single GPIO chip allows us to handle ACPI GPIO
translation in the core in a more generic way, since the two GPIO chips
share the same parent ACPI device.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/gpio/gpio-sch.c | 293 ++++++++++++++++++------------------------------
 1 file changed, 112 insertions(+), 181 deletions(-)

diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
index 41e91d70301e..99720c8bc8ed 100644
--- a/drivers/gpio/gpio-sch.c
+++ b/drivers/gpio/gpio-sch.c
@@ -29,290 +29,221 @@
 
 #include <linux/gpio.h>
 
-static DEFINE_SPINLOCK(gpio_lock);
-
-#define CGEN	(0x00)
-#define CGIO	(0x04)
-#define CGLV	(0x08)
-
-#define RGEN	(0x20)
-#define RGIO	(0x24)
-#define RGLV	(0x28)
-
-static unsigned short gpio_ba;
-
-static int sch_gpio_core_direction_in(struct gpio_chip *gc, unsigned  gpio_num)
-{
-	u8 curr_dirs;
-	unsigned short offset, bit;
-
-	spin_lock(&gpio_lock);
-
-	offset = CGIO + gpio_num / 8;
-	bit = gpio_num % 8;
-
-	curr_dirs = inb(gpio_ba + offset);
-
-	if (!(curr_dirs & (1 << bit)))
-		outb(curr_dirs | (1 << bit), gpio_ba + offset);
+#define GEN	0x00
+#define GIO	0x04
+#define GLV	0x08
+
+struct sch_gpio {
+	struct gpio_chip chip;
+	spinlock_t lock;
+	unsigned short iobase;
+	unsigned short core_base;
+	unsigned short resume_base;
+};
 
-	spin_unlock(&gpio_lock);
-	return 0;
-}
+#define to_sch_gpio(c)	container_of(c, struct sch_gpio, chip)
 
-static int sch_gpio_core_get(struct gpio_chip *gc, unsigned gpio_num)
+static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
+				unsigned reg)
 {
-	int res;
-	unsigned short offset, bit;
+	unsigned base = 0;
 
-	offset = CGLV + gpio_num / 8;
-	bit = gpio_num % 8;
+	if (gpio >= sch->resume_base) {
+		gpio -= sch->resume_base;
+		base += 0x20;
+	}
 
-	res = !!(inb(gpio_ba + offset) & (1 << bit));
-	return res;
+	return base + reg + gpio / 8;
 }
 
-static void sch_gpio_core_set(struct gpio_chip *gc, unsigned gpio_num, int val)
+static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
 {
-	u8 curr_vals;
-	unsigned short offset, bit;
-
-	spin_lock(&gpio_lock);
-
-	offset = CGLV + gpio_num / 8;
-	bit = gpio_num % 8;
-
-	curr_vals = inb(gpio_ba + offset);
-
-	if (val)
-		outb(curr_vals | (1 << bit), gpio_ba + offset);
-	else
-		outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
-	spin_unlock(&gpio_lock);
+	if (gpio >= sch->resume_base)
+		gpio -= sch->resume_base;
+	return gpio % 8;
 }
 
-static int sch_gpio_core_direction_out(struct gpio_chip *gc,
-					unsigned gpio_num, int val)
+static void sch_gpio_enable(struct sch_gpio *sch, unsigned gpio)
 {
-	u8 curr_dirs;
 	unsigned short offset, bit;
+	u8 enable;
 
-	spin_lock(&gpio_lock);
+	spin_lock(&sch->lock);
 
-	offset = CGIO + gpio_num / 8;
-	bit = gpio_num % 8;
-
-	curr_dirs = inb(gpio_ba + offset);
-	if (curr_dirs & (1 << bit))
-		outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
+	offset = sch_gpio_offset(sch, gpio, GEN);
+	bit = sch_gpio_bit(sch, gpio);
 
-	spin_unlock(&gpio_lock);
+	enable = inb(sch->iobase + offset);
+	if (!(enable & (1 << bit)))
+		outb(enable | (1 << bit), sch->iobase + offset);
 
-	/*
-	 * according to the datasheet, writing to the level register has no
-	 * effect when GPIO is programmed as input.
-	 * Actually the the level register is read-only when configured as input.
-	 * Thus presetting the output level before switching to output is _NOT_ possible.
-	 * Hence we set the level after configuring the GPIO as output.
-	 * But we cannot prevent a short low pulse if direction is set to high
-	 * and an external pull-up is connected.
-	 */
-	sch_gpio_core_set(gc, gpio_num, val);
-	return 0;
+	spin_unlock(&sch->lock);
 }
 
-static struct gpio_chip sch_gpio_core = {
-	.label			= "sch_gpio_core",
-	.owner			= THIS_MODULE,
-	.direction_input	= sch_gpio_core_direction_in,
-	.get			= sch_gpio_core_get,
-	.direction_output	= sch_gpio_core_direction_out,
-	.set			= sch_gpio_core_set,
-};
-
-static int sch_gpio_resume_direction_in(struct gpio_chip *gc,
-					unsigned gpio_num)
+static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned  gpio_num)
 {
+	struct sch_gpio *sch = to_sch_gpio(gc);
 	u8 curr_dirs;
 	unsigned short offset, bit;
 
-	spin_lock(&gpio_lock);
+	spin_lock(&sch->lock);
 
-	offset = RGIO + gpio_num / 8;
-	bit = gpio_num % 8;
+	offset = sch_gpio_offset(sch, gpio_num, GIO);
+	bit = sch_gpio_bit(sch, gpio_num);
 
-	curr_dirs = inb(gpio_ba + offset);
+	curr_dirs = inb(sch->iobase + offset);
 
 	if (!(curr_dirs & (1 << bit)))
-		outb(curr_dirs | (1 << bit), gpio_ba + offset);
+		outb(curr_dirs | (1 << bit), sch->iobase + offset);
 
-	spin_unlock(&gpio_lock);
+	spin_unlock(&sch->lock);
 	return 0;
 }
 
-static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num)
+static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
 {
+	struct sch_gpio *sch = to_sch_gpio(gc);
+	int res;
 	unsigned short offset, bit;
 
-	offset = RGLV + gpio_num / 8;
-	bit = gpio_num % 8;
+	offset = sch_gpio_offset(sch, gpio_num, GLV);
+	bit = sch_gpio_bit(sch, gpio_num);
+
+	res = !!(inb(sch->iobase + offset) & (1 << bit));
 
-	return !!(inb(gpio_ba + offset) & (1 << bit));
+	return res;
 }
 
-static void sch_gpio_resume_set(struct gpio_chip *gc,
-				unsigned gpio_num, int val)
+static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
 {
+	struct sch_gpio *sch = to_sch_gpio(gc);
 	u8 curr_vals;
 	unsigned short offset, bit;
 
-	spin_lock(&gpio_lock);
+	spin_lock(&sch->lock);
 
-	offset = RGLV + gpio_num / 8;
-	bit = gpio_num % 8;
+	offset = sch_gpio_offset(sch, gpio_num, GLV);
+	bit = sch_gpio_bit(sch, gpio_num);
 
-	curr_vals = inb(gpio_ba + offset);
+	curr_vals = inb(sch->iobase + offset);
 
 	if (val)
-		outb(curr_vals | (1 << bit), gpio_ba + offset);
+		outb(curr_vals | (1 << bit), sch->iobase + offset);
 	else
-		outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
+		outb((curr_vals & ~(1 << bit)), sch->iobase + offset);
 
-	spin_unlock(&gpio_lock);
+	spin_unlock(&sch->lock);
 }
 
-static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
-					unsigned gpio_num, int val)
+static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
+				  int val)
 {
+	struct sch_gpio *sch = to_sch_gpio(gc);
 	u8 curr_dirs;
 	unsigned short offset, bit;
 
-	offset = RGIO + gpio_num / 8;
-	bit = gpio_num % 8;
+	spin_lock(&sch->lock);
 
-	spin_lock(&gpio_lock);
+	offset = sch_gpio_offset(sch, gpio_num, GIO);
+	bit = sch_gpio_bit(sch, gpio_num);
 
-	curr_dirs = inb(gpio_ba + offset);
+	curr_dirs = inb(sch->iobase + offset);
 	if (curr_dirs & (1 << bit))
-		outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
+		outb(curr_dirs & ~(1 << bit), sch->iobase + offset);
 
-	spin_unlock(&gpio_lock);
+	spin_unlock(&sch->lock);
 
 	/*
-	* according to the datasheet, writing to the level register has no
-	* effect when GPIO is programmed as input.
-	* Actually the the level register is read-only when configured as input.
-	* Thus presetting the output level before switching to output is _NOT_ possible.
-	* Hence we set the level after configuring the GPIO as output.
-	* But we cannot prevent a short low pulse if direction is set to high
-	* and an external pull-up is connected.
-	*/
-	sch_gpio_resume_set(gc, gpio_num, val);
+	 * according to the datasheet, writing to the level register has no
+	 * effect when GPIO is programmed as input.
+	 * Actually the the level register is read-only when configured as input.
+	 * Thus presetting the output level before switching to output is _NOT_ possible.
+	 * Hence we set the level after configuring the GPIO as output.
+	 * But we cannot prevent a short low pulse if direction is set to high
+	 * and an external pull-up is connected.
+	 */
+	sch_gpio_set(gc, gpio_num, val);
 	return 0;
 }
 
-static struct gpio_chip sch_gpio_resume = {
-	.label			= "sch_gpio_resume",
+static struct gpio_chip sch_gpio_chip = {
+	.label			= "sch_gpio",
 	.owner			= THIS_MODULE,
-	.direction_input	= sch_gpio_resume_direction_in,
-	.get			= sch_gpio_resume_get,
-	.direction_output	= sch_gpio_resume_direction_out,
-	.set			= sch_gpio_resume_set,
+	.direction_input	= sch_gpio_direction_in,
+	.get			= sch_gpio_get,
+	.direction_output	= sch_gpio_direction_out,
+	.set			= sch_gpio_set,
 };
 
 static int sch_gpio_probe(struct platform_device *pdev)
 {
+	struct sch_gpio *sch;
 	struct resource *res;
-	int err, id;
 
-	id = pdev->id;
-	if (!id)
-		return -ENODEV;
+	sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL);
+	if (!sch)
+		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 	if (!res)
 		return -EBUSY;
 
-	if (!request_region(res->start, resource_size(res), pdev->name))
+	if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
+				 pdev->name))
 		return -EBUSY;
 
-	gpio_ba = res->start;
+	spin_lock_init(&sch->lock);
+	sch->iobase = res->start;
+	sch->chip = sch_gpio_chip;
+	sch->chip.label = dev_name(&pdev->dev);
+	sch->chip.dev = &pdev->dev;
 
-	switch (id) {
+	switch (pdev->id) {
 	case PCI_DEVICE_ID_INTEL_SCH_LPC:
-		sch_gpio_core.base = 0;
-		sch_gpio_core.ngpio = 10;
-		sch_gpio_resume.base = 10;
-		sch_gpio_resume.ngpio = 4;
+		sch->core_base = 0;
+		sch->resume_base = 10;
+		sch->chip.ngpio = 14;
+
 		/*
 		 * GPIO[6:0] enabled by default
 		 * GPIO7 is configured by the CMC as SLPIOVR
 		 * Enable GPIO[9:8] core powered gpios explicitly
 		 */
-		outb(0x3, gpio_ba + CGEN + 1);
+		sch_gpio_enable(sch, 8);
+		sch_gpio_enable(sch, 9);
 		/*
 		 * SUS_GPIO[2:0] enabled by default
 		 * Enable SUS_GPIO3 resume powered gpio explicitly
 		 */
-		outb(0x8, gpio_ba + RGEN);
+		sch_gpio_enable(sch, 13);
 		break;
 
 	case PCI_DEVICE_ID_INTEL_ITC_LPC:
-		sch_gpio_core.base = 0;
-		sch_gpio_core.ngpio = 5;
-		sch_gpio_resume.base = 5;
-		sch_gpio_resume.ngpio = 9;
+		sch->core_base = 0;
+		sch->resume_base = 5;
+		sch->chip.ngpio = 14;
 		break;
 
 	case PCI_DEVICE_ID_INTEL_CENTERTON_ILB:
-		sch_gpio_core.base = 0;
-		sch_gpio_core.ngpio = 21;
-		sch_gpio_resume.base = 21;
-		sch_gpio_resume.ngpio = 9;
+		sch->core_base = 0;
+		sch->resume_base = 21;
+		sch->chip.ngpio = 30;
 		break;
 
 	default:
-		err = -ENODEV;
-		goto err_sch_gpio_core;
+		return -ENODEV;
 	}
 
-	sch_gpio_core.dev = &pdev->dev;
-	sch_gpio_resume.dev = &pdev->dev;
-
-	err = gpiochip_add(&sch_gpio_core);
-	if (err < 0)
-		goto err_sch_gpio_core;
+	platform_set_drvdata(pdev, sch);
 
-	err = gpiochip_add(&sch_gpio_resume);
-	if (err < 0)
-		goto err_sch_gpio_resume;
-
-	return 0;
-
-err_sch_gpio_resume:
-	gpiochip_remove(&sch_gpio_core);
-
-err_sch_gpio_core:
-	release_region(res->start, resource_size(res));
-	gpio_ba = 0;
-
-	return err;
+	return gpiochip_add(&sch->chip);
 }
 
 static int sch_gpio_remove(struct platform_device *pdev)
 {
-	struct resource *res;
-	if (gpio_ba) {
-
-		gpiochip_remove(&sch_gpio_core);
-		gpiochip_remove(&sch_gpio_resume);
-
-		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-
-		release_region(res->start, resource_size(res));
-		gpio_ba = 0;
-	}
+	struct sch_gpio *sch = platform_get_drvdata(pdev);
 
+	gpiochip_remove(&sch->chip);
 	return 0;
 }
 
-- 
1.8.4.5



^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [PATCH v3 08/15] leds: leds-gpio: Add support for GPIO descriptors
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (6 preceding siblings ...)
  2014-10-01  2:15   ` [PATCH v3 07/15] gpio: sch: Consolidate core and resume banks Rafael J. Wysocki
@ 2014-10-01  2:15   ` Rafael J. Wysocki
       [not found]     ` <1490183.QvrzPxsV7q-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
  2014-10-01  2:16   ` [PATCH v3 09/15] leds: leds-gpio: Make use of device property API Rafael J. Wysocki
                     ` (5 subsequent siblings)
  13 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

GPIO descriptors are the preferred way over legacy GPIO numbers
nowadays. Convert the driver to use GPIO descriptors internally but
still allow passing legacy GPIO numbers from platform data to support
existing platforms.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Acked-by: Bryan Wu <cooloney@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/leds/leds-gpio.c | 80 +++++++++++++++++++++++++++---------------------
 include/linux/leds.h     |  1 +
 2 files changed, 46 insertions(+), 35 deletions(-)

diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 57ff20fecf57..c84e913527f0 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/leds.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -24,11 +25,10 @@
 
 struct gpio_led_data {
 	struct led_classdev cdev;
-	unsigned gpio;
+	struct gpio_desc *gpiod;
 	struct work_struct work;
 	u8 new_level;
 	u8 can_sleep;
-	u8 active_low;
 	u8 blinking;
 	int (*platform_gpio_blink_set)(unsigned gpio, int state,
 			unsigned long *delay_on, unsigned long *delay_off);
@@ -40,12 +40,16 @@ static void gpio_led_work(struct work_struct *work)
 		container_of(work, struct gpio_led_data, work);
 
 	if (led_dat->blinking) {
-		led_dat->platform_gpio_blink_set(led_dat->gpio,
-						 led_dat->new_level,
-						 NULL, NULL);
+		int gpio = desc_to_gpio(led_dat->gpiod);
+		int level = led_dat->new_level;
+
+		if (gpiod_is_active_low(led_dat->gpiod))
+			level = !level;
+
+		led_dat->platform_gpio_blink_set(gpio, level, NULL, NULL);
 		led_dat->blinking = 0;
 	} else
-		gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level);
+		gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level);
 }
 
 static void gpio_led_set(struct led_classdev *led_cdev,
@@ -60,9 +64,6 @@ static void gpio_led_set(struct led_classdev *led_cdev,
 	else
 		level = 1;
 
-	if (led_dat->active_low)
-		level = !level;
-
 	/* Setting GPIOs with I2C/etc requires a task context, and we don't
 	 * seem to have a reliable way to know if we're already in one; so
 	 * let's just assume the worst.
@@ -72,11 +73,16 @@ static void gpio_led_set(struct led_classdev *led_cdev,
 		schedule_work(&led_dat->work);
 	} else {
 		if (led_dat->blinking) {
-			led_dat->platform_gpio_blink_set(led_dat->gpio, level,
-							 NULL, NULL);
+			int gpio = desc_to_gpio(led_dat->gpiod);
+
+			if (gpiod_is_active_low(led_dat->gpiod))
+				level = !level;
+
+			led_dat->platform_gpio_blink_set(gpio, level, NULL,
+							 NULL);
 			led_dat->blinking = 0;
 		} else
-			gpio_set_value(led_dat->gpio, level);
+			gpiod_set_value(led_dat->gpiod, level);
 	}
 }
 
@@ -85,9 +91,10 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
 {
 	struct gpio_led_data *led_dat =
 		container_of(led_cdev, struct gpio_led_data, cdev);
+	int gpio = desc_to_gpio(led_dat->gpiod);
 
 	led_dat->blinking = 1;
-	return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK,
+	return led_dat->platform_gpio_blink_set(gpio, GPIO_LED_BLINK,
 						delay_on, delay_off);
 }
 
@@ -97,24 +104,33 @@ static int create_gpio_led(const struct gpio_led *template,
 {
 	int ret, state;
 
-	led_dat->gpio = -1;
+	if (!template->gpiod) {
+		unsigned long flags = 0;
 
-	/* skip leds that aren't available */
-	if (!gpio_is_valid(template->gpio)) {
-		dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n",
-				template->gpio, template->name);
-		return 0;
-	}
+		/* skip leds that aren't available */
+		if (!gpio_is_valid(template->gpio)) {
+			dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n",
+					template->gpio, template->name);
+			return 0;
+		}
 
-	ret = devm_gpio_request(parent, template->gpio, template->name);
-	if (ret < 0)
-		return ret;
+		if (template->active_low)
+			flags |= GPIOF_ACTIVE_LOW;
+
+		ret = devm_gpio_request_one(parent, template->gpio, flags,
+					    template->name);
+		if (ret < 0)
+			return ret;
+
+		led_dat->gpiod = gpio_to_desc(template->gpio);
+		if (IS_ERR(led_dat->gpiod))
+			return PTR_ERR(led_dat->gpiod);
+	}
 
 	led_dat->cdev.name = template->name;
 	led_dat->cdev.default_trigger = template->default_trigger;
-	led_dat->gpio = template->gpio;
-	led_dat->can_sleep = gpio_cansleep(template->gpio);
-	led_dat->active_low = template->active_low;
+	led_dat->gpiod = template->gpiod;
+	led_dat->can_sleep = gpiod_cansleep(template->gpiod);
 	led_dat->blinking = 0;
 	if (blink_set) {
 		led_dat->platform_gpio_blink_set = blink_set;
@@ -122,30 +138,24 @@ static int create_gpio_led(const struct gpio_led *template,
 	}
 	led_dat->cdev.brightness_set = gpio_led_set;
 	if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP)
-		state = !!gpio_get_value_cansleep(led_dat->gpio) ^ led_dat->active_low;
+		state = !!gpiod_get_value_cansleep(led_dat->gpiod);
 	else
 		state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
 	led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
 	if (!template->retain_state_suspended)
 		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
 
-	ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
+	ret = gpiod_direction_output(led_dat->gpiod, state);
 	if (ret < 0)
 		return ret;
 
 	INIT_WORK(&led_dat->work, gpio_led_work);
 
-	ret = led_classdev_register(parent, &led_dat->cdev);
-	if (ret < 0)
-		return ret;
-
-	return 0;
+	return led_classdev_register(parent, &led_dat->cdev);
 }
 
 static void delete_gpio_led(struct gpio_led_data *led)
 {
-	if (!gpio_is_valid(led->gpio))
-		return;
 	led_classdev_unregister(&led->cdev);
 	cancel_work_sync(&led->work);
 }
diff --git a/include/linux/leds.h b/include/linux/leds.h
index e43686472197..879a113b3d57 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -246,6 +246,7 @@ struct led_platform_data {
 struct gpio_led {
 	const char *name;
 	const char *default_trigger;
+	struct gpio_desc *gpiod;
 	unsigned 	gpio;
 	unsigned	active_low : 1;
 	unsigned	retain_state_suspended : 1;
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [PATCH v3 09/15] leds: leds-gpio: Make use of device property API
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (7 preceding siblings ...)
  2014-10-01  2:15   ` [PATCH v3 08/15] leds: leds-gpio: Add support for GPIO descriptors Rafael J. Wysocki
@ 2014-10-01  2:16   ` Rafael J. Wysocki
  2014-10-03 14:07     ` Mark Rutland
  2014-10-01  2:17   ` [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support Rafael J. Wysocki
                     ` (4 subsequent siblings)
  13 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Max Eliaser <max@meliaserlow.dyndns.tv>

Make use of device property API in this driver so that both OF and ACPI
based system can use the same driver.

Signed-off-by: Max Eliaser <max.eliaser@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/leds/leds-gpio.c |   99 +++++++++++++++++++----------------------------
 1 file changed, 42 insertions(+), 57 deletions(-)

Index: linux-pm/drivers/leds/leds-gpio.c
===================================================================
--- linux-pm.orig/drivers/leds/leds-gpio.c
+++ linux-pm/drivers/leds/leds-gpio.c
@@ -15,13 +15,11 @@
 #include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/leds.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/of_gpio.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/property.h>
 
 struct gpio_led_data {
 	struct led_classdev cdev;
@@ -171,65 +169,59 @@ static inline int sizeof_gpio_leds_priv(
 		(sizeof(struct gpio_led_data) * num_leds);
 }
 
-/* Code to create from OpenFirmware platform devices */
-#ifdef CONFIG_OF_GPIO
-static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
+static int gpio_leds_create_led(struct device *dev, void *child, void *data)
+{
+	struct gpio_leds_priv *priv = data;
+	struct gpio_led led = {};
+	const char *state = NULL;
+
+	led.gpiod = devm_get_named_gpiod_from_child(dev, child, "gpios", 0);
+	if (IS_ERR(led.gpiod))
+		return PTR_ERR(led.gpiod);
+
+	device_child_property_read_string(dev, child, "label", &led.name);
+	device_child_property_read_string(dev, child, "linux,default-trigger",
+					  &led.default_trigger);
+
+	device_child_property_read_string(dev, child, "linux,default_state",
+					  &state);
+	if (state) {
+		if (!strcmp(state, "keep"))
+			led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
+		else if (!strcmp(state, "on"))
+			led.default_state = LEDS_GPIO_DEFSTATE_ON;
+		else
+			led.default_state = LEDS_GPIO_DEFSTATE_OFF;
+	}
+
+	if (!device_get_child_property(dev, child, "retain-state-suspended", NULL))
+		led.retain_state_suspended = 1;
+
+	return create_gpio_led(&led, &priv->leds[priv->num_leds++], dev, NULL);
+}
+
+static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node, *child;
 	struct gpio_leds_priv *priv;
-	int count, ret;
+	int ret, count;
 
-	/* count LEDs in this device, so we know how much to allocate */
-	count = of_get_available_child_count(np);
+	count = device_get_child_node_count(&pdev->dev);
 	if (!count)
 		return ERR_PTR(-ENODEV);
 
-	for_each_available_child_of_node(np, child)
-		if (of_get_gpio(child, 0) == -EPROBE_DEFER)
-			return ERR_PTR(-EPROBE_DEFER);
-
 	priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count),
 			GFP_KERNEL);
 	if (!priv)
 		return ERR_PTR(-ENOMEM);
 
-	for_each_available_child_of_node(np, child) {
-		struct gpio_led led = {};
-		enum of_gpio_flags flags;
-		const char *state;
-
-		led.gpio = of_get_gpio_flags(child, 0, &flags);
-		led.active_low = flags & OF_GPIO_ACTIVE_LOW;
-		led.name = of_get_property(child, "label", NULL) ? : child->name;
-		led.default_trigger =
-			of_get_property(child, "linux,default-trigger", NULL);
-		state = of_get_property(child, "default-state", NULL);
-		if (state) {
-			if (!strcmp(state, "keep"))
-				led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
-			else if (!strcmp(state, "on"))
-				led.default_state = LEDS_GPIO_DEFSTATE_ON;
-			else
-				led.default_state = LEDS_GPIO_DEFSTATE_OFF;
-		}
-
-		if (of_get_property(child, "retain-state-suspended", NULL))
-			led.retain_state_suspended = 1;
-
-		ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
-				      &pdev->dev, NULL);
-		if (ret < 0) {
-			of_node_put(child);
-			goto err;
-		}
+	ret = device_for_each_child_node(&pdev->dev, gpio_leds_create_led, priv);
+	if (ret) {
+		for (count = priv->num_leds - 2; count >= 0; count--)
+			delete_gpio_led(&priv->leds[count]);
+		return ERR_PTR(ret);
 	}
 
 	return priv;
-
-err:
-	for (count = priv->num_leds - 2; count >= 0; count--)
-		delete_gpio_led(&priv->leds[count]);
-	return ERR_PTR(-ENODEV);
 }
 
 static const struct of_device_id of_gpio_leds_match[] = {
@@ -238,13 +230,6 @@ static const struct of_device_id of_gpio
 };
 
 MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
-#else /* CONFIG_OF_GPIO */
-static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
-{
-	return ERR_PTR(-ENODEV);
-}
-#endif /* CONFIG_OF_GPIO */
-
 
 static int gpio_led_probe(struct platform_device *pdev)
 {
@@ -273,7 +258,7 @@ static int gpio_led_probe(struct platfor
 			}
 		}
 	} else {
-		priv = gpio_leds_create_of(pdev);
+		priv = gpio_leds_create(pdev);
 		if (IS_ERR(priv))
 			return PTR_ERR(priv);
 	}
@@ -300,7 +285,7 @@ static struct platform_driver gpio_led_d
 	.driver		= {
 		.name	= "leds-gpio",
 		.owner	= THIS_MODULE,
-		.of_match_table = of_match_ptr(of_gpio_leds_match),
+		.of_match_table = of_gpio_leds_match,
 	},
 };
 

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (8 preceding siblings ...)
  2014-10-01  2:16   ` [PATCH v3 09/15] leds: leds-gpio: Make use of device property API Rafael J. Wysocki
@ 2014-10-01  2:17   ` Rafael J. Wysocki
  2014-10-01  8:13     ` Arnd Bergmann
  2014-10-01  2:17   ` [PATCH v3 11/15] input: gpio_keys_polled - Add support for GPIO descriptors Rafael J. Wysocki
                     ` (3 subsequent siblings)
  13 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Max Eliaser <max@meliaserlow.dyndns.tv>

This allows the driver to probe from ACPI namespace.

Signed-off-by: Max Eliaser <max.eliaser@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Bryan Wu <cooloney@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/leds/leds-gpio.c |    8 ++++++++
 1 file changed, 8 insertions(+)

Index: linux-pm/drivers/leds/leds-gpio.c
===================================================================
--- linux-pm.orig/drivers/leds/leds-gpio.c
+++ linux-pm/drivers/leds/leds-gpio.c
@@ -231,6 +231,13 @@ static const struct of_device_id of_gpio
 
 MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
 
+static const struct acpi_device_id acpi_gpio_leds_match[] = {
+	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
+	{},
+};
+
+MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
+
 static int gpio_led_probe(struct platform_device *pdev)
 {
 	struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -286,6 +293,7 @@ static struct platform_driver gpio_led_d
 		.name	= "leds-gpio",
 		.owner	= THIS_MODULE,
 		.of_match_table = of_gpio_leds_match,
+		.acpi_match_table = acpi_gpio_leds_match,
 	},
 };
 

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 11/15] input: gpio_keys_polled - Add support for GPIO descriptors
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (9 preceding siblings ...)
  2014-10-01  2:17   ` [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support Rafael J. Wysocki
@ 2014-10-01  2:17   ` Rafael J. Wysocki
  2014-10-01  8:13     ` Arnd Bergmann
  2014-10-01  2:20   ` [PATCH v3 12/15] input: gpio_keys_polled - Make use of device property API Rafael J. Wysocki
                     ` (2 subsequent siblings)
  13 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Aaron Lu <aaron.lu@intel.com>

GPIO descriptors are the preferred way over legacy GPIO numbers
nowadays. Convert the driver to use GPIO descriptors internally but
still allow passing legacy GPIO numbers from platform data to support
existing platforms.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/input/keyboard/gpio_keys_polled.c | 39 +++++++++++++++++++++----------
 include/linux/gpio_keys.h                 |  3 +++
 2 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
index 432d36395f35..b7a514ced509 100644
--- a/drivers/input/keyboard/gpio_keys_polled.c
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -23,6 +23,7 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/gpio_keys.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -51,15 +52,14 @@ static void gpio_keys_polled_check_state(struct input_dev *input,
 	int state;
 
 	if (bdata->can_sleep)
-		state = !!gpio_get_value_cansleep(button->gpio);
+		state = !!gpiod_get_value_cansleep(button->gpiod);
 	else
-		state = !!gpio_get_value(button->gpio);
+		state = !!gpiod_get_value(button->gpiod);
 
 	if (state != bdata->last_state) {
 		unsigned int type = button->type ?: EV_KEY;
 
-		input_event(input, type, button->code,
-			    !!(state ^ button->active_low));
+		input_event(input, type, button->code, state);
 		input_sync(input);
 		bdata->count = 0;
 		bdata->last_state = state;
@@ -259,7 +259,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
 	for (i = 0; i < pdata->nbuttons; i++) {
 		struct gpio_keys_button *button = &pdata->buttons[i];
 		struct gpio_keys_button_data *bdata = &bdev->data[i];
-		unsigned int gpio = button->gpio;
 		unsigned int type = button->type ?: EV_KEY;
 
 		if (button->wakeup) {
@@ -267,15 +266,31 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
 			return -EINVAL;
 		}
 
-		error = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_IN,
-					      button->desc ? : DRV_NAME);
-		if (error) {
-			dev_err(dev, "unable to claim gpio %u, err=%d\n",
-				gpio, error);
-			return error;
+		/*
+		 * Legacy GPIO number so request the GPIO here and
+		 * convert it to descriptor.
+		 */
+		if (!button->gpiod && gpio_is_valid(button->gpio)) {
+			unsigned flags = 0;
+
+			if (button->active_low)
+				flags |= GPIOF_ACTIVE_LOW;
+
+			error = devm_gpio_request_one(&pdev->dev, button->gpio,
+					flags, button->desc ? : DRV_NAME);
+			if (error) {
+				dev_err(dev, "unable to claim gpio %u, err=%d\n",
+					button->gpio, error);
+				return error;
+			}
+
+			button->gpiod = gpio_to_desc(button->gpio);
 		}
 
-		bdata->can_sleep = gpio_cansleep(gpio);
+		if (IS_ERR(button->gpiod))
+			return PTR_ERR(button->gpiod);
+
+		bdata->can_sleep = gpiod_cansleep(button->gpiod);
 		bdata->last_state = -1;
 		bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
 						pdata->poll_interval);
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
index 8b622468952c..ee2d8c6f9130 100644
--- a/include/linux/gpio_keys.h
+++ b/include/linux/gpio_keys.h
@@ -2,6 +2,7 @@
 #define _GPIO_KEYS_H
 
 struct device;
+struct gpio_desc;
 
 /**
  * struct gpio_keys_button - configuration parameters
@@ -17,6 +18,7 @@ struct device;
  *			disable button via sysfs
  * @value:		axis value for %EV_ABS
  * @irq:		Irq number in case of interrupt keys
+ * @gpiod:		GPIO descriptor
  */
 struct gpio_keys_button {
 	unsigned int code;
@@ -29,6 +31,7 @@ struct gpio_keys_button {
 	bool can_disable;
 	int value;
 	unsigned int irq;
+	struct gpio_desc *gpiod;
 };
 
 /**
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [PATCH v3 12/15] input: gpio_keys_polled - Make use of device property API
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (10 preceding siblings ...)
  2014-10-01  2:17   ` [PATCH v3 11/15] input: gpio_keys_polled - Add support for GPIO descriptors Rafael J. Wysocki
@ 2014-10-01  2:20   ` Rafael J. Wysocki
  2014-10-01  2:20   ` [PATCH v3 13/15] input: gpio_keys_polled - Add ACPI probing support Rafael J. Wysocki
  2014-10-01  2:21   ` [PATCH v3 14/15] misc: at25: Make use of device property API Rafael J. Wysocki
  13 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:20 UTC (permalink / raw)
  To: linux-kernel, Dmitry Torokhov
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Bryan Wu, Lee Jones,
	Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Aaron Lu <aaron.lu@intel.com>

Make use of device property API in this driver so that both OF based
system and ACPI based system can use this driver.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

Dmitry, does this look better than the previous one to you?

---
 drivers/input/keyboard/gpio_keys_polled.c |  119 +++++++++++++-----------------
 1 file changed, 52 insertions(+), 67 deletions(-)

Index: linux-pm/drivers/input/keyboard/gpio_keys_polled.c
===================================================================
--- linux-pm.orig/drivers/input/keyboard/gpio_keys_polled.c
+++ linux-pm/drivers/input/keyboard/gpio_keys_polled.c
@@ -25,9 +25,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio_keys.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/of_gpio.h>
+#include <linux/property.h>
 
 #define DRV_NAME	"gpio-keys-polled"
 
@@ -102,21 +100,57 @@ static void gpio_keys_polled_close(struc
 		pdata->disable(bdev->dev);
 }
 
-#ifdef CONFIG_OF
+static int gpio_keys_polled_get_button(struct device *dev, void *child,
+				       void *data)
+{
+	struct gpio_keys_platform_data *pdata = data;
+	struct gpio_keys_button *button;
+	struct gpio_desc *desc;
+
+	desc = devm_get_named_gpiod_from_child(dev, child, "gpios", 0);
+	if (IS_ERR(desc)) {
+		int err = PTR_ERR(desc);
+
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get gpio flags, error: %d\n",
+				err);
+		return err;
+	}
+
+	button = &pdata->buttons[pdata->nbuttons++];
+	button->gpiod = desc;
+
+	if (device_child_property_read_u32(dev, child, "linux,code",
+					   &button->code)) {
+		dev_err(dev, "Button without keycode: %d\n",
+			pdata->nbuttons - 1);
+		return -EINVAL;
+	}
+
+	device_child_property_read_string(dev, child, "label", &button->desc);
+
+	if (device_child_property_read_u32(dev, child, "linux,input-type",
+					   &button->type))
+		button->type = EV_KEY;
+
+	button->wakeup = !device_get_child_property(dev, child,
+						    "gpio-key,wakeup", NULL);
+
+	if (device_child_property_read_u32(dev, child, "debounce-interval",
+					   &button->debounce_interval))
+		button->debounce_interval = 5;
+
+	return 0;
+}
+
 static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev)
 {
-	struct device_node *node, *pp;
 	struct gpio_keys_platform_data *pdata;
 	struct gpio_keys_button *button;
 	int error;
 	int nbuttons;
-	int i;
-
-	node = dev->of_node;
-	if (!node)
-		return NULL;
 
-	nbuttons = of_get_child_count(node);
+	nbuttons = device_get_child_node_count(dev);
 	if (nbuttons == 0)
 		return NULL;
 
@@ -126,54 +160,14 @@ static struct gpio_keys_platform_data *g
 		return ERR_PTR(-ENOMEM);
 
 	pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
-	pdata->nbuttons = nbuttons;
 
-	pdata->rep = !!of_get_property(node, "autorepeat", NULL);
-	of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
+	pdata->rep = !device_get_property(dev, "autorepeat", NULL);
+	device_property_read_u32(dev, "poll-interval", &pdata->poll_interval);
 
-	i = 0;
-	for_each_child_of_node(node, pp) {
-		int gpio;
-		enum of_gpio_flags flags;
-
-		if (!of_find_property(pp, "gpios", NULL)) {
-			pdata->nbuttons--;
-			dev_warn(dev, "Found button without gpios\n");
-			continue;
-		}
-
-		gpio = of_get_gpio_flags(pp, 0, &flags);
-		if (gpio < 0) {
-			error = gpio;
-			if (error != -EPROBE_DEFER)
-				dev_err(dev,
-					"Failed to get gpio flags, error: %d\n",
-					error);
-			return ERR_PTR(error);
-		}
-
-		button = &pdata->buttons[i++];
-
-		button->gpio = gpio;
-		button->active_low = flags & OF_GPIO_ACTIVE_LOW;
-
-		if (of_property_read_u32(pp, "linux,code", &button->code)) {
-			dev_err(dev, "Button without keycode: 0x%x\n",
-				button->gpio);
-			return ERR_PTR(-EINVAL);
-		}
-
-		button->desc = of_get_property(pp, "label", NULL);
-
-		if (of_property_read_u32(pp, "linux,input-type", &button->type))
-			button->type = EV_KEY;
-
-		button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
-
-		if (of_property_read_u32(pp, "debounce-interval",
-					 &button->debounce_interval))
-			button->debounce_interval = 5;
-	}
+	error = device_for_each_child_node(dev, gpio_keys_polled_get_button,
+					   pdata);
+	if (error)
+		return ERR_PTR(error);
 
 	if (pdata->nbuttons == 0)
 		return ERR_PTR(-EINVAL);
@@ -187,15 +181,6 @@ static const struct of_device_id gpio_ke
 };
 MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
 
-#else
-
-static inline struct gpio_keys_platform_data *
-gpio_keys_polled_get_devtree_pdata(struct device *dev)
-{
-	return NULL;
-}
-#endif
-
 static int gpio_keys_polled_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -323,7 +308,7 @@ static struct platform_driver gpio_keys_
 	.driver	= {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
-		.of_match_table = of_match_ptr(gpio_keys_polled_of_match),
+		.of_match_table = gpio_keys_polled_of_match,
 	},
 };
 module_platform_driver(gpio_keys_polled_driver);

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 13/15] input: gpio_keys_polled - Add ACPI probing support
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (11 preceding siblings ...)
  2014-10-01  2:20   ` [PATCH v3 12/15] input: gpio_keys_polled - Make use of device property API Rafael J. Wysocki
@ 2014-10-01  2:20   ` Rafael J. Wysocki
  2014-10-01  7:48     ` Dmitry Torokhov
  2014-10-01  2:21   ` [PATCH v3 14/15] misc: at25: Make use of device property API Rafael J. Wysocki
  13 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

Allow the driver to probe from ACPI namespace.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/input/keyboard/gpio_keys_polled.c |    7 +++++++
 1 file changed, 7 insertions(+)

Index: linux-pm/drivers/input/keyboard/gpio_keys_polled.c
===================================================================
--- linux-pm.orig/drivers/input/keyboard/gpio_keys_polled.c
+++ linux-pm/drivers/input/keyboard/gpio_keys_polled.c
@@ -181,6 +181,12 @@ static const struct of_device_id gpio_ke
 };
 MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
 
+static const struct acpi_device_id gpio_keys_polled_acpi_match[] = {
+	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, gpio_keys_polled_acpi_match);
+
 static int gpio_keys_polled_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -309,6 +315,7 @@ static struct platform_driver gpio_keys_
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
 		.of_match_table = gpio_keys_polled_of_match,
+		.acpi_match_table = gpio_keys_polled_acpi_match,
 	},
 };
 module_platform_driver(gpio_keys_polled_driver);

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 14/15] misc: at25: Make use of device property API
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
                     ` (12 preceding siblings ...)
  2014-10-01  2:20   ` [PATCH v3 13/15] input: gpio_keys_polled - Add ACPI probing support Rafael J. Wysocki
@ 2014-10-01  2:21   ` Rafael J. Wysocki
       [not found]     ` <2074642.sV7QBxD3Ne-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
  13 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:21 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

Make use of device property API in this driver so that both DT and ACPI
based systems can use this driver.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/misc/eeprom/at25.c | 34 +++++++++++++---------------------
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 634f72929e12..58f6cdd2551c 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -18,7 +18,7 @@
 
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
-#include <linux/of.h>
+#include <linux/property.h>
 
 /*
  * NOTE: this is an *EEPROM* driver.  The vagaries of product naming
@@ -301,35 +301,33 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
 
 /*-------------------------------------------------------------------------*/
 
-static int at25_np_to_chip(struct device *dev,
-			   struct device_node *np,
-			   struct spi_eeprom *chip)
+static int at25_fw_to_chip(struct device *dev, struct spi_eeprom *chip)
 {
 	u32 val;
 
 	memset(chip, 0, sizeof(*chip));
-	strncpy(chip->name, np->name, sizeof(chip->name));
+	strncpy(chip->name, "at25", sizeof(chip->name));
 
-	if (of_property_read_u32(np, "size", &val) == 0 ||
-	    of_property_read_u32(np, "at25,byte-len", &val) == 0) {
+	if (device_property_read_u32(dev, "size", &val) == 0 ||
+	    device_property_read_u32(dev, "at25,byte-len", &val) == 0) {
 		chip->byte_len = val;
 	} else {
 		dev_err(dev, "Error: missing \"size\" property\n");
 		return -ENODEV;
 	}
 
-	if (of_property_read_u32(np, "pagesize", &val) == 0 ||
-	    of_property_read_u32(np, "at25,page-size", &val) == 0) {
+	if (device_property_read_u32(dev, "pagesize", &val) == 0 ||
+	    device_property_read_u32(dev, "at25,page-size", &val) == 0) {
 		chip->page_size = (u16)val;
 	} else {
 		dev_err(dev, "Error: missing \"pagesize\" property\n");
 		return -ENODEV;
 	}
 
-	if (of_property_read_u32(np, "at25,addr-mode", &val) == 0) {
+	if (device_property_read_u32(dev, "at25,addr-mode", &val) == 0) {
 		chip->flags = (u16)val;
 	} else {
-		if (of_property_read_u32(np, "address-width", &val)) {
+		if (device_property_read_u32(dev, "address-width", &val)) {
 			dev_err(dev,
 				"Error: missing \"address-width\" property\n");
 			return -ENODEV;
@@ -350,7 +348,7 @@ static int at25_np_to_chip(struct device *dev,
 				val);
 			return -ENODEV;
 		}
-		if (of_find_property(np, "read-only", NULL))
+		if (!device_get_property(dev, "read-only", NULL))
 			chip->flags |= EE_READONLY;
 	}
 	return 0;
@@ -360,21 +358,15 @@ static int at25_probe(struct spi_device *spi)
 {
 	struct at25_data	*at25 = NULL;
 	struct spi_eeprom	chip;
-	struct device_node	*np = spi->dev.of_node;
 	int			err;
 	int			sr;
 	int			addrlen;
 
 	/* Chip description */
 	if (!spi->dev.platform_data) {
-		if (np) {
-			err = at25_np_to_chip(&spi->dev, np, &chip);
-			if (err)
-				return err;
-		} else {
-			dev_err(&spi->dev, "Error: no chip description\n");
-			return -ENODEV;
-		}
+		err = at25_fw_to_chip(&spi->dev, &chip);
+		if (err)
+			return err;
 	} else
 		chip = *(struct spi_eeprom *)spi->dev.platform_data;
 
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [PATCH v3 15/15] misc: at25: Add ACPI probing support
  2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
@ 2014-10-01  2:22       ` Rafael J. Wysocki
  2014-10-01  2:10   ` [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware Rafael J. Wysocki
                         ` (12 subsequent siblings)
  13 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:22 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Mika Westerberg, linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

Add support for matching using DT compatible string from ACPI _DSD.

Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
drivers/misc/eeprom/at25.c | 7 +++++++
 drivers/misc/eeprom/at25.c |    7 +++++++
 1 file changed, 7 insertions(+)

Index: linux-pm/drivers/misc/eeprom/at25.c
===================================================================
--- linux-pm.orig/drivers/misc/eeprom/at25.c
+++ linux-pm/drivers/misc/eeprom/at25.c
@@ -459,11 +459,18 @@ static const struct of_device_id at25_of
 };
 MODULE_DEVICE_TABLE(of, at25_of_match);
 
+static const struct acpi_device_id at25_acpi_match[] = {
+	{ "PRP0001" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, at25_acpi_match);
+
 static struct spi_driver at25_driver = {
 	.driver = {
 		.name		= "at25",
 		.owner		= THIS_MODULE,
 		.of_match_table = at25_of_match,
+		.acpi_match_table = at25_acpi_match,
 	},
 	.probe		= at25_probe,
 	.remove		= at25_remove,

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [PATCH v3 15/15] misc: at25: Add ACPI probing support
@ 2014-10-01  2:22       ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01  2:22 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

From: Mika Westerberg <mika.westerberg@linux.intel.com>

Add support for matching using DT compatible string from ACPI _DSD.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/misc/eeprom/at25.c | 7 +++++++
 drivers/misc/eeprom/at25.c |    7 +++++++
 1 file changed, 7 insertions(+)

Index: linux-pm/drivers/misc/eeprom/at25.c
===================================================================
--- linux-pm.orig/drivers/misc/eeprom/at25.c
+++ linux-pm/drivers/misc/eeprom/at25.c
@@ -459,11 +459,18 @@ static const struct of_device_id at25_of
 };
 MODULE_DEVICE_TABLE(of, at25_of_match);
 
+static const struct acpi_device_id at25_acpi_match[] = {
+	{ "PRP0001" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, at25_acpi_match);
+
 static struct spi_driver at25_driver = {
 	.driver = {
 		.name		= "at25",
 		.owner		= THIS_MODULE,
 		.of_match_table = at25_of_match,
+		.acpi_match_table = at25_acpi_match,
 	},
 	.probe		= at25_probe,
 	.remove		= at25_remove,


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 01/15] ACPI: Add support for device specific properties
  2014-10-01  2:08   ` [PATCH v3 01/15] ACPI: Add support for device specific properties Rafael J. Wysocki
@ 2014-10-01  7:38     ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  7:38 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 04:08:56 Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> Device Tree is used in many embedded systems to describe the system
> configuration to the OS. It supports attaching properties or name-value
> pairs to the devices it describe. With these properties one can pass
> additional information to the drivers that would not be available
> otherwise.
> 
> ACPI is another configuration mechanism (among other things) typically
> seen, but not limited to, x86 machines. ACPI allows passing arbitrary
> data from methods but there has not been mechanism equivalent to Device
> Tree until the introduction of _DSD in the recent publication of the
> ACPI 5.1 specification.
> 
> In order to facilitate ACPI usage in systems where Device Tree is
> typically used, it would be beneficial to standardize a way to retrieve
> Device Tree style properties from ACPI devices, which is what we do in
> this patch.
> 
> If a given device described in ACPI namespace wants to export properties it
> must implement _DSD method (Device Specific Data, introduced with ACPI 5.1)
> that returns the properties in a package of packages. For example:
> 
>         Name (_DSD, Package () {
>                 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>                 Package () {
>                         Package () {"name1", <VALUE1>},
>                         Package () {"name2", <VALUE2>},
>                         ...
>                 }
>         })
> 
> The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301
> and is documented in the ACPI 5.1 companion document called "_DSD
> Implementation Guide" [1], [2].
> 
> We add several helper functions that can be used to extract these
> properties and convert them to different Linux data types.
> 
> The ultimate goal is that we only have one device property API that
> retrieves the requested properties from Device Tree or from ACPI
> transparent to the caller.
> 
> [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
> [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> 
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> Signed-off-by: Darren Hart <dvhart@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 

Looks good to me.

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware
  2014-10-01  2:10   ` [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware Rafael J. Wysocki
@ 2014-10-01  7:47     ` Arnd Bergmann
  2014-10-01 22:09       ` Rafael J. Wysocki
  2014-10-02  0:03     ` Greg Kroah-Hartman
  1 sibling, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  7:47 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Greg Kroah-Hartman, Mika Westerberg, linux-acpi,
	devicetree, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
	Bryan Wu, Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Wednesday 01 October 2014 04:10:03 Rafael J. Wysocki wrote:
> From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> 
> Add a uniform interface by which device drivers can request device
> properties from the platform firmware by providing a property name
> and the corresponding data type.  The purpose of it is to help to
> write portable code that won't depend on any particular platform
> firmware interface.
> 
> Three general helper functions, device_get_property(),
> device_read_property() and device_read_property_array() are provided.
> The first one allows the raw value of a given device property to be
> accessed.  The remaining two allow the value of a numeric or string
> property and multiple numeric or string values of one array
> property to be acquired, respectively.  Static inline wrappers are also
> provided for the various property data types that can be passed to
> device_read_property() or device_read_property_array() for extra type
> checking.

These look great!

> In addition to that, new generic routines are provided for retrieving
> properties from device description objects in the platform firmware
> in case a device driver needs/wants to access properties of a child
> object of a given device object.  There are cases in which there is
> no struct device representation of such child objects and this
> additional API is useful then.  Again, three functions are provided,
> device_get_child_property(), device_read_child_property(),
> device_read_child_property_array(), in analogy with device_get_property(),
> device_read_property() and device_read_property_array() described above,
> respectively, along with static inline wrappers for all of the propery
> data types that can be used.  For all of them, the first argument is
> a struct device pointer to the parent device object and the second
> argument is a (void *) pointer to the child description provided by
> the platform firmware (either ACPI or FDT).

I still have my reservations against the child accessors, and would
like to hear what other people think. Passing a void pointer rather
than struct fw_dev_node has both advantages and disadvantages, and
I won't complain about either one if enough other people on the DT
side would like to see the addition of the child functions.

> Finally, device_for_each_child_node() is added for iterating over
> the children of the device description object associated with a
> given device.
> 
> The interface covers both ACPI and Device Trees.
> 
> This change set includes material from Mika Westerberg and Aaron Lu.
> 

Regarding device_for_each_child_node(), the syntax is inconsistent
with what we normally use, which can probably be changed. All of the
DT for_each_* helpers are macros that are used like

	struct device *dev = ...;
	void *child; /* iterator */

	device_for_each_child_node(dev, child) {
		u32 something;
		device_child_property_read_u32(dev, child, "propname", &something);

		do_something(dev, something);
	}

If we get a consensus on having the child interfaces, I'd rather see
them done this way than with a callback pointer, for consistency
reasons.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property
  2014-10-01  2:10   ` [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property Rafael J. Wysocki
@ 2014-10-01  7:48     ` Arnd Bergmann
  2014-10-03 13:43     ` Mark Rutland
  1 sibling, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  7:48 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 04:10:40 Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> We have lots of existing Device Tree enabled drivers and allocating
> separate _HID for each is not feasible. Instead we allocate special _HID
> "PRP0001" that means that the match should be done using Device Tree
> compatible property using driver's .of_match_table instead.
> 
> If there is a need to distinguish from where the device is enumerated
> (DT/ACPI) driver can check dev->of_node or ACPI_COMPATION(dev).
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> 

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 13/15] input: gpio_keys_polled - Add ACPI probing support
  2014-10-01  2:20   ` [PATCH v3 13/15] input: gpio_keys_polled - Add ACPI probing support Rafael J. Wysocki
@ 2014-10-01  7:48     ` Dmitry Torokhov
  2014-10-01  9:15       ` Mika Westerberg
  0 siblings, 1 reply; 152+ messages in thread
From: Dmitry Torokhov @ 2014-10-01  7:48 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

On Wed, Oct 01, 2014 at 04:20:43AM +0200, Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> Allow the driver to probe from ACPI namespace.
> 
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/input/keyboard/gpio_keys_polled.c |    7 +++++++
>  1 file changed, 7 insertions(+)
> 
> Index: linux-pm/drivers/input/keyboard/gpio_keys_polled.c
> ===================================================================
> --- linux-pm.orig/drivers/input/keyboard/gpio_keys_polled.c
> +++ linux-pm/drivers/input/keyboard/gpio_keys_polled.c
> @@ -181,6 +181,12 @@ static const struct of_device_id gpio_ke
>  };
>  MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
>  
> +static const struct acpi_device_id gpio_keys_polled_acpi_match[] = {
> +	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(acpi, gpio_keys_polled_acpi_match);
> +
>  static int gpio_keys_polled_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -309,6 +315,7 @@ static struct platform_driver gpio_keys_
>  		.name	= DRV_NAME,
>  		.owner	= THIS_MODULE,
>  		.of_match_table = gpio_keys_polled_of_match,
> +		.acpi_match_table = gpio_keys_polled_acpi_match,
o
Hmm, why do we need the generic "PRP0001" in every driver? The ACPI device
should have PRP0001 and ACPI bus should know to look into OF matching table
for such devices.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-01  2:11   ` [PATCH v3 04/15] ACPI: Document ACPI device specific properties Rafael J. Wysocki
@ 2014-10-01  7:59     ` Arnd Bergmann
  2014-10-02 10:41       ` Mika Westerberg
  0 siblings, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  7:59 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 04:11:20 Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> This document describes the data format and interfaces of ACPI device
> specific properties.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Darren Hart <dvhart@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Overall looks sane, but I wonder if we should try harder to not duplicate
some of the mistakes we made in the DT bindings. Two points in particular
stick out:

> +2.3 Strings
> +-----------
> +String properties can be used to describe many things like labels for GPIO
> +buttons, compability ids, etc.
> +
> +A string property looks like this:
> +
> +	Package () {"pwm-names", "backlight"},

The way we name things in DT using separate "foos" and "foo-names" properties
is a bit quirky. Those are always defined on a per-subsystem level, not
a per-device level though, so it should be possible to come up with a
better representation in ACPI.

Since the device driver should never look into the "foo-names" property
itself but just pass down the name into the subsystem, the "foo" subsystem
could instead have a way to add an (optional) name for each reference.

This is something the DT syntax doesn't allow because you can't have
both a phandle and a string in a single property but I think the ACPI
packages can do it, and it wouldn't change the basic structure.

> +The referenced ACPI device is returned in args->adev if found.
> +
> +In addition to simple object references it is also possible to have object
> +references with arguments. These are represented in ASL as follows:
> +
> +	Device (\_SB.PCI0.PWM)
> +	{
> +		Name (_DSD, Package () {
> +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +			Package () {
> +				Package () {"#pwm-cells", 2}
> +			}
> +		})
> +	}
> +

Similarly, the "#foo-cells" syntax is an artifact of the limitations of the
DT syntax, and I'd assume there would be a better way to encode this
in ACPI. Also, a "cell" in Open Firmware is defined as a big-endian
32-bit value, which doesn't directly correspond to something in ACPI,
and the '#' character is an artifact of the use of the Forth language
in Open Firmware, which you also don't have here.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 05/15] gpio / ACPI: Add support for _DSD device properties
  2014-10-01  2:12   ` [PATCH v3 05/15] gpio / ACPI: Add support for _DSD device properties Rafael J. Wysocki
@ 2014-10-01  8:03         ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  8:03 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mika Westerberg,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Wednesday 01 October 2014 04:12:41 Rafael J. Wysocki wrote:
> +       static const char * const suffixes[] = { "gpios", "gpio" };
> +       struct acpi_device *adev = ACPI_COMPANION(dev);
>         struct acpi_gpio_info info;
>         struct gpio_desc *desc;
> +       char propname[32];
> +       int i;
>  
> -       desc = acpi_get_gpiod_by_index(dev, idx, &info);
> -       if (IS_ERR(desc))
> -               return desc;
> +       /* Try first from _DSD */
> +       for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
> +               if (con_id && strcmp(con_id, "gpios")) {
> +                       snprintf(propname, sizeof(propname), "%s-%s",
> +                                con_id, suffixes[i]);
> +               } else {
> +                       snprintf(propname, sizeof(propname), "%s",
> +                                suffixes[i]);
> +               }

The general interface seems fine, but I'd be happier if you didn't
try to support all four of the possible syntaxes we have in DT.
It would be much better to have only "gpios" and not "gpio", and
the "foo-gpios" syntax should be replaced with whatever method you
use to name other subsystem specific links. For most subsystems
we now use something like "gpio-names", but unfortunately the GPIO
binding goes back to the time before we had come to that agreement.
The same applies to regulators.

This is ultimately up to the gpio maintainers though.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 05/15] gpio / ACPI: Add support for _DSD device properties
@ 2014-10-01  8:03         ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  8:03 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 04:12:41 Rafael J. Wysocki wrote:
> +       static const char * const suffixes[] = { "gpios", "gpio" };
> +       struct acpi_device *adev = ACPI_COMPANION(dev);
>         struct acpi_gpio_info info;
>         struct gpio_desc *desc;
> +       char propname[32];
> +       int i;
>  
> -       desc = acpi_get_gpiod_by_index(dev, idx, &info);
> -       if (IS_ERR(desc))
> -               return desc;
> +       /* Try first from _DSD */
> +       for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
> +               if (con_id && strcmp(con_id, "gpios")) {
> +                       snprintf(propname, sizeof(propname), "%s-%s",
> +                                con_id, suffixes[i]);
> +               } else {
> +                       snprintf(propname, sizeof(propname), "%s",
> +                                suffixes[i]);
> +               }

The general interface seems fine, but I'd be happier if you didn't
try to support all four of the possible syntaxes we have in DT.
It would be much better to have only "gpios" and not "gpio", and
the "foo-gpios" syntax should be replaced with whatever method you
use to name other subsystem specific links. For most subsystems
we now use something like "gpio-names", but unfortunately the GPIO
binding goes back to the time before we had come to that agreement.
The same applies to regulators.

This is ultimately up to the gpio maintainers though.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 08/15] leds: leds-gpio: Add support for GPIO descriptors
  2014-10-01  2:15   ` [PATCH v3 08/15] leds: leds-gpio: Add support for GPIO descriptors Rafael J. Wysocki
@ 2014-10-01  8:05         ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  8:05 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mika Westerberg,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Wednesday 01 October 2014 04:15:41 Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> 
> GPIO descriptors are the preferred way over legacy GPIO numbers
> nowadays. Convert the driver to use GPIO descriptors internally but
> still allow passing legacy GPIO numbers from platform data to support
> existing platforms.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> Acked-by: Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Acked-by: Bryan Wu <cooloney-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> 

Nice!

Acked-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 08/15] leds: leds-gpio: Add support for GPIO descriptors
@ 2014-10-01  8:05         ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  8:05 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 04:15:41 Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> GPIO descriptors are the preferred way over legacy GPIO numbers
> nowadays. Convert the driver to use GPIO descriptors internally but
> still allow passing legacy GPIO numbers from platform data to support
> existing platforms.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Acked-by: Alexandre Courbot <acourbot@nvidia.com>
> Acked-by: Bryan Wu <cooloney@gmail.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 

Nice!

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01  2:17   ` [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support Rafael J. Wysocki
@ 2014-10-01  8:13     ` Arnd Bergmann
  2014-10-01  9:13       ` Mika Westerberg
  2014-10-01 16:30       ` Dmitry Torokhov
  0 siblings, 2 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  8:13 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 04:17:02 Rafael J. Wysocki wrote:
> Index: linux-pm/drivers/leds/leds-gpio.c
> ===================================================================
> --- linux-pm.orig/drivers/leds/leds-gpio.c
> +++ linux-pm/drivers/leds/leds-gpio.c
> @@ -231,6 +231,13 @@ static const struct of_device_id of_gpio
>  
>  MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
>  
> +static const struct acpi_device_id acpi_gpio_leds_match[] = {
> +       { "PRP0001" }, /* Device Tree shoehorned into ACPI */
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
> +
>  static int gpio_led_probe(struct platform_device *pdev)
>  {
>         struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
> @@ -286,6 +293,7 @@ static struct platform_driver gpio_led_d
>                 .name   = "leds-gpio",
>                 .owner  = THIS_MODULE,
>                 .of_match_table = of_gpio_leds_match,
> +               .acpi_match_table = acpi_gpio_leds_match,
>         },
>  };

Is this something you'd have to do in every driver you want to support
_PRP based probing? For the ".acpi_match_table =" reference, I think
you could actually provide a generic acpi_device_id table exported from
core code that you refer to, so each driver just does

	.acpi_match_table = acpi_match_by_of_compatible,

(or whatever you want to call it).

Regarding the MODULE_DEVICE_TABLE, I suspect the above won't work the
way you are hoping for, because once you get to dozens or hundreds of
drivers doing this, each device will show up with the same string,
so udev will try to load all the modules that list "PRP0001". That
doesn't look right. With the code from patch 3, you can probably drop
the acpi MODULE_DEVICE_TABLE() entirely and get the correct behavior.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 11/15] input: gpio_keys_polled - Add support for GPIO descriptors
  2014-10-01  2:17   ` [PATCH v3 11/15] input: gpio_keys_polled - Add support for GPIO descriptors Rafael J. Wysocki
@ 2014-10-01  8:13     ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  8:13 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 04:17:46 Rafael J. Wysocki wrote:
> From: Aaron Lu <aaron.lu@intel.com>
> 
> GPIO descriptors are the preferred way over legacy GPIO numbers
> nowadays. Convert the driver to use GPIO descriptors internally but
> still allow passing legacy GPIO numbers from platform data to support
> existing platforms.
> 
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Acked-by: Alexandre Courbot <acourbot@nvidia.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 14/15] misc: at25: Make use of device property API
  2014-10-01  2:21   ` [PATCH v3 14/15] misc: at25: Make use of device property API Rafael J. Wysocki
@ 2014-10-01  8:14         ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  8:14 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mika Westerberg,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Wednesday 01 October 2014 04:21:18 Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> 
> Make use of device property API in this driver so that both DT and ACPI
> based systems can use this driver.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> 

Looks good,

Acked-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 14/15] misc: at25: Make use of device property API
@ 2014-10-01  8:14         ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  8:14 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 04:21:18 Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> Make use of device property API in this driver so that both DT and ACPI
> based systems can use this driver.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 

Looks good,

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 15/15] misc: at25: Add ACPI probing support
  2014-10-01  2:22       ` Rafael J. Wysocki
  (?)
@ 2014-10-01  8:15       ` Arnd Bergmann
  -1 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01  8:15 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 04:22:27 Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> Add support for matching using DT compatible string from ACPI _DSD.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 

Same comment applies as in patch 13.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01  8:13     ` Arnd Bergmann
@ 2014-10-01  9:13       ` Mika Westerberg
  2014-10-01 10:01         ` Arnd Bergmann
  2014-10-01 16:30       ` Dmitry Torokhov
  1 sibling, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-10-01  9:13 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wed, Oct 01, 2014 at 10:13:04AM +0200, Arnd Bergmann wrote:
> On Wednesday 01 October 2014 04:17:02 Rafael J. Wysocki wrote:
> > Index: linux-pm/drivers/leds/leds-gpio.c
> > ===================================================================
> > --- linux-pm.orig/drivers/leds/leds-gpio.c
> > +++ linux-pm/drivers/leds/leds-gpio.c
> > @@ -231,6 +231,13 @@ static const struct of_device_id of_gpio
> >  
> >  MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
> >  
> > +static const struct acpi_device_id acpi_gpio_leds_match[] = {
> > +       { "PRP0001" }, /* Device Tree shoehorned into ACPI */
> > +       {},
> > +};
> > +
> > +MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
> > +
> >  static int gpio_led_probe(struct platform_device *pdev)
> >  {
> >         struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
> > @@ -286,6 +293,7 @@ static struct platform_driver gpio_led_d
> >                 .name   = "leds-gpio",
> >                 .owner  = THIS_MODULE,
> >                 .of_match_table = of_gpio_leds_match,
> > +               .acpi_match_table = acpi_gpio_leds_match,
> >         },
> >  };
> 
> Is this something you'd have to do in every driver you want to support
> _PRP based probing? For the ".acpi_match_table =" reference, I think
> you could actually provide a generic acpi_device_id table exported from
> core code that you refer to, so each driver just does
> 
> 	.acpi_match_table = acpi_match_by_of_compatible,
> 
> (or whatever you want to call it).

That's a good idea.

> Regarding the MODULE_DEVICE_TABLE, I suspect the above won't work the
> way you are hoping for, because once you get to dozens or hundreds of
> drivers doing this, each device will show up with the same string,
> so udev will try to load all the modules that list "PRP0001". That
> doesn't look right. With the code from patch 3, you can probably drop
> the acpi MODULE_DEVICE_TABLE() entirely and get the correct behavior.

It actually works like this now:

 # cd /sys/bus/platform/devices/PRP0001\:00/
 DRIVER=leds-gpio
 MODALIAS=of:Nprp0001TacpiCgpio-leds

 # cat modalias 
 of:Nprp0001TacpiCgpio-leds

In other words the modalias changes to be of:Nprp0001Tacpi, e.g
name=prp0001, type=acpi and then list of compatible values.

Udev then loads only module that matches the modalias so it should not
load everything listing PRP0001 in their MODULE_DEVICE_TABLE().

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 13/15] input: gpio_keys_polled - Add ACPI probing support
  2014-10-01  7:48     ` Dmitry Torokhov
@ 2014-10-01  9:15       ` Mika Westerberg
  2014-10-01 16:28         ` Dmitry Torokhov
  0 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-10-01  9:15 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

On Wed, Oct 01, 2014 at 12:48:46AM -0700, Dmitry Torokhov wrote:
> On Wed, Oct 01, 2014 at 04:20:43AM +0200, Rafael J. Wysocki wrote:
> > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > 
> > Allow the driver to probe from ACPI namespace.
> > 
> > Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/input/keyboard/gpio_keys_polled.c |    7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > Index: linux-pm/drivers/input/keyboard/gpio_keys_polled.c
> > ===================================================================
> > --- linux-pm.orig/drivers/input/keyboard/gpio_keys_polled.c
> > +++ linux-pm/drivers/input/keyboard/gpio_keys_polled.c
> > @@ -181,6 +181,12 @@ static const struct of_device_id gpio_ke
> >  };
> >  MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
> >  
> > +static const struct acpi_device_id gpio_keys_polled_acpi_match[] = {
> > +	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(acpi, gpio_keys_polled_acpi_match);
> > +
> >  static int gpio_keys_polled_probe(struct platform_device *pdev)
> >  {
> >  	struct device *dev = &pdev->dev;
> > @@ -309,6 +315,7 @@ static struct platform_driver gpio_keys_
> >  		.name	= DRV_NAME,
> >  		.owner	= THIS_MODULE,
> >  		.of_match_table = gpio_keys_polled_of_match,
> > +		.acpi_match_table = gpio_keys_polled_acpi_match,
> o
> Hmm, why do we need the generic "PRP0001" in every driver? The ACPI device
> should have PRP0001 and ACPI bus should know to look into OF matching table
> for such devices.

Arnd had a good idea for this. How about,

	.acpi_match_table = acpi_match_by_of_compatible,

where acpi_match_by_of_compatible is provided by ACPI core? Does that
work better for you?

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01  9:13       ` Mika Westerberg
@ 2014-10-01 10:01         ` Arnd Bergmann
  2014-10-01 11:59           ` Mika Westerberg
  0 siblings, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01 10:01 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 12:13:09 Mika Westerberg wrote:
> 
> > Regarding the MODULE_DEVICE_TABLE, I suspect the above won't work the
> > way you are hoping for, because once you get to dozens or hundreds of
> > drivers doing this, each device will show up with the same string,
> > so udev will try to load all the modules that list "PRP0001". That
> > doesn't look right. With the code from patch 3, you can probably drop
> > the acpi MODULE_DEVICE_TABLE() entirely and get the correct behavior.
> 
> It actually works like this now:
> 
>  # cd /sys/bus/platform/devices/PRP0001\:00/
>  DRIVER=leds-gpio
>  MODALIAS=of:Nprp0001TacpiCgpio-leds
> 
>  # cat modalias 
>  of:Nprp0001TacpiCgpio-leds
> 
> In other words the modalias changes to be of:Nprp0001Tacpi, e.g
> name=prp0001, type=acpi and then list of compatible values.
> 
> Udev then loads only module that matches the modalias so it should not
> load everything listing PRP0001 in their MODULE_DEVICE_TABLE().

I'm not completely following yet. I can see how this works now, but
how is this better than just using the existing modalias for OF?

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01 10:01         ` Arnd Bergmann
@ 2014-10-01 11:59           ` Mika Westerberg
  2014-10-01 13:52             ` Arnd Bergmann
  0 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-10-01 11:59 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wed, Oct 01, 2014 at 12:01:34PM +0200, Arnd Bergmann wrote:
> On Wednesday 01 October 2014 12:13:09 Mika Westerberg wrote:
> > 
> > > Regarding the MODULE_DEVICE_TABLE, I suspect the above won't work the
> > > way you are hoping for, because once you get to dozens or hundreds of
> > > drivers doing this, each device will show up with the same string,
> > > so udev will try to load all the modules that list "PRP0001". That
> > > doesn't look right. With the code from patch 3, you can probably drop
> > > the acpi MODULE_DEVICE_TABLE() entirely and get the correct behavior.
> > 
> > It actually works like this now:
> > 
> >  # cd /sys/bus/platform/devices/PRP0001\:00/
> >  DRIVER=leds-gpio
> >  MODALIAS=of:Nprp0001TacpiCgpio-leds
> > 
> >  # cat modalias 
> >  of:Nprp0001TacpiCgpio-leds
> > 
> > In other words the modalias changes to be of:Nprp0001Tacpi, e.g
> > name=prp0001, type=acpi and then list of compatible values.
> > 
> > Udev then loads only module that matches the modalias so it should not
> > load everything listing PRP0001 in their MODULE_DEVICE_TABLE().
> 
> I'm not completely following yet. I can see how this works now, but
> how is this better than just using the existing modalias for OF?

You mean using just what of_device_get_modalias() would create? In that
case, what do we put to name and type fields?

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01 11:59           ` Mika Westerberg
@ 2014-10-01 13:52             ` Arnd Bergmann
  2014-10-01 14:04               ` Mika Westerberg
  0 siblings, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01 13:52 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 14:59:01 Mika Westerberg wrote:
> On Wed, Oct 01, 2014 at 12:01:34PM +0200, Arnd Bergmann wrote:
> > On Wednesday 01 October 2014 12:13:09 Mika Westerberg wrote:
> > > 
> > > > Regarding the MODULE_DEVICE_TABLE, I suspect the above won't work the
> > > > way you are hoping for, because once you get to dozens or hundreds of
> > > > drivers doing this, each device will show up with the same string,
> > > > so udev will try to load all the modules that list "PRP0001". That
> > > > doesn't look right. With the code from patch 3, you can probably drop
> > > > the acpi MODULE_DEVICE_TABLE() entirely and get the correct behavior.
> > > 
> > > It actually works like this now:
> > > 
> > >  # cd /sys/bus/platform/devices/PRP0001\:00/
> > >  DRIVER=leds-gpio
> > >  MODALIAS=of:Nprp0001TacpiCgpio-leds
> > > 
> > >  # cat modalias 
> > >  of:Nprp0001TacpiCgpio-leds
> > > 
> > > In other words the modalias changes to be of:Nprp0001Tacpi, e.g
> > > name=prp0001, type=acpi and then list of compatible values.
> > > 
> > > Udev then loads only module that matches the modalias so it should not
> > > load everything listing PRP0001 in their MODULE_DEVICE_TABLE().
> > 
> > I'm not completely following yet. I can see how this works now, but
> > how is this better than just using the existing modalias for OF?
> 
> You mean using just what of_device_get_modalias() would create? In that
> case, what do we put to name and type fields?

Sorry, I think we're still both misunderstanding one another. You were
talking about the modalias created by the device scanning above, while
I meant the one in the MODULE_DEVICE_TABLE. 

With the entry you create in create_modalias(), you will only ever
match against the MODULE_DEVICE_TABLE(of, of_gpio_leds_match)
line, not against the MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match),
so I think you can just drop the latter.

On the question what to put into the name and type fields, that is
unrelated. The type is supposed to be for the 'device_type' property
in DT, which we should never rely on in a driver that supports both
APCI and DT. In Linux we only use that for "pci", "cpu" and "memory",
all of which have their own way of getting probed in ACPI.
The "name" is normally ignored in DT as well, except for backwards
compatibility with old bindings, but I would argue that you should not
just put "prp0001" in there. Either leave it empty like type, or use
the name of the device as it appears in the ACPI tables, such as "DEV0"
or "PWM".

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01 13:52             ` Arnd Bergmann
@ 2014-10-01 14:04               ` Mika Westerberg
       [not found]                 ` <20141001140441.GF1786-3PARRvDOhMZrdx17CPfAsdBPR1lH4CV8@public.gmane.org>
  0 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-10-01 14:04 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wed, Oct 01, 2014 at 03:52:42PM +0200, Arnd Bergmann wrote:
> On Wednesday 01 October 2014 14:59:01 Mika Westerberg wrote:
> > On Wed, Oct 01, 2014 at 12:01:34PM +0200, Arnd Bergmann wrote:
> > > On Wednesday 01 October 2014 12:13:09 Mika Westerberg wrote:
> > > > 
> > > > > Regarding the MODULE_DEVICE_TABLE, I suspect the above won't work the
> > > > > way you are hoping for, because once you get to dozens or hundreds of
> > > > > drivers doing this, each device will show up with the same string,
> > > > > so udev will try to load all the modules that list "PRP0001". That
> > > > > doesn't look right. With the code from patch 3, you can probably drop
> > > > > the acpi MODULE_DEVICE_TABLE() entirely and get the correct behavior.
> > > > 
> > > > It actually works like this now:
> > > > 
> > > >  # cd /sys/bus/platform/devices/PRP0001\:00/
> > > >  DRIVER=leds-gpio
> > > >  MODALIAS=of:Nprp0001TacpiCgpio-leds
> > > > 
> > > >  # cat modalias 
> > > >  of:Nprp0001TacpiCgpio-leds
> > > > 
> > > > In other words the modalias changes to be of:Nprp0001Tacpi, e.g
> > > > name=prp0001, type=acpi and then list of compatible values.
> > > > 
> > > > Udev then loads only module that matches the modalias so it should not
> > > > load everything listing PRP0001 in their MODULE_DEVICE_TABLE().
> > > 
> > > I'm not completely following yet. I can see how this works now, but
> > > how is this better than just using the existing modalias for OF?
> > 
> > You mean using just what of_device_get_modalias() would create? In that
> > case, what do we put to name and type fields?
> 
> Sorry, I think we're still both misunderstanding one another. You were
> talking about the modalias created by the device scanning above, while
> I meant the one in the MODULE_DEVICE_TABLE. 

Right, got it now.

> With the entry you create in create_modalias(), you will only ever
> match against the MODULE_DEVICE_TABLE(of, of_gpio_leds_match)
> line, not against the MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match),
> so I think you can just drop the latter.

Indeed.

> On the question what to put into the name and type fields, that is
> unrelated. The type is supposed to be for the 'device_type' property
> in DT, which we should never rely on in a driver that supports both
> APCI and DT. In Linux we only use that for "pci", "cpu" and "memory",
> all of which have their own way of getting probed in ACPI.
> The "name" is normally ignored in DT as well, except for backwards
> compatibility with old bindings, but I would argue that you should not
> just put "prp0001" in there. Either leave it empty like type, or use
> the name of the device as it appears in the ACPI tables, such as "DEV0"
> or "PWM".

OK, I think it makes sense to leave them empty. I remember I tried that
at some point but it didn't work without N and T fields. Is there some
example what to put there in case of empty?

Something like "of:N*T*Cgpio-leds" perhaps?

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01 14:04               ` Mika Westerberg
@ 2014-10-01 14:14                     ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01 14:14 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Wednesday 01 October 2014 17:04:41 Mika Westerberg wrote:
> 
> > On the question what to put into the name and type fields, that is
> > unrelated. The type is supposed to be for the 'device_type' property
> > in DT, which we should never rely on in a driver that supports both
> > APCI and DT. In Linux we only use that for "pci", "cpu" and "memory",
> > all of which have their own way of getting probed in ACPI.
> > The "name" is normally ignored in DT as well, except for backwards
> > compatibility with old bindings, but I would argue that you should not
> > just put "prp0001" in there. Either leave it empty like type, or use
> > the name of the device as it appears in the ACPI tables, such as "DEV0"
> > or "PWM".
> 
> OK, I think it makes sense to leave them empty. I remember I tried that
> at some point but it didn't work without N and T fields. Is there some
> example what to put there in case of empty?
> 
> Something like "of:N*T*Cgpio-leds" perhaps?

Sorry, don't know. If I read the code right, the type field in DT ends
up being "<NULL>" for any device that doesn't set the device_type 
property, but that seems a bit silly and probably isn't worth copying.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
@ 2014-10-01 14:14                     ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01 14:14 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wednesday 01 October 2014 17:04:41 Mika Westerberg wrote:
> 
> > On the question what to put into the name and type fields, that is
> > unrelated. The type is supposed to be for the 'device_type' property
> > in DT, which we should never rely on in a driver that supports both
> > APCI and DT. In Linux we only use that for "pci", "cpu" and "memory",
> > all of which have their own way of getting probed in ACPI.
> > The "name" is normally ignored in DT as well, except for backwards
> > compatibility with old bindings, but I would argue that you should not
> > just put "prp0001" in there. Either leave it empty like type, or use
> > the name of the device as it appears in the ACPI tables, such as "DEV0"
> > or "PWM".
> 
> OK, I think it makes sense to leave them empty. I remember I tried that
> at some point but it didn't work without N and T fields. Is there some
> example what to put there in case of empty?
> 
> Something like "of:N*T*Cgpio-leds" perhaps?

Sorry, don't know. If I read the code right, the type field in DT ends
up being "<NULL>" for any device that doesn't set the device_type 
property, but that seems a bit silly and probably isn't worth copying.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 13/15] input: gpio_keys_polled - Add ACPI probing support
  2014-10-01  9:15       ` Mika Westerberg
@ 2014-10-01 16:28         ` Dmitry Torokhov
  2014-10-02  9:53           ` Mika Westerberg
  0 siblings, 1 reply; 152+ messages in thread
From: Dmitry Torokhov @ 2014-10-01 16:28 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

On Wed, Oct 01, 2014 at 12:15:35PM +0300, Mika Westerberg wrote:
> On Wed, Oct 01, 2014 at 12:48:46AM -0700, Dmitry Torokhov wrote:
> > On Wed, Oct 01, 2014 at 04:20:43AM +0200, Rafael J. Wysocki wrote:
> > > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > 
> > > Allow the driver to probe from ACPI namespace.
> > > 
> > > Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > ---
> > >  drivers/input/keyboard/gpio_keys_polled.c |    7 +++++++
> > >  1 file changed, 7 insertions(+)
> > > 
> > > Index: linux-pm/drivers/input/keyboard/gpio_keys_polled.c
> > > ===================================================================
> > > --- linux-pm.orig/drivers/input/keyboard/gpio_keys_polled.c
> > > +++ linux-pm/drivers/input/keyboard/gpio_keys_polled.c
> > > @@ -181,6 +181,12 @@ static const struct of_device_id gpio_ke
> > >  };
> > >  MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
> > >  
> > > +static const struct acpi_device_id gpio_keys_polled_acpi_match[] = {
> > > +	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
> > > +	{ },
> > > +};
> > > +MODULE_DEVICE_TABLE(acpi, gpio_keys_polled_acpi_match);
> > > +
> > >  static int gpio_keys_polled_probe(struct platform_device *pdev)
> > >  {
> > >  	struct device *dev = &pdev->dev;
> > > @@ -309,6 +315,7 @@ static struct platform_driver gpio_keys_
> > >  		.name	= DRV_NAME,
> > >  		.owner	= THIS_MODULE,
> > >  		.of_match_table = gpio_keys_polled_of_match,
> > > +		.acpi_match_table = gpio_keys_polled_acpi_match,
> > o
> > Hmm, why do we need the generic "PRP0001" in every driver? The ACPI device
> > should have PRP0001 and ACPI bus should know to look into OF matching table
> > for such devices.
> 
> Arnd had a good idea for this. How about,
> 
> 	.acpi_match_table = acpi_match_by_of_compatible,
> 
> where acpi_match_by_of_compatible is provided by ACPI core? Does that
> work better for you?

I still do not see the point. ACPI core knows how to handle
drv->of_match_table, so unless we need to support ACPI_only binding in a
given driver I do not understand why we need to add boilerplate code.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01  8:13     ` Arnd Bergmann
  2014-10-01  9:13       ` Mika Westerberg
@ 2014-10-01 16:30       ` Dmitry Torokhov
  2014-10-01 18:11           ` Darren Hart
  1 sibling, 1 reply; 152+ messages in thread
From: Dmitry Torokhov @ 2014-10-01 16:30 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, Mika Westerberg, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Bryan Wu, Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Wed, Oct 01, 2014 at 10:13:04AM +0200, Arnd Bergmann wrote:
> On Wednesday 01 October 2014 04:17:02 Rafael J. Wysocki wrote:
> > Index: linux-pm/drivers/leds/leds-gpio.c
> > ===================================================================
> > --- linux-pm.orig/drivers/leds/leds-gpio.c
> > +++ linux-pm/drivers/leds/leds-gpio.c
> > @@ -231,6 +231,13 @@ static const struct of_device_id of_gpio
> >  
> >  MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
> >  
> > +static const struct acpi_device_id acpi_gpio_leds_match[] = {
> > +       { "PRP0001" }, /* Device Tree shoehorned into ACPI */
> > +       {},
> > +};
> > +
> > +MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
> > +
> >  static int gpio_led_probe(struct platform_device *pdev)
> >  {
> >         struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
> > @@ -286,6 +293,7 @@ static struct platform_driver gpio_led_d
> >                 .name   = "leds-gpio",
> >                 .owner  = THIS_MODULE,
> >                 .of_match_table = of_gpio_leds_match,
> > +               .acpi_match_table = acpi_gpio_leds_match,
> >         },
> >  };
> 
> Is this something you'd have to do in every driver you want to support
> _PRP based probing? For the ".acpi_match_table =" reference, I think
> you could actually provide a generic acpi_device_id table exported from
> core code that you refer to, so each driver just does
> 
> 	.acpi_match_table = acpi_match_by_of_compatible,

No, I think in absence of drv->acpi_match_table ACPI core should just go and
use drv->of_match_table to do the matching and be done with it.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01 16:30       ` Dmitry Torokhov
@ 2014-10-01 18:11           ` Darren Hart
  0 siblings, 0 replies; 152+ messages in thread
From: Darren Hart @ 2014-10-01 18:11 UTC (permalink / raw)
  To: Dmitry Torokhov, Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, Mika Westerberg, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Bryan Wu, Lee Jones, Grant Likely, Aaron Lu

On 10/1/14, 9:30, "Dmitry Torokhov" <dmitry.torokhov@gmail.com> wrote:

>On Wed, Oct 01, 2014 at 10:13:04AM +0200, Arnd Bergmann wrote:
>> On Wednesday 01 October 2014 04:17:02 Rafael J. Wysocki wrote:
>> > Index: linux-pm/drivers/leds/leds-gpio.c
>> > ===================================================================
>> > --- linux-pm.orig/drivers/leds/leds-gpio.c
>> > +++ linux-pm/drivers/leds/leds-gpio.c
>> > @@ -231,6 +231,13 @@ static const struct of_device_id of_gpio
>> >  
>> >  MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
>> >  
>> > +static const struct acpi_device_id acpi_gpio_leds_match[] = {
>> > +       { "PRP0001" }, /* Device Tree shoehorned into ACPI */
>> > +       {},
>> > +};
>> > +
>> > +MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
>> > +
>> >  static int gpio_led_probe(struct platform_device *pdev)
>> >  {
>> >         struct gpio_led_platform_data *pdata =
>>dev_get_platdata(&pdev->dev);
>> > @@ -286,6 +293,7 @@ static struct platform_driver gpio_led_d
>> >                 .name   = "leds-gpio",
>> >                 .owner  = THIS_MODULE,
>> >                 .of_match_table = of_gpio_leds_match,
>> > +               .acpi_match_table = acpi_gpio_leds_match,
>> >         },
>> >  };
>> 
>> Is this something you'd have to do in every driver you want to support
>> _PRP based probing? For the ".acpi_match_table =" reference, I think
>> you could actually provide a generic acpi_device_id table exported from
>> core code that you refer to, so each driver just does
>> 
>> 	.acpi_match_table = acpi_match_by_of_compatible,
>
>No, I think in absence of drv->acpi_match_table ACPI core should just go
>and
>use drv->of_match_table to do the matching and be done with it.

But then you will match drivers that have of-only support that don't know
anything about ACPI and haven't been updated to use the new API. Worse,
some of those drivers will assume of node structs and such and potentially
panic. Unless I'm sorry mistaken here....

-- 
Darren Hart
Intel Open Source Technology Center




^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
@ 2014-10-01 18:11           ` Darren Hart
  0 siblings, 0 replies; 152+ messages in thread
From: Darren Hart @ 2014-10-01 18:11 UTC (permalink / raw)
  To: Dmitry Torokhov, Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, Mika Westerberg, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Bryan Wu, Lee Jones, Grant Likely, Aaron Lu

On 10/1/14, 9:30, "Dmitry Torokhov" <dmitry.torokhov@gmail.com> wrote:

>On Wed, Oct 01, 2014 at 10:13:04AM +0200, Arnd Bergmann wrote:
>> On Wednesday 01 October 2014 04:17:02 Rafael J. Wysocki wrote:
>> > Index: linux-pm/drivers/leds/leds-gpio.c
>> > ===================================================================
>> > --- linux-pm.orig/drivers/leds/leds-gpio.c
>> > +++ linux-pm/drivers/leds/leds-gpio.c
>> > @@ -231,6 +231,13 @@ static const struct of_device_id of_gpio
>> >  
>> >  MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
>> >  
>> > +static const struct acpi_device_id acpi_gpio_leds_match[] = {
>> > +       { "PRP0001" }, /* Device Tree shoehorned into ACPI */
>> > +       {},
>> > +};
>> > +
>> > +MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
>> > +
>> >  static int gpio_led_probe(struct platform_device *pdev)
>> >  {
>> >         struct gpio_led_platform_data *pdata =
>>dev_get_platdata(&pdev->dev);
>> > @@ -286,6 +293,7 @@ static struct platform_driver gpio_led_d
>> >                 .name   = "leds-gpio",
>> >                 .owner  = THIS_MODULE,
>> >                 .of_match_table = of_gpio_leds_match,
>> > +               .acpi_match_table = acpi_gpio_leds_match,
>> >         },
>> >  };
>> 
>> Is this something you'd have to do in every driver you want to support
>> _PRP based probing? For the ".acpi_match_table =" reference, I think
>> you could actually provide a generic acpi_device_id table exported from
>> core code that you refer to, so each driver just does
>> 
>> 	.acpi_match_table = acpi_match_by_of_compatible,
>
>No, I think in absence of drv->acpi_match_table ACPI core should just go
>and
>use drv->of_match_table to do the matching and be done with it.

But then you will match drivers that have of-only support that don't know
anything about ACPI and haven't been updated to use the new API. Worse,
some of those drivers will assume of node structs and such and potentially
panic. Unless I'm sorry mistaken here....

-- 
Darren Hart
Intel Open Source Technology Center




^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01 18:11           ` Darren Hart
  (?)
@ 2014-10-01 18:21           ` Dmitry Torokhov
  -1 siblings, 0 replies; 152+ messages in thread
From: Dmitry Torokhov @ 2014-10-01 18:21 UTC (permalink / raw)
  To: Darren Hart
  Cc: Arnd Bergmann, Rafael J. Wysocki, linux-kernel, Mika Westerberg,
	linux-acpi, devicetree, Greg Kroah-Hartman, Linus Walleij,
	Alexandre Courbot, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu

On Wed, Oct 01, 2014 at 11:11:46AM -0700, Darren Hart wrote:
> On 10/1/14, 9:30, "Dmitry Torokhov" <dmitry.torokhov@gmail.com> wrote:
> 
> >On Wed, Oct 01, 2014 at 10:13:04AM +0200, Arnd Bergmann wrote:
> >> On Wednesday 01 October 2014 04:17:02 Rafael J. Wysocki wrote:
> >> > Index: linux-pm/drivers/leds/leds-gpio.c
> >> > ===================================================================
> >> > --- linux-pm.orig/drivers/leds/leds-gpio.c
> >> > +++ linux-pm/drivers/leds/leds-gpio.c
> >> > @@ -231,6 +231,13 @@ static const struct of_device_id of_gpio
> >> >  
> >> >  MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
> >> >  
> >> > +static const struct acpi_device_id acpi_gpio_leds_match[] = {
> >> > +       { "PRP0001" }, /* Device Tree shoehorned into ACPI */
> >> > +       {},
> >> > +};
> >> > +
> >> > +MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
> >> > +
> >> >  static int gpio_led_probe(struct platform_device *pdev)
> >> >  {
> >> >         struct gpio_led_platform_data *pdata =
> >>dev_get_platdata(&pdev->dev);
> >> > @@ -286,6 +293,7 @@ static struct platform_driver gpio_led_d
> >> >                 .name   = "leds-gpio",
> >> >                 .owner  = THIS_MODULE,
> >> >                 .of_match_table = of_gpio_leds_match,
> >> > +               .acpi_match_table = acpi_gpio_leds_match,
> >> >         },
> >> >  };
> >> 
> >> Is this something you'd have to do in every driver you want to support
> >> _PRP based probing? For the ".acpi_match_table =" reference, I think
> >> you could actually provide a generic acpi_device_id table exported from
> >> core code that you refer to, so each driver just does
> >> 
> >> 	.acpi_match_table = acpi_match_by_of_compatible,
> >
> >No, I think in absence of drv->acpi_match_table ACPI core should just go
> >and
> >use drv->of_match_table to do the matching and be done with it.
> 
> But then you will match drivers that have of-only support that don't know
> anything about ACPI and haven't been updated to use the new API. Worse,
> some of those drivers will assume of node structs and such and potentially
> panic. Unless I'm sorry mistaken here....

Does ACPI set dev->of_node pointer? I'd expect them to fail right there...

-- 
Dmitry

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01 18:11           ` Darren Hart
  (?)
  (?)
@ 2014-10-01 18:22           ` Arnd Bergmann
  -1 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-01 18:22 UTC (permalink / raw)
  To: Darren Hart
  Cc: Dmitry Torokhov, Rafael J. Wysocki, linux-kernel,
	Mika Westerberg, linux-acpi, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Bryan Wu, Lee Jones,
	Grant Likely, Aaron Lu

On Wednesday 01 October 2014 11:11:46 Darren Hart wrote:
> >
> >No, I think in absence of drv->acpi_match_table ACPI core should just go
> >and
> >use drv->of_match_table to do the matching and be done with it.
> 
> But then you will match drivers that have of-only support that don't know
> anything about ACPI and haven't been updated to use the new API. Worse,
> some of those drivers will assume of node structs and such and potentially
> panic. Unless I'm sorry mistaken here....
> 

I don't think that is a huge danger: most drivers tend to check for
the presence of dev->of_node before calling any of the DT interfaces,
you'd only ever enter the probe function if the compatible string matches
(i.e. an old kernel with a new ACPI table), and most users of ACPI
systems will disable CONFIG_OF at compile time, so the accessors looking
at the of_node are not there.

In theory it's possible that something goes wrong here, but it's not
very likely to ever cause problems.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware
  2014-10-01  7:47     ` Arnd Bergmann
@ 2014-10-01 22:09       ` Rafael J. Wysocki
  2014-10-01 23:01         ` Rafael J. Wysocki
  2014-10-02  7:46         ` Arnd Bergmann
  0 siblings, 2 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01 22:09 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-kernel, Greg Kroah-Hartman, Mika Westerberg, linux-acpi,
	devicetree, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
	Bryan Wu, Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Wednesday, October 01, 2014 09:47:40 AM Arnd Bergmann wrote:
> On Wednesday 01 October 2014 04:10:03 Rafael J. Wysocki wrote:
> > From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> > 
> > Add a uniform interface by which device drivers can request device
> > properties from the platform firmware by providing a property name
> > and the corresponding data type.  The purpose of it is to help to
> > write portable code that won't depend on any particular platform
> > firmware interface.
> > 
> > Three general helper functions, device_get_property(),
> > device_read_property() and device_read_property_array() are provided.
> > The first one allows the raw value of a given device property to be
> > accessed.  The remaining two allow the value of a numeric or string
> > property and multiple numeric or string values of one array
> > property to be acquired, respectively.  Static inline wrappers are also
> > provided for the various property data types that can be passed to
> > device_read_property() or device_read_property_array() for extra type
> > checking.
> 
> These look great!
> 
> > In addition to that, new generic routines are provided for retrieving
> > properties from device description objects in the platform firmware
> > in case a device driver needs/wants to access properties of a child
> > object of a given device object.  There are cases in which there is
> > no struct device representation of such child objects and this
> > additional API is useful then.  Again, three functions are provided,
> > device_get_child_property(), device_read_child_property(),
> > device_read_child_property_array(), in analogy with device_get_property(),
> > device_read_property() and device_read_property_array() described above,
> > respectively, along with static inline wrappers for all of the propery
> > data types that can be used.  For all of them, the first argument is
> > a struct device pointer to the parent device object and the second
> > argument is a (void *) pointer to the child description provided by
> > the platform firmware (either ACPI or FDT).
> 
> I still have my reservations against the child accessors, and would
> like to hear what other people think. Passing a void pointer rather
> than struct fw_dev_node has both advantages and disadvantages, and
> I won't complain about either one if enough other people on the DT
> side would like to see the addition of the child functions.

I actually would rather like to know if the people on the DT side have any
problems with the child functions.

Because, suppose that they wouldn't like those functions at all.  What are we
supposed to do, then, honestly?  Add the whole DT vs ACPI logic to the leds-gpio
and gpio_keys_polled drivers?  But these drivers have no reason whatsoever
to include that.  Zero.

So suggestions welcome.

[BTW, In principle we also could use something like

typedef union dev_node {
	struct acpi_device *acpi_node;
	struct device_node *of_node;
} dev_node_t;

instead of the (void *) for more type safety.  It still is useful to pass the
parent pointer along with that, though.]

> > Finally, device_for_each_child_node() is added for iterating over
> > the children of the device description object associated with a
> > given device.
> > 
> > The interface covers both ACPI and Device Trees.
> > 
> > This change set includes material from Mika Westerberg and Aaron Lu.
> > 
> 
> Regarding device_for_each_child_node(), the syntax is inconsistent
> with what we normally use, which can probably be changed. All of the
> DT for_each_* helpers are macros that are used like
> 
> 	struct device *dev = ...;
> 	void *child; /* iterator */
> 
> 	device_for_each_child_node(dev, child) {
> 		u32 something;
> 		device_child_property_read_u32(dev, child, "propname", &something);
> 
> 		do_something(dev, something);
> 	}
> 
> If we get a consensus on having the child interfaces, I'd rather see
> them done this way than with a callback pointer, for consistency
> reasons.

That certainly is doable, although the resulting macro would generate a rather
large chunk of code each time it is used.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware
  2014-10-01 22:09       ` Rafael J. Wysocki
@ 2014-10-01 23:01         ` Rafael J. Wysocki
  2014-10-02  7:46         ` Arnd Bergmann
  1 sibling, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-01 23:01 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-kernel, Greg Kroah-Hartman, Mika Westerberg, linux-acpi,
	devicetree, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
	Bryan Wu, Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Thursday, October 02, 2014 12:09:44 AM Rafael J. Wysocki wrote:
> On Wednesday, October 01, 2014 09:47:40 AM Arnd Bergmann wrote:
> > On Wednesday 01 October 2014 04:10:03 Rafael J. Wysocki wrote:
> > > From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> > > 
> > > Add a uniform interface by which device drivers can request device
> > > properties from the platform firmware by providing a property name
> > > and the corresponding data type.  The purpose of it is to help to
> > > write portable code that won't depend on any particular platform
> > > firmware interface.
> > > 
> > > Three general helper functions, device_get_property(),
> > > device_read_property() and device_read_property_array() are provided.
> > > The first one allows the raw value of a given device property to be
> > > accessed.  The remaining two allow the value of a numeric or string
> > > property and multiple numeric or string values of one array
> > > property to be acquired, respectively.  Static inline wrappers are also
> > > provided for the various property data types that can be passed to
> > > device_read_property() or device_read_property_array() for extra type
> > > checking.
> > 
> > These look great!
> > 
> > > In addition to that, new generic routines are provided for retrieving
> > > properties from device description objects in the platform firmware
> > > in case a device driver needs/wants to access properties of a child
> > > object of a given device object.  There are cases in which there is
> > > no struct device representation of such child objects and this
> > > additional API is useful then.  Again, three functions are provided,
> > > device_get_child_property(), device_read_child_property(),
> > > device_read_child_property_array(), in analogy with device_get_property(),
> > > device_read_property() and device_read_property_array() described above,
> > > respectively, along with static inline wrappers for all of the propery
> > > data types that can be used.  For all of them, the first argument is
> > > a struct device pointer to the parent device object and the second
> > > argument is a (void *) pointer to the child description provided by
> > > the platform firmware (either ACPI or FDT).
> > 
> > I still have my reservations against the child accessors, and would
> > like to hear what other people think. Passing a void pointer rather
> > than struct fw_dev_node has both advantages and disadvantages, and
> > I won't complain about either one if enough other people on the DT
> > side would like to see the addition of the child functions.
> 
> I actually would rather like to know if the people on the DT side have any
> problems with the child functions.
> 
> Because, suppose that they wouldn't like those functions at all.  What are we
> supposed to do, then, honestly?  Add the whole DT vs ACPI logic to the leds-gpio
> and gpio_keys_polled drivers?  But these drivers have no reason whatsoever
> to include that.  Zero.
> 
> So suggestions welcome.
> 
> [BTW, In principle we also could use something like
> 
> typedef union dev_node {
> 	struct acpi_device *acpi_node;
> 	struct device_node *of_node;
> } dev_node_t;
> 
> instead of the (void *) for more type safety.  It still is useful to pass the
> parent pointer along with that, though.]
> 
> > > Finally, device_for_each_child_node() is added for iterating over
> > > the children of the device description object associated with a
> > > given device.
> > > 
> > > The interface covers both ACPI and Device Trees.
> > > 
> > > This change set includes material from Mika Westerberg and Aaron Lu.
> > > 
> > 
> > Regarding device_for_each_child_node(), the syntax is inconsistent
> > with what we normally use, which can probably be changed. All of the
> > DT for_each_* helpers are macros that are used like
> > 
> > 	struct device *dev = ...;
> > 	void *child; /* iterator */
> > 
> > 	device_for_each_child_node(dev, child) {
> > 		u32 something;
> > 		device_child_property_read_u32(dev, child, "propname", &something);
> > 
> > 		do_something(dev, something);
> > 	}
> > 
> > If we get a consensus on having the child interfaces, I'd rather see
> > them done this way than with a callback pointer, for consistency
> > reasons.
> 
> That certainly is doable, although the resulting macro would generate a rather
> large chunk of code each time it is used.

On a second thought I'm not so sure, because we need to iterate either this
way or that way depending on a condition evaluated at run time.  I have no
idea how to do that in a macro at the moment.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware
  2014-10-01  2:10   ` [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware Rafael J. Wysocki
  2014-10-01  7:47     ` Arnd Bergmann
@ 2014-10-02  0:03     ` Greg Kroah-Hartman
  1 sibling, 0 replies; 152+ messages in thread
From: Greg Kroah-Hartman @ 2014-10-02  0:03 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

On Wed, Oct 01, 2014 at 04:10:03AM +0200, Rafael J. Wysocki wrote:
> From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> 
> Add a uniform interface by which device drivers can request device
> properties from the platform firmware by providing a property name
> and the corresponding data type.  The purpose of it is to help to
> write portable code that won't depend on any particular platform
> firmware interface.
> 
> Three general helper functions, device_get_property(),
> device_read_property() and device_read_property_array() are provided.
> The first one allows the raw value of a given device property to be
> accessed.  The remaining two allow the value of a numeric or string
> property and multiple numeric or string values of one array
> property to be acquired, respectively.  Static inline wrappers are also
> provided for the various property data types that can be passed to
> device_read_property() or device_read_property_array() for extra type
> checking.
> 
> In addition to that, new generic routines are provided for retrieving
> properties from device description objects in the platform firmware
> in case a device driver needs/wants to access properties of a child
> object of a given device object.  There are cases in which there is
> no struct device representation of such child objects and this
> additional API is useful then.  Again, three functions are provided,
> device_get_child_property(), device_read_child_property(),
> device_read_child_property_array(), in analogy with device_get_property(),
> device_read_property() and device_read_property_array() described above,
> respectively, along with static inline wrappers for all of the propery
> data types that can be used.  For all of them, the first argument is
> a struct device pointer to the parent device object and the second
> argument is a (void *) pointer to the child description provided by
> the platform firmware (either ACPI or FDT).
> 
> Finally, device_for_each_child_node() is added for iterating over
> the children of the device description object associated with a
> given device.
> 
> The interface covers both ACPI and Device Trees.
> 
> This change set includes material from Mika Westerberg and Aaron Lu.
> 
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> 
> Greg, please let me know if you're fine with this one.

Looks good to me:

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware
  2014-10-01 22:09       ` Rafael J. Wysocki
  2014-10-01 23:01         ` Rafael J. Wysocki
@ 2014-10-02  7:46         ` Arnd Bergmann
  2014-10-02 16:50           ` Rafael J. Wysocki
  1 sibling, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-02  7:46 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Greg Kroah-Hartman, Mika Westerberg, linux-acpi,
	devicetree, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
	Bryan Wu, Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Thursday 02 October 2014 00:09:44 Rafael J. Wysocki wrote:
> On Wednesday, October 01, 2014 09:47:40 AM Arnd Bergmann wrote:
> > On Wednesday 01 October 2014 04:10:03 Rafael J. Wysocki wrote:
> > I still have my reservations against the child accessors, and would
> > like to hear what other people think. Passing a void pointer rather
> > than struct fw_dev_node has both advantages and disadvantages, and
> > I won't complain about either one if enough other people on the DT
> > side would like to see the addition of the child functions.
> 
> I actually would rather like to know if the people on the DT side have any
> problems with the child functions.

Sure, any kind of feedback would be helpful really. 

> Because, suppose that they wouldn't like those functions at all.  What are we
> supposed to do, then, honestly?  Add the whole DT vs ACPI logic to the leds-gpio
> and gpio_keys_polled drivers?  But these drivers have no reason whatsoever
> to include that.  Zero.
> 
> So suggestions welcome.
> 
> [BTW, In principle we also could use something like
> 
> typedef union dev_node {
> 	struct acpi_device *acpi_node;
> 	struct device_node *of_node;
> } dev_node_t;
> 
> instead of the (void *) for more type safety.  It still is useful to pass the
> parent pointer along with that, though.]

Yes, I'm not worried about the implementation details.

> > > Finally, device_for_each_child_node() is added for iterating over
> > > the children of the device description object associated with a
> > > given device.
> > > 
> > > The interface covers both ACPI and Device Trees.
> > > 
> > > This change set includes material from Mika Westerberg and Aaron Lu.
> > > 
> > 
> > Regarding device_for_each_child_node(), the syntax is inconsistent
> > with what we normally use, which can probably be changed. All of the
> > DT for_each_* helpers are macros that are used like
> > 
> > 	struct device *dev = ...;
> > 	void *child; /* iterator */
> > 
> > 	device_for_each_child_node(dev, child) {
> > 		u32 something;
> > 		device_child_property_read_u32(dev, child, "propname", &something);
> > 
> > 		do_something(dev, something);
> > 	}
> > 
> > If we get a consensus on having the child interfaces, I'd rather see
> > them done this way than with a callback pointer, for consistency
> > reasons.
> 
> That certainly is doable, although the resulting macro would generate a rather
> large chunk of code each time it is used.


#define device_for_each_child_node(dev, child) \
	for (child = device_get_next_child_node(dev, NULL), child, \
	     child = device_get_next_child_node(dev, child))

void *device_get_next_child_node(struct device *dev, void *child)
{
	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
		return of_get_next_child(dev->of_node, child);
	else if (IS_ENABLED(CONFIG_ACPI) && ...)
		return acpi_get_next_child(dev, child);
	return NULL;
}

Not any more code than what we have today for the DT-only case, and it's
really just a function call in a loop.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 13/15] input: gpio_keys_polled - Add ACPI probing support
  2014-10-01 16:28         ` Dmitry Torokhov
@ 2014-10-02  9:53           ` Mika Westerberg
  0 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-10-02  9:53 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot, Bryan Wu,
	Lee Jones, Grant Likely, Arnd Bergmann, Aaron Lu, Darren Hart

On Wed, Oct 01, 2014 at 09:28:02AM -0700, Dmitry Torokhov wrote:
> On Wed, Oct 01, 2014 at 12:15:35PM +0300, Mika Westerberg wrote:
> > On Wed, Oct 01, 2014 at 12:48:46AM -0700, Dmitry Torokhov wrote:
> > > On Wed, Oct 01, 2014 at 04:20:43AM +0200, Rafael J. Wysocki wrote:
> > > > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > > 
> > > > Allow the driver to probe from ACPI namespace.
> > > > 
> > > > Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> > > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > > ---
> > > >  drivers/input/keyboard/gpio_keys_polled.c |    7 +++++++
> > > >  1 file changed, 7 insertions(+)
> > > > 
> > > > Index: linux-pm/drivers/input/keyboard/gpio_keys_polled.c
> > > > ===================================================================
> > > > --- linux-pm.orig/drivers/input/keyboard/gpio_keys_polled.c
> > > > +++ linux-pm/drivers/input/keyboard/gpio_keys_polled.c
> > > > @@ -181,6 +181,12 @@ static const struct of_device_id gpio_ke
> > > >  };
> > > >  MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
> > > >  
> > > > +static const struct acpi_device_id gpio_keys_polled_acpi_match[] = {
> > > > +	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
> > > > +	{ },
> > > > +};
> > > > +MODULE_DEVICE_TABLE(acpi, gpio_keys_polled_acpi_match);
> > > > +
> > > >  static int gpio_keys_polled_probe(struct platform_device *pdev)
> > > >  {
> > > >  	struct device *dev = &pdev->dev;
> > > > @@ -309,6 +315,7 @@ static struct platform_driver gpio_keys_
> > > >  		.name	= DRV_NAME,
> > > >  		.owner	= THIS_MODULE,
> > > >  		.of_match_table = gpio_keys_polled_of_match,
> > > > +		.acpi_match_table = gpio_keys_polled_acpi_match,
> > > o
> > > Hmm, why do we need the generic "PRP0001" in every driver? The ACPI device
> > > should have PRP0001 and ACPI bus should know to look into OF matching table
> > > for such devices.
> > 
> > Arnd had a good idea for this. How about,
> > 
> > 	.acpi_match_table = acpi_match_by_of_compatible,
> > 
> > where acpi_match_by_of_compatible is provided by ACPI core? Does that
> > work better for you?
> 
> I still do not see the point. ACPI core knows how to handle
> drv->of_match_table, so unless we need to support ACPI_only binding in a
> given driver I do not understand why we need to add boilerplate code.

You are right - we can get rid of that completely.

In case a device has compatible property, .of_match_table and does not
have .acpi_match_table we match against .of_match_table in ACPI core.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-01 14:14                     ` Arnd Bergmann
  (?)
@ 2014-10-02  9:55                     ` Mika Westerberg
  2014-10-02 10:44                       ` Arnd Bergmann
  -1 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-10-02  9:55 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wed, Oct 01, 2014 at 04:14:20PM +0200, Arnd Bergmann wrote:
> On Wednesday 01 October 2014 17:04:41 Mika Westerberg wrote:
> > 
> > > On the question what to put into the name and type fields, that is
> > > unrelated. The type is supposed to be for the 'device_type' property
> > > in DT, which we should never rely on in a driver that supports both
> > > APCI and DT. In Linux we only use that for "pci", "cpu" and "memory",
> > > all of which have their own way of getting probed in ACPI.
> > > The "name" is normally ignored in DT as well, except for backwards
> > > compatibility with old bindings, but I would argue that you should not
> > > just put "prp0001" in there. Either leave it empty like type, or use
> > > the name of the device as it appears in the ACPI tables, such as "DEV0"
> > > or "PWM".
> > 
> > OK, I think it makes sense to leave them empty. I remember I tried that
> > at some point but it didn't work without N and T fields. Is there some
> > example what to put there in case of empty?
> > 
> > Something like "of:N*T*Cgpio-leds" perhaps?
> 
> Sorry, don't know. If I read the code right, the type field in DT ends
> up being "<NULL>" for any device that doesn't set the device_type 
> property, but that seems a bit silly and probably isn't worth copying.

OK, I checked and udev wants to have both N and T but they can be left
empty. If there are no objections the modalias will look like this:

[root@mnw01 ~]# cat /sys/bus/spi/devices/spi-PRP0001\:00/modalias 
of:Nat25TCatmel,at25

In other words name is the ACPI device name (AT25) in lower case, T is
left empty and C is the compatible property.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-01  7:59     ` Arnd Bergmann
@ 2014-10-02 10:41       ` Mika Westerberg
  2014-10-02 11:51         ` Arnd Bergmann
  0 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-10-02 10:41 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Wed, Oct 01, 2014 at 09:59:14AM +0200, Arnd Bergmann wrote:
> On Wednesday 01 October 2014 04:11:20 Rafael J. Wysocki wrote:
> > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > 
> > This document describes the data format and interfaces of ACPI device
> > specific properties.
> > 
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Signed-off-by: Darren Hart <dvhart@linux.intel.com>
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Overall looks sane, but I wonder if we should try harder to not duplicate
> some of the mistakes we made in the DT bindings. Two points in particular
> stick out:
> 
> > +2.3 Strings
> > +-----------
> > +String properties can be used to describe many things like labels for GPIO
> > +buttons, compability ids, etc.
> > +
> > +A string property looks like this:
> > +
> > +	Package () {"pwm-names", "backlight"},
> 
> The way we name things in DT using separate "foos" and "foo-names" properties
> is a bit quirky. Those are always defined on a per-subsystem level, not
> a per-device level though, so it should be possible to come up with a
> better representation in ACPI.
> 
> Since the device driver should never look into the "foo-names" property
> itself but just pass down the name into the subsystem, the "foo" subsystem
> could instead have a way to add an (optional) name for each reference.
> 
> This is something the DT syntax doesn't allow because you can't have
> both a phandle and a string in a single property but I think the ACPI
> packages can do it, and it wouldn't change the basic structure.

ACPI packages can hold anything (even other packages) but one goal with
the _DSD implementation was to reuse existing DT bindings wherever it
makes sense even if they would not always be optimal for ACPI. So the
current acpi_dev_get_property_reference() is modelled after
corresponding DT function and it allows only integer arguments to
accompany the reference.

Doing that allows taking the existing DT description, package it inside
ACPI _DSD and be done with it.

> > +The referenced ACPI device is returned in args->adev if found.
> > +
> > +In addition to simple object references it is also possible to have object
> > +references with arguments. These are represented in ASL as follows:
> > +
> > +	Device (\_SB.PCI0.PWM)
> > +	{
> > +		Name (_DSD, Package () {
> > +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +			Package () {
> > +				Package () {"#pwm-cells", 2}
> > +			}
> > +		})
> > +	}
> > +
> 
> Similarly, the "#foo-cells" syntax is an artifact of the limitations of the
> DT syntax, and I'd assume there would be a better way to encode this
> in ACPI. Also, a "cell" in Open Firmware is defined as a big-endian
> 32-bit value, which doesn't directly correspond to something in ACPI,
> and the '#' character is an artifact of the use of the Forth language
> in Open Firmware, which you also don't have here.

Same here, we tried to make it follow closely the DT description. It is
probably not the best/optimal encoding for ACPI but it is documented
well in Documentation/devicetree/bindings so why not use it.

The summary email from Darren at KS also mentions that for the existing
drivers, the existing schemas should be common for both implementations [1].

For new bindings we probably should look out if they can be better
represented using ACPI types.

[1] http://lwn.net/Articles/609373/

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support
  2014-10-02  9:55                     ` Mika Westerberg
@ 2014-10-02 10:44                       ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-02 10:44 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Thursday 02 October 2014 12:55:36 Mika Westerberg wrote:
> On Wed, Oct 01, 2014 at 04:14:20PM +0200, Arnd Bergmann wrote:
> > On Wednesday 01 October 2014 17:04:41 Mika Westerberg wrote:
> > > 
> > > > On the question what to put into the name and type fields, that is
> > > > unrelated. The type is supposed to be for the 'device_type' property
> > > > in DT, which we should never rely on in a driver that supports both
> > > > APCI and DT. In Linux we only use that for "pci", "cpu" and "memory",
> > > > all of which have their own way of getting probed in ACPI.
> > > > The "name" is normally ignored in DT as well, except for backwards
> > > > compatibility with old bindings, but I would argue that you should not
> > > > just put "prp0001" in there. Either leave it empty like type, or use
> > > > the name of the device as it appears in the ACPI tables, such as "DEV0"
> > > > or "PWM".
> > > 
> > > OK, I think it makes sense to leave them empty. I remember I tried that
> > > at some point but it didn't work without N and T fields. Is there some
> > > example what to put there in case of empty?
> > > 
> > > Something like "of:N*T*Cgpio-leds" perhaps?
> > 
> > Sorry, don't know. If I read the code right, the type field in DT ends
> > up being "<NULL>" for any device that doesn't set the device_type 
> > property, but that seems a bit silly and probably isn't worth copying.
> 
> OK, I checked and udev wants to have both N and T but they can be left
> empty. If there are no objections the modalias will look like this:
> 
> [root@mnw01 ~]# cat /sys/bus/spi/devices/spi-PRP0001\:00/modalias 
> of:Nat25TCatmel,at25
> 
> In other words name is the ACPI device name (AT25) in lower case, T is
> left empty and C is the compatible property.

Yes, seems ok to me.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 10:41       ` Mika Westerberg
@ 2014-10-02 11:51         ` Arnd Bergmann
  2014-10-02 12:15           ` Mika Westerberg
  0 siblings, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-02 11:51 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Thursday 02 October 2014 13:41:23 Mika Westerberg wrote:
> On Wed, Oct 01, 2014 at 09:59:14AM +0200, Arnd Bergmann wrote:
> > On Wednesday 01 October 2014 04:11:20 Rafael J. Wysocki wrote:
> > > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> > > +The referenced ACPI device is returned in args->adev if found.
> > > +
> > > +In addition to simple object references it is also possible to have object
> > > +references with arguments. These are represented in ASL as follows:
> > > +
> > > +	Device (\_SB.PCI0.PWM)
> > > +	{
> > > +		Name (_DSD, Package () {
> > > +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > > +			Package () {
> > > +				Package () {"#pwm-cells", 2}
> > > +			}
> > > +		})
> > > +	}
> > > +
> > 
> > Similarly, the "#foo-cells" syntax is an artifact of the limitations of the
> > DT syntax, and I'd assume there would be a better way to encode this
> > in ACPI. Also, a "cell" in Open Firmware is defined as a big-endian
> > 32-bit value, which doesn't directly correspond to something in ACPI,
> > and the '#' character is an artifact of the use of the Forth language
> > in Open Firmware, which you also don't have here.
> 
> Same here, we tried to make it follow closely the DT description. It is
> probably not the best/optimal encoding for ACPI but it is documented
> well in Documentation/devicetree/bindings so why not use it.
> 
> The summary email from Darren at KS also mentions that for the existing
> drivers, the existing schemas should be common for both implementations [1].
> 
> For new bindings we probably should look out if they can be better
> represented using ACPI types.
> 
> [1] http://lwn.net/Articles/609373/

I thought when we had discussed the subsystem specific bindings, the
consensus there was to have subsystem specific accessors and
properties/tables.

I would argue that for everything that ACPI already has (interrupts,
registers, gpio, dmaengine, ...) the native method should be used,
possibly using _DSD to provide naming for otherwise anonymous references.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 11:51         ` Arnd Bergmann
@ 2014-10-02 12:15           ` Mika Westerberg
  2014-10-02 12:46             ` Arnd Bergmann
  2014-10-03 13:48             ` Mark Rutland
  0 siblings, 2 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-10-02 12:15 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Thu, Oct 02, 2014 at 01:51:24PM +0200, Arnd Bergmann wrote:
> On Thursday 02 October 2014 13:41:23 Mika Westerberg wrote:
> > On Wed, Oct 01, 2014 at 09:59:14AM +0200, Arnd Bergmann wrote:
> > > On Wednesday 01 October 2014 04:11:20 Rafael J. Wysocki wrote:
> > > > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > 
> > > > +The referenced ACPI device is returned in args->adev if found.
> > > > +
> > > > +In addition to simple object references it is also possible to have object
> > > > +references with arguments. These are represented in ASL as follows:
> > > > +
> > > > +	Device (\_SB.PCI0.PWM)
> > > > +	{
> > > > +		Name (_DSD, Package () {
> > > > +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > > > +			Package () {
> > > > +				Package () {"#pwm-cells", 2}
> > > > +			}
> > > > +		})
> > > > +	}
> > > > +
> > > 
> > > Similarly, the "#foo-cells" syntax is an artifact of the limitations of the
> > > DT syntax, and I'd assume there would be a better way to encode this
> > > in ACPI. Also, a "cell" in Open Firmware is defined as a big-endian
> > > 32-bit value, which doesn't directly correspond to something in ACPI,
> > > and the '#' character is an artifact of the use of the Forth language
> > > in Open Firmware, which you also don't have here.
> > 
> > Same here, we tried to make it follow closely the DT description. It is
> > probably not the best/optimal encoding for ACPI but it is documented
> > well in Documentation/devicetree/bindings so why not use it.
> > 
> > The summary email from Darren at KS also mentions that for the existing
> > drivers, the existing schemas should be common for both implementations [1].
> > 
> > For new bindings we probably should look out if they can be better
> > represented using ACPI types.
> > 
> > [1] http://lwn.net/Articles/609373/
> 
> I thought when we had discussed the subsystem specific bindings, the
> consensus there was to have subsystem specific accessors and
> properties/tables.
> 
> I would argue that for everything that ACPI already has (interrupts,
> registers, gpio, dmaengine, ...) the native method should be used,
> possibly using _DSD to provide naming for otherwise anonymous references.

Absolutely. That's precisely what we do in the GPIO patch of this
series. E.g we use ACPI GpioIo/GpioInt _CRS resources but give name to
the GPIOs with the help of _DSD.

For things that don't have correspondence in ACPI but have well defined
existing DT schema, like PWMs, we should follow that.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 12:15           ` Mika Westerberg
@ 2014-10-02 12:46             ` Arnd Bergmann
  2014-10-02 13:36               ` Mika Westerberg
  2014-10-03 13:48             ` Mark Rutland
  1 sibling, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-02 12:46 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Thursday 02 October 2014 15:15:08 Mika Westerberg wrote:
> > I thought when we had discussed the subsystem specific bindings, the
> > consensus there was to have subsystem specific accessors and
> > properties/tables.
> > 
> > I would argue that for everything that ACPI already has (interrupts,
> > registers, gpio, dmaengine, ...) the native method should be used,
> > possibly using _DSD to provide naming for otherwise anonymous references.
> 
> Absolutely. That's precisely what we do in the GPIO patch of this
> series. E.g we use ACPI GpioIo/GpioInt _CRS resources but give name to
> the GPIOs with the help of _DSD.

Ok, I've looked at the example again:

+       Device (DEV0)
+       {
+               Name (_CRS, ResourceTemplate () {
+                       GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+                               "\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
+                       GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+                               "\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
+                       ...
+               })
+
+               Name (_DSD, Package () {
+                       ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+                       Package () {
+                               Package () {"reset-gpio", {^DEV0, 0, 0, 0}},
+                               Package () {"shutdown-gpio", {^DEV0, 1, 0, 0}},
+                       }
+               })
+       }

tell me if I'm interpreting this right: you use _CRS to define a reference
to the actual GPIO controller here, but then in your _DSD you have something
that is a bit like the DT gpio binding, except that it doesn't refer to
a GPIO controller but to the GPIO using device itself.

When a driver calls dev_get_named_gpiod_from_child, you then lookup the
"reset-gpio" (or other) properties to find the reference to the _CRS.

Why can't you instead have a "gpio-names" property in _DSD that just
links from a string to an index as we do in all the other bindings?
It sounds to me like that would be simpler and more consistent with
the way things are done in ACPI, and have no effect that would be visible
to the driver.
 
> For things that don't have correspondence in ACPI but have well defined
> existing DT schema, like PWMs, we should follow that.

Only for stuff that is visible to drivers. I think it's important
that a driver calling pwm_get() today should keep working with
ACPI when the pwm subsystem is extended to support that.

However, that does not necessarily mean using #pwm-cells and pwm-names
properties when there is a better way to express the same in ACPI
syntax. AFAICT, the #foo-names is completely redundant for ACPI
as the length of a property in a list of similar elements is part
of the binary data (if not, please correct me), and I already commented
that I think the foo-names stuff could be encoded in the package
directly in a way we can't do in DT.

Even if you want to do automatic translation between DT and ACPI,
I think it would be possible to treat these two the same:

(forgive any syntax errors)

	Name (_DSD, Package () {
		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
		Package () {
			Package () { "pwms" { "led-red", ^PWM0, 0, 10 },
					    { "led-green", ^PWM0, 1, 20 }},
	}

vs.

	pwm-slave {
		pwms = <&pwm0 0 10>, <&pwm1 1 20>;
		pwm-names = "led-red", "led-green";
	};


	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 12:46             ` Arnd Bergmann
@ 2014-10-02 13:36               ` Mika Westerberg
  2014-10-02 14:29                 ` Arnd Bergmann
  2014-10-03  2:03                 ` Rafael J. Wysocki
  0 siblings, 2 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-10-02 13:36 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Thu, Oct 02, 2014 at 02:46:30PM +0200, Arnd Bergmann wrote:
> On Thursday 02 October 2014 15:15:08 Mika Westerberg wrote:
> > > I thought when we had discussed the subsystem specific bindings, the
> > > consensus there was to have subsystem specific accessors and
> > > properties/tables.
> > > 
> > > I would argue that for everything that ACPI already has (interrupts,
> > > registers, gpio, dmaengine, ...) the native method should be used,
> > > possibly using _DSD to provide naming for otherwise anonymous references.
> > 
> > Absolutely. That's precisely what we do in the GPIO patch of this
> > series. E.g we use ACPI GpioIo/GpioInt _CRS resources but give name to
> > the GPIOs with the help of _DSD.
> 
> Ok, I've looked at the example again:
> 
> +       Device (DEV0)
> +       {
> +               Name (_CRS, ResourceTemplate () {
> +                       GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
> +                               "\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
> +                       GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
> +                               "\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
> +                       ...
> +               })
> +
> +               Name (_DSD, Package () {
> +                       ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +                       Package () {
> +                               Package () {"reset-gpio", {^DEV0, 0, 0, 0}},
> +                               Package () {"shutdown-gpio", {^DEV0, 1, 0, 0}},
> +                       }
> +               })
> +       }
> 
> tell me if I'm interpreting this right: you use _CRS to define a reference
> to the actual GPIO controller here, but then in your _DSD you have something
> that is a bit like the DT gpio binding, except that it doesn't refer to
> a GPIO controller but to the GPIO using device itself.

That's right. However, it is not limited to the device itself, it can be
parent device for example. Typically not the GPIO controller, though.

> When a driver calls dev_get_named_gpiod_from_child, you then lookup the
> "reset-gpio" (or other) properties to find the reference to the _CRS.

That's right.

> Why can't you instead have a "gpio-names" property in _DSD that just
> links from a string to an index as we do in all the other bindings?
> It sounds to me like that would be simpler and more consistent with
> the way things are done in ACPI, and have no effect that would be visible
> to the driver.

The ACPI GpioIo/GpioInt entry can also contain pinlist, for example:


            Name (_CRS, ResourceTemplate () {
                GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
                        "\\_SB.PCI0.LPC", 0, ResourceConsumer) {10, 21, 50, 13} <-- this is the pinlist
                ...
            })

            Device (BTN0)
            {
                Name (_DSD, Package () {
                    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package () {
		        ...
                        Package () {"gpios", Package () {^^BTNS, 0, 2, 1}},
                    }
                })
            }

Format of the package is:

  { reference, crs_index, pin_index, active_low },

So {^^BTNS, 0, 2, 1} will select pin 50 and mark it as active_low.

In addition to name we also use it to select correct pin in pinlist and
provide additional active_low information which would not be available
for plain GpioIo() resource.

> > For things that don't have correspondence in ACPI but have well defined
> > existing DT schema, like PWMs, we should follow that.
> 
> Only for stuff that is visible to drivers. I think it's important
> that a driver calling pwm_get() today should keep working with
> ACPI when the pwm subsystem is extended to support that.

Of course.

> However, that does not necessarily mean using #pwm-cells and pwm-names
> properties when there is a better way to express the same in ACPI
> syntax. AFAICT, the #foo-names is completely redundant for ACPI
> as the length of a property in a list of similar elements is part
> of the binary data (if not, please correct me), and I already commented
> that I think the foo-names stuff could be encoded in the package
> directly in a way we can't do in DT.

Yes, it can be included in the package, however see below.

> Even if you want to do automatic translation between DT and ACPI,
> I think it would be possible to treat these two the same:
> 
> (forgive any syntax errors)
> 
> 	Name (_DSD, Package () {
> 		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> 		Package () {
> 			Package () { "pwms" { "led-red", ^PWM0, 0, 10 },
> 					    { "led-green", ^PWM0, 1, 20 }},

Even though the above would fit better in ACPI, it is not allowed to
have multiple values for a single property. One reason for that is that
we validate each property and check that they match what is expected and
having strict set of possible values makes it easier.

Putting everything to a single package results this:

		Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}

But I think the below looks better:

		Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
		Package () { "pwm-names", Package () {"led-red", "led-green"}}

and it is trivial to match with the corresponding DT fragment.

> 	}
> 
> vs.
> 
> 	pwm-slave {
> 		pwms = <&pwm0 0 10>, <&pwm1 1 20>;
> 		pwm-names = "led-red", "led-green";
> 	};
> 

I don't have strong feelings which way it should be. The current
implementation limits references so that you can have only integer
arguments, like {ref0, int, int, ref1, int} but if people think it is
better to allow strings there as well, it can be changed.

I would like to get comments from Darren and Rafael about this, though.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 13:36               ` Mika Westerberg
@ 2014-10-02 14:29                 ` Arnd Bergmann
  2014-10-02 14:38                   ` Mika Westerberg
  2014-10-03  2:03                 ` Rafael J. Wysocki
  1 sibling, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-02 14:29 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Thursday 02 October 2014 16:36:54 Mika Westerberg wrote:
> 
> > Even if you want to do automatic translation between DT and ACPI,
> > I think it would be possible to treat these two the same:
> > 
> > (forgive any syntax errors)
> > 
> >       Name (_DSD, Package () {
> >               ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> >               Package () {
> >                       Package () { "pwms" { "led-red", ^PWM0, 0, 10 },
> >                                           { "led-green", ^PWM0, 1, 20 }},
> 
> Even though the above would fit better in ACPI, it is not allowed to
> have multiple values for a single property. One reason for that is that
> we validate each property and check that they match what is expected and
> having strict set of possible values makes it easier.

Ok, so you basically have the same limitation that we have in DT.

We have syntactical sugar in dtc that allows us to write


	pwms = <&pwm0 0 10>, <&pwm1 1 20>;

or

	pwms = <&pwm0 0 10   &pwm1 1 20>;

but the binary representation of the two is the same. This is the
only reason why we need the #size-cells property and I guess you
do too.	

> Putting everything to a single package results this:
> 
>                 Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> 
> But I think the below looks better:
> 
>                 Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
>                 Package () { "pwm-names", Package () {"led-red", "led-green"}}

Ok, if you have no way to separate the individual entries in a list of
references, I don't care much, and I can see the "pwm-names" as being more
consistent with the DT syntax.

Is this a limitation in the way that the AML syntax and compiler works,
or is this a decision you made specifically for the _DSD syntax and that
could still be changed if there is an overwhelming interest?

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 14:29                 ` Arnd Bergmann
@ 2014-10-02 14:38                   ` Mika Westerberg
  2014-10-02 14:55                     ` Arnd Bergmann
  0 siblings, 1 reply; 152+ messages in thread
From: Mika Westerberg @ 2014-10-02 14:38 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Thu, Oct 02, 2014 at 04:29:03PM +0200, Arnd Bergmann wrote:
> Is this a limitation in the way that the AML syntax and compiler works,
> or is this a decision you made specifically for the _DSD syntax and that
> could still be changed if there is an overwhelming interest?

It is only limitation of the _DSD device property UUID specification and
our implementation. It can be changed if needed.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 14:38                   ` Mika Westerberg
@ 2014-10-02 14:55                     ` Arnd Bergmann
  2014-10-03 13:56                       ` Mark Rutland
  0 siblings, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-02 14:55 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Thursday 02 October 2014 17:38:09 Mika Westerberg wrote:
> On Thu, Oct 02, 2014 at 04:29:03PM +0200, Arnd Bergmann wrote:
> > Is this a limitation in the way that the AML syntax and compiler works,
> > or is this a decision you made specifically for the _DSD syntax and that
> > could still be changed if there is an overwhelming interest?
> 
> It is only limitation of the _DSD device property UUID specification and
> our implementation. It can be changed if needed.

Ok, I see. I think it would be nice if this could be changed in order
to avoid having to copy the #xxx-cells and xxx-names properties from
DT, by providing a more natural syntax.

I'm not blaming you though if you don't want to go through the pain of
updating the spec though, and I won't complain loudly if you don't.

Maybe someone else has an opinion on the matter.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware
  2014-10-02  7:46         ` Arnd Bergmann
@ 2014-10-02 16:50           ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-02 16:50 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-kernel, Greg Kroah-Hartman, Mika Westerberg, linux-acpi,
	devicetree, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
	Bryan Wu, Lee Jones, Grant Likely, Aaron Lu, Darren Hart

On Thursday, October 02, 2014 09:46:29 AM Arnd Bergmann wrote:
> On Thursday 02 October 2014 00:09:44 Rafael J. Wysocki wrote:
> > On Wednesday, October 01, 2014 09:47:40 AM Arnd Bergmann wrote:
> > > On Wednesday 01 October 2014 04:10:03 Rafael J. Wysocki wrote:
> > > I still have my reservations against the child accessors, and would
> > > like to hear what other people think. Passing a void pointer rather
> > > than struct fw_dev_node has both advantages and disadvantages, and
> > > I won't complain about either one if enough other people on the DT
> > > side would like to see the addition of the child functions.
> > 
> > I actually would rather like to know if the people on the DT side have any
> > problems with the child functions.
> 
> Sure, any kind of feedback would be helpful really. 
> 
> > Because, suppose that they wouldn't like those functions at all.  What are we
> > supposed to do, then, honestly?  Add the whole DT vs ACPI logic to the leds-gpio
> > and gpio_keys_polled drivers?  But these drivers have no reason whatsoever
> > to include that.  Zero.
> > 
> > So suggestions welcome.
> > 
> > [BTW, In principle we also could use something like
> > 
> > typedef union dev_node {
> > 	struct acpi_device *acpi_node;
> > 	struct device_node *of_node;
> > } dev_node_t;
> > 
> > instead of the (void *) for more type safety.  It still is useful to pass the
> > parent pointer along with that, though.]
> 
> Yes, I'm not worried about the implementation details.
> 
> > > > Finally, device_for_each_child_node() is added for iterating over
> > > > the children of the device description object associated with a
> > > > given device.
> > > > 
> > > > The interface covers both ACPI and Device Trees.
> > > > 
> > > > This change set includes material from Mika Westerberg and Aaron Lu.
> > > > 
> > > 
> > > Regarding device_for_each_child_node(), the syntax is inconsistent
> > > with what we normally use, which can probably be changed. All of the
> > > DT for_each_* helpers are macros that are used like
> > > 
> > > 	struct device *dev = ...;
> > > 	void *child; /* iterator */
> > > 
> > > 	device_for_each_child_node(dev, child) {
> > > 		u32 something;
> > > 		device_child_property_read_u32(dev, child, "propname", &something);
> > > 
> > > 		do_something(dev, something);
> > > 	}
> > > 
> > > If we get a consensus on having the child interfaces, I'd rather see
> > > them done this way than with a callback pointer, for consistency
> > > reasons.
> > 
> > That certainly is doable, although the resulting macro would generate a rather
> > large chunk of code each time it is used.
> 
> 
> #define device_for_each_child_node(dev, child) \
> 	for (child = device_get_next_child_node(dev, NULL), child, \
> 	     child = device_get_next_child_node(dev, child))
> 
> void *device_get_next_child_node(struct device *dev, void *child)
> {
> 	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
> 		return of_get_next_child(dev->of_node, child);
> 	else if (IS_ENABLED(CONFIG_ACPI) && ...)
> 		return acpi_get_next_child(dev, child);
> 	return NULL;
> }
> 
> Not any more code than what we have today for the DT-only case, and it's
> really just a function call in a loop.

OK, I see what you mean.

Now we have the if () on every iteration instead of just doing that once
upfront.  Not a big deal I suppose, but slightly ugly to me.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 13:36               ` Mika Westerberg
  2014-10-02 14:29                 ` Arnd Bergmann
@ 2014-10-03  2:03                 ` Rafael J. Wysocki
  2014-10-03  8:12                   ` Mika Westerberg
  2014-10-03 13:58                   ` Mark Rutland
  1 sibling, 2 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-03  2:03 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Arnd Bergmann, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Thursday, October 02, 2014 04:36:54 PM Mika Westerberg wrote:
> On Thu, Oct 02, 2014 at 02:46:30PM +0200, Arnd Bergmann wrote:
> > On Thursday 02 October 2014 15:15:08 Mika Westerberg wrote:

[cut]

> 
> Putting everything to a single package results this:
> 
> 		Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> 
> But I think the below looks better:

I agree.

> 		Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> 		Package () { "pwm-names", Package () {"led-red", "led-green"}}
> 
> and it is trivial to match with the corresponding DT fragment.
> 
> > 	}
> > 
> > vs.
> > 
> > 	pwm-slave {
> > 		pwms = <&pwm0 0 10>, <&pwm1 1 20>;
> > 		pwm-names = "led-red", "led-green";
> > 	};
> > 
> 
> I don't have strong feelings which way it should be. The current
> implementation limits references so that you can have only integer
> arguments, like {ref0, int, int, ref1, int} but if people think it is
> better to allow strings there as well, it can be changed.
> 
> I would like to get comments from Darren and Rafael about this, though.

In my opinion there needs to be a "canonical" representation of the
binding that people always can expect to work.  It seems reasonable to
use the one exactly matching the DT representation for that.

In addition to that we can add other representations that the code will
also parse correctly as alternatives.  In the future.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-03  2:03                 ` Rafael J. Wysocki
@ 2014-10-03  8:12                   ` Mika Westerberg
  2014-10-03 13:58                   ` Mark Rutland
  1 sibling, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-10-03  8:12 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Arnd Bergmann, linux-kernel, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Grant Likely, Aaron Lu,
	Darren Hart

On Fri, Oct 03, 2014 at 04:03:51AM +0200, Rafael J. Wysocki wrote:
> On Thursday, October 02, 2014 04:36:54 PM Mika Westerberg wrote:
> > On Thu, Oct 02, 2014 at 02:46:30PM +0200, Arnd Bergmann wrote:
> > > On Thursday 02 October 2014 15:15:08 Mika Westerberg wrote:
> 
> [cut]
> 
> > 
> > Putting everything to a single package results this:
> > 
> > 		Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> > 
> > But I think the below looks better:
> 
> I agree.
> 
> > 		Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> > 		Package () { "pwm-names", Package () {"led-red", "led-green"}}
> > 
> > and it is trivial to match with the corresponding DT fragment.
> > 
> > > 	}
> > > 
> > > vs.
> > > 
> > > 	pwm-slave {
> > > 		pwms = <&pwm0 0 10>, <&pwm1 1 20>;
> > > 		pwm-names = "led-red", "led-green";
> > > 	};
> > > 
> > 
> > I don't have strong feelings which way it should be. The current
> > implementation limits references so that you can have only integer
> > arguments, like {ref0, int, int, ref1, int} but if people think it is
> > better to allow strings there as well, it can be changed.
> > 
> > I would like to get comments from Darren and Rafael about this, though.
> 
> In my opinion there needs to be a "canonical" representation of the
> binding that people always can expect to work.  It seems reasonable to
> use the one exactly matching the DT representation for that.
> 
> In addition to that we can add other representations that the code will
> also parse correctly as alternatives.  In the future.

OK, so if no objections and Arnd promised not to complain too loudly, I
would like to keep this as is for now.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property
  2014-10-01  2:10   ` [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property Rafael J. Wysocki
  2014-10-01  7:48     ` Arnd Bergmann
@ 2014-10-03 13:43     ` Mark Rutland
  2014-10-03 17:59       ` Dmitry Torokhov
  1 sibling, 1 reply; 152+ messages in thread
From: Mark Rutland @ 2014-10-03 13:43 UTC (permalink / raw)
  To: Rafael J. Wysocki, grant.likely
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Arnd Bergmann, Aaron Lu,
	Darren Hart

Hi Rafael,

On Wed, Oct 01, 2014 at 03:10:40AM +0100, Rafael J. Wysocki wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> We have lots of existing Device Tree enabled drivers and allocating
> separate _HID for each is not feasible. Instead we allocate special
> _HID "PRP0001" that means that the match should be done using Device
> Tree compatible property using driver's .of_match_table instead.

That's hopefully not the precise meaning of "PRP0001" unless we're
attempting no semblance of OS independence here?

I'm still of the opinion that marrying ACPI to existing (and often
ill-defined) DT bindings is a bad idea. While it's expedient, I believe
this is going to be a long-term maintenance nightmare.

I'm very concerned with the prospect of model mismatch between the two
(e.g. DT clocks properties where ACPI has traditionally been in charge
of clock management). I've not seen any high-level guidelines w.r.t.
what should live in _DSD properties and what should not (at least not in
the ACPI spec itself). There are almost certainly properties that only
make sense if !ACPI, and likely there will be some that only make sense
if ACPI.

So I think that in its current level of standardisation, _DSD only makes
sense for simple device properties, and not relationships between
devices, except where ACPI already has some kind of a model (which
currently seems to cover interrupts and GPIOs). I'd also hope that we
could expose a 'clean' subset of DT bidnings (i.e. those which aren't
known to be kept around only for compatibility with legacy DTBs).

I do not believe it makes sense to share such a low-level interface.
Given the aforementioned model differences, and the fact that we don't
need to support _every_ device tree binding, I don't see why this can't
be handled with separate probe paths in the drivers we care about (as we
already do for DT vs platform data).

Mark.

> If there is a need to distinguish from where the device is enumerated
> (DT/ACPI) driver can check dev->of_node or ACPI_COMPATION(dev).
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/acpi/property.c |   34 +++++++++++++++++
>  drivers/acpi/scan.c     |   91 ++++++++++++++++++++++++++++++++++++++++++------
>  include/acpi/acpi_bus.h |    1 
>  include/linux/acpi.h    |    8 +---
>  4 files changed, 118 insertions(+), 16 deletions(-)
> 
> Index: linux-pm/drivers/acpi/property.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/property.c
> +++ linux-pm/drivers/acpi/property.c
> @@ -76,6 +76,37 @@ static bool acpi_properties_format_valid
>  	return true;
>  }
>  
> +static void acpi_init_of_compatible(struct acpi_device *adev)
> +{
> +	const union acpi_object *of_compatible;
> +	struct acpi_hardware_id *hwid;
> +	bool acpi_of = false;
> +
> +	/*
> +	 * Check if the special PRP0001 ACPI ID is present and in that
> +	 * case we fill in Device Tree compatible properties for this
> +	 * device.
> +	 */
> +	list_for_each_entry(hwid, &adev->pnp.ids, list) {
> +		if (!strcmp(hwid->id, "PRP0001")) {
> +			acpi_of = true;
> +			break;
> +		}
> +	}
> +
> +	if (!acpi_of)
> +		return;
> +
> +	if (acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
> +					&of_compatible)) {
> +		acpi_handle_warn(adev->handle,
> +				 "PRP0001 requires compatible property\n");
> +		return;
> +	}
> +
> +	adev->data.of_compatible = of_compatible;
> +}
> +
>  void acpi_init_properties(struct acpi_device *adev)
>  {
>  	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
> @@ -119,6 +150,8 @@ void acpi_init_properties(struct acpi_de
>  
>  		adev->data.pointer = buf.pointer;
>  		adev->data.properties = properties;
> +
> +		acpi_init_of_compatible(adev);
>  		return;
>  	}
>  
> @@ -130,6 +163,7 @@ void acpi_init_properties(struct acpi_de
>  void acpi_free_properties(struct acpi_device *adev)
>  {
>  	ACPI_FREE((void *)adev->data.pointer);
> +	adev->data.of_compatible = NULL;
>  	adev->data.pointer = NULL;
>  	adev->data.properties = NULL;
>  }
> Index: linux-pm/drivers/acpi/scan.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/scan.c
> +++ linux-pm/drivers/acpi/scan.c
> @@ -124,17 +124,43 @@ static int create_modalias(struct acpi_d
>  	if (list_empty(&acpi_dev->pnp.ids))
>  		return 0;
>  
> -	len = snprintf(modalias, size, "acpi:");
> -	size -= len;
> +	/*
> +	 * If the device has PRP0001 we expose DT compatible modalias
> +	 * instead.
> +	 */
> +	if (acpi_dev->data.of_compatible) {
> +		const union acpi_object *of_compatible, *obj;
> +		int i;
> +
> +		len = snprintf(modalias, size, "of:Nprp0001Tacpi");
> +
> +		of_compatible = acpi_dev->data.of_compatible;
> +		for (i = 0; i < of_compatible->package.count; i++) {
> +			obj = &of_compatible->package.elements[i];
> +
> +			count = snprintf(&modalias[len], size, "C%s",
> +					 obj->string.pointer);
> +			if (count < 0)
> +				return -EINVAL;
> +			if (count >= size)
> +				return -ENOMEM;
> +
> +			len += count;
> +			size -= count;
> +		}
> +	} else {
> +		len = snprintf(modalias, size, "acpi:");
> +		size -= len;
>  
> -	list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
> -		count = snprintf(&modalias[len], size, "%s:", id->id);
> -		if (count < 0)
> -			return -EINVAL;
> -		if (count >= size)
> -			return -ENOMEM;
> -		len += count;
> -		size -= count;
> +		list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
> +			count = snprintf(&modalias[len], size, "%s:", id->id);
> +			if (count < 0)
> +				return -EINVAL;
> +			if (count >= size)
> +				return -ENOMEM;
> +			len += count;
> +			size -= count;
> +		}
>  	}
>  
>  	modalias[len] = '\0';
> @@ -864,6 +890,51 @@ int acpi_match_device_ids(struct acpi_de
>  }
>  EXPORT_SYMBOL(acpi_match_device_ids);
>  
> +/* Performs match for special "PRP0001" shoehorn ACPI ID */
> +static bool acpi_of_driver_match_device(struct device *dev,
> +					const struct device_driver *drv)
> +{
> +	struct acpi_device *adev = ACPI_COMPANION(dev);
> +	const union acpi_object *of_compatible;
> +	int i;
> +
> +	/*
> +	 * If the ACPI device does not have corresponding compatible
> +	 * property or the driver in question does not have DT matching
> +	 * table we consider the match succesful (matches the ACPI ID).
> +	 */
> +	of_compatible = adev->data.of_compatible;
> +	if (!drv->of_match_table || !of_compatible)
> +		return true;
> +
> +	/* Now we can look for the driver DT compatible strings */
> +	for (i = 0; i < of_compatible->package.count; i++) {
> +		const struct of_device_id *id;
> +		const union acpi_object *obj;
> +
> +		obj = &of_compatible->package.elements[i];
> +
> +		for (id = drv->of_match_table; id->compatible[0]; id++)
> +			if (!strcasecmp(obj->string.pointer, id->compatible))
> +				return true;
> +	}
> +
> +	return false;
> +}
> +
> +bool acpi_driver_match_device(struct device *dev,
> +			      const struct device_driver *drv)
> +{
> +	const struct acpi_device_id *id;
> +
> +	id = acpi_match_device(drv->acpi_match_table, dev);
> +	if (!id)
> +		return false;
> +
> +	return acpi_of_driver_match_device(dev, drv);
> +}
> +EXPORT_SYMBOL_GPL(acpi_driver_match_device);
> +
>  static void acpi_free_power_resources_lists(struct acpi_device *device)
>  {
>  	int i;
> Index: linux-pm/include/acpi/acpi_bus.h
> ===================================================================
> --- linux-pm.orig/include/acpi/acpi_bus.h
> +++ linux-pm/include/acpi/acpi_bus.h
> @@ -341,6 +341,7 @@ struct acpi_device_physical_node {
>  struct acpi_device_data {
>  	const union acpi_object *pointer;
>  	const union acpi_object *properties;
> +	const union acpi_object *of_compatible;
>  };
>  
>  /* Device */
> Index: linux-pm/include/linux/acpi.h
> ===================================================================
> --- linux-pm.orig/include/linux/acpi.h
> +++ linux-pm/include/linux/acpi.h
> @@ -424,12 +424,8 @@ extern int acpi_nvs_for_each_region(int
>  const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
>  					       const struct device *dev);
>  
> -static inline bool acpi_driver_match_device(struct device *dev,
> -					    const struct device_driver *drv)
> -{
> -	return !!acpi_match_device(drv->acpi_match_table, dev);
> -}
> -
> +extern bool acpi_driver_match_device(struct device *dev,
> +				     const struct device_driver *drv);
>  int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
>  int acpi_device_modalias(struct device *, char *, int);
>  
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 12:15           ` Mika Westerberg
  2014-10-02 12:46             ` Arnd Bergmann
@ 2014-10-03 13:48             ` Mark Rutland
  2014-10-04  0:16               ` Rafael J. Wysocki
  1 sibling, 1 reply; 152+ messages in thread
From: Mark Rutland @ 2014-10-03 13:48 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Arnd Bergmann, Rafael J. Wysocki, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Thu, Oct 02, 2014 at 01:15:08PM +0100, Mika Westerberg wrote:
> On Thu, Oct 02, 2014 at 01:51:24PM +0200, Arnd Bergmann wrote:
> > On Thursday 02 October 2014 13:41:23 Mika Westerberg wrote:
> > > On Wed, Oct 01, 2014 at 09:59:14AM +0200, Arnd Bergmann wrote:
> > > > On Wednesday 01 October 2014 04:11:20 Rafael J. Wysocki wrote:
> > > > > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > 
> > > > > +The referenced ACPI device is returned in args->adev if found.
> > > > > +
> > > > > +In addition to simple object references it is also possible to have object
> > > > > +references with arguments. These are represented in ASL as follows:
> > > > > +
> > > > > +	Device (\_SB.PCI0.PWM)
> > > > > +	{
> > > > > +		Name (_DSD, Package () {
> > > > > +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > > > > +			Package () {
> > > > > +				Package () {"#pwm-cells", 2}
> > > > > +			}
> > > > > +		})
> > > > > +	}
> > > > > +
> > > > 
> > > > Similarly, the "#foo-cells" syntax is an artifact of the limitations of the
> > > > DT syntax, and I'd assume there would be a better way to encode this
> > > > in ACPI. Also, a "cell" in Open Firmware is defined as a big-endian
> > > > 32-bit value, which doesn't directly correspond to something in ACPI,
> > > > and the '#' character is an artifact of the use of the Forth language
> > > > in Open Firmware, which you also don't have here.
> > > 
> > > Same here, we tried to make it follow closely the DT description. It is
> > > probably not the best/optimal encoding for ACPI but it is documented
> > > well in Documentation/devicetree/bindings so why not use it.
> > > 
> > > The summary email from Darren at KS also mentions that for the existing
> > > drivers, the existing schemas should be common for both implementations [1].
> > > 
> > > For new bindings we probably should look out if they can be better
> > > represented using ACPI types.
> > > 
> > > [1] http://lwn.net/Articles/609373/
> > 
> > I thought when we had discussed the subsystem specific bindings, the
> > consensus there was to have subsystem specific accessors and
> > properties/tables.
> > 
> > I would argue that for everything that ACPI already has (interrupts,
> > registers, gpio, dmaengine, ...) the native method should be used,
> > possibly using _DSD to provide naming for otherwise anonymous references.
> 
> Absolutely. That's precisely what we do in the GPIO patch of this
> series. E.g we use ACPI GpioIo/GpioInt _CRS resources but give name to
> the GPIOs with the help of _DSD.
> 
> For things that don't have correspondence in ACPI but have well defined
> existing DT schema, like PWMs, we should follow that.

I'm rather concerned that while that's expedient for us, that's going to
end up in the creation of Linux-only ACPI tables. If any other OS vendor
decides they need to model this information and doesn't wnat to pick up
Linux _DSD bindings, what happens if they try to get an explicit object
model defined in ACPI for those objects?

Mark.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-02 14:55                     ` Arnd Bergmann
@ 2014-10-03 13:56                       ` Mark Rutland
  2014-10-03 15:02                         ` Arnd Bergmann
  0 siblings, 1 reply; 152+ messages in thread
From: Mark Rutland @ 2014-10-03 13:56 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mika Westerberg, Rafael J. Wysocki, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Thu, Oct 02, 2014 at 03:55:56PM +0100, Arnd Bergmann wrote:
> On Thursday 02 October 2014 17:38:09 Mika Westerberg wrote:
> > On Thu, Oct 02, 2014 at 04:29:03PM +0200, Arnd Bergmann wrote:
> > > Is this a limitation in the way that the AML syntax and compiler works,
> > > or is this a decision you made specifically for the _DSD syntax and that
> > > could still be changed if there is an overwhelming interest?
> > 
> > It is only limitation of the _DSD device property UUID specification and
> > our implementation. It can be changed if needed.
> 
> Ok, I see. I think it would be nice if this could be changed in order
> to avoid having to copy the #xxx-cells and xxx-names properties from
> DT, by providing a more natural syntax.

I'd certainly not like to see #foo-cells in _DSD given it should be
possible with a package to have a package description like the
following:

	Package () {
		Package () { ^ref1, data, data }, 
		Package () { ^ref2, dta, data, data },
	}

Where the #foo-cells is implicit in each instance. That makes variadic
properties possible, and makes it possible to perform validation on each
tuple even in the binary format, which we can't do with a DTB

I'm not so sure on foo-names unless we made names an explicit
requirement from the start (which I wish was the case on the DT side).
Even then we might need other parallel properties anyway (think
clock-indicies).

Mark.


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-03  2:03                 ` Rafael J. Wysocki
  2014-10-03  8:12                   ` Mika Westerberg
@ 2014-10-03 13:58                   ` Mark Rutland
  2014-10-03 14:38                     ` Rafael J. Wysocki
  1 sibling, 1 reply; 152+ messages in thread
From: Mark Rutland @ 2014-10-03 13:58 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, Arnd Bergmann, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Fri, Oct 03, 2014 at 03:03:51AM +0100, Rafael J. Wysocki wrote:
> On Thursday, October 02, 2014 04:36:54 PM Mika Westerberg wrote:
> > On Thu, Oct 02, 2014 at 02:46:30PM +0200, Arnd Bergmann wrote:
> > > On Thursday 02 October 2014 15:15:08 Mika Westerberg wrote:
> 
> [cut]
> 
> > 
> > Putting everything to a single package results this:
> > 
> > 		Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> > 
> > But I think the below looks better:
> 
> I agree.
> 
> > 		Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> > 		Package () { "pwm-names", Package () {"led-red", "led-green"}}
> > 
> > and it is trivial to match with the corresponding DT fragment.
> > 
> > > 	}
> > > 
> > > vs.
> > > 
> > > 	pwm-slave {
> > > 		pwms = <&pwm0 0 10>, <&pwm1 1 20>;
> > > 		pwm-names = "led-red", "led-green";
> > > 	};
> > > 
> > 
> > I don't have strong feelings which way it should be. The current
> > implementation limits references so that you can have only integer
> > arguments, like {ref0, int, int, ref1, int} but if people think it is
> > better to allow strings there as well, it can be changed.
> > 
> > I would like to get comments from Darren and Rafael about this, though.
> 
> In my opinion there needs to be a "canonical" representation of the
> binding that people always can expect to work.  It seems reasonable to
> use the one exactly matching the DT representation for that.

I don't follow. The two forms would share the same high-level accessors,
but the binary representation is already different. Why should we choose
the inferior layout given they are already different binary formats?

Mark.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 09/15] leds: leds-gpio: Make use of device property API
  2014-10-01  2:16   ` [PATCH v3 09/15] leds: leds-gpio: Make use of device property API Rafael J. Wysocki
@ 2014-10-03 14:07     ` Mark Rutland
  2014-10-04  0:18       ` Rafael J. Wysocki
  0 siblings, 1 reply; 152+ messages in thread
From: Mark Rutland @ 2014-10-03 14:07 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely,
	Arnd Bergmann, Aaron Lu, Darren Hart

On Wed, Oct 01, 2014 at 03:16:25AM +0100, Rafael J. Wysocki wrote:
> From: Max Eliaser <max@meliaserlow.dyndns.tv>
> 
> Make use of device property API in this driver so that both OF and ACPI
> based system can use the same driver.
> 
> Signed-off-by: Max Eliaser <max.eliaser@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/leds/leds-gpio.c |   99 +++++++++++++++++++----------------------------
>  1 file changed, 42 insertions(+), 57 deletions(-)
> 
> Index: linux-pm/drivers/leds/leds-gpio.c
> ===================================================================
> --- linux-pm.orig/drivers/leds/leds-gpio.c
> +++ linux-pm/drivers/leds/leds-gpio.c
> @@ -15,13 +15,11 @@
>  #include <linux/gpio.h>
>  #include <linux/gpio/consumer.h>
>  #include <linux/leds.h>
> -#include <linux/of.h>
> -#include <linux/of_platform.h>
> -#include <linux/of_gpio.h>
>  #include <linux/slab.h>
>  #include <linux/workqueue.h>
>  #include <linux/module.h>
>  #include <linux/err.h>
> +#include <linux/property.h>
>  
>  struct gpio_led_data {
>  	struct led_classdev cdev;
> @@ -171,65 +169,59 @@ static inline int sizeof_gpio_leds_priv(
>  		(sizeof(struct gpio_led_data) * num_leds);
>  }
>  
> -/* Code to create from OpenFirmware platform devices */
> -#ifdef CONFIG_OF_GPIO
> -static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
> +static int gpio_leds_create_led(struct device *dev, void *child, void *data)
> +{
> +	struct gpio_leds_priv *priv = data;
> +	struct gpio_led led = {};
> +	const char *state = NULL;
> +
> +	led.gpiod = devm_get_named_gpiod_from_child(dev, child, "gpios", 0);
> +	if (IS_ERR(led.gpiod))
> +		return PTR_ERR(led.gpiod);
> +
> +	device_child_property_read_string(dev, child, "label", &led.name);
> +	device_child_property_read_string(dev, child, "linux,default-trigger",
> +					  &led.default_trigger);
> +
> +	device_child_property_read_string(dev, child, "linux,default_state",
> +					  &state);

Do we really want "linux," properties in ACPI tables?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-03 14:38                     ` Rafael J. Wysocki
@ 2014-10-03 14:35                       ` Mark Rutland
  2014-10-04  0:13                         ` Rafael J. Wysocki
  0 siblings, 1 reply; 152+ messages in thread
From: Mark Rutland @ 2014-10-03 14:35 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, Arnd Bergmann, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Fri, Oct 03, 2014 at 03:38:49PM +0100, Rafael J. Wysocki wrote:
> On Friday, October 03, 2014 02:58:26 PM Mark Rutland wrote:
> > On Fri, Oct 03, 2014 at 03:03:51AM +0100, Rafael J. Wysocki wrote:
> > > On Thursday, October 02, 2014 04:36:54 PM Mika Westerberg wrote:
> > > > On Thu, Oct 02, 2014 at 02:46:30PM +0200, Arnd Bergmann wrote:
> > > > > On Thursday 02 October 2014 15:15:08 Mika Westerberg wrote:
> > > 
> > > [cut]
> > > 
> > > > 
> > > > Putting everything to a single package results this:
> > > > 
> > > > 		Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> > > > 
> > > > But I think the below looks better:
> > > 
> > > I agree.
> > > 
> > > > 		Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> > > > 		Package () { "pwm-names", Package () {"led-red", "led-green"}}
> > > > 
> > > > and it is trivial to match with the corresponding DT fragment.
> > > > 
> > > > > 	}
> > > > > 
> > > > > vs.
> > > > > 
> > > > > 	pwm-slave {
> > > > > 		pwms = <&pwm0 0 10>, <&pwm1 1 20>;
> > > > > 		pwm-names = "led-red", "led-green";
> > > > > 	};
> > > > > 
> > > > 
> > > > I don't have strong feelings which way it should be. The current
> > > > implementation limits references so that you can have only integer
> > > > arguments, like {ref0, int, int, ref1, int} but if people think it is
> > > > better to allow strings there as well, it can be changed.
> > > > 
> > > > I would like to get comments from Darren and Rafael about this, though.
> > > 
> > > In my opinion there needs to be a "canonical" representation of the
> > > binding that people always can expect to work.  It seems reasonable to
> > > use the one exactly matching the DT representation for that.
> > 
> > I don't follow. The two forms would share the same high-level accessors,
> > but the binary representation is already different. Why should we choose
> > the inferior layout given they are already different binary formats?
> 
> Well, why is it inferior in the first place?  It represents the same information
> and I'm not sure why the binary formats matter here?

Because people get the format wrong regardless of documentation. The
format:

Package () {
	Package () { ^ref1, data, data },
	Package () { ^ref2, data },
	Package () { ^ref3, data, data, data },
}

Is superior to the format:

Package () { ^ref1, data, data, ^ref2, data, ^ref3, data, data, data }

Because in the former you have delimiters that can be used to verify
each tuple. Imagine someone misses a data element for one of these
tuples. In the former layout you can detect this easily while in the
latter you cannot.

Additionally, the former can represent variadic phandle/reference + args
formats, which the latter cannot. The DT pinctrl bindings look the way
they do because we can't represent variadic args in DT due to a lack of
delimiters.

You have the ability to embed structure in the binary format. Throwing
this away because it doesn't quite match DT does not to me sounds like
the right tradeoff.

> If I'm to create a _DSD with that information and have a DT template, it
> surely is easier to copy it exactly than to figure out how to resolve it
> to represent something I can actually put in there. 

Sure, you can put something together fast. However, that doesn't make it
necessarily better.

If you want to make reusing DT templates easier, why not just embed a
DTB and be done with it?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-03 13:58                   ` Mark Rutland
@ 2014-10-03 14:38                     ` Rafael J. Wysocki
  2014-10-03 14:35                       ` Mark Rutland
  0 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-03 14:38 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Mika Westerberg, Arnd Bergmann, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Friday, October 03, 2014 02:58:26 PM Mark Rutland wrote:
> On Fri, Oct 03, 2014 at 03:03:51AM +0100, Rafael J. Wysocki wrote:
> > On Thursday, October 02, 2014 04:36:54 PM Mika Westerberg wrote:
> > > On Thu, Oct 02, 2014 at 02:46:30PM +0200, Arnd Bergmann wrote:
> > > > On Thursday 02 October 2014 15:15:08 Mika Westerberg wrote:
> > 
> > [cut]
> > 
> > > 
> > > Putting everything to a single package results this:
> > > 
> > > 		Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> > > 
> > > But I think the below looks better:
> > 
> > I agree.
> > 
> > > 		Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> > > 		Package () { "pwm-names", Package () {"led-red", "led-green"}}
> > > 
> > > and it is trivial to match with the corresponding DT fragment.
> > > 
> > > > 	}
> > > > 
> > > > vs.
> > > > 
> > > > 	pwm-slave {
> > > > 		pwms = <&pwm0 0 10>, <&pwm1 1 20>;
> > > > 		pwm-names = "led-red", "led-green";
> > > > 	};
> > > > 
> > > 
> > > I don't have strong feelings which way it should be. The current
> > > implementation limits references so that you can have only integer
> > > arguments, like {ref0, int, int, ref1, int} but if people think it is
> > > better to allow strings there as well, it can be changed.
> > > 
> > > I would like to get comments from Darren and Rafael about this, though.
> > 
> > In my opinion there needs to be a "canonical" representation of the
> > binding that people always can expect to work.  It seems reasonable to
> > use the one exactly matching the DT representation for that.
> 
> I don't follow. The two forms would share the same high-level accessors,
> but the binary representation is already different. Why should we choose
> the inferior layout given they are already different binary formats?

Well, why is it inferior in the first place?  It represents the same information
and I'm not sure why the binary formats matter here?

If I'm to create a _DSD with that information and have a DT template, it
surely is easier to copy it exactly than to figure out how to resolve it
to represent something I can actually put in there. 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-03 13:56                       ` Mark Rutland
@ 2014-10-03 15:02                         ` Arnd Bergmann
  2014-10-03 23:58                           ` Rafael J. Wysocki
  0 siblings, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-03 15:02 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Mika Westerberg, Rafael J. Wysocki, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Friday 03 October 2014 14:56:10 Mark Rutland wrote:
> On Thu, Oct 02, 2014 at 03:55:56PM +0100, Arnd Bergmann wrote:
> > On Thursday 02 October 2014 17:38:09 Mika Westerberg wrote:
> > > On Thu, Oct 02, 2014 at 04:29:03PM +0200, Arnd Bergmann wrote:
> > > > Is this a limitation in the way that the AML syntax and compiler works,
> > > > or is this a decision you made specifically for the _DSD syntax and that
> > > > could still be changed if there is an overwhelming interest?
> > > 
> > > It is only limitation of the _DSD device property UUID specification and
> > > our implementation. It can be changed if needed.
> > 
> > Ok, I see. I think it would be nice if this could be changed in order
> > to avoid having to copy the #xxx-cells and xxx-names properties from
> > DT, by providing a more natural syntax.
> 
> I'd certainly not like to see #foo-cells in _DSD given it should be
> possible with a package to have a package description like the
> following:
> 
>         Package () {
>                 Package () { ^ref1, data, data }, 
>                 Package () { ^ref2, dta, data, data },
>         }
> 
> Where the #foo-cells is implicit in each instance. That makes variadic
> properties possible, and makes it possible to perform validation on each
> tuple even in the binary format, which we can't do with a DTB
> 
> I'm not so sure on foo-names unless we made names an explicit
> requirement from the start (which I wish was the case on the DT side).
> Even then we might need other parallel properties anyway (think
> clock-indicies).

I suppose it might even be possible to define the ACPI references to
have an optional string, so you can do

         Package () {
                 Package () { ^ref1, data, data }, 
                 Package () { "foo", ^ref2, data, data, data },
         }

The parser should be able to interpret both anonymous and named
references just by looking at the type of the first member.
You might not want to allow mixing them in a single property, but
that is more a style question than a technical requirement.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property
  2014-10-03 13:43     ` Mark Rutland
@ 2014-10-03 17:59       ` Dmitry Torokhov
  2014-10-04  0:02           ` Rafael J. Wysocki
  0 siblings, 1 reply; 152+ messages in thread
From: Dmitry Torokhov @ 2014-10-03 17:59 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Rafael J. Wysocki, grant.likely, linux-kernel, Mika Westerberg,
	linux-acpi, devicetree, Greg Kroah-Hartman, Linus Walleij,
	Alexandre Courbot, Bryan Wu, Lee Jones, Arnd Bergmann, Aaron Lu,
	Darren Hart

On Fri, Oct 03, 2014 at 02:43:03PM +0100, Mark Rutland wrote:
> Hi Rafael,
> 
> On Wed, Oct 01, 2014 at 03:10:40AM +0100, Rafael J. Wysocki wrote:
> > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > 
> > We have lots of existing Device Tree enabled drivers and allocating
> > separate _HID for each is not feasible. Instead we allocate special
> > _HID "PRP0001" that means that the match should be done using Device
> > Tree compatible property using driver's .of_match_table instead.
> 
> That's hopefully not the precise meaning of "PRP0001" unless we're
> attempting no semblance of OS independence here?
> 
> I'm still of the opinion that marrying ACPI to existing (and often
> ill-defined) DT bindings is a bad idea. While it's expedient, I believe
> this is going to be a long-term maintenance nightmare.
> 
> I'm very concerned with the prospect of model mismatch between the two
> (e.g. DT clocks properties where ACPI has traditionally been in charge
> of clock management). I've not seen any high-level guidelines w.r.t.
> what should live in _DSD properties and what should not (at least not in
> the ACPI spec itself). There are almost certainly properties that only
> make sense if !ACPI, and likely there will be some that only make sense
> if ACPI.
> 
> So I think that in its current level of standardisation, _DSD only makes
> sense for simple device properties, and not relationships between
> devices, except where ACPI already has some kind of a model (which
> currently seems to cover interrupts and GPIOs). I'd also hope that we
> could expose a 'clean' subset of DT bidnings (i.e. those which aren't
> known to be kept around only for compatibility with legacy DTBs).
> 
> I do not believe it makes sense to share such a low-level interface.
> Given the aforementioned model differences, and the fact that we don't
> need to support _every_ device tree binding, I don't see why this can't
> be handled with separate probe paths in the drivers we care about (as we
> already do for DT vs platform data).

Because as a driver writer I do not want to implement N+1 ways of
getting device configuration. I want one API that works independently of
the underlying platform. The DT vs platform data is bad enough already.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-03 15:02                         ` Arnd Bergmann
@ 2014-10-03 23:58                           ` Rafael J. Wysocki
  2014-10-04 10:56                             ` Arnd Bergmann
  0 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-03 23:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mark Rutland, Mika Westerberg, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Friday, October 03, 2014 05:02:13 PM Arnd Bergmann wrote:
> On Friday 03 October 2014 14:56:10 Mark Rutland wrote:
> > On Thu, Oct 02, 2014 at 03:55:56PM +0100, Arnd Bergmann wrote:
> > > On Thursday 02 October 2014 17:38:09 Mika Westerberg wrote:
> > > > On Thu, Oct 02, 2014 at 04:29:03PM +0200, Arnd Bergmann wrote:
> > > > > Is this a limitation in the way that the AML syntax and compiler works,
> > > > > or is this a decision you made specifically for the _DSD syntax and that
> > > > > could still be changed if there is an overwhelming interest?
> > > > 
> > > > It is only limitation of the _DSD device property UUID specification and
> > > > our implementation. It can be changed if needed.
> > > 
> > > Ok, I see. I think it would be nice if this could be changed in order
> > > to avoid having to copy the #xxx-cells and xxx-names properties from
> > > DT, by providing a more natural syntax.
> > 
> > I'd certainly not like to see #foo-cells in _DSD given it should be
> > possible with a package to have a package description like the
> > following:
> > 
> >         Package () {
> >                 Package () { ^ref1, data, data }, 
> >                 Package () { ^ref2, dta, data, data },
> >         }
> > 
> > Where the #foo-cells is implicit in each instance. That makes variadic
> > properties possible, and makes it possible to perform validation on each
> > tuple even in the binary format, which we can't do with a DTB
> > 
> > I'm not so sure on foo-names unless we made names an explicit
> > requirement from the start (which I wish was the case on the DT side).
> > Even then we might need other parallel properties anyway (think
> > clock-indicies).
> 
> I suppose it might even be possible to define the ACPI references to
> have an optional string, so you can do
> 
>          Package () {
>                  Package () { ^ref1, data, data }, 
>                  Package () { "foo", ^ref2, data, data, data },
>          }
> 
> The parser should be able to interpret both anonymous and named
> references just by looking at the type of the first member.
> You might not want to allow mixing them in a single property, but
> that is more a style question than a technical requirement.

Yes, that only is a matter of implementing the parser.

For now, it simply is easier for us to parse the

	Package () { ^ref1, data, data }

format only, because we have functions for parsing lists of strings,
lists of numbers etc. for other purposes anyway and we can re-use them
for the names etc.  I don't see a reason why the parser cannot be extended in
the future to handle "all in one" packages, but not necessarily at the moment.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property
  2014-10-03 17:59       ` Dmitry Torokhov
@ 2014-10-04  0:02           ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-04  0:02 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Mark Rutland, grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mika Westerberg,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Bryan Wu, Lee Jones,
	Arnd Bergmann, Aaron Lu, Darren Hart

On Friday, October 03, 2014 10:59:10 AM Dmitry Torokhov wrote:
> On Fri, Oct 03, 2014 at 02:43:03PM +0100, Mark Rutland wrote:
> > Hi Rafael,
> > 
> > On Wed, Oct 01, 2014 at 03:10:40AM +0100, Rafael J. Wysocki wrote:
> > > From: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> > > 
> > > We have lots of existing Device Tree enabled drivers and allocating
> > > separate _HID for each is not feasible. Instead we allocate special
> > > _HID "PRP0001" that means that the match should be done using Device
> > > Tree compatible property using driver's .of_match_table instead.
> > 
> > That's hopefully not the precise meaning of "PRP0001" unless we're
> > attempting no semblance of OS independence here?
> > 
> > I'm still of the opinion that marrying ACPI to existing (and often
> > ill-defined) DT bindings is a bad idea. While it's expedient, I believe
> > this is going to be a long-term maintenance nightmare.
> > 
> > I'm very concerned with the prospect of model mismatch between the two
> > (e.g. DT clocks properties where ACPI has traditionally been in charge
> > of clock management). I've not seen any high-level guidelines w.r.t.
> > what should live in _DSD properties and what should not (at least not in
> > the ACPI spec itself). There are almost certainly properties that only
> > make sense if !ACPI, and likely there will be some that only make sense
> > if ACPI.
> > 
> > So I think that in its current level of standardisation, _DSD only makes
> > sense for simple device properties, and not relationships between
> > devices, except where ACPI already has some kind of a model (which
> > currently seems to cover interrupts and GPIOs). I'd also hope that we
> > could expose a 'clean' subset of DT bidnings (i.e. those which aren't
> > known to be kept around only for compatibility with legacy DTBs).
> > 
> > I do not believe it makes sense to share such a low-level interface.
> > Given the aforementioned model differences, and the fact that we don't
> > need to support _every_ device tree binding, I don't see why this can't
> > be handled with separate probe paths in the drivers we care about (as we
> > already do for DT vs platform data).
> 
> Because as a driver writer I do not want to implement N+1 ways of
> getting device configuration. I want one API that works independently of
> the underlying platform. The DT vs platform data is bad enough already.

Well stated, thanks!

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property
@ 2014-10-04  0:02           ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-04  0:02 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Mark Rutland, grant.likely, linux-kernel, Mika Westerberg,
	linux-acpi, devicetree, Greg Kroah-Hartman, Linus Walleij,
	Alexandre Courbot, Bryan Wu, Lee Jones, Arnd Bergmann, Aaron Lu,
	Darren Hart

On Friday, October 03, 2014 10:59:10 AM Dmitry Torokhov wrote:
> On Fri, Oct 03, 2014 at 02:43:03PM +0100, Mark Rutland wrote:
> > Hi Rafael,
> > 
> > On Wed, Oct 01, 2014 at 03:10:40AM +0100, Rafael J. Wysocki wrote:
> > > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > 
> > > We have lots of existing Device Tree enabled drivers and allocating
> > > separate _HID for each is not feasible. Instead we allocate special
> > > _HID "PRP0001" that means that the match should be done using Device
> > > Tree compatible property using driver's .of_match_table instead.
> > 
> > That's hopefully not the precise meaning of "PRP0001" unless we're
> > attempting no semblance of OS independence here?
> > 
> > I'm still of the opinion that marrying ACPI to existing (and often
> > ill-defined) DT bindings is a bad idea. While it's expedient, I believe
> > this is going to be a long-term maintenance nightmare.
> > 
> > I'm very concerned with the prospect of model mismatch between the two
> > (e.g. DT clocks properties where ACPI has traditionally been in charge
> > of clock management). I've not seen any high-level guidelines w.r.t.
> > what should live in _DSD properties and what should not (at least not in
> > the ACPI spec itself). There are almost certainly properties that only
> > make sense if !ACPI, and likely there will be some that only make sense
> > if ACPI.
> > 
> > So I think that in its current level of standardisation, _DSD only makes
> > sense for simple device properties, and not relationships between
> > devices, except where ACPI already has some kind of a model (which
> > currently seems to cover interrupts and GPIOs). I'd also hope that we
> > could expose a 'clean' subset of DT bidnings (i.e. those which aren't
> > known to be kept around only for compatibility with legacy DTBs).
> > 
> > I do not believe it makes sense to share such a low-level interface.
> > Given the aforementioned model differences, and the fact that we don't
> > need to support _every_ device tree binding, I don't see why this can't
> > be handled with separate probe paths in the drivers we care about (as we
> > already do for DT vs platform data).
> 
> Because as a driver writer I do not want to implement N+1 ways of
> getting device configuration. I want one API that works independently of
> the underlying platform. The DT vs platform data is bad enough already.

Well stated, thanks!

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-03 14:35                       ` Mark Rutland
@ 2014-10-04  0:13                         ` Rafael J. Wysocki
       [not found]                           ` <6568619.UkU5qISONv-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
  0 siblings, 1 reply; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-04  0:13 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Mika Westerberg, Arnd Bergmann, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Friday, October 03, 2014 03:35:47 PM Mark Rutland wrote:
> On Fri, Oct 03, 2014 at 03:38:49PM +0100, Rafael J. Wysocki wrote:
> > On Friday, October 03, 2014 02:58:26 PM Mark Rutland wrote:
> > > On Fri, Oct 03, 2014 at 03:03:51AM +0100, Rafael J. Wysocki wrote:
> > > > On Thursday, October 02, 2014 04:36:54 PM Mika Westerberg wrote:
> > > > > On Thu, Oct 02, 2014 at 02:46:30PM +0200, Arnd Bergmann wrote:
> > > > > > On Thursday 02 October 2014 15:15:08 Mika Westerberg wrote:
> > > > 
> > > > [cut]
> > > > 
> > > > > 
> > > > > Putting everything to a single package results this:
> > > > > 
> > > > > 		Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> > > > > 
> > > > > But I think the below looks better:
> > > > 
> > > > I agree.
> > > > 
> > > > > 		Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> > > > > 		Package () { "pwm-names", Package () {"led-red", "led-green"}}
> > > > > 
> > > > > and it is trivial to match with the corresponding DT fragment.
> > > > > 
> > > > > > 	}
> > > > > > 
> > > > > > vs.
> > > > > > 
> > > > > > 	pwm-slave {
> > > > > > 		pwms = <&pwm0 0 10>, <&pwm1 1 20>;
> > > > > > 		pwm-names = "led-red", "led-green";
> > > > > > 	};
> > > > > > 
> > > > > 
> > > > > I don't have strong feelings which way it should be. The current
> > > > > implementation limits references so that you can have only integer
> > > > > arguments, like {ref0, int, int, ref1, int} but if people think it is
> > > > > better to allow strings there as well, it can be changed.
> > > > > 
> > > > > I would like to get comments from Darren and Rafael about this, though.
> > > > 
> > > > In my opinion there needs to be a "canonical" representation of the
> > > > binding that people always can expect to work.  It seems reasonable to
> > > > use the one exactly matching the DT representation for that.
> > > 
> > > I don't follow. The two forms would share the same high-level accessors,
> > > but the binary representation is already different. Why should we choose
> > > the inferior layout given they are already different binary formats?
> > 
> > Well, why is it inferior in the first place?  It represents the same information
> > and I'm not sure why the binary formats matter here?
> 
> Because people get the format wrong regardless of documentation. The
> format:
> 
> Package () {
> 	Package () { ^ref1, data, data },
> 	Package () { ^ref2, data },
> 	Package () { ^ref3, data, data, data },
> }
> 
> Is superior to the format:
> 
> Package () { ^ref1, data, data, ^ref2, data, ^ref3, data, data, data }
> 
> Because in the former you have delimiters that can be used to verify
> each tuple. Imagine someone misses a data element for one of these
> tuples. In the former layout you can detect this easily while in the
> latter you cannot.

I agree with this particular thing (although other people seem to have
problems with too many package nesting levels) but I'm not sure what that
has to do with the example given above (let me quote again):

> Putting everything to a single package results this:
> 
> 	Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> 
> But I think the below looks better:
> 
> 	Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> 	Package () { "pwm-names", Package () {"led-red", "led-green"}}
> 
> and it is trivial to match with the corresponding DT fragment.

that I was commenting.  Both cases contains the

	Package () { ^ref1, data, data, ^ref2, data, ^ref3, data, data, data }

format that you don't like, don't they?

> Additionally, the former can represent variadic phandle/reference + args
> formats, which the latter cannot. The DT pinctrl bindings look the way
> they do because we can't represent variadic args in DT due to a lack of
> delimiters.
> 
> You have the ability to embed structure in the binary format. Throwing
> this away because it doesn't quite match DT does not to me sounds like
> the right tradeoff.
> 
> > If I'm to create a _DSD with that information and have a DT template, it
> > surely is easier to copy it exactly than to figure out how to resolve it
> > to represent something I can actually put in there. 
> 
> Sure, you can put something together fast. However, that doesn't make it
> necessarily better.
> 
> If you want to make reusing DT templates easier, why not just embed a
> DTB and be done with it?

Because that sucks?

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-03 13:48             ` Mark Rutland
@ 2014-10-04  0:16               ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-04  0:16 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Mika Westerberg, Arnd Bergmann, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Friday, October 03, 2014 02:48:49 PM Mark Rutland wrote:
> On Thu, Oct 02, 2014 at 01:15:08PM +0100, Mika Westerberg wrote:
> > On Thu, Oct 02, 2014 at 01:51:24PM +0200, Arnd Bergmann wrote:
> > > On Thursday 02 October 2014 13:41:23 Mika Westerberg wrote:
> > > > On Wed, Oct 01, 2014 at 09:59:14AM +0200, Arnd Bergmann wrote:
> > > > > On Wednesday 01 October 2014 04:11:20 Rafael J. Wysocki wrote:
> > > > > > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > > 
> > > > > > +The referenced ACPI device is returned in args->adev if found.
> > > > > > +
> > > > > > +In addition to simple object references it is also possible to have object
> > > > > > +references with arguments. These are represented in ASL as follows:
> > > > > > +
> > > > > > +	Device (\_SB.PCI0.PWM)
> > > > > > +	{
> > > > > > +		Name (_DSD, Package () {
> > > > > > +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > > > > > +			Package () {
> > > > > > +				Package () {"#pwm-cells", 2}
> > > > > > +			}
> > > > > > +		})
> > > > > > +	}
> > > > > > +
> > > > > 
> > > > > Similarly, the "#foo-cells" syntax is an artifact of the limitations of the
> > > > > DT syntax, and I'd assume there would be a better way to encode this
> > > > > in ACPI. Also, a "cell" in Open Firmware is defined as a big-endian
> > > > > 32-bit value, which doesn't directly correspond to something in ACPI,
> > > > > and the '#' character is an artifact of the use of the Forth language
> > > > > in Open Firmware, which you also don't have here.
> > > > 
> > > > Same here, we tried to make it follow closely the DT description. It is
> > > > probably not the best/optimal encoding for ACPI but it is documented
> > > > well in Documentation/devicetree/bindings so why not use it.
> > > > 
> > > > The summary email from Darren at KS also mentions that for the existing
> > > > drivers, the existing schemas should be common for both implementations [1].
> > > > 
> > > > For new bindings we probably should look out if they can be better
> > > > represented using ACPI types.
> > > > 
> > > > [1] http://lwn.net/Articles/609373/
> > > 
> > > I thought when we had discussed the subsystem specific bindings, the
> > > consensus there was to have subsystem specific accessors and
> > > properties/tables.
> > > 
> > > I would argue that for everything that ACPI already has (interrupts,
> > > registers, gpio, dmaengine, ...) the native method should be used,
> > > possibly using _DSD to provide naming for otherwise anonymous references.
> > 
> > Absolutely. That's precisely what we do in the GPIO patch of this
> > series. E.g we use ACPI GpioIo/GpioInt _CRS resources but give name to
> > the GPIOs with the help of _DSD.
> > 
> > For things that don't have correspondence in ACPI but have well defined
> > existing DT schema, like PWMs, we should follow that.
> 
> I'm rather concerned that while that's expedient for us, that's going to
> end up in the creation of Linux-only ACPI tables. If any other OS vendor
> decides they need to model this information and doesn't wnat to pick up
> Linux _DSD bindings, what happens if they try to get an explicit object
> model defined in ACPI for those objects?

That depends on whether or not systems with that model show up in the market.
If they do, we will do our best to support them.

We do that for Apple already as much as we practically can.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 09/15] leds: leds-gpio: Make use of device property API
  2014-10-03 14:07     ` Mark Rutland
@ 2014-10-04  0:18       ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-04  0:18 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-kernel, Mika Westerberg, linux-acpi, devicetree,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely,
	Arnd Bergmann, Aaron Lu, Darren Hart

On Friday, October 03, 2014 03:07:28 PM Mark Rutland wrote:
> On Wed, Oct 01, 2014 at 03:16:25AM +0100, Rafael J. Wysocki wrote:
> > From: Max Eliaser <max@meliaserlow.dyndns.tv>
> > 
> > Make use of device property API in this driver so that both OF and ACPI
> > based system can use the same driver.
> > 
> > Signed-off-by: Max Eliaser <max.eliaser@intel.com>
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/leds/leds-gpio.c |   99 +++++++++++++++++++----------------------------
> >  1 file changed, 42 insertions(+), 57 deletions(-)
> > 
> > Index: linux-pm/drivers/leds/leds-gpio.c
> > ===================================================================
> > --- linux-pm.orig/drivers/leds/leds-gpio.c
> > +++ linux-pm/drivers/leds/leds-gpio.c
> > @@ -15,13 +15,11 @@
> >  #include <linux/gpio.h>
> >  #include <linux/gpio/consumer.h>
> >  #include <linux/leds.h>
> > -#include <linux/of.h>
> > -#include <linux/of_platform.h>
> > -#include <linux/of_gpio.h>
> >  #include <linux/slab.h>
> >  #include <linux/workqueue.h>
> >  #include <linux/module.h>
> >  #include <linux/err.h>
> > +#include <linux/property.h>
> >  
> >  struct gpio_led_data {
> >  	struct led_classdev cdev;
> > @@ -171,65 +169,59 @@ static inline int sizeof_gpio_leds_priv(
> >  		(sizeof(struct gpio_led_data) * num_leds);
> >  }
> >  
> > -/* Code to create from OpenFirmware platform devices */
> > -#ifdef CONFIG_OF_GPIO
> > -static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
> > +static int gpio_leds_create_led(struct device *dev, void *child, void *data)
> > +{
> > +	struct gpio_leds_priv *priv = data;
> > +	struct gpio_led led = {};
> > +	const char *state = NULL;
> > +
> > +	led.gpiod = devm_get_named_gpiod_from_child(dev, child, "gpios", 0);
> > +	if (IS_ERR(led.gpiod))
> > +		return PTR_ERR(led.gpiod);
> > +
> > +	device_child_property_read_string(dev, child, "label", &led.name);
> > +	device_child_property_read_string(dev, child, "linux,default-trigger",
> > +					  &led.default_trigger);
> > +
> > +	device_child_property_read_string(dev, child, "linux,default_state",
> > +					  &state);
> 
> Do we really want "linux," properties in ACPI tables?

Yes, we do.

"linux" here need not mean this is Linux-specific.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-03 23:58                           ` Rafael J. Wysocki
@ 2014-10-04 10:56                             ` Arnd Bergmann
  2014-10-05 21:40                                 ` Rafael J. Wysocki
  0 siblings, 1 reply; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-04 10:56 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mark Rutland, Mika Westerberg, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Saturday 04 October 2014 01:58:30 Rafael J. Wysocki wrote:
> On Friday, October 03, 2014 05:02:13 PM Arnd Bergmann wrote:
> > On Friday 03 October 2014 14:56:10 Mark Rutland wrote:
> > > On Thu, Oct 02, 2014 at 03:55:56PM +0100, Arnd Bergmann wrote:
> > > I'd certainly not like to see #foo-cells in _DSD given it should be
> > > possible with a package to have a package description like the
> > > following:
> > > 
> > >         Package () {
> > >                 Package () { ^ref1, data, data }, 
> > >                 Package () { ^ref2, dta, data, data },
> > >         }
> > > 
> > > Where the #foo-cells is implicit in each instance. That makes variadic
> > > properties possible, and makes it possible to perform validation on each
> > > tuple even in the binary format, which we can't do with a DTB
> > > 
> > > I'm not so sure on foo-names unless we made names an explicit
> > > requirement from the start (which I wish was the case on the DT side).
> > > Even then we might need other parallel properties anyway (think
> > > clock-indicies).
> > 
> > I suppose it might even be possible to define the ACPI references to
> > have an optional string, so you can do
> > 
> >          Package () {
> >                  Package () { ^ref1, data, data }, 
> >                  Package () { "foo", ^ref2, data, data, data },
> >          }
> > 
> > The parser should be able to interpret both anonymous and named
> > references just by looking at the type of the first member.
> > You might not want to allow mixing them in a single property, but
> > that is more a style question than a technical requirement.
> 
> Yes, that only is a matter of implementing the parser.
> 
> For now, it simply is easier for us to parse the
> 
>         Package () { ^ref1, data, data }
> 
> format only, because we have functions for parsing lists of strings,
> lists of numbers etc. for other purposes anyway and we can re-use them
> for the names etc.  I don't see a reason why the parser cannot be extended in
> the future to handle "all in one" packages, but not necessarily at the moment.

It only really makes sense to do it that way though if it's used
consistently, and all references do naming like this rather than
the foo-names method.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-04  0:13                         ` Rafael J. Wysocki
@ 2014-10-04 10:59                               ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-04 10:59 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mark Rutland, Mika Westerberg,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, grant.likely-QSEj5FYQhm4dnm+yROfE0A, Aaron Lu,
	Darren Hart

On Saturday 04 October 2014 02:13:23 Rafael J. Wysocki wrote:
> > Because people get the format wrong regardless of documentation. The
> > format:
> > 
> > Package () {
> >       Package () { ^ref1, data, data },
> >       Package () { ^ref2, data },
> >       Package () { ^ref3, data, data, data },
> > }
> > 
> > Is superior to the format:
> > 
> > Package () { ^ref1, data, data, ^ref2, data, ^ref3, data, data, data }
> > 
> > Because in the former you have delimiters that can be used to verify
> > each tuple. Imagine someone misses a data element for one of these
> > tuples. In the former layout you can detect this easily while in the
> > latter you cannot.
> 
> I agree with this particular thing (although other people seem to have
> problems with too many package nesting levels) but I'm not sure what that
> has to do with the example given above (let me quote again):
> 
> > Putting everything to a single package results this:
> > 
> >       Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> > 
> > But I think the below looks better:
> > 
> >       Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> >       Package () { "pwm-names", Package () {"led-red", "led-green"}}
> > 
> > and it is trivial to match with the corresponding DT fragment.
> 
> that I was commenting.  Both cases contains the
> 
>         Package () { ^ref1, data, data, ^ref2, data, ^ref3, data, data, data }
> 
> format that you don't like, don't they?
> 

There are two independent issues:

a) avoiding the need for "pwm-names" by embedding the name in the
   "pwms" property

b) avoiding the need for "#pwm-cells" by having explicit separators between
   entries in a "pwms" property.

It would be possible to do one but not the other.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
@ 2014-10-04 10:59                               ` Arnd Bergmann
  0 siblings, 0 replies; 152+ messages in thread
From: Arnd Bergmann @ 2014-10-04 10:59 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mark Rutland, Mika Westerberg, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Saturday 04 October 2014 02:13:23 Rafael J. Wysocki wrote:
> > Because people get the format wrong regardless of documentation. The
> > format:
> > 
> > Package () {
> >       Package () { ^ref1, data, data },
> >       Package () { ^ref2, data },
> >       Package () { ^ref3, data, data, data },
> > }
> > 
> > Is superior to the format:
> > 
> > Package () { ^ref1, data, data, ^ref2, data, ^ref3, data, data, data }
> > 
> > Because in the former you have delimiters that can be used to verify
> > each tuple. Imagine someone misses a data element for one of these
> > tuples. In the former layout you can detect this easily while in the
> > latter you cannot.
> 
> I agree with this particular thing (although other people seem to have
> problems with too many package nesting levels) but I'm not sure what that
> has to do with the example given above (let me quote again):
> 
> > Putting everything to a single package results this:
> > 
> >       Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> > 
> > But I think the below looks better:
> > 
> >       Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> >       Package () { "pwm-names", Package () {"led-red", "led-green"}}
> > 
> > and it is trivial to match with the corresponding DT fragment.
> 
> that I was commenting.  Both cases contains the
> 
>         Package () { ^ref1, data, data, ^ref2, data, ^ref3, data, data, data }
> 
> format that you don't like, don't they?
> 

There are two independent issues:

a) avoiding the need for "pwm-names" by embedding the name in the
   "pwms" property

b) avoiding the need for "#pwm-cells" by having explicit separators between
   entries in a "pwms" property.

It would be possible to do one but not the other.

	Arnd

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 05/15] gpio / ACPI: Add support for _DSD device properties
  2014-10-01  8:03         ` Arnd Bergmann
  (?)
@ 2014-10-05 10:36         ` Alexandre Courbot
  2014-10-05 21:20           ` Rafael J. Wysocki
  -1 siblings, 1 reply; 152+ messages in thread
From: Alexandre Courbot @ 2014-10-05 10:36 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, Mika Westerberg,
	ACPI Devel Maling List, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Grant Likely, Aaron Lu, Darren Hart

On Wed, Oct 1, 2014 at 5:03 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 01 October 2014 04:12:41 Rafael J. Wysocki wrote:
>> +       static const char * const suffixes[] = { "gpios", "gpio" };
>> +       struct acpi_device *adev = ACPI_COMPANION(dev);
>>         struct acpi_gpio_info info;
>>         struct gpio_desc *desc;
>> +       char propname[32];
>> +       int i;
>>
>> -       desc = acpi_get_gpiod_by_index(dev, idx, &info);
>> -       if (IS_ERR(desc))
>> -               return desc;
>> +       /* Try first from _DSD */
>> +       for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
>> +               if (con_id && strcmp(con_id, "gpios")) {
>> +                       snprintf(propname, sizeof(propname), "%s-%s",
>> +                                con_id, suffixes[i]);
>> +               } else {
>> +                       snprintf(propname, sizeof(propname), "%s",
>> +                                suffixes[i]);
>> +               }
>
> The general interface seems fine, but I'd be happier if you didn't
> try to support all four of the possible syntaxes we have in DT.
> It would be much better to have only "gpios" and not "gpio", and
> the "foo-gpios" syntax should be replaced with whatever method you
> use to name other subsystem specific links. For most subsystems
> we now use something like "gpio-names", but unfortunately the GPIO
> binding goes back to the time before we had come to that agreement.
> The same applies to regulators.

Wouldn't restricting the naming scheme cause problems for ACPI drivers
that want to reuse existing DT bindings? Since DT bindings are set in
stone, this means we would have to use different properties for DT and
ACPI.

I agree that there are too much ways to define GPIOs, but I'm afraid
we will have to carry them over for the sake of consistency.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 05/15] gpio / ACPI: Add support for _DSD device properties
  2014-10-05 10:36         ` Alexandre Courbot
@ 2014-10-05 21:20           ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-05 21:20 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Arnd Bergmann, Linux Kernel Mailing List, Mika Westerberg,
	ACPI Devel Maling List, devicetree, Greg Kroah-Hartman,
	Linus Walleij, Dmitry Torokhov, Bryan Wu, Lee Jones,
	Grant Likely, Aaron Lu, Darren Hart

On Sunday, October 05, 2014 07:36:04 PM Alexandre Courbot wrote:
> On Wed, Oct 1, 2014 at 5:03 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Wednesday 01 October 2014 04:12:41 Rafael J. Wysocki wrote:
> >> +       static const char * const suffixes[] = { "gpios", "gpio" };
> >> +       struct acpi_device *adev = ACPI_COMPANION(dev);
> >>         struct acpi_gpio_info info;
> >>         struct gpio_desc *desc;
> >> +       char propname[32];
> >> +       int i;
> >>
> >> -       desc = acpi_get_gpiod_by_index(dev, idx, &info);
> >> -       if (IS_ERR(desc))
> >> -               return desc;
> >> +       /* Try first from _DSD */
> >> +       for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
> >> +               if (con_id && strcmp(con_id, "gpios")) {
> >> +                       snprintf(propname, sizeof(propname), "%s-%s",
> >> +                                con_id, suffixes[i]);
> >> +               } else {
> >> +                       snprintf(propname, sizeof(propname), "%s",
> >> +                                suffixes[i]);
> >> +               }
> >
> > The general interface seems fine, but I'd be happier if you didn't
> > try to support all four of the possible syntaxes we have in DT.
> > It would be much better to have only "gpios" and not "gpio", and
> > the "foo-gpios" syntax should be replaced with whatever method you
> > use to name other subsystem specific links. For most subsystems
> > we now use something like "gpio-names", but unfortunately the GPIO
> > binding goes back to the time before we had come to that agreement.
> > The same applies to regulators.
> 
> Wouldn't restricting the naming scheme cause problems for ACPI drivers
> that want to reuse existing DT bindings? Since DT bindings are set in
> stone, this means we would have to use different properties for DT and
> ACPI.

Which we would like to avoid.

Generally speaking, there are drivers (or upper-layer code) that will use
separate code paths for ACPI and DTs anyway (like the PCI root bridge
code) and in those cases having ACPI-specific properties or device data
in general is not really a problem.

However, for pieces of code that we'd like to use the unified properties
API going forward, we very much need the properties to be the same for
DTs and ACPI.

> I agree that there are too much ways to define GPIOs, but I'm afraid
> we will have to carry them over for the sake of consistency.

Well, I suppose so.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-04 10:56                             ` Arnd Bergmann
@ 2014-10-05 21:40                                 ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-05 21:40 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mark Rutland, Mika Westerberg,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, grant.likely-QSEj5FYQhm4dnm+yROfE0A, Aaron Lu,
	Darren Hart

On Saturday, October 04, 2014 12:56:21 PM Arnd Bergmann wrote:
> On Saturday 04 October 2014 01:58:30 Rafael J. Wysocki wrote:
> > On Friday, October 03, 2014 05:02:13 PM Arnd Bergmann wrote:
> > > On Friday 03 October 2014 14:56:10 Mark Rutland wrote:
> > > > On Thu, Oct 02, 2014 at 03:55:56PM +0100, Arnd Bergmann wrote:
> > > > I'd certainly not like to see #foo-cells in _DSD given it should be
> > > > possible with a package to have a package description like the
> > > > following:
> > > > 
> > > >         Package () {
> > > >                 Package () { ^ref1, data, data }, 
> > > >                 Package () { ^ref2, dta, data, data },
> > > >         }
> > > > 
> > > > Where the #foo-cells is implicit in each instance. That makes variadic
> > > > properties possible, and makes it possible to perform validation on each
> > > > tuple even in the binary format, which we can't do with a DTB
> > > > 
> > > > I'm not so sure on foo-names unless we made names an explicit
> > > > requirement from the start (which I wish was the case on the DT side).
> > > > Even then we might need other parallel properties anyway (think
> > > > clock-indicies).
> > > 
> > > I suppose it might even be possible to define the ACPI references to
> > > have an optional string, so you can do
> > > 
> > >          Package () {
> > >                  Package () { ^ref1, data, data }, 
> > >                  Package () { "foo", ^ref2, data, data, data },
> > >          }
> > > 
> > > The parser should be able to interpret both anonymous and named
> > > references just by looking at the type of the first member.
> > > You might not want to allow mixing them in a single property, but
> > > that is more a style question than a technical requirement.
> > 
> > Yes, that only is a matter of implementing the parser.
> > 
> > For now, it simply is easier for us to parse the
> > 
> >         Package () { ^ref1, data, data }
> > 
> > format only, because we have functions for parsing lists of strings,
> > lists of numbers etc. for other purposes anyway and we can re-use them
> > for the names etc.  I don't see a reason why the parser cannot be extended in
> > the future to handle "all in one" packages, but not necessarily at the moment.
> 
> It only really makes sense to do it that way though if it's used
> consistently, and all references do naming like this rather than
> the foo-names method.

This almost sounds like "this will only makes sense if it's beautiful"
which I'm not sure I agree with. :-)

As long as it is clear what information is represented, I have no problems
with having multiple ways of expressing it and using them however people
like.  In fact, we don't even really know at this point which way will turn
out to be most convenient eventually.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
@ 2014-10-05 21:40                                 ` Rafael J. Wysocki
  0 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-05 21:40 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mark Rutland, Mika Westerberg, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Saturday, October 04, 2014 12:56:21 PM Arnd Bergmann wrote:
> On Saturday 04 October 2014 01:58:30 Rafael J. Wysocki wrote:
> > On Friday, October 03, 2014 05:02:13 PM Arnd Bergmann wrote:
> > > On Friday 03 October 2014 14:56:10 Mark Rutland wrote:
> > > > On Thu, Oct 02, 2014 at 03:55:56PM +0100, Arnd Bergmann wrote:
> > > > I'd certainly not like to see #foo-cells in _DSD given it should be
> > > > possible with a package to have a package description like the
> > > > following:
> > > > 
> > > >         Package () {
> > > >                 Package () { ^ref1, data, data }, 
> > > >                 Package () { ^ref2, dta, data, data },
> > > >         }
> > > > 
> > > > Where the #foo-cells is implicit in each instance. That makes variadic
> > > > properties possible, and makes it possible to perform validation on each
> > > > tuple even in the binary format, which we can't do with a DTB
> > > > 
> > > > I'm not so sure on foo-names unless we made names an explicit
> > > > requirement from the start (which I wish was the case on the DT side).
> > > > Even then we might need other parallel properties anyway (think
> > > > clock-indicies).
> > > 
> > > I suppose it might even be possible to define the ACPI references to
> > > have an optional string, so you can do
> > > 
> > >          Package () {
> > >                  Package () { ^ref1, data, data }, 
> > >                  Package () { "foo", ^ref2, data, data, data },
> > >          }
> > > 
> > > The parser should be able to interpret both anonymous and named
> > > references just by looking at the type of the first member.
> > > You might not want to allow mixing them in a single property, but
> > > that is more a style question than a technical requirement.
> > 
> > Yes, that only is a matter of implementing the parser.
> > 
> > For now, it simply is easier for us to parse the
> > 
> >         Package () { ^ref1, data, data }
> > 
> > format only, because we have functions for parsing lists of strings,
> > lists of numbers etc. for other purposes anyway and we can re-use them
> > for the names etc.  I don't see a reason why the parser cannot be extended in
> > the future to handle "all in one" packages, but not necessarily at the moment.
> 
> It only really makes sense to do it that way though if it's used
> consistently, and all references do naming like this rather than
> the foo-names method.

This almost sounds like "this will only makes sense if it's beautiful"
which I'm not sure I agree with. :-)

As long as it is clear what information is represented, I have no problems
with having multiple ways of expressing it and using them however people
like.  In fact, we don't even really know at this point which way will turn
out to be most convenient eventually.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [PATCH v3 04/15] ACPI: Document ACPI device specific properties
  2014-10-04 10:59                               ` Arnd Bergmann
  (?)
@ 2014-10-05 22:26                               ` Rafael J. Wysocki
  -1 siblings, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-05 22:26 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mark Rutland, Mika Westerberg, linux-kernel, linux-acpi,
	devicetree, Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, grant.likely, Aaron Lu,
	Darren Hart

On Saturday, October 04, 2014 12:59:59 PM Arnd Bergmann wrote:
> On Saturday 04 October 2014 02:13:23 Rafael J. Wysocki wrote:
> > > Because people get the format wrong regardless of documentation. The
> > > format:
> > > 
> > > Package () {
> > >       Package () { ^ref1, data, data },
> > >       Package () { ^ref2, data },
> > >       Package () { ^ref3, data, data, data },
> > > }
> > > 
> > > Is superior to the format:
> > > 
> > > Package () { ^ref1, data, data, ^ref2, data, ^ref3, data, data, data }
> > > 
> > > Because in the former you have delimiters that can be used to verify
> > > each tuple. Imagine someone misses a data element for one of these
> > > tuples. In the former layout you can detect this easily while in the
> > > latter you cannot.
> > 
> > I agree with this particular thing (although other people seem to have
> > problems with too many package nesting levels) but I'm not sure what that
> > has to do with the example given above (let me quote again):
> > 
> > > Putting everything to a single package results this:
> > > 
> > >       Package () { "pwms", Package () {"led-red", ^PWM0, 0, 10, "led-green", ^PWM0, 1, 10 }}
> > > 
> > > But I think the below looks better:
> > > 
> > >       Package () { "pwms", Package () {^PWM0, 0, 10, ^PWM0, 1, 10 }}
> > >       Package () { "pwm-names", Package () {"led-red", "led-green"}}
> > > 
> > > and it is trivial to match with the corresponding DT fragment.
> > 
> > that I was commenting.  Both cases contains the
> > 
> >         Package () { ^ref1, data, data, ^ref2, data, ^ref3, data, data, data }
> > 
> > format that you don't like, don't they?
> > 
> 
> There are two independent issues:
> 
> a) avoiding the need for "pwm-names" by embedding the name in the
>    "pwms" property
> 
> b) avoiding the need for "#pwm-cells" by having explicit separators between
>    entries in a "pwms" property.
> 
> It would be possible to do one but not the other.

OK

So aside from theorethical considerations it's good to look at what the
current code is doing in my opinion.

In the current patchset, acpi_dev_get_property_reference() is only used
in one place, which is acpi_get_gpiod_by_index().  That, in turn, is only
used by acpi_find_gpio() and by dev_get_named_gpiod_from_child() (and its
devm variant).  acpi_find_gpio() passes 0 as index (which means it only
cares about the first reference in the list) and the _get_named_gpiod_from_child()
thigs are used by leds-gpio and gpio-keys-polled.  Each of them also uses
0 as the index (so they only care about the first reference in the list as well).

Thus, arguably, acpi_dev_get_property_reference() in its current form is
sufficient for what we need at the moment.  There simply is no need to make
it more complicated right now and we can extend it in the future if need be.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 01/16] ACPI: Add support for device specific properties
  2014-09-16 11:52 ` [RFC PATCH v2 01/16] ACPI: Add support for device specific properties Mika Westerberg
@ 2014-10-06 13:50     ` Grant Likely
  0 siblings, 0 replies; 152+ messages in thread
From: Grant Likely @ 2014-10-06 13:50 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Arnd Bergmann, Aaron Lu, Darren Hart, Mika Westerberg

On Tue, 16 Sep 2014 14:52:32 +0300
, Mika Westerberg <mika.westerberg@linux.intel.com>
 wrote:
> Device Tree is used in many embedded systems to describe the system
> configuration to the OS. It supports attaching properties or name-value
> pairs to the devices it describe. With these properties one can pass
> additional information to the drivers that would not be available
> otherwise.
> 
> ACPI is another configuration mechanism (among other things) typically
> seen, but not limited to, x86 machines. ACPI allows passing arbitrary
> data from methods but there has not been mechanism equivalent to Device
> Tree until the introduction of _DSD in the recent publication of the
> ACPI 5.1 specification.
> 
> In order to facilitate ACPI usage in systems where Device Tree is
> typically used, it would be beneficial to standardize a way to retrieve
> Device Tree style properties from ACPI devices, which is what we do in
> this patch.
> 
> If a given device described in ACPI namespace wants to export properties it
> must implement _DSD method (Device Specific Data, introduced with ACPI 5.1)
> that returns the properties in a package of packages. For example:
> 
> 	Name (_DSD, Package () {
> 		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> 		Package () {
> 			Package () {"name1", <VALUE1>},
> 			Package () {"name2", <VALUE2>},
> 			...
> 		}
> 	})
> 
> The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301
> and is documented in the ACPI 5.1 companion document called "_DSD
> Implementation Guide" [1], [2].
> 
> We add several helper functions that can be used to extract these
> properties and convert them to different Linux data types.
> 
> The ultimate goal is that we only have one device property API that
> retrieves the requested properties from Device Tree or from ACPI
> transparent to the caller.
> 
> [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
> [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> 
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> Signed-off-by: Darren Hart <dvhart@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/acpi/Makefile   |   1 +
>  drivers/acpi/internal.h |   6 +
>  drivers/acpi/property.c | 364 ++++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/acpi/scan.c     |   2 +
>  include/acpi/acpi_bus.h |   7 +
>  include/linux/acpi.h    |  40 ++++++
>  6 files changed, 420 insertions(+)
>  create mode 100644 drivers/acpi/property.c
> 
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 505d4d79fe3e..ba2cafe18fe4 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -46,6 +46,7 @@ acpi-y				+= acpi_pnp.o
>  acpi-y				+= power.o
>  acpi-y				+= event.o
>  acpi-y				+= sysfs.o
> +acpi-y				+= property.o
>  acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
>  acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
>  acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
> diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
> index 4c5cf77e7576..e34290c7af9f 100644
> --- a/drivers/acpi/internal.h
> +++ b/drivers/acpi/internal.h
> @@ -181,4 +181,10 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev);
>  bool acpi_osi_is_win8(void);
>  #endif
>  
> +/*--------------------------------------------------------------------------
> +				Device properties
> +  -------------------------------------------------------------------------- */
> +void acpi_init_properties(struct acpi_device *adev);
> +void acpi_free_properties(struct acpi_device *adev);
> +
>  #endif /* _ACPI_INTERNAL_H_ */
> diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> new file mode 100644
> index 000000000000..c4a3e800e82c
> --- /dev/null
> +++ b/drivers/acpi/property.c
> @@ -0,0 +1,364 @@
> +/*
> + * ACPI device specific properties support.
> + *
> + * Copyright (C) 2014, Intel Corporation
> + * All rights reserved.
> + *
> + * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
> + *          Darren Hart <dvhart@linux.intel.com>
> + *          Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/device.h>
> +#include <linux/export.h>
> +
> +#include "internal.h"
> +
> +/* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
> +static const u8 prp_uuid[16] = {
> +	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
> +	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
> +};

?

What is the encoding used here? I see the first 4 bytes for "daffd814"
encoded in little endian (0x14 first), and then the remaining values
encoded in big-endian for each number. Is this typical for UUID values?

Otherwise the patch looks okay.

g.


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 01/16] ACPI: Add support for device specific properties
@ 2014-10-06 13:50     ` Grant Likely
  0 siblings, 0 replies; 152+ messages in thread
From: Grant Likely @ 2014-10-06 13:50 UTC (permalink / raw)
  To: Mika Westerberg, Rafael J. Wysocki
  Cc: linux-acpi, devicetree, linux-kernel, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Arnd Bergmann, Aaron Lu, Darren Hart, Mika Westerberg

On Tue, 16 Sep 2014 14:52:32 +0300
, Mika Westerberg <mika.westerberg@linux.intel.com>
 wrote:
> Device Tree is used in many embedded systems to describe the system
> configuration to the OS. It supports attaching properties or name-value
> pairs to the devices it describe. With these properties one can pass
> additional information to the drivers that would not be available
> otherwise.
> 
> ACPI is another configuration mechanism (among other things) typically
> seen, but not limited to, x86 machines. ACPI allows passing arbitrary
> data from methods but there has not been mechanism equivalent to Device
> Tree until the introduction of _DSD in the recent publication of the
> ACPI 5.1 specification.
> 
> In order to facilitate ACPI usage in systems where Device Tree is
> typically used, it would be beneficial to standardize a way to retrieve
> Device Tree style properties from ACPI devices, which is what we do in
> this patch.
> 
> If a given device described in ACPI namespace wants to export properties it
> must implement _DSD method (Device Specific Data, introduced with ACPI 5.1)
> that returns the properties in a package of packages. For example:
> 
> 	Name (_DSD, Package () {
> 		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> 		Package () {
> 			Package () {"name1", <VALUE1>},
> 			Package () {"name2", <VALUE2>},
> 			...
> 		}
> 	})
> 
> The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301
> and is documented in the ACPI 5.1 companion document called "_DSD
> Implementation Guide" [1], [2].
> 
> We add several helper functions that can be used to extract these
> properties and convert them to different Linux data types.
> 
> The ultimate goal is that we only have one device property API that
> retrieves the requested properties from Device Tree or from ACPI
> transparent to the caller.
> 
> [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
> [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> 
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> Signed-off-by: Darren Hart <dvhart@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/acpi/Makefile   |   1 +
>  drivers/acpi/internal.h |   6 +
>  drivers/acpi/property.c | 364 ++++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/acpi/scan.c     |   2 +
>  include/acpi/acpi_bus.h |   7 +
>  include/linux/acpi.h    |  40 ++++++
>  6 files changed, 420 insertions(+)
>  create mode 100644 drivers/acpi/property.c
> 
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 505d4d79fe3e..ba2cafe18fe4 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -46,6 +46,7 @@ acpi-y				+= acpi_pnp.o
>  acpi-y				+= power.o
>  acpi-y				+= event.o
>  acpi-y				+= sysfs.o
> +acpi-y				+= property.o
>  acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
>  acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
>  acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
> diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
> index 4c5cf77e7576..e34290c7af9f 100644
> --- a/drivers/acpi/internal.h
> +++ b/drivers/acpi/internal.h
> @@ -181,4 +181,10 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev);
>  bool acpi_osi_is_win8(void);
>  #endif
>  
> +/*--------------------------------------------------------------------------
> +				Device properties
> +  -------------------------------------------------------------------------- */
> +void acpi_init_properties(struct acpi_device *adev);
> +void acpi_free_properties(struct acpi_device *adev);
> +
>  #endif /* _ACPI_INTERNAL_H_ */
> diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> new file mode 100644
> index 000000000000..c4a3e800e82c
> --- /dev/null
> +++ b/drivers/acpi/property.c
> @@ -0,0 +1,364 @@
> +/*
> + * ACPI device specific properties support.
> + *
> + * Copyright (C) 2014, Intel Corporation
> + * All rights reserved.
> + *
> + * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
> + *          Darren Hart <dvhart@linux.intel.com>
> + *          Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/device.h>
> +#include <linux/export.h>
> +
> +#include "internal.h"
> +
> +/* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
> +static const u8 prp_uuid[16] = {
> +	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
> +	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
> +};

?

What is the encoding used here? I see the first 4 bytes for "daffd814"
encoded in little endian (0x14 first), and then the remaining values
encoded in big-endian for each number. Is this typical for UUID values?

Otherwise the patch looks okay.

g.


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 01/16] ACPI: Add support for device specific properties
  2014-10-06 13:50     ` Grant Likely
@ 2014-10-06 14:32         ` Mika Westerberg
  -1 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-10-06 14:32 UTC (permalink / raw)
  To: Grant Likely
  Cc: Rafael J. Wysocki, linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Linus Walleij, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Arnd Bergmann, Aaron Lu, Darren Hart

On Mon, Oct 06, 2014 at 02:50:21PM +0100, Grant Likely wrote:
> On Tue, 16 Sep 2014 14:52:32 +0300
> , Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
>  wrote:
> > Device Tree is used in many embedded systems to describe the system
> > configuration to the OS. It supports attaching properties or name-value
> > pairs to the devices it describe. With these properties one can pass
> > additional information to the drivers that would not be available
> > otherwise.
> > 
> > ACPI is another configuration mechanism (among other things) typically
> > seen, but not limited to, x86 machines. ACPI allows passing arbitrary
> > data from methods but there has not been mechanism equivalent to Device
> > Tree until the introduction of _DSD in the recent publication of the
> > ACPI 5.1 specification.
> > 
> > In order to facilitate ACPI usage in systems where Device Tree is
> > typically used, it would be beneficial to standardize a way to retrieve
> > Device Tree style properties from ACPI devices, which is what we do in
> > this patch.
> > 
> > If a given device described in ACPI namespace wants to export properties it
> > must implement _DSD method (Device Specific Data, introduced with ACPI 5.1)
> > that returns the properties in a package of packages. For example:
> > 
> > 	Name (_DSD, Package () {
> > 		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > 		Package () {
> > 			Package () {"name1", <VALUE1>},
> > 			Package () {"name2", <VALUE2>},
> > 			...
> > 		}
> > 	})
> > 
> > The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301
> > and is documented in the ACPI 5.1 companion document called "_DSD
> > Implementation Guide" [1], [2].
> > 
> > We add several helper functions that can be used to extract these
> > properties and convert them to different Linux data types.
> > 
> > The ultimate goal is that we only have one device property API that
> > retrieves the requested properties from Device Tree or from ACPI
> > transparent to the caller.
> > 
> > [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
> > [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> > 
> > Reviewed-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > Reviewed-by: Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>
> > Signed-off-by: Darren Hart <dvhart-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> > Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> > ---
> >  drivers/acpi/Makefile   |   1 +
> >  drivers/acpi/internal.h |   6 +
> >  drivers/acpi/property.c | 364 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  drivers/acpi/scan.c     |   2 +
> >  include/acpi/acpi_bus.h |   7 +
> >  include/linux/acpi.h    |  40 ++++++
> >  6 files changed, 420 insertions(+)
> >  create mode 100644 drivers/acpi/property.c
> > 
> > diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> > index 505d4d79fe3e..ba2cafe18fe4 100644
> > --- a/drivers/acpi/Makefile
> > +++ b/drivers/acpi/Makefile
> > @@ -46,6 +46,7 @@ acpi-y				+= acpi_pnp.o
> >  acpi-y				+= power.o
> >  acpi-y				+= event.o
> >  acpi-y				+= sysfs.o
> > +acpi-y				+= property.o
> >  acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
> >  acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
> >  acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
> > diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
> > index 4c5cf77e7576..e34290c7af9f 100644
> > --- a/drivers/acpi/internal.h
> > +++ b/drivers/acpi/internal.h
> > @@ -181,4 +181,10 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev);
> >  bool acpi_osi_is_win8(void);
> >  #endif
> >  
> > +/*--------------------------------------------------------------------------
> > +				Device properties
> > +  -------------------------------------------------------------------------- */
> > +void acpi_init_properties(struct acpi_device *adev);
> > +void acpi_free_properties(struct acpi_device *adev);
> > +
> >  #endif /* _ACPI_INTERNAL_H_ */
> > diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> > new file mode 100644
> > index 000000000000..c4a3e800e82c
> > --- /dev/null
> > +++ b/drivers/acpi/property.c
> > @@ -0,0 +1,364 @@
> > +/*
> > + * ACPI device specific properties support.
> > + *
> > + * Copyright (C) 2014, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Authors: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> > + *          Darren Hart <dvhart-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> > + *          Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/acpi.h>
> > +#include <linux/device.h>
> > +#include <linux/export.h>
> > +
> > +#include "internal.h"
> > +
> > +/* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
> > +static const u8 prp_uuid[16] = {
> > +	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
> > +	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
> > +};
> 
> ?
> 
> What is the encoding used here? I see the first 4 bytes for "daffd814"
> encoded in little endian (0x14 first), and then the remaining values
> encoded in big-endian for each number. Is this typical for UUID values?

The buffer format is explained in ACPI 5.1 spec, page 823.

I generated the above so that I compiled a _DSD with correct UUID using
iASL and then disassambled it with the same tool.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 01/16] ACPI: Add support for device specific properties
@ 2014-10-06 14:32         ` Mika Westerberg
  0 siblings, 0 replies; 152+ messages in thread
From: Mika Westerberg @ 2014-10-06 14:32 UTC (permalink / raw)
  To: Grant Likely
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, linux-kernel,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Arnd Bergmann, Aaron Lu,
	Darren Hart

On Mon, Oct 06, 2014 at 02:50:21PM +0100, Grant Likely wrote:
> On Tue, 16 Sep 2014 14:52:32 +0300
> , Mika Westerberg <mika.westerberg@linux.intel.com>
>  wrote:
> > Device Tree is used in many embedded systems to describe the system
> > configuration to the OS. It supports attaching properties or name-value
> > pairs to the devices it describe. With these properties one can pass
> > additional information to the drivers that would not be available
> > otherwise.
> > 
> > ACPI is another configuration mechanism (among other things) typically
> > seen, but not limited to, x86 machines. ACPI allows passing arbitrary
> > data from methods but there has not been mechanism equivalent to Device
> > Tree until the introduction of _DSD in the recent publication of the
> > ACPI 5.1 specification.
> > 
> > In order to facilitate ACPI usage in systems where Device Tree is
> > typically used, it would be beneficial to standardize a way to retrieve
> > Device Tree style properties from ACPI devices, which is what we do in
> > this patch.
> > 
> > If a given device described in ACPI namespace wants to export properties it
> > must implement _DSD method (Device Specific Data, introduced with ACPI 5.1)
> > that returns the properties in a package of packages. For example:
> > 
> > 	Name (_DSD, Package () {
> > 		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > 		Package () {
> > 			Package () {"name1", <VALUE1>},
> > 			Package () {"name2", <VALUE2>},
> > 			...
> > 		}
> > 	})
> > 
> > The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301
> > and is documented in the ACPI 5.1 companion document called "_DSD
> > Implementation Guide" [1], [2].
> > 
> > We add several helper functions that can be used to extract these
> > properties and convert them to different Linux data types.
> > 
> > The ultimate goal is that we only have one device property API that
> > retrieves the requested properties from Device Tree or from ACPI
> > transparent to the caller.
> > 
> > [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
> > [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> > 
> > Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> > Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> > Signed-off-by: Darren Hart <dvhart@linux.intel.com>
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > ---
> >  drivers/acpi/Makefile   |   1 +
> >  drivers/acpi/internal.h |   6 +
> >  drivers/acpi/property.c | 364 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  drivers/acpi/scan.c     |   2 +
> >  include/acpi/acpi_bus.h |   7 +
> >  include/linux/acpi.h    |  40 ++++++
> >  6 files changed, 420 insertions(+)
> >  create mode 100644 drivers/acpi/property.c
> > 
> > diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> > index 505d4d79fe3e..ba2cafe18fe4 100644
> > --- a/drivers/acpi/Makefile
> > +++ b/drivers/acpi/Makefile
> > @@ -46,6 +46,7 @@ acpi-y				+= acpi_pnp.o
> >  acpi-y				+= power.o
> >  acpi-y				+= event.o
> >  acpi-y				+= sysfs.o
> > +acpi-y				+= property.o
> >  acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
> >  acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
> >  acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
> > diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
> > index 4c5cf77e7576..e34290c7af9f 100644
> > --- a/drivers/acpi/internal.h
> > +++ b/drivers/acpi/internal.h
> > @@ -181,4 +181,10 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev);
> >  bool acpi_osi_is_win8(void);
> >  #endif
> >  
> > +/*--------------------------------------------------------------------------
> > +				Device properties
> > +  -------------------------------------------------------------------------- */
> > +void acpi_init_properties(struct acpi_device *adev);
> > +void acpi_free_properties(struct acpi_device *adev);
> > +
> >  #endif /* _ACPI_INTERNAL_H_ */
> > diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> > new file mode 100644
> > index 000000000000..c4a3e800e82c
> > --- /dev/null
> > +++ b/drivers/acpi/property.c
> > @@ -0,0 +1,364 @@
> > +/*
> > + * ACPI device specific properties support.
> > + *
> > + * Copyright (C) 2014, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
> > + *          Darren Hart <dvhart@linux.intel.com>
> > + *          Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/acpi.h>
> > +#include <linux/device.h>
> > +#include <linux/export.h>
> > +
> > +#include "internal.h"
> > +
> > +/* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
> > +static const u8 prp_uuid[16] = {
> > +	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
> > +	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
> > +};
> 
> ?
> 
> What is the encoding used here? I see the first 4 bytes for "daffd814"
> encoded in little endian (0x14 first), and then the remaining values
> encoded in big-endian for each number. Is this typical for UUID values?

The buffer format is explained in ACPI 5.1 spec, page 823.

I generated the above so that I compiled a _DSD with correct UUID using
iASL and then disassambled it with the same tool.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 01/16] ACPI: Add support for device specific properties
  2014-10-06 14:32         ` Mika Westerberg
@ 2014-10-06 16:25           ` Darren Hart
  -1 siblings, 0 replies; 152+ messages in thread
From: Darren Hart @ 2014-10-06 16:25 UTC (permalink / raw)
  To: Mika Westerberg, Grant Likely
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, linux-kernel,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Arnd Bergmann, Aaron Lu

On 10/6/14, 7:32, "Mika Westerberg" <mika.westerberg@linux.intel.com>
wrote:

>On Mon, Oct 06, 2014 at 02:50:21PM +0100, Grant Likely wrote:
>>
>> > +/* ACPI _DSD device properties UUID:
>>daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
>> > +static const u8 prp_uuid[16] = {
>> > +	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
>> > +	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
>> > +};
>> 
>> ?
>> 
>> What is the encoding used here? I see the first 4 bytes for "daffd814"
>> encoded in little endian (0x14 first), and then the remaining values
>> encoded in big-endian for each number. Is this typical for UUID values?
>
>The buffer format is explained in ACPI 5.1 spec, page 823.
>
>I generated the above so that I compiled a _DSD with correct UUID using
>iASL and then disassambled it with the same tool.
>

I bugged Mika with the same question, it's a fairly non-intuitive encoding
:-)

-- 
Darren Hart
Intel Open Source Technology Center




^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 01/16] ACPI: Add support for device specific properties
@ 2014-10-06 16:25           ` Darren Hart
  0 siblings, 0 replies; 152+ messages in thread
From: Darren Hart @ 2014-10-06 16:25 UTC (permalink / raw)
  To: Mika Westerberg, Grant Likely
  Cc: Rafael J. Wysocki, linux-acpi, devicetree, linux-kernel,
	Greg Kroah-Hartman, Linus Walleij, Alexandre Courbot,
	Dmitry Torokhov, Bryan Wu, Lee Jones, Arnd Bergmann, Aaron Lu

On 10/6/14, 7:32, "Mika Westerberg" <mika.westerberg@linux.intel.com>
wrote:

>On Mon, Oct 06, 2014 at 02:50:21PM +0100, Grant Likely wrote:
>>
>> > +/* ACPI _DSD device properties UUID:
>>daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
>> > +static const u8 prp_uuid[16] = {
>> > +	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
>> > +	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
>> > +};
>> 
>> ?
>> 
>> What is the encoding used here? I see the first 4 bytes for "daffd814"
>> encoded in little endian (0x14 first), and then the remaining values
>> encoded in big-endian for each number. Is this typical for UUID values?
>
>The buffer format is explained in ACPI 5.1 spec, page 823.
>
>I generated the above so that I compiled a _DSD with correct UUID using
>iASL and then disassambled it with the same tool.
>

I bugged Mika with the same question, it's a fairly non-intuitive encoding
:-)

-- 
Darren Hart
Intel Open Source Technology Center




^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-09-26  3:21                   ` Darren Hart
  2014-09-26  8:36                     ` Arnd Bergmann
@ 2014-10-07 13:37                     ` Linus Walleij
  2014-10-07 15:37                       ` Andy Shevchenko
  2014-10-07 23:57                       ` Rafael J. Wysocki
  1 sibling, 2 replies; 152+ messages in thread
From: Linus Walleij @ 2014-10-07 13:37 UTC (permalink / raw)
  To: Darren Hart, Andy Shevchenko, Len Brown
  Cc: Arnd Bergmann, Rafael J. Wysocki, David Woodhouse,
	Mika Westerberg, Grant Likely, Mark Rutland,
	ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Fri, Sep 26, 2014 at 5:21 AM, Darren Hart <dvhart@infradead.org> wrote:
> On Wed, Sep 24, 2014 at 11:12:36AM +0200, Arnd Bergmann wrote:

> So as Mika has pointed out, LEDs aren't the only ones affected. Several drivers
> will need to walk through non-device child nodes, and it seems to me that having
> a firmware-independent mechanism to do so benefits the drivers by both making
> them smaller and by increasing the reusability of new drivers and drivers
> updated to use the new API across platforms.

In a recent round of reviews, for the OF case, that led to drivers
which used device_initcall() without being a module, getting a match
and handle to the parent device, and then walking over the nodes
and instantiating child objects (Linux devices usually) in the process.

It was done as a response to the remark from Rob Herring that
we were modeling things in the device tree as devices when they
really weren't, we were just doing it that way because it fits the
Linux device model and it's easier.

So we have that case too.

The question is if it's anything close to generalizable.

> Grant, Linus W? Thoughts?

I'm uncertain on the whole subject, I called on the others
because of that...

For a while I had Andy Schevenko patch the GPIO and
SFI core too, but it timed out due to no response from Len
Brown. (Maybe I should just merge that stuff!) Do you (Intel) also
want to unify the Medfield SFI thing into this or have you
given up on it?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-10-07 13:37                     ` Linus Walleij
@ 2014-10-07 15:37                       ` Andy Shevchenko
  2014-10-07 23:57                       ` Rafael J. Wysocki
  1 sibling, 0 replies; 152+ messages in thread
From: Andy Shevchenko @ 2014-10-07 15:37 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Darren Hart, Len Brown, Arnd Bergmann, Rafael J. Wysocki,
	David Woodhouse, Mika Westerberg, Grant Likely, Mark Rutland,
	ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Tue, 2014-10-07 at 15:37 +0200, Linus Walleij wrote:
> On Fri, Sep 26, 2014 at 5:21 AM, Darren Hart <dvhart@infradead.org> wrote:
> > On Wed, Sep 24, 2014 at 11:12:36AM +0200, Arnd Bergmann wrote:
> 
> > So as Mika has pointed out, LEDs aren't the only ones affected. Several drivers
> > will need to walk through non-device child nodes, and it seems to me that having
> > a firmware-independent mechanism to do so benefits the drivers by both making
> > them smaller and by increasing the reusability of new drivers and drivers
> > updated to use the new API across platforms.
> 
> In a recent round of reviews, for the OF case, that led to drivers
> which used device_initcall() without being a module, getting a match
> and handle to the parent device, and then walking over the nodes
> and instantiating child objects (Linux devices usually) in the process.
> 
> It was done as a response to the remark from Rob Herring that
> we were modeling things in the device tree as devices when they
> really weren't, we were just doing it that way because it fits the
> Linux device model and it's easier.
> 
> So we have that case too.
> 
> The question is if it's anything close to generalizable.
> 
> > Grant, Linus W? Thoughts?
> 
> I'm uncertain on the whole subject, I called on the others
> because of that...
> 
> For a while I had Andy Schevenko patch the GPIO and
> SFI core too, but it timed out due to no response from Len
> Brown. (Maybe I should just merge that stuff!) Do you (Intel) also
> want to unify the Medfield SFI thing into this or have you
> given up on it?

I think SFI is quite outdated stuff, though I have still Medfield device
close to me.

I don't think there will be any new platform with SFI (on the other hand
we never know :-) ). Thus, my opinion you may go ahead without worrying
about SFI.

-- 
Andy Shevchenko <andriy.shevchenko@intel.com>
Intel Finland Oy


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface
  2014-10-07 13:37                     ` Linus Walleij
  2014-10-07 15:37                       ` Andy Shevchenko
@ 2014-10-07 23:57                       ` Rafael J. Wysocki
  1 sibling, 0 replies; 152+ messages in thread
From: Rafael J. Wysocki @ 2014-10-07 23:57 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Darren Hart, Andy Shevchenko, Len Brown, Arnd Bergmann,
	David Woodhouse, Mika Westerberg, Grant Likely, Mark Rutland,
	ACPI Devel Maling List, devicetree, linux-kernel,
	Greg Kroah-Hartman, Alexandre Courbot, Dmitry Torokhov, Bryan Wu,
	Lee Jones, Aaron Lu

On Tuesday, October 07, 2014 03:37:04 PM Linus Walleij wrote:
> On Fri, Sep 26, 2014 at 5:21 AM, Darren Hart <dvhart@infradead.org> wrote:
> > On Wed, Sep 24, 2014 at 11:12:36AM +0200, Arnd Bergmann wrote:
> 
> > So as Mika has pointed out, LEDs aren't the only ones affected. Several drivers
> > will need to walk through non-device child nodes, and it seems to me that having
> > a firmware-independent mechanism to do so benefits the drivers by both making
> > them smaller and by increasing the reusability of new drivers and drivers
> > updated to use the new API across platforms.
> 
> In a recent round of reviews, for the OF case, that led to drivers
> which used device_initcall() without being a module, getting a match
> and handle to the parent device, and then walking over the nodes
> and instantiating child objects (Linux devices usually) in the process.
> 
> It was done as a response to the remark from Rob Herring that
> we were modeling things in the device tree as devices when they
> really weren't, we were just doing it that way because it fits the
> Linux device model and it's easier.
> 
> So we have that case too.
> 
> The question is if it's anything close to generalizable.

Well, OK.

Can you please have a look at these patchse in v4:

https://patchwork.kernel.org/patch/5040161/
https://patchwork.kernel.org/patch/5040081/
https://patchwork.kernel.org/patch/5040061/

We now have an ACK from Dmitry on the gpio_keys_polled thing and Bryan
said he was OK with the leds changes already in v2 (IIRC).

Also Alexandre is saying that he's not opposed to the changes in
https://patchwork.kernel.org/patch/5040161/, although there may be a better
way.

And we have AKCs from Greg on the driver core changes, so it looks like
GPIO really is the only missing thing and we need that code to support
our hardware.

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 152+ messages in thread

end of thread, other threads:[~2014-10-07 23:37 UTC | newest]

Thread overview: 152+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-16 11:52 [RFC PATCH v2 00/16] Add ACPI _DSD and unified device properties support Mika Westerberg
2014-09-16 11:52 ` Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 01/16] ACPI: Add support for device specific properties Mika Westerberg
2014-10-06 13:50   ` Grant Likely
2014-10-06 13:50     ` Grant Likely
     [not found]     ` <20141006135021.0EB04C43FBE-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2014-10-06 14:32       ` Mika Westerberg
2014-10-06 14:32         ` Mika Westerberg
2014-10-06 16:25         ` Darren Hart
2014-10-06 16:25           ` Darren Hart
2014-09-16 11:52 ` [RFC PATCH v2 02/16] Driver core: Unified device properties interface for platform firmware Mika Westerberg
2014-09-17 18:28   ` Greg Kroah-Hartman
2014-09-16 11:52 ` [RFC PATCH v2 03/16] ACPI: Allow drivers to match using Device Tree compatible property Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 04/16] ACPI: Document ACPI device specific properties Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 05/16] mfd: Add ACPI support Mika Westerberg
2014-09-16 21:54   ` Lee Jones
2014-09-16 21:54     ` Lee Jones
2014-09-24 12:00   ` Lee Jones
2014-09-24 12:00     ` Lee Jones
2014-09-16 11:52 ` [RFC PATCH v2 06/16] gpio / ACPI: Add support for _DSD device properties Mika Westerberg
2014-09-23 15:27   ` Linus Walleij
2014-09-16 11:52 ` [RFC PATCH v2 07/16] gpio: Add support for unified device properties interface Mika Westerberg
     [not found]   ` <1410868367-11056-8-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2014-09-23 15:25     ` Linus Walleij
2014-09-23 15:25       ` Linus Walleij
2014-09-23 15:45       ` Arnd Bergmann
2014-09-23 15:52         ` Mika Westerberg
2014-09-23 15:52           ` Mika Westerberg
2014-09-23 16:17           ` Dmitry Torokhov
     [not found]             ` <20140923161724.GA40700-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org>
2014-09-23 20:31               ` Rafael J. Wysocki
2014-09-23 20:31                 ` Rafael J. Wysocki
2014-09-23 16:25         ` Rafael J. Wysocki
2014-09-23 16:25           ` Rafael J. Wysocki
     [not found]           ` <2895905.coa5UvrkJk-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-09-23 16:26             ` Arnd Bergmann
2014-09-23 16:26               ` Arnd Bergmann
2014-09-23 20:47               ` Rafael J. Wysocki
     [not found]                 ` <1579761.oeYleOAY1N-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-09-24  7:55                   ` Arnd Bergmann
2014-09-24  7:55                     ` Arnd Bergmann
2014-09-24 14:08                     ` Rafael J. Wysocki
2014-09-23 21:15               ` Darren Hart
2014-09-24  9:12                 ` Arnd Bergmann
2014-09-24  9:38                   ` Mika Westerberg
2014-09-24 14:11                     ` Rafael J. Wysocki
2014-09-26  3:21                   ` Darren Hart
2014-09-26  8:36                     ` Arnd Bergmann
2014-09-26 14:42                       ` Rafael J. Wysocki
2014-10-07 13:37                     ` Linus Walleij
2014-10-07 15:37                       ` Andy Shevchenko
2014-10-07 23:57                       ` Rafael J. Wysocki
2014-09-16 11:52 ` [RFC PATCH v2 08/16] gpio: sch: Consolidate core and resume banks Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 09/16] leds: leds-gpio: Add support for GPIO descriptors Mika Westerberg
2014-09-19  8:18   ` Alexandre Courbot
2014-09-24  7:55   ` Linus Walleij
2014-09-24  9:42     ` Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 10/16] leds: leds-gpio: Make use of device property API Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 11/16] leds: leds-gpio: Add ACPI probing support Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 12/16] input: gpio_keys_polled - Add support for GPIO descriptors Mika Westerberg
2014-09-19  8:22   ` Alexandre Courbot
2014-09-24  8:02   ` Linus Walleij
2014-09-16 11:52 ` [RFC PATCH v2 13/16] input: gpio_keys_polled - Make use of device property API Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 14/16] input: gpio_keys_polled - Add ACPI probing support Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 15/16] misc: at25: Make use of device property API Mika Westerberg
2014-09-16 11:52 ` [RFC PATCH v2 16/16] misc: at25: Add ACPI probing support Mika Westerberg
2014-09-21  0:26 ` [RFC PATCH v2 00/16] Add ACPI _DSD and unified device properties support Rafael J. Wysocki
2014-09-24  8:34   ` Lee Jones
2014-09-24  9:45     ` Mika Westerberg
2014-09-22 23:29 ` Bryan Wu
2014-10-01  2:08 ` [PATCH v3 00/15] " Rafael J. Wysocki
2014-10-01  2:08   ` [PATCH v3 01/15] ACPI: Add support for device specific properties Rafael J. Wysocki
2014-10-01  7:38     ` Arnd Bergmann
2014-10-01  2:10   ` [PATCH v3 02/15] Driver core: Unified device properties interface for platform firmware Rafael J. Wysocki
2014-10-01  7:47     ` Arnd Bergmann
2014-10-01 22:09       ` Rafael J. Wysocki
2014-10-01 23:01         ` Rafael J. Wysocki
2014-10-02  7:46         ` Arnd Bergmann
2014-10-02 16:50           ` Rafael J. Wysocki
2014-10-02  0:03     ` Greg Kroah-Hartman
2014-10-01  2:10   ` [PATCH v3 03/15] ACPI: Allow drivers to match using Device Tree compatible property Rafael J. Wysocki
2014-10-01  7:48     ` Arnd Bergmann
2014-10-03 13:43     ` Mark Rutland
2014-10-03 17:59       ` Dmitry Torokhov
2014-10-04  0:02         ` Rafael J. Wysocki
2014-10-04  0:02           ` Rafael J. Wysocki
2014-10-01  2:11   ` [PATCH v3 04/15] ACPI: Document ACPI device specific properties Rafael J. Wysocki
2014-10-01  7:59     ` Arnd Bergmann
2014-10-02 10:41       ` Mika Westerberg
2014-10-02 11:51         ` Arnd Bergmann
2014-10-02 12:15           ` Mika Westerberg
2014-10-02 12:46             ` Arnd Bergmann
2014-10-02 13:36               ` Mika Westerberg
2014-10-02 14:29                 ` Arnd Bergmann
2014-10-02 14:38                   ` Mika Westerberg
2014-10-02 14:55                     ` Arnd Bergmann
2014-10-03 13:56                       ` Mark Rutland
2014-10-03 15:02                         ` Arnd Bergmann
2014-10-03 23:58                           ` Rafael J. Wysocki
2014-10-04 10:56                             ` Arnd Bergmann
2014-10-05 21:40                               ` Rafael J. Wysocki
2014-10-05 21:40                                 ` Rafael J. Wysocki
2014-10-03  2:03                 ` Rafael J. Wysocki
2014-10-03  8:12                   ` Mika Westerberg
2014-10-03 13:58                   ` Mark Rutland
2014-10-03 14:38                     ` Rafael J. Wysocki
2014-10-03 14:35                       ` Mark Rutland
2014-10-04  0:13                         ` Rafael J. Wysocki
     [not found]                           ` <6568619.UkU5qISONv-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-10-04 10:59                             ` Arnd Bergmann
2014-10-04 10:59                               ` Arnd Bergmann
2014-10-05 22:26                               ` Rafael J. Wysocki
2014-10-03 13:48             ` Mark Rutland
2014-10-04  0:16               ` Rafael J. Wysocki
2014-10-01  2:12   ` [PATCH v3 05/15] gpio / ACPI: Add support for _DSD device properties Rafael J. Wysocki
     [not found]     ` <4786851.38d7sjpzag-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-10-01  8:03       ` Arnd Bergmann
2014-10-01  8:03         ` Arnd Bergmann
2014-10-05 10:36         ` Alexandre Courbot
2014-10-05 21:20           ` Rafael J. Wysocki
     [not found]   ` <1852462.V1jlbi8OPt-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-10-01  2:14     ` [PATCH v3 06/15] gpio: Support for unified device properties interface Rafael J. Wysocki
2014-10-01  2:14       ` Rafael J. Wysocki
2014-10-01  2:22     ` [PATCH v3 15/15] misc: at25: Add ACPI probing support Rafael J. Wysocki
2014-10-01  2:22       ` Rafael J. Wysocki
2014-10-01  8:15       ` Arnd Bergmann
2014-10-01  2:15   ` [PATCH v3 07/15] gpio: sch: Consolidate core and resume banks Rafael J. Wysocki
2014-10-01  2:15   ` [PATCH v3 08/15] leds: leds-gpio: Add support for GPIO descriptors Rafael J. Wysocki
     [not found]     ` <1490183.QvrzPxsV7q-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-10-01  8:05       ` Arnd Bergmann
2014-10-01  8:05         ` Arnd Bergmann
2014-10-01  2:16   ` [PATCH v3 09/15] leds: leds-gpio: Make use of device property API Rafael J. Wysocki
2014-10-03 14:07     ` Mark Rutland
2014-10-04  0:18       ` Rafael J. Wysocki
2014-10-01  2:17   ` [PATCH v3 10/15] leds: leds-gpio: Add ACPI probing support Rafael J. Wysocki
2014-10-01  8:13     ` Arnd Bergmann
2014-10-01  9:13       ` Mika Westerberg
2014-10-01 10:01         ` Arnd Bergmann
2014-10-01 11:59           ` Mika Westerberg
2014-10-01 13:52             ` Arnd Bergmann
2014-10-01 14:04               ` Mika Westerberg
     [not found]                 ` <20141001140441.GF1786-3PARRvDOhMZrdx17CPfAsdBPR1lH4CV8@public.gmane.org>
2014-10-01 14:14                   ` Arnd Bergmann
2014-10-01 14:14                     ` Arnd Bergmann
2014-10-02  9:55                     ` Mika Westerberg
2014-10-02 10:44                       ` Arnd Bergmann
2014-10-01 16:30       ` Dmitry Torokhov
2014-10-01 18:11         ` Darren Hart
2014-10-01 18:11           ` Darren Hart
2014-10-01 18:21           ` Dmitry Torokhov
2014-10-01 18:22           ` Arnd Bergmann
2014-10-01  2:17   ` [PATCH v3 11/15] input: gpio_keys_polled - Add support for GPIO descriptors Rafael J. Wysocki
2014-10-01  8:13     ` Arnd Bergmann
2014-10-01  2:20   ` [PATCH v3 12/15] input: gpio_keys_polled - Make use of device property API Rafael J. Wysocki
2014-10-01  2:20   ` [PATCH v3 13/15] input: gpio_keys_polled - Add ACPI probing support Rafael J. Wysocki
2014-10-01  7:48     ` Dmitry Torokhov
2014-10-01  9:15       ` Mika Westerberg
2014-10-01 16:28         ` Dmitry Torokhov
2014-10-02  9:53           ` Mika Westerberg
2014-10-01  2:21   ` [PATCH v3 14/15] misc: at25: Make use of device property API Rafael J. Wysocki
     [not found]     ` <2074642.sV7QBxD3Ne-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-10-01  8:14       ` Arnd Bergmann
2014-10-01  8:14         ` Arnd Bergmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.