RE: [RFC PATCH 3/4] pinctrl: Add ACPI support

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

 




> -----Original Message-----
> From: Mika Westerberg [mailto:mika.westerberg@xxxxxxxxxxxxxxx]
> Sent: 04 April, 2016 16:37
> To: Tirdea, Irina
> Cc: Rafael J. Wysocki; Len Brown; Linus Walleij; linux-gpio@xxxxxxxxxxxxxxx; linux-acpi@xxxxxxxxxxxxxxx; Rob Herring; Heikki Krogerus;
> Andy Shevchenko; Purdila, Octavian; Ciocan, Cristina; devicetree@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx
> Subject: Re: [RFC PATCH 3/4] pinctrl: Add ACPI support
> 
> On Thu, Mar 31, 2016 at 02:44:44PM +0300, Irina Tirdea wrote:
> > Add ACPI support for pin controller properties. These are
> > based on ACPI _DSD properties and follow the device tree
> > model based on states and node configurations. The states
> > are defined as _DSD properties and configuration nodes
> > are defined using the _DSD Hierarchical Properties Extension.
> >
> > A configuration node supports the generic device tree properties.
> >
> > The implementation is based on device tree code from devicetree.c.
> >
> > Signed-off-by: Irina Tirdea <irina.tirdea@xxxxxxxxx>
> 
> Looks good to me. Few minor comments below, though.

Thanks for the review, Mika!

> 
> > ---
> >  Documentation/acpi/pinctrl-properties.txt | 274 +++++++++++++++++++++++++
> >  drivers/pinctrl/Makefile                  |   1 +
> >  drivers/pinctrl/acpi.c                    | 322 ++++++++++++++++++++++++++++++
> >  drivers/pinctrl/acpi.h                    |  32 +++
> >  drivers/pinctrl/core.c                    |  26 +++
> >  drivers/pinctrl/core.h                    |   2 +
> >  6 files changed, 657 insertions(+)
> >  create mode 100644 Documentation/acpi/pinctrl-properties.txt
> >  create mode 100644 drivers/pinctrl/acpi.c
> >  create mode 100644 drivers/pinctrl/acpi.h
> >
> > diff --git a/Documentation/acpi/pinctrl-properties.txt b/Documentation/acpi/pinctrl-properties.txt
> > new file mode 100644
> > index 0000000..e93aaaf
> > --- /dev/null
> > +++ b/Documentation/acpi/pinctrl-properties.txt
> > @@ -0,0 +1,274 @@
> > += _DSD Device Properties related to pin controllers =
> > +
> > +== Introduction ==
> > +
> > +This document is an extension of the pin control subsystem in Linux [1]
> > +and provides a way to describe pin controller properties in ACPI. It is
> > +based on the Device Specific Data (_DSD) configuration object [2] that
> > +was introduced in ACPI 5.1.
> > +
> > +Pin controllers are hardware modules that control pins by allowing pin
> > +multiplexing and configuration. Pin multiplexing allows using the same
> > +physical pins for multiple functions; for example, one pin or group of pins
> > +may be used for the I2C bus, SPI bus or as general-purpose GPIO pin. Pin
> > +configuration allows setting various properties such as pull-up/down,
> > +tri-state, drive-strength, etc.
> > +
> > +Hardware modules whose signals are affected by pin configuration are
> > +designated client devices. For a client device to operate correctly,
> > +certain pin controllers must set up certain specific pin configurations.
> > +Some client devices need a single static pin configuration, e.g. set up
> > +during initialization. Others need to reconfigure pins at run-time,
> > +for example to tri-state pins when the device is inactive. Hence, each
> > +client device can define a set of named states. Each named state is
> > +mapped to a pin controller configuration that describes the pin multiplexing
> > +or configuration for that state.
> > +
> > +In ACPI, each pin controller and each client device is represented as an
> > +ACPI device, just like any other hardware module. The pin controller
> > +properties are defined using _DSD properties [2] under these devices.
> > +The named states are defined using Device Properties UUID [3] under the
> > +ACPI client device. The configuration nodes are defined using Hierarchical
> > +Properties Extension UUID [4] and are split between the ACPI client device
> > +and the pin controller device. The configuration nodes contain properties
> > +that describe pin multiplexing or configuration that very similar to the
> > +ones used for device tree [5].
> > +
> > +== Example ==
> > +
> > +For example, let's consider an accelerometer connected to the I2C bus on
> > +a platform with a Baytrail pin controller. The accelerometer uses 2 GPIO
> > +pins for I2C (SDA, SCL) and one GPIO pin for interrupt.
> > +
> > +The name for the pins, groups and functions used are the ones defined in the
> > +pin controller driver, in the same way as it is done for device tree [5].
> > +
> > +For the I2C pins, the pin controller driver defines one group called
> > +"i2c5_grp" that can be multiplexed with functions "i2c" or "gpio".
> > +In our case, we need to select function "i2c" for group "i2c5_grp" in
> > +the ACPI description.
> > +
> > +For the GPIO pin, the pin controller driver defines the name "GPIO_S5[00]"
> 
> BTW, those pin names were changed for Baytrail pinctrl driver so you
> should probably do that here also.
> 
Right, will update it according to the current naming.
> > +for the pin with index 0 that we use. We need to configure this pin to
> > +pull-down with pull strength of 10000 Ohms. We might also want to disable
> > +the bias for the GPIO interrupt pin when entering sleep.
> > +
> > +Here is an ASL example for this device:
> > +
> > +  // Pin controller device
> > +  Scope (_SB.GPO0)
> > +  {
> > +      Name (MUX0, Package()
> > +      {
> > +          ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +          Package()
> > +          {
> > +              Package (2) {"function", "i2c"},
> > +              Package (2) {"groups", Package () {"i2c5_grp"}},
> > +          }
> > +      })
> > +
> > +      Name (CFG0, Package()
> > +      {
> > +          ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +          Package()
> > +          {
> > +              Package (2) {"pins", Package () {"GPIO_S5[00]"}},
> > +              Package (2) {"bias-pull-down", 10000},
> > +          }
> > +      })
> > +
> > +      Name (CFG1, Package()
> > +      {
> > +          ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +          Package()
> > +          {
> > +              Package (2) {"pins", Package () {"GPIO_S5[00]"}},
> > +              Package (2) {"bias-disable", 0},
> > +          }
> > +      })
> > +  }
> > +
> > +
<snip>
> > +  Scope (GPO0)
> > +  {
> > +      Name (DPN0, Package()
> 
> Maybe we should use node names that relate to the pinctrl subsystem and
> not the ones used in the hierarchical properties extension example? I mean
> real examples.
> 
OK, I will use MUX0 and CFG0 instead.
> > +      {
> > +          ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +          Package() {...}
> > +      })
> > +      Name (DPN1, Package()
> > +      {
> > +          ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +          Package() {...}
> > +      })
> > +  }
> > +
> > +Each DPN data subnode is a regular _DSD node that uses Device Properties
> > +UUID [3]. There are 2 types of subnodes, depending on the properties it
> > +contains: pin multiplexing nodes and pin configuration nodes.
> > +
> > +==== Pin multiplexing nodes  ====
> > +
> > +The pin multiplexing nodes must contain a property named "function" and
> > +define a mux function to be applied to a list of pin groups. The properties
> > +supported by this node are the same as for device tree [5]. The name for the
> > +pins, groups and functions used are the ones defined in the pin controller
> > +driver, in the same way as it is done for device tree [5]. The format for
> > +this data subnode is:
> > +
> > +  Name (DPN0, Package()
> 
> Same here.
> 
> > +  {
> > +      ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +          Package()
> > +          {
> > +              Package (2) {"function", functioname},
> > +              Package (2) {"groups", Package () {groupname1, groupname2, ...}},
> > +          }
> > +  })
> > +
> > +  functioname - the pinmux function to select.
> > +  groups - the list of groups to select with this function
> > +
> > +==== Pin configuration nodes  ====
> > +
> > +The pin configuration nodes do not contain a property named "function".
> > +They must contain a property named "group" or "pins". They will also
> > +contain one or more configuration properties like bias-pull-up,
> > +drive-open-drain, etc. The properties supported by this node are the
> > +same as for device tree. Standard pinctrl properties are defined in the
> > +device tree documentation [5] and in <include/linux/pinctrl/pinconf-generic.h>.
> > +Pinctrl drivers may also define their own custom properties. The name for the
> > +pins/groups  used are the ones defined in the pin controller driver, in the
> > +same way as it is done for device tree [5]. The format for the data subnode is:
> > +
> > +  Name (DPN0, Package()
> 
> And here.
> 
> > +  {
> > +      ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +          Package()
> > +          {
> > +              Package (2) {"pins", Package () {pin1, pin2, ...}},
> > +              Package (2) {configname1, configval1},
> 
> These should be enclosed in quotes, like "configname1" and so on.
> 
OK. Should all string properties be enclosed in quotes or only the property names
(e.g. should I also change values like "configval1", "pin1", "statename1", etc.)?
> > +              Package (2) {configname2, configval2},
> > +          }
> > +  })
> > +
> > +  pins - list of pins that properties in the node apply to
> > +  configname - name of the pin configuration property
> > +  configval - value of the pin configuration property
> > +
> > +== References ==
> > +
> > +[1] Documentation/pinctrl.txt
> > +[2] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel-1_1.htm
> > +[3] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> > +[4] http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf
> > +[5] Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
> > diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> > index e4bc115..12d3af6 100644
> > --- a/drivers/pinctrl/Makefile
> > +++ b/drivers/pinctrl/Makefile
> > @@ -6,6 +6,7 @@ obj-y				+= core.o pinctrl-utils.o
> >  obj-$(CONFIG_PINMUX)		+= pinmux.o
> >  obj-$(CONFIG_PINCONF)		+= pinconf.o
> >  obj-$(CONFIG_OF)		+= devicetree.o
> > +obj-$(CONFIG_ACPI)		+= acpi.o
> >  obj-$(CONFIG_GENERIC_PINCONF)	+= pinconf-generic.o
> >  obj-$(CONFIG_PINCTRL_ADI2)	+= pinctrl-adi2.o
> >  obj-$(CONFIG_PINCTRL_AS3722)	+= pinctrl-as3722.o
> > diff --git a/drivers/pinctrl/acpi.c b/drivers/pinctrl/acpi.c
> > new file mode 100644
> > index 0000000..bed1d88
> > --- /dev/null
> > +++ b/drivers/pinctrl/acpi.c
> > @@ -0,0 +1,322 @@
> > +/*
> > + * ACPI integration for the pin control subsystem
> > + *
> > + * Copyright (c) 2016, Intel Corporation.
> > + *
> > + * Derived from:
> > + *  devicetree.c - Copyright (C) 2012 NVIDIA CORPORATION
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> > + * more details.
> > + */
> > +
> > +#include <linux/acpi.h>
> > +#include <linux/device.h>
> > +#include <linux/pinctrl/pinctrl.h>
> > +#include <linux/pinctrl/pinconf-generic.h>
> > +
> > +#include "acpi.h"
> > +#include "core.h"
> > +#include "pinconf.h"
> > +#include "pinctrl-utils.h"
> > +
> > +/**
> > + * struct pinctrl_acpi_map - mapping table chunk parsed from ACPI
> > + * @node: list node for struct pinctrl's @fw_maps field
> > + * @pctldev: the pin controller that allocated this struct, and will free it
> > + * @maps: the mapping table entries
> > + */
> > +struct pinctrl_acpi_map {
> > +	struct list_head node;
> > +	struct pinctrl_dev *pctldev;
> > +	struct pinctrl_map *map;
> > +	unsigned num_maps;
> > +};
> > +
> > +static void acpi_maps_list_dh(acpi_handle handle, void *data)
> > +{
> > +	/* The address of this function is used as a key. */
> > +}
> > +
> > +static struct list_head *acpi_get_maps(struct device *dev)
> > +{
> > +	acpi_handle handle = ACPI_HANDLE(dev);
> > +	struct list_head *maps;
> > +	acpi_status status;
> > +
> > +	status = acpi_get_data(handle, acpi_maps_list_dh, (void **)&maps);
> > +	if (ACPI_FAILURE(status))
> > +		return NULL;
> > +
> > +	return maps;
> > +}
> > +
> > +static void acpi_free_maps(struct device *dev, struct list_head *maps)
> > +{
> > +	acpi_handle handle = ACPI_HANDLE(dev);
> > +
> > +	acpi_detach_data(handle, acpi_maps_list_dh);
> > +	kfree(maps);
> > +}
> > +
> > +static int acpi_init_maps(struct device *dev)
> > +{
> > +	acpi_handle handle = ACPI_HANDLE(dev);
> > +	struct list_head *maps;
> > +	acpi_status status;
> > +
> > +	maps = kzalloc(sizeof(*maps), GFP_KERNEL);
> > +	if (!maps)
> > +		return -ENOMEM;
> > +
> > +	INIT_LIST_HEAD(maps);
> > +
> > +	status = acpi_attach_data(handle, acpi_maps_list_dh, maps);
> > +	if (ACPI_FAILURE(status))
> 
> This leaks maps.
Oops. I'll fix this.
> 
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux