* Re: [PATCH v2 2/2] mtd: spi-nor: add driver for STM32 quad spi flash controller
From: Ludovic BARRE @ 2017-04-10 9:08 UTC (permalink / raw)
To: Marek Vasut, Cyrille Pitchen
Cc: David Woodhouse, Brian Norris, Boris Brezillon,
Richard Weinberger, Alexandre Torgue, Rob Herring,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <5ec38e39-661d-8a83-4168-b9f3d986bcd1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 04/07/2017 01:55 AM, Marek Vasut wrote:
> On 03/31/2017 07:02 PM, Ludovic Barre wrote:
>> From: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>
>>
>> The quadspi is a specialized communication interface targeting single,
>> dual or quad SPI Flash memories.
>>
>> It can operate in any of the following modes:
>> -indirect mode: all the operations are performed using the quadspi
>> registers
>> -read memory-mapped mode: the external Flash memory is mapped to the
>> microcontroller address space and is seen by the system as if it was
>> an internal memory
>>
>> Signed-off-by: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>
>> ---
>> drivers/mtd/spi-nor/Kconfig | 7 +
>> drivers/mtd/spi-nor/Makefile | 1 +
>> drivers/mtd/spi-nor/stm32-quadspi.c | 690 ++++++++++++++++++++++++++++++++++++
>> 3 files changed, 698 insertions(+)
>> create mode 100644 drivers/mtd/spi-nor/stm32-quadspi.c
>>
> [...]
>
>> +struct stm32_qspi_flash {
>> + struct spi_nor nor;
>> + u32 cs;
>> + u32 fsize;
>> + u32 presc;
>> + struct stm32_qspi *qspi;
>> +};
> [...]
>
>> +struct stm32_qspi_cmd {
>> + struct {
>> + u8 addr_width;
>> + u8 dummy;
>> + u8 data;
>> + } conf;
> Is there any benefit in having this structure here or could you just
> make the struct stm32_qspi_cmd flat ?
no benefit, it was just to regroup, so I can do a flat structure
>
>> + u8 opcode;
>> + u32 framemode;
>> + u32 qspimode;
>> + u32 addr;
>> + size_t len;
>> + void *buf;
>> +};
> [...]
>
>> +static ssize_t stm32_qspi_read(struct spi_nor *nor, loff_t from, size_t len,
>> + u_char *buf)
>> +{
>> + struct stm32_qspi_flash *flash = nor->priv;
>> + struct stm32_qspi *qspi = flash->qspi;
>> + struct stm32_qspi_cmd cmd;
>> + int err;
>> +
>> + dev_dbg(qspi->dev, "read(%#.2x): buf:%p from:%#.8x len:%#x\n",
>> + nor->read_opcode, buf, (u32)from, len);
>> +
>> + memset(&cmd, 0, sizeof(cmd));
>> + cmd.opcode = nor->read_opcode;
>> + cmd.conf.addr_width = nor->addr_width;
>> + cmd.addr = (u32)from;
> loff_t (from) can be 64bit ... how do we handle this ?
I'm surprise by the question,
the SPI NOR device uses 3 Bytes or 4 bytes address mode.
So, the stm32 qspi controller has a 32 bit register for NOR address.
On the other hand the framework and other drivers used this variable
(from) like
a 32 bits.
>
>> + cmd.conf.data = 1;
>> + cmd.conf.dummy = nor->read_dummy;
>> + cmd.len = len;
>> + cmd.buf = buf;
>> + cmd.qspimode = qspi->read_mode;
>> +
>> + stm32_qspi_set_framemode(nor, &cmd, true);
>> + err = stm32_qspi_send(flash, &cmd);
>> +
>> + return err ? err : len;
>> +}
> [...]
>
>> +static irqreturn_t stm32_qspi_irq(int irq, void *dev_id)
>> +{
>> + struct stm32_qspi *qspi = (struct stm32_qspi *)dev_id;
>> + u32 cr, sr, fcr = 0;
>> +
>> + cr = readl_relaxed(qspi->io_base + QUADSPI_CR);
>> + sr = readl_relaxed(qspi->io_base + QUADSPI_SR);
>> +
>> + if ((cr & CR_TCIE) && (sr & SR_TCF)) {
>> + /* tx complete */
>> + fcr |= FCR_CTCF;
>> + complete(&qspi->cmd_completion);
>> + } else {
>> + dev_info(qspi->dev, "spurious interrupt\n");
> You probably want to ratelimit this one ...
yes it's better if there is an issue.
>
>> + }
>> +
>> + writel_relaxed(fcr, qspi->io_base + QUADSPI_FCR);
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static int stm32_qspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
>> +{
>> + struct stm32_qspi_flash *flash = nor->priv;
>> + struct stm32_qspi *qspi = flash->qspi;
>> +
>> + mutex_lock(&qspi->lock);
>> + return 0;
>> +}
>> +
>> +static void stm32_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
>> +{
>> + struct stm32_qspi_flash *flash = nor->priv;
>> + struct stm32_qspi *qspi = flash->qspi;
>> +
>> + mutex_unlock(&qspi->lock);
>> +}
>> +
>> +static int stm32_qspi_flash_setup(struct stm32_qspi *qspi,
>> + struct device_node *np)
>> +{
>> + u32 width, flash_read, presc, cs_num, max_rate = 0;
>> + struct stm32_qspi_flash *flash;
>> + struct mtd_info *mtd;
>> + int ret;
>> +
>> + of_property_read_u32(np, "reg", &cs_num);
>> + if (cs_num >= STM32_MAX_NORCHIP)
>> + return -EINVAL;
>> +
>> + of_property_read_u32(np, "spi-max-frequency", &max_rate);
>> + if (!max_rate)
>> + return -EINVAL;
>> +
>> + presc = DIV_ROUND_UP(qspi->clk_rate, max_rate) - 1;
>> +
>> + if (of_property_read_u32(np, "spi-rx-bus-width", &width))
>> + width = 1;
>> +
>> + if (width == 4)
>> + flash_read = SPI_NOR_QUAD;
>> + else if (width == 2)
>> + flash_read = SPI_NOR_DUAL;
>> + else if (width == 1)
>> + flash_read = SPI_NOR_NORMAL;
>> + else
>> + return -EINVAL;
>> +
>> + flash = &qspi->flash[cs_num];
>> + flash->qspi = qspi;
>> + flash->cs = cs_num;
>> + flash->presc = presc;
>> +
>> + flash->nor.dev = qspi->dev;
>> + spi_nor_set_flash_node(&flash->nor, np);
>> + flash->nor.priv = flash;
>> + mtd = &flash->nor.mtd;
>> + mtd->priv = &flash->nor;
>> +
>> + flash->nor.read = stm32_qspi_read;
>> + flash->nor.write = stm32_qspi_write;
>> + flash->nor.erase = stm32_qspi_erase;
>> + flash->nor.read_reg = stm32_qspi_read_reg;
>> + flash->nor.write_reg = stm32_qspi_write_reg;
>> + flash->nor.prepare = stm32_qspi_prep;
>> + flash->nor.unprepare = stm32_qspi_unprep;
>> +
>> + writel_relaxed(LPTR_DFT_TIMEOUT, qspi->io_base + QUADSPI_LPTR);
>> +
>> + writel_relaxed(CR_PRESC(presc) | CR_FTHRES(3) | CR_TCEN | CR_SSHIFT
>> + | CR_EN, qspi->io_base + QUADSPI_CR);
>> +
>> + /*
>> + * in stm32 qspi controller, QUADSPI_DCR register has a fsize field
>> + * which define the size of nor flash.
>> + * if fsize is NULL, the controller can't sent spi-nor command.
>> + * set a temporary value just to discover the nor flash with
>> + * "spi_nor_scan". After, the right value (mtd->size) can be set.
>> + */
> Is 25 the smallest value ? Use a macro for this ...
25 is an arbitrary choice, I will define a smallest value
>
>> + flash->fsize = 25;
>> +
>> + ret = spi_nor_scan(&flash->nor, NULL, flash_read);
>> + if (ret) {
>> + dev_err(qspi->dev, "device scan failed\n");
>> + return ret;
>> + }
>> +
>> + /* number of bytes in Flash memory = 2^[FSIZE+1] */
>> + flash->fsize = __fls(mtd->size) - 1;
>> +
>> + writel_relaxed(DCR_CSHT(1), qspi->io_base + QUADSPI_DCR);
>> +
>> + ret = mtd_device_register(mtd, NULL, 0);
>> + if (ret) {
>> + dev_err(qspi->dev, "mtd device parse failed\n");
>> + return ret;
>> + }
>> +
>> + dev_dbg(qspi->dev, "read mm:%s cs:%d bus:%d\n",
>> + qspi->read_mode == CCR_FMODE_MM ? "yes" : "no", cs_num, width);
>> +
>> + return 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
* [PATCH] ARM: mxs: add support for I2SE Duckbill 2 boards
From: Michael Heimpold @ 2017-04-10 9:08 UTC (permalink / raw)
To: shawnguo
Cc: mark.rutland, devicetree, stefan.wahren, robh+dt,
Michael Heimpold, Michael Heimpold, kernel, fabio.estevam,
frowand.list, linux-arm-kernel
In-Reply-To: <20170410082400.GA1872@dragon>
The Duckbill devices are small, pen-drive sized boards based on
NXP's i.MX28 SoC. While the initial variants (Duckbill series)
were equipped with a micro SD card slot only, the latest generation
(Duckbill 2 series) have an additional internal eMMC onboard.
To distinguish between both generations, a new device tree
compatible string was introduced. To get the MAC address fixup
applied, we need to check for this new string here, too.
Signed-off-by: Michael Heimpold <michael.heimpold@i2se.com>
---
arch/arm/mach-mxs/mach-mxs.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index e4f2108..1c6062d 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -419,7 +419,8 @@ static void __init mxs_machine_init(void)
crystalfontz_init();
else if (of_machine_is_compatible("eukrea,mbmx283lc"))
eukrea_mbmx283lc_init();
- else if (of_machine_is_compatible("i2se,duckbill"))
+ else if (of_machine_is_compatible("i2se,duckbill") ||
+ of_machine_is_compatible("i2se,duckbill-2"))
duckbill_init();
else if (of_machine_is_compatible("msr,m28cu3"))
m28cu3_init();
--
2.6.1
^ permalink raw reply related
* Re: [RESEND PATCH v4] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
From: Quentin Schulz @ 2017-04-10 9:18 UTC (permalink / raw)
To: sre-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, wens-jdAy2FN1RRM,
linux-I+IVW8TIWO2tmTQ+vhA3Yw,
maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
jic23-DgEjT+Ai2ygdnm+yROfE0A, knaack.h-Mmb7MZpHnFY,
lars-Qo5EllUWu/uELgA04lAiVw, pmeerw-jW+XmwGofnusTnJN9+BGXg,
lee.jones-QSEj5FYQhm4dnm+yROfE0A, icenowy-ymACFijhrKM
Cc: thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA, linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170404063441.7656-1-quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Hi Lee,
Just to make sure you didn't miss that patch (can't find it in
for-mfd-next and for-mfd-next-next).
Thanks,
Quentin
On 04/04/2017 08:34, Quentin Schulz wrote:
> The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose the
> battery voltage, battery charge and discharge currents, AC-in and VBUS
> voltages and currents, 2 GPIOs muxable in ADC mode and PMIC temperature.
>
> This adds support for most of AXP20X and AXP22X ADCs.
>
> Signed-off-by: Quentin Schulz <quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> Acked-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> Reviewed-by: Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
>
> Lee, could you merge this through the mfd tree please?
> => https://lkml.org/lkml/2017/3/22/47
>
> v4:
> - added missing space at the beginning of a comment,
> - tidied axp20x_adc_offset_voltage and axp20x_write_raw to use switch case
> instead of if conditions,
> - added MODULE_DEVICE_TABLE for axp20x_adc_id_match for module autoloading,
> - merged two lines in axp20x_remove,
>
> v3:
> - moved from switch to if condition in axp20x_adc_raw and
> axp22x_adc_raw,
> - removed DT support as DT node has been dropped,
> - use of platform_device_id
> - correctly defined the name of the iio device (name used to probe the
> driver),
> - added goto for errors in probe,
> - added iio_map_array_unregister to the remove function,
>
> v2:
> - removed unused defines,
> - changed BIT(x) to 1 << x when describing bits purpose for which 2 <<
> x or 3 << x exists, to be consistent,
> - changed ADC rate defines to macro formulas,
> - reordered IIO channels, now different measures (current/voltage) of
> the same part of the PMIC (e.g. battery), have the same IIO channel in
> their respective IIO type. When a part of the PMIC have only one
> measure, a number is jumped,
> - left IIO channel mapping in DT to use iio_map structure,
> - removed indexing of ADC internal temperature,
> - removed unused iio_dev structure in axp20x_adc_iio,
> - added a structure for data specific to AXP20X or AXP22X PMICs instead
> of using an ID and an if condition when needing to separate the
> behaviour of both,
> - added a comment on batt_chrg_i really being on 12bits rather than
> what the Chinese datasheets say (13 bits),
> - corrected the offset for AXP22X PMIC temperature,
> - set the ADC rate to a value (100Hz) shared by the AXP20X and AXP22X,
> - created macro formulas to compute the ADC rate for each,
> - added a condition on presence of ADC_EN2 reg before setting/resetting
> it,
> - switched from devm_iio_device_unregister to the non-devm function
> because of the need for a remove function,
> - removed some dead code,
>
> drivers/iio/adc/Kconfig | 10 +
> drivers/iio/adc/Makefile | 1 +
> drivers/iio/adc/axp20x_adc.c | 617 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 628 insertions(+)
> create mode 100644 drivers/iio/adc/axp20x_adc.c
>
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index d777a97..d15e1bd 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -154,6 +154,16 @@ config AT91_SAMA5D2_ADC
> To compile this driver as a module, choose M here: the module will be
> called at91-sama5d2_adc.
>
> +config AXP20X_ADC
> + tristate "X-Powers AXP20X and AXP22X ADC driver"
> + depends on MFD_AXP20X
> + help
> + Say yes here to have support for X-Powers power management IC (PMIC)
> + AXP20X and AXP22X ADC devices.
> +
> + To compile this driver as a module, choose M here: the module will be
> + called axp20x_adc.
> +
> config AXP288_ADC
> tristate "X-Powers AXP288 ADC driver"
> depends on MFD_AXP20X
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index b11bb57..17899b5 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
> obj-$(CONFIG_AD799X) += ad799x.o
> obj-$(CONFIG_AT91_ADC) += at91_adc.o
> obj-$(CONFIG_AT91_SAMA5D2_ADC) += at91-sama5d2_adc.o
> +obj-$(CONFIG_AXP20X_ADC) += axp20x_adc.o
> obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
> obj-$(CONFIG_BCM_IPROC_ADC) += bcm_iproc_adc.o
> obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o
> diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c
> new file mode 100644
> index 0000000..11e1771
> --- /dev/null
> +++ b/drivers/iio/adc/axp20x_adc.c
> @@ -0,0 +1,617 @@
> +/* ADC driver for AXP20X and AXP22X PMICs
> + *
> + * Copyright (c) 2016 Free Electrons NextThing Co.
> + * Quentin Schulz <quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@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/completion.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/thermal.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/driver.h>
> +#include <linux/iio/machine.h>
> +#include <linux/mfd/axp20x.h>
> +
> +#define AXP20X_ADC_EN1_MASK GENMASK(7, 0)
> +
> +#define AXP20X_ADC_EN2_MASK (GENMASK(3, 2) | BIT(7))
> +#define AXP22X_ADC_EN1_MASK (GENMASK(7, 5) | BIT(0))
> +
> +#define AXP20X_GPIO10_IN_RANGE_GPIO0 BIT(0)
> +#define AXP20X_GPIO10_IN_RANGE_GPIO1 BIT(1)
> +#define AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(x) ((x) & BIT(0))
> +#define AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(x) (((x) & BIT(0)) << 1)
> +
> +#define AXP20X_ADC_RATE_MASK GENMASK(7, 6)
> +#define AXP20X_ADC_RATE_HZ(x) ((ilog2((x) / 25) << 6) & AXP20X_ADC_RATE_MASK)
> +#define AXP22X_ADC_RATE_HZ(x) ((ilog2((x) / 100) << 6) & AXP20X_ADC_RATE_MASK)
> +
> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg) \
> + { \
> + .type = _type, \
> + .indexed = 1, \
> + .channel = _channel, \
> + .address = _reg, \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
> + BIT(IIO_CHAN_INFO_SCALE), \
> + .datasheet_name = _name, \
> + }
> +
> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
> + { \
> + .type = _type, \
> + .indexed = 1, \
> + .channel = _channel, \
> + .address = _reg, \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
> + BIT(IIO_CHAN_INFO_SCALE) |\
> + BIT(IIO_CHAN_INFO_OFFSET),\
> + .datasheet_name = _name, \
> + }
> +
> +struct axp_data;
> +
> +struct axp20x_adc_iio {
> + struct regmap *regmap;
> + struct axp_data *data;
> +};
> +
> +enum axp20x_adc_channel_v {
> + AXP20X_ACIN_V = 0,
> + AXP20X_VBUS_V,
> + AXP20X_TS_IN,
> + AXP20X_GPIO0_V,
> + AXP20X_GPIO1_V,
> + AXP20X_IPSOUT_V,
> + AXP20X_BATT_V,
> +};
> +
> +enum axp20x_adc_channel_i {
> + AXP20X_ACIN_I = 0,
> + AXP20X_VBUS_I,
> + AXP20X_BATT_CHRG_I,
> + AXP20X_BATT_DISCHRG_I,
> +};
> +
> +enum axp22x_adc_channel_v {
> + AXP22X_TS_IN = 0,
> + AXP22X_BATT_V,
> +};
> +
> +enum axp22x_adc_channel_i {
> + AXP22X_BATT_CHRG_I = 1,
> + AXP22X_BATT_DISCHRG_I,
> +};
> +
> +static struct iio_map axp20x_maps[] = {
> + {
> + .consumer_dev_name = "axp20x-usb-power-supply",
> + .consumer_channel = "vbus_v",
> + .adc_channel_label = "vbus_v",
> + }, {
> + .consumer_dev_name = "axp20x-usb-power-supply",
> + .consumer_channel = "vbus_i",
> + .adc_channel_label = "vbus_i",
> + }, {
> + .consumer_dev_name = "axp20x-ac-power-supply",
> + .consumer_channel = "acin_v",
> + .adc_channel_label = "acin_v",
> + }, {
> + .consumer_dev_name = "axp20x-ac-power-supply",
> + .consumer_channel = "acin_i",
> + .adc_channel_label = "acin_i",
> + }, {
> + .consumer_dev_name = "axp20x-battery-power-supply",
> + .consumer_channel = "batt_v",
> + .adc_channel_label = "batt_v",
> + }, {
> + .consumer_dev_name = "axp20x-battery-power-supply",
> + .consumer_channel = "batt_chrg_i",
> + .adc_channel_label = "batt_chrg_i",
> + }, {
> + .consumer_dev_name = "axp20x-battery-power-supply",
> + .consumer_channel = "batt_dischrg_i",
> + .adc_channel_label = "batt_dischrg_i",
> + }, { /* sentinel */ }
> +};
> +
> +static struct iio_map axp22x_maps[] = {
> + {
> + .consumer_dev_name = "axp20x-battery-power-supply",
> + .consumer_channel = "batt_v",
> + .adc_channel_label = "batt_v",
> + }, {
> + .consumer_dev_name = "axp20x-battery-power-supply",
> + .consumer_channel = "batt_chrg_i",
> + .adc_channel_label = "batt_chrg_i",
> + }, {
> + .consumer_dev_name = "axp20x-battery-power-supply",
> + .consumer_channel = "batt_dischrg_i",
> + .adc_channel_label = "batt_dischrg_i",
> + }, { /* sentinel */ }
> +};
> +
> +/*
> + * Channels are mapped by physical system. Their channels share the same index.
> + * i.e. acin_i is in_current0_raw and acin_v is in_voltage0_raw.
> + * The only exception is for the battery. batt_v will be in_voltage6_raw and
> + * charge current in_current6_raw and discharge current will be in_current7_raw.
> + */
> +static const struct iio_chan_spec axp20x_adc_channels[] = {
> + AXP20X_ADC_CHANNEL(AXP20X_ACIN_V, "acin_v", IIO_VOLTAGE,
> + AXP20X_ACIN_V_ADC_H),
> + AXP20X_ADC_CHANNEL(AXP20X_ACIN_I, "acin_i", IIO_CURRENT,
> + AXP20X_ACIN_I_ADC_H),
> + AXP20X_ADC_CHANNEL(AXP20X_VBUS_V, "vbus_v", IIO_VOLTAGE,
> + AXP20X_VBUS_V_ADC_H),
> + AXP20X_ADC_CHANNEL(AXP20X_VBUS_I, "vbus_i", IIO_CURRENT,
> + AXP20X_VBUS_I_ADC_H),
> + {
> + .type = IIO_TEMP,
> + .address = AXP20X_TEMP_ADC_H,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE) |
> + BIT(IIO_CHAN_INFO_OFFSET),
> + .datasheet_name = "pmic_temp",
> + },
> + AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO0_V, "gpio0_v", IIO_VOLTAGE,
> + AXP20X_GPIO0_V_ADC_H),
> + AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO1_V, "gpio1_v", IIO_VOLTAGE,
> + AXP20X_GPIO1_V_ADC_H),
> + AXP20X_ADC_CHANNEL(AXP20X_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,
> + AXP20X_IPSOUT_V_HIGH_H),
> + AXP20X_ADC_CHANNEL(AXP20X_BATT_V, "batt_v", IIO_VOLTAGE,
> + AXP20X_BATT_V_H),
> + AXP20X_ADC_CHANNEL(AXP20X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
> + AXP20X_BATT_CHRG_I_H),
> + AXP20X_ADC_CHANNEL(AXP20X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
> + AXP20X_BATT_DISCHRG_I_H),
> +};
> +
> +static const struct iio_chan_spec axp22x_adc_channels[] = {
> + {
> + .type = IIO_TEMP,
> + .address = AXP22X_PMIC_TEMP_H,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE) |
> + BIT(IIO_CHAN_INFO_OFFSET),
> + .datasheet_name = "pmic_temp",
> + },
> + AXP20X_ADC_CHANNEL(AXP22X_BATT_V, "batt_v", IIO_VOLTAGE,
> + AXP20X_BATT_V_H),
> + AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
> + AXP20X_BATT_CHRG_I_H),
> + AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
> + AXP20X_BATT_DISCHRG_I_H),
> +};
> +
> +static int axp20x_adc_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan, int *val)
> +{
> + struct axp20x_adc_iio *info = iio_priv(indio_dev);
> + int size = 12;
> +
> + /*
> + * N.B.: Unlike the Chinese datasheets tell, the charging current is
> + * stored on 12 bits, not 13 bits. Only discharging current is on 13
> + * bits.
> + */
> + if (chan->type == IIO_CURRENT && chan->channel == AXP20X_BATT_DISCHRG_I)
> + size = 13;
> + else
> + size = 12;
> +
> + *val = axp20x_read_variable_width(info->regmap, chan->address, size);
> + if (*val < 0)
> + return *val;
> +
> + return IIO_VAL_INT;
> +}
> +
> +static int axp22x_adc_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan, int *val)
> +{
> + struct axp20x_adc_iio *info = iio_priv(indio_dev);
> + int size;
> +
> + /*
> + * N.B.: Unlike the Chinese datasheets tell, the charging current is
> + * stored on 12 bits, not 13 bits. Only discharging current is on 13
> + * bits.
> + */
> + if (chan->type == IIO_CURRENT && chan->channel == AXP22X_BATT_DISCHRG_I)
> + size = 13;
> + else
> + size = 12;
> +
> + *val = axp20x_read_variable_width(info->regmap, chan->address, size);
> + if (*val < 0)
> + return *val;
> +
> + return IIO_VAL_INT;
> +}
> +
> +static int axp20x_adc_scale_voltage(int channel, int *val, int *val2)
> +{
> + switch (channel) {
> + case AXP20X_ACIN_V:
> + case AXP20X_VBUS_V:
> + *val = 1;
> + *val2 = 700000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case AXP20X_GPIO0_V:
> + case AXP20X_GPIO1_V:
> + *val = 0;
> + *val2 = 500000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case AXP20X_BATT_V:
> + *val = 1;
> + *val2 = 100000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case AXP20X_IPSOUT_V:
> + *val = 1;
> + *val2 = 400000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int axp20x_adc_scale_current(int channel, int *val, int *val2)
> +{
> + switch (channel) {
> + case AXP20X_ACIN_I:
> + *val = 0;
> + *val2 = 625000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case AXP20X_VBUS_I:
> + *val = 0;
> + *val2 = 375000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case AXP20X_BATT_DISCHRG_I:
> + case AXP20X_BATT_CHRG_I:
> + *val = 0;
> + *val2 = 500000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int axp20x_adc_scale(struct iio_chan_spec const *chan, int *val,
> + int *val2)
> +{
> + switch (chan->type) {
> + case IIO_VOLTAGE:
> + return axp20x_adc_scale_voltage(chan->channel, val, val2);
> +
> + case IIO_CURRENT:
> + return axp20x_adc_scale_current(chan->channel, val, val2);
> +
> + case IIO_TEMP:
> + *val = 100;
> + return IIO_VAL_INT;
> +
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,
> + int *val2)
> +{
> + switch (chan->type) {
> + case IIO_VOLTAGE:
> + if (chan->channel != AXP22X_BATT_V)
> + return -EINVAL;
> +
> + *val = 1;
> + *val2 = 100000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case IIO_CURRENT:
> + *val = 0;
> + *val2 = 500000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case IIO_TEMP:
> + *val = 100;
> + return IIO_VAL_INT;
> +
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int axp20x_adc_offset_voltage(struct iio_dev *indio_dev, int channel,
> + int *val)
> +{
> + struct axp20x_adc_iio *info = iio_priv(indio_dev);
> + int ret;
> +
> + ret = regmap_read(info->regmap, AXP20X_GPIO10_IN_RANGE, val);
> + if (ret < 0)
> + return ret;
> +
> + switch (channel) {
> + case AXP20X_GPIO0_V:
> + *val &= AXP20X_GPIO10_IN_RANGE_GPIO0;
> + break;
> +
> + case AXP20X_GPIO1_V:
> + *val &= AXP20X_GPIO10_IN_RANGE_GPIO1;
> + break;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + *val = !!(*val) * 700000;
> +
> + return IIO_VAL_INT;
> +}
> +
> +static int axp20x_adc_offset(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan, int *val)
> +{
> + switch (chan->type) {
> + case IIO_VOLTAGE:
> + return axp20x_adc_offset_voltage(indio_dev, chan->channel, val);
> +
> + case IIO_TEMP:
> + *val = -1447;
> + return IIO_VAL_INT;
> +
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int axp20x_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan, int *val,
> + int *val2, long mask)
> +{
> + switch (mask) {
> + case IIO_CHAN_INFO_OFFSET:
> + return axp20x_adc_offset(indio_dev, chan, val);
> +
> + case IIO_CHAN_INFO_SCALE:
> + return axp20x_adc_scale(chan, val, val2);
> +
> + case IIO_CHAN_INFO_RAW:
> + return axp20x_adc_raw(indio_dev, chan, val);
> +
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int axp22x_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan, int *val,
> + int *val2, long mask)
> +{
> + switch (mask) {
> + case IIO_CHAN_INFO_OFFSET:
> + *val = -2677;
> + return IIO_VAL_INT;
> +
> + case IIO_CHAN_INFO_SCALE:
> + return axp22x_adc_scale(chan, val, val2);
> +
> + case IIO_CHAN_INFO_RAW:
> + return axp22x_adc_raw(indio_dev, chan, val);
> +
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int axp20x_write_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan, int val, int val2,
> + long mask)
> +{
> + struct axp20x_adc_iio *info = iio_priv(indio_dev);
> + unsigned int reg, regval;
> +
> + /*
> + * The AXP20X PMIC allows the user to choose between 0V and 0.7V offsets
> + * for (independently) GPIO0 and GPIO1 when in ADC mode.
> + */
> + if (mask != IIO_CHAN_INFO_OFFSET)
> + return -EINVAL;
> +
> + if (val != 0 && val != 700000)
> + return -EINVAL;
> +
> + switch (chan->channel) {
> + case AXP20X_GPIO0_V:
> + reg = AXP20X_GPIO10_IN_RANGE_GPIO0;
> + regval = AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(!!val);
> + break;
> +
> + case AXP20X_GPIO1_V:
> + reg = AXP20X_GPIO10_IN_RANGE_GPIO1;
> + regval = AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(!!val);
> + break;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE, reg,
> + regval);
> +}
> +
> +static const struct iio_info axp20x_adc_iio_info = {
> + .read_raw = axp20x_read_raw,
> + .write_raw = axp20x_write_raw,
> + .driver_module = THIS_MODULE,
> +};
> +
> +static const struct iio_info axp22x_adc_iio_info = {
> + .read_raw = axp22x_read_raw,
> + .driver_module = THIS_MODULE,
> +};
> +
> +static int axp20x_adc_rate(int rate)
> +{
> + return AXP20X_ADC_RATE_HZ(rate);
> +}
> +
> +static int axp22x_adc_rate(int rate)
> +{
> + return AXP22X_ADC_RATE_HZ(rate);
> +}
> +
> +struct axp_data {
> + const struct iio_info *iio_info;
> + int num_channels;
> + struct iio_chan_spec const *channels;
> + unsigned long adc_en1_mask;
> + int (*adc_rate)(int rate);
> + bool adc_en2;
> + struct iio_map *maps;
> +};
> +
> +static const struct axp_data axp20x_data = {
> + .iio_info = &axp20x_adc_iio_info,
> + .num_channels = ARRAY_SIZE(axp20x_adc_channels),
> + .channels = axp20x_adc_channels,
> + .adc_en1_mask = AXP20X_ADC_EN1_MASK,
> + .adc_rate = axp20x_adc_rate,
> + .adc_en2 = true,
> + .maps = axp20x_maps,
> +};
> +
> +static const struct axp_data axp22x_data = {
> + .iio_info = &axp22x_adc_iio_info,
> + .num_channels = ARRAY_SIZE(axp22x_adc_channels),
> + .channels = axp22x_adc_channels,
> + .adc_en1_mask = AXP22X_ADC_EN1_MASK,
> + .adc_rate = axp22x_adc_rate,
> + .adc_en2 = false,
> + .maps = axp22x_maps,
> +};
> +
> +static const struct platform_device_id axp20x_adc_id_match[] = {
> + { .name = "axp20x-adc", .driver_data = (kernel_ulong_t)&axp20x_data, },
> + { .name = "axp22x-adc", .driver_data = (kernel_ulong_t)&axp22x_data, },
> + { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(platform, axp20x_adc_id_match);
> +
> +static int axp20x_probe(struct platform_device *pdev)
> +{
> + struct axp20x_adc_iio *info;
> + struct iio_dev *indio_dev;
> + struct axp20x_dev *axp20x_dev;
> + int ret;
> +
> + axp20x_dev = dev_get_drvdata(pdev->dev.parent);
> +
> + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + info = iio_priv(indio_dev);
> + platform_set_drvdata(pdev, indio_dev);
> +
> + info->regmap = axp20x_dev->regmap;
> + indio_dev->dev.parent = &pdev->dev;
> + indio_dev->dev.of_node = pdev->dev.of_node;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> +
> + info->data = (struct axp_data *)platform_get_device_id(pdev)->driver_data;
> +
> + indio_dev->name = platform_get_device_id(pdev)->name;
> + indio_dev->info = info->data->iio_info;
> + indio_dev->num_channels = info->data->num_channels;
> + indio_dev->channels = info->data->channels;
> +
> + /* Enable the ADCs on IP */
> + regmap_write(info->regmap, AXP20X_ADC_EN1, info->data->adc_en1_mask);
> +
> + if (info->data->adc_en2)
> + /* Enable GPIO0/1 and internal temperature ADCs */
> + regmap_update_bits(info->regmap, AXP20X_ADC_EN2,
> + AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK);
> +
> + /* Configure ADCs rate */
> + regmap_update_bits(info->regmap, AXP20X_ADC_RATE, AXP20X_ADC_RATE_MASK,
> + info->data->adc_rate(100));
> +
> + ret = iio_map_array_register(indio_dev, info->data->maps);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "failed to register IIO maps: %d\n", ret);
> + goto fail_map;
> + }
> +
> + ret = iio_device_register(indio_dev);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "could not register the device\n");
> + goto fail_register;
> + }
> +
> + return 0;
> +
> +fail_register:
> + iio_map_array_unregister(indio_dev);
> +
> +fail_map:
> + regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> +
> + if (info->data->adc_en2)
> + regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
> +
> + return ret;
> +}
> +
> +static int axp20x_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> + struct axp20x_adc_iio *info = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> + iio_map_array_unregister(indio_dev);
> +
> + regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> +
> + if (info->data->adc_en2)
> + regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
> +
> + return 0;
> +}
> +
> +static struct platform_driver axp20x_adc_driver = {
> + .driver = {
> + .name = "axp20x-adc",
> + },
> + .id_table = axp20x_adc_id_match,
> + .probe = axp20x_probe,
> + .remove = axp20x_remove,
> +};
> +
> +module_platform_driver(axp20x_adc_driver);
> +
> +MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");
> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>");
> +MODULE_LICENSE("GPL");
>
--
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH V2] PM / OPP: Use - instead of @ for DT entries
From: Viresh Kumar @ 2017-04-10 9:21 UTC (permalink / raw)
To: Rafael Wysocki, Chanwoo Choi, MyungJoo Ham, Kyungmin Park,
Kukjin Kim, Krzysztof Kozlowski, Javier Martinez Canillas,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Benoît Cousson,
Tony Lindgren, Rob Herring, Mark Rutland, Daniel Mack,
Haojian Zhuang, Robert Jarzmik, Maxime Ripard, Chen-Yu Tsai,
Masahiro Yamada
Cc: devicetree, linaro-kernel, Vincent Guittot, linux-pm,
Viresh Kumar, linux-kernel, linux-samsung-soc, linux-omap,
linux-arm-kernel
Compiling the DT file with W=1, DTC warns like follows:
Warning (unit_address_vs_reg): Node /opp_table0/opp@1000000000 has a
unit name, but no reg property
Fix this by replacing '@' with '-' as the OPP nodes will never have a
"reg" property.
Reported-by: Krzysztof Kozlowski <krzk@kernel.org>
Reported-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Suggested-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> (sunxi)
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
---
V2:
- Added more *-by tags.
- Included TI DT and example files as well.
.../devicetree/bindings/cpufreq/ti-cpufreq.txt | 20 +++----
.../devicetree/bindings/devfreq/exynos-bus.txt | 46 +++++++--------
Documentation/devicetree/bindings/opp/opp.txt | 38 ++++++-------
arch/arm/boot/dts/am4372.dtsi | 10 ++--
arch/arm/boot/dts/exynos3250.dtsi | 46 +++++++--------
arch/arm/boot/dts/exynos4210.dtsi | 32 +++++------
arch/arm/boot/dts/exynos4412-prime.dtsi | 4 +-
arch/arm/boot/dts/exynos4412.dtsi | 66 +++++++++++-----------
arch/arm/boot/dts/exynos5420.dtsi | 40 ++++++-------
arch/arm/boot/dts/exynos5800.dtsi | 56 +++++++++---------
arch/arm/boot/dts/pxa25x.dtsi | 8 +--
arch/arm/boot/dts/pxa27x.dtsi | 14 ++---
arch/arm/boot/dts/sun8i-a33.dtsi | 8 +--
arch/arm/boot/dts/uniphier-pro5.dtsi | 32 +++++------
arch/arm/boot/dts/uniphier-pxs2.dtsi | 16 +++---
arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi | 48 ++++++++--------
arch/arm64/boot/dts/exynos/exynos5433.dtsi | 50 ++++++++--------
arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi | 14 ++---
arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi | 32 +++++------
arch/arm64/boot/dts/zte/zx296718.dtsi | 10 ++--
20 files changed, 295 insertions(+), 295 deletions(-)
diff --git a/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt
index ba0e15ad5bd9..0c38e4b8fc51 100644
--- a/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt
+++ b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt
@@ -63,64 +63,64 @@ cpu0_opp_table: opp-table {
* because they can not be enabled simultaneously on a
* single SoC.
*/
- opp50@300000000 {
+ opp50-300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <950000 931000 969000>;
opp-supported-hw = <0x06 0x0010>;
opp-suspend;
};
- opp100@275000000 {
+ opp100-275000000 {
opp-hz = /bits/ 64 <275000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x01 0x00FF>;
opp-suspend;
};
- opp100@300000000 {
+ opp100-300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x06 0x0020>;
opp-suspend;
};
- opp100@500000000 {
+ opp100-500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x01 0xFFFF>;
};
- opp100@600000000 {
+ opp100-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x06 0x0040>;
};
- opp120@600000000 {
+ opp120-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1200000 1176000 1224000>;
opp-supported-hw = <0x01 0xFFFF>;
};
- opp120@720000000 {
+ opp120-720000000 {
opp-hz = /bits/ 64 <720000000>;
opp-microvolt = <1200000 1176000 1224000>;
opp-supported-hw = <0x06 0x0080>;
};
- oppturbo@720000000 {
+ oppturbo-720000000 {
opp-hz = /bits/ 64 <720000000>;
opp-microvolt = <1260000 1234800 1285200>;
opp-supported-hw = <0x01 0xFFFF>;
};
- oppturbo@800000000 {
+ oppturbo-800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <1260000 1234800 1285200>;
opp-supported-hw = <0x06 0x0100>;
};
- oppnitro@1000000000 {
+ oppnitro-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1325000 1298500 1351500>;
opp-supported-hw = <0x04 0x0200>;
diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
index d085ef90d27c..f8e946471a58 100644
--- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
+++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
@@ -202,23 +202,23 @@ is able to support the bus frequency for all Exynos SoCs.
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
opp-microvolt = <800000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
opp-microvolt = <800000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
opp-microvolt = <800000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <825000>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <875000>;
};
@@ -292,23 +292,23 @@ is able to support the bus frequency for all Exynos SoCs.
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
opp-microvolt = <900000>;
};
- opp@80000000 {
+ opp-80000000 {
opp-hz = /bits/ 64 <80000000>;
opp-microvolt = <900000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
opp-microvolt = <1000000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
opp-microvolt = <1000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <1000000>;
};
@@ -318,19 +318,19 @@ is able to support the bus frequency for all Exynos SoCs.
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
};
- opp@80000000 {
+ opp-80000000 {
opp-hz = /bits/ 64 <80000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
};
};
@@ -339,19 +339,19 @@ is able to support the bus frequency for all Exynos SoCs.
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
};
- opp@80000000 {
+ opp-80000000 {
opp-hz = /bits/ 64 <80000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
- opp@300000000 {
+ opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
};
};
@@ -360,13 +360,13 @@ is able to support the bus frequency for all Exynos SoCs.
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
};
- opp@80000000 {
+ opp-80000000 {
opp-hz = /bits/ 64 <80000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
};
diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt
index 63725498bd20..e36d261b9ba6 100644
--- a/Documentation/devicetree/bindings/opp/opp.txt
+++ b/Documentation/devicetree/bindings/opp/opp.txt
@@ -186,20 +186,20 @@ Example 1: Single cluster Dual-core ARM cortex A9, switch DVFS states together.
compatible = "operating-points-v2";
opp-shared;
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <975000 970000 985000>;
opp-microamp = <70000>;
clock-latency-ns = <300000>;
opp-suspend;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
opp-microvolt = <1000000 980000 1010000>;
opp-microamp = <80000>;
clock-latency-ns = <310000>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1025000>;
clock-latency-ns = <290000>;
@@ -265,20 +265,20 @@ independently.
* independently.
*/
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <975000 970000 985000>;
opp-microamp = <70000>;
clock-latency-ns = <300000>;
opp-suspend;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
opp-microvolt = <1000000 980000 1010000>;
opp-microamp = <80000>;
clock-latency-ns = <310000>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1025000>;
opp-microamp = <90000;
@@ -341,20 +341,20 @@ DVFS state together.
compatible = "operating-points-v2";
opp-shared;
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <975000 970000 985000>;
opp-microamp = <70000>;
clock-latency-ns = <300000>;
opp-suspend;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
opp-microvolt = <1000000 980000 1010000>;
opp-microamp = <80000>;
clock-latency-ns = <310000>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1025000>;
opp-microamp = <90000>;
@@ -367,20 +367,20 @@ DVFS state together.
compatible = "operating-points-v2";
opp-shared;
- opp@1300000000 {
+ opp-1300000000 {
opp-hz = /bits/ 64 <1300000000>;
opp-microvolt = <1050000 1045000 1055000>;
opp-microamp = <95000>;
clock-latency-ns = <400000>;
opp-suspend;
};
- opp@1400000000 {
+ opp-1400000000 {
opp-hz = /bits/ 64 <1400000000>;
opp-microvolt = <1075000>;
opp-microamp = <100000>;
clock-latency-ns = <400000>;
};
- opp@1500000000 {
+ opp-1500000000 {
opp-hz = /bits/ 64 <1500000000>;
opp-microvolt = <1100000 1010000 1110000>;
opp-microamp = <95000>;
@@ -409,7 +409,7 @@ Example 4: Handling multiple regulators
compatible = "operating-points-v2";
opp-shared;
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <970000>, /* Supply 0 */
<960000>, /* Supply 1 */
@@ -422,7 +422,7 @@ Example 4: Handling multiple regulators
/* OR */
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <975000 970000 985000>, /* Supply 0 */
<965000 960000 975000>, /* Supply 1 */
@@ -435,7 +435,7 @@ Example 4: Handling multiple regulators
/* OR */
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <975000 970000 985000>, /* Supply 0 */
<965000 960000 975000>, /* Supply 1 */
@@ -467,7 +467,7 @@ Example 5: opp-supported-hw
status = "okay";
opp-shared;
- opp@600000000 {
+ opp-600000000 {
/*
* Supports all substrate and process versions for 0xF
* cuts, i.e. only first four cuts.
@@ -478,7 +478,7 @@ Example 5: opp-supported-hw
...
};
- opp@800000000 {
+ opp-800000000 {
/*
* Supports:
* - cuts: only one, 6th cut (represented by 6th bit).
@@ -510,7 +510,7 @@ Example 5: opp-supported-hw
compatible = "operating-points-v2";
opp-shared;
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt-slow = <915000 900000 925000>;
opp-microvolt-fast = <975000 970000 985000>;
@@ -518,7 +518,7 @@ Example 5: opp-supported-hw
opp-microamp-fast = <71000>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt-slow = <915000 900000 925000>, /* Supply vcc0 */
<925000 910000 935000>; /* Supply vcc1 */
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 97fcaf415de1..1532ffe1de63 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -60,32 +60,32 @@
cpu0_opp_table: opp_table0 {
compatible = "operating-points-v2";
- opp50@300000000 {
+ opp50-300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <950000 931000 969000>;
opp-supported-hw = <0xFF 0x01>;
opp-suspend;
};
- opp100@600000000 {
+ opp100-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0xFF 0x04>;
};
- opp120@720000000 {
+ opp120-720000000 {
opp-hz = /bits/ 64 <720000000>;
opp-microvolt = <1200000 1176000 1224000>;
opp-supported-hw = <0xFF 0x08>;
};
- oppturbo@800000000 {
+ oppturbo-800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <1260000 1234800 1285200>;
opp-supported-hw = <0xFF 0x10>;
};
- oppnitro@1000000000 {
+ oppnitro-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1325000 1298500 1351500>;
opp-supported-hw = <0xFF 0x20>;
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index 9c28ef4508e0..590ee442d0ae 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -745,23 +745,23 @@
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
opp-microvolt = <800000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
opp-microvolt = <800000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
opp-microvolt = <800000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <825000>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <875000>;
};
@@ -835,23 +835,23 @@
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
opp-microvolt = <900000>;
};
- opp@80000000 {
+ opp-80000000 {
opp-hz = /bits/ 64 <80000000>;
opp-microvolt = <900000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
opp-microvolt = <1000000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
opp-microvolt = <1000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <1000000>;
};
@@ -861,19 +861,19 @@
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
};
- opp@80000000 {
+ opp-80000000 {
opp-hz = /bits/ 64 <80000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
};
};
@@ -882,19 +882,19 @@
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
};
- opp@80000000 {
+ opp-80000000 {
opp-hz = /bits/ 64 <80000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
- opp@300000000 {
+ opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
};
};
@@ -903,13 +903,13 @@
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
};
- opp@80000000 {
+ opp-80000000 {
opp-hz = /bits/ 64 <80000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index f9408188f97f..3678d5b44d80 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -335,15 +335,15 @@
compatible = "operating-points-v2";
opp-shared;
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
opp-microvolt = <1025000>;
};
- opp@267000000 {
+ opp-267000000 {
opp-hz = /bits/ 64 <267000000>;
opp-microvolt = <1050000>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <1150000>;
};
@@ -353,13 +353,13 @@
compatible = "operating-points-v2";
opp-shared;
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
};
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
};
@@ -368,10 +368,10 @@
compatible = "operating-points-v2";
opp-shared;
- opp@5000000 {
+ opp-5000000 {
opp-hz = /bits/ 64 <5000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
};
@@ -380,10 +380,10 @@
compatible = "operating-points-v2";
opp-shared;
- opp@10000000 {
+ opp-10000000 {
opp-hz = /bits/ 64 <10000000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
};
};
@@ -392,13 +392,13 @@
compatible = "operating-points-v2";
opp-shared;
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
};
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
};
};
@@ -407,13 +407,13 @@
compatible = "operating-points-v2";
opp-shared;
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
};
diff --git a/arch/arm/boot/dts/exynos4412-prime.dtsi b/arch/arm/boot/dts/exynos4412-prime.dtsi
index e75bc170c89c..a67bd953d754 100644
--- a/arch/arm/boot/dts/exynos4412-prime.dtsi
+++ b/arch/arm/boot/dts/exynos4412-prime.dtsi
@@ -20,12 +20,12 @@
};
&cpu0_opp_table {
- opp@1600000000 {
+ opp-1600000000 {
opp-hz = /bits/ 64 <1600000000>;
opp-microvolt = <1350000>;
clock-latency-ns = <200000>;
};
- opp@1704000000 {
+ opp-1704000000 {
opp-hz = /bits/ 64 <1704000000>;
opp-microvolt = <1350000>;
clock-latency-ns = <200000>;
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index 235bbb69ad7c..ce240d0198b3 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -76,73 +76,73 @@
compatible = "operating-points-v2";
opp-shared;
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <900000>;
clock-latency-ns = <200000>;
};
- opp@300000000 {
+ opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <900000>;
clock-latency-ns = <200000>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <925000>;
clock-latency-ns = <200000>;
};
- opp@500000000 {
+ opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <950000>;
clock-latency-ns = <200000>;
};
- opp@600000000 {
+ opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <975000>;
clock-latency-ns = <200000>;
};
- opp@700000000 {
+ opp-700000000 {
opp-hz = /bits/ 64 <700000000>;
opp-microvolt = <987500>;
clock-latency-ns = <200000>;
};
- opp@800000000 {
+ opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <1000000>;
clock-latency-ns = <200000>;
opp-suspend;
};
- opp@900000000 {
+ opp-900000000 {
opp-hz = /bits/ 64 <900000000>;
opp-microvolt = <1037500>;
clock-latency-ns = <200000>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1087500>;
clock-latency-ns = <200000>;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
opp-microvolt = <1137500>;
clock-latency-ns = <200000>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1187500>;
clock-latency-ns = <200000>;
};
- opp@1300000000 {
+ opp-1300000000 {
opp-hz = /bits/ 64 <1300000000>;
opp-microvolt = <1250000>;
clock-latency-ns = <200000>;
};
- opp@1400000000 {
+ opp-1400000000 {
opp-hz = /bits/ 64 <1400000000>;
opp-microvolt = <1287500>;
clock-latency-ns = <200000>;
};
- cpu0_opp_1500: opp@1500000000 {
+ cpu0_opp_1500: opp-1500000000 {
opp-hz = /bits/ 64 <1500000000>;
opp-microvolt = <1350000>;
clock-latency-ns = <200000>;
@@ -433,23 +433,23 @@
compatible = "operating-points-v2";
opp-shared;
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
opp-microvolt = <900000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
opp-microvolt = <900000>;
};
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
opp-microvolt = <900000>;
};
- opp@267000000 {
+ opp-267000000 {
opp-hz = /bits/ 64 <267000000>;
opp-microvolt = <950000>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <1050000>;
};
@@ -459,16 +459,16 @@
compatible = "operating-points-v2";
opp-shared;
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
};
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
};
- opp@267000000 {
+ opp-267000000 {
opp-hz = /bits/ 64 <267000000>;
};
};
@@ -525,19 +525,19 @@
compatible = "operating-points-v2";
opp-shared;
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
opp-microvolt = <900000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
opp-microvolt = <925000>;
};
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
opp-microvolt = <950000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <1000000>;
};
@@ -547,10 +547,10 @@
compatible = "operating-points-v2";
opp-shared;
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
};
@@ -559,10 +559,10 @@
compatible = "operating-points-v2";
opp-shared;
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
};
};
@@ -571,10 +571,10 @@
compatible = "operating-points-v2";
opp-shared;
- opp@50000000 {
+ opp-50000000 {
opp-hz = /bits/ 64 <50000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
};
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 7dc9dc82afd8..5cd6c7389d51 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -49,62 +49,62 @@
cluster_a15_opp_table: opp_table0 {
compatible = "operating-points-v2";
opp-shared;
- opp@1800000000 {
+ opp-1800000000 {
opp-hz = /bits/ 64 <1800000000>;
opp-microvolt = <1250000>;
clock-latency-ns = <140000>;
};
- opp@1700000000 {
+ opp-1700000000 {
opp-hz = /bits/ 64 <1700000000>;
opp-microvolt = <1212500>;
clock-latency-ns = <140000>;
};
- opp@1600000000 {
+ opp-1600000000 {
opp-hz = /bits/ 64 <1600000000>;
opp-microvolt = <1175000>;
clock-latency-ns = <140000>;
};
- opp@1500000000 {
+ opp-1500000000 {
opp-hz = /bits/ 64 <1500000000>;
opp-microvolt = <1137500>;
clock-latency-ns = <140000>;
};
- opp@1400000000 {
+ opp-1400000000 {
opp-hz = /bits/ 64 <1400000000>;
opp-microvolt = <1112500>;
clock-latency-ns = <140000>;
};
- opp@1300000000 {
+ opp-1300000000 {
opp-hz = /bits/ 64 <1300000000>;
opp-microvolt = <1062500>;
clock-latency-ns = <140000>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1037500>;
clock-latency-ns = <140000>;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
opp-microvolt = <1012500>;
clock-latency-ns = <140000>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = < 987500>;
clock-latency-ns = <140000>;
};
- opp@900000000 {
+ opp-900000000 {
opp-hz = /bits/ 64 <900000000>;
opp-microvolt = < 962500>;
clock-latency-ns = <140000>;
};
- opp@800000000 {
+ opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = < 937500>;
clock-latency-ns = <140000>;
};
- opp@700000000 {
+ opp-700000000 {
opp-hz = /bits/ 64 <700000000>;
opp-microvolt = < 912500>;
clock-latency-ns = <140000>;
@@ -114,42 +114,42 @@
cluster_a7_opp_table: opp_table1 {
compatible = "operating-points-v2";
opp-shared;
- opp@1300000000 {
+ opp-1300000000 {
opp-hz = /bits/ 64 <1300000000>;
opp-microvolt = <1275000>;
clock-latency-ns = <140000>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1212500>;
clock-latency-ns = <140000>;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
opp-microvolt = <1162500>;
clock-latency-ns = <140000>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1112500>;
clock-latency-ns = <140000>;
};
- opp@900000000 {
+ opp-900000000 {
opp-hz = /bits/ 64 <900000000>;
opp-microvolt = <1062500>;
clock-latency-ns = <140000>;
};
- opp@800000000 {
+ opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <1025000>;
clock-latency-ns = <140000>;
};
- opp@700000000 {
+ opp-700000000 {
opp-hz = /bits/ 64 <700000000>;
opp-microvolt = <975000>;
clock-latency-ns = <140000>;
};
- opp@600000000 {
+ opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <937500>;
clock-latency-ns = <140000>;
diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi
index 8213016803e5..9ddb6bacac5a 100644
--- a/arch/arm/boot/dts/exynos5800.dtsi
+++ b/arch/arm/boot/dts/exynos5800.dtsi
@@ -24,60 +24,60 @@
};
&cluster_a15_opp_table {
- opp@1700000000 {
+ opp-1700000000 {
opp-microvolt = <1250000>;
};
- opp@1600000000 {
+ opp-1600000000 {
opp-microvolt = <1250000>;
};
- opp@1500000000 {
+ opp-1500000000 {
opp-microvolt = <1100000>;
};
- opp@1400000000 {
+ opp-1400000000 {
opp-microvolt = <1100000>;
};
- opp@1300000000 {
+ opp-1300000000 {
opp-microvolt = <1100000>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-microvolt = <1000000>;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-microvolt = <1000000>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-microvolt = <1000000>;
};
- opp@900000000 {
+ opp-900000000 {
opp-microvolt = <1000000>;
};
- opp@800000000 {
+ opp-800000000 {
opp-microvolt = <900000>;
};
- opp@700000000 {
+ opp-700000000 {
opp-microvolt = <900000>;
};
- opp@600000000 {
+ opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <900000>;
clock-latency-ns = <140000>;
};
- opp@500000000 {
+ opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <900000>;
clock-latency-ns = <140000>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <900000>;
clock-latency-ns = <140000>;
};
- opp@300000000 {
+ opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <900000>;
clock-latency-ns = <140000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <900000>;
clock-latency-ns = <140000>;
@@ -85,46 +85,46 @@
};
&cluster_a7_opp_table {
- opp@1300000000 {
+ opp-1300000000 {
opp-microvolt = <1250000>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-microvolt = <1250000>;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-microvolt = <1250000>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-microvolt = <1100000>;
};
- opp@900000000 {
+ opp-900000000 {
opp-microvolt = <1100000>;
};
- opp@800000000 {
+ opp-800000000 {
opp-microvolt = <1100000>;
};
- opp@700000000 {
+ opp-700000000 {
opp-microvolt = <1000000>;
};
- opp@600000000 {
+ opp-600000000 {
opp-microvolt = <1000000>;
};
- opp@500000000 {
+ opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <1000000>;
clock-latency-ns = <140000>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <1000000>;
clock-latency-ns = <140000>;
};
- opp@300000000 {
+ opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <900000>;
clock-latency-ns = <140000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <900000>;
clock-latency-ns = <140000>;
diff --git a/arch/arm/boot/dts/pxa25x.dtsi b/arch/arm/boot/dts/pxa25x.dtsi
index f9f4726396a0..95d59be97213 100644
--- a/arch/arm/boot/dts/pxa25x.dtsi
+++ b/arch/arm/boot/dts/pxa25x.dtsi
@@ -93,22 +93,22 @@
pxa250_opp_table: opp_table0 {
compatible = "operating-points-v2";
- opp@99532800 {
+ opp-99532800 {
opp-hz = /bits/ 64 <99532800>;
opp-microvolt = <1000000 950000 1650000>;
clock-latency-ns = <20>;
};
- opp@199065600 {
+ opp-199065600 {
opp-hz = /bits/ 64 <199065600>;
opp-microvolt = <1000000 950000 1650000>;
clock-latency-ns = <20>;
};
- opp@298598400 {
+ opp-298598400 {
opp-hz = /bits/ 64 <298598400>;
opp-microvolt = <1100000 1045000 1650000>;
clock-latency-ns = <20>;
};
- opp@398131200 {
+ opp-398131200 {
opp-hz = /bits/ 64 <398131200>;
opp-microvolt = <1300000 1235000 1650000>;
clock-latency-ns = <20>;
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index e0fab48ba6fa..5f1d6da02a4c 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -141,37 +141,37 @@
pxa270_opp_table: opp_table0 {
compatible = "operating-points-v2";
- opp@104000000 {
+ opp-104000000 {
opp-hz = /bits/ 64 <104000000>;
opp-microvolt = <900000 900000 1705000>;
clock-latency-ns = <20>;
};
- opp@156000000 {
+ opp-156000000 {
opp-hz = /bits/ 64 <156000000>;
opp-microvolt = <1000000 1000000 1705000>;
clock-latency-ns = <20>;
};
- opp@208000000 {
+ opp-208000000 {
opp-hz = /bits/ 64 <208000000>;
opp-microvolt = <1180000 1180000 1705000>;
clock-latency-ns = <20>;
};
- opp@312000000 {
+ opp-312000000 {
opp-hz = /bits/ 64 <312000000>;
opp-microvolt = <1250000 1250000 1705000>;
clock-latency-ns = <20>;
};
- opp@416000000 {
+ opp-416000000 {
opp-hz = /bits/ 64 <416000000>;
opp-microvolt = <1350000 1350000 1705000>;
clock-latency-ns = <20>;
};
- opp@520000000 {
+ opp-520000000 {
opp-hz = /bits/ 64 <520000000>;
opp-microvolt = <1450000 1450000 1705000>;
clock-latency-ns = <20>;
};
- opp@624000000 {
+ opp-624000000 {
opp-hz = /bits/ 64 <624000000>;
opp-microvolt = <1550000 1550000 1705000>;
clock-latency-ns = <20>;
diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi
index 0467fb365bfc..7c7f8d8abfa0 100644
--- a/arch/arm/boot/dts/sun8i-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a33.dtsi
@@ -49,25 +49,25 @@
compatible = "operating-points-v2";
opp-shared;
- opp@648000000 {
+ opp-648000000 {
opp-hz = /bits/ 64 <648000000>;
opp-microvolt = <1040000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
- opp@816000000 {
+ opp-816000000 {
opp-hz = /bits/ 64 <816000000>;
opp-microvolt = <1100000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
- opp@1008000000 {
+ opp-1008000000 {
opp-hz = /bits/ 64 <1008000000>;
opp-microvolt = <1200000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1320000>;
clock-latency-ns = <244144>; /* 8 32k periods */
diff --git a/arch/arm/boot/dts/uniphier-pro5.dtsi b/arch/arm/boot/dts/uniphier-pro5.dtsi
index dbc5e5333163..22ef2842be3a 100644
--- a/arch/arm/boot/dts/uniphier-pro5.dtsi
+++ b/arch/arm/boot/dts/uniphier-pro5.dtsi
@@ -77,67 +77,67 @@
compatible = "operating-points-v2";
opp-shared;
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
clock-latency-ns = <300>;
};
- opp@116667000 {
+ opp-116667000 {
opp-hz = /bits/ 64 <116667000>;
clock-latency-ns = <300>;
};
- opp@150000000 {
+ opp-150000000 {
opp-hz = /bits/ 64 <150000000>;
clock-latency-ns = <300>;
};
- opp@175000000 {
+ opp-175000000 {
opp-hz = /bits/ 64 <175000000>;
clock-latency-ns = <300>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
clock-latency-ns = <300>;
};
- opp@233334000 {
+ opp-233334000 {
opp-hz = /bits/ 64 <233334000>;
clock-latency-ns = <300>;
};
- opp@300000000 {
+ opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
clock-latency-ns = <300>;
};
- opp@350000000 {
+ opp-350000000 {
opp-hz = /bits/ 64 <350000000>;
clock-latency-ns = <300>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
clock-latency-ns = <300>;
};
- opp@466667000 {
+ opp-466667000 {
opp-hz = /bits/ 64 <466667000>;
clock-latency-ns = <300>;
};
- opp@600000000 {
+ opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
clock-latency-ns = <300>;
};
- opp@700000000 {
+ opp-700000000 {
opp-hz = /bits/ 64 <700000000>;
clock-latency-ns = <300>;
};
- opp@800000000 {
+ opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
clock-latency-ns = <300>;
};
- opp@933334000 {
+ opp-933334000 {
opp-hz = /bits/ 64 <933334000>;
clock-latency-ns = <300>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
clock-latency-ns = <300>;
};
- opp@1400000000 {
+ opp-1400000000 {
opp-hz = /bits/ 64 <1400000000>;
clock-latency-ns = <300>;
};
diff --git a/arch/arm/boot/dts/uniphier-pxs2.dtsi b/arch/arm/boot/dts/uniphier-pxs2.dtsi
index e9e031d63c1a..acaaa2187843 100644
--- a/arch/arm/boot/dts/uniphier-pxs2.dtsi
+++ b/arch/arm/boot/dts/uniphier-pxs2.dtsi
@@ -97,35 +97,35 @@
compatible = "operating-points-v2";
opp-shared;
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
clock-latency-ns = <300>;
};
- opp@150000000 {
+ opp-150000000 {
opp-hz = /bits/ 64 <150000000>;
clock-latency-ns = <300>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
clock-latency-ns = <300>;
};
- opp@300000000 {
+ opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
clock-latency-ns = <300>;
};
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
clock-latency-ns = <300>;
};
- opp@600000000 {
+ opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
clock-latency-ns = <300>;
};
- opp@800000000 {
+ opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
clock-latency-ns = <300>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
clock-latency-ns = <300>;
};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
index c42dc39c3223..ec11343dc528 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
@@ -94,27 +94,27 @@
compatible = "operating-points-v2";
opp-shared;
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <1075000>;
};
- opp@267000000 {
+ opp-267000000 {
opp-hz = /bits/ 64 <267000000>;
opp-microvolt = <1000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <975000>;
};
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
opp-microvolt = <962500>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
opp-microvolt = <950000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
opp-microvolt = <937500>;
};
@@ -123,19 +123,19 @@
bus_g2d_266_opp_table: opp_table3 {
compatible = "operating-points-v2";
- opp@267000000 {
+ opp-267000000 {
opp-hz = /bits/ 64 <267000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
};
@@ -143,13 +143,13 @@
bus_gscl_opp_table: opp_table4 {
compatible = "operating-points-v2";
- opp@333000000 {
+ opp-333000000 {
opp-hz = /bits/ 64 <333000000>;
};
- opp@222000000 {
+ opp-222000000 {
opp-hz = /bits/ 64 <222000000>;
};
- opp@166500000 {
+ opp-166500000 {
opp-hz = /bits/ 64 <166500000>;
};
};
@@ -158,22 +158,22 @@
compatible = "operating-points-v2";
opp-shared;
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
};
- opp@267000000 {
+ opp-267000000 {
opp-hz = /bits/ 64 <267000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
- opp@160000000 {
+ opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
};
@@ -181,16 +181,16 @@
bus_noc2_opp_table: opp_table6 {
compatible = "operating-points-v2";
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
};
- opp@200000000 {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
- opp@134000000 {
+ opp-134000000 {
opp-hz = /bits/ 64 <134000000>;
};
- opp@100000000 {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index 16072c1c3ed3..727f36abf3d4 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -119,43 +119,43 @@
compatible = "operating-points-v2";
opp-shared;
- opp@400000000 {
+ opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <900000>;
};
- opp@500000000 {
+ opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <925000>;
};
- opp@600000000 {
+ opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <950000>;
};
- opp@700000000 {
+ opp-700000000 {
opp-hz = /bits/ 64 <700000000>;
opp-microvolt = <975000>;
};
- opp@800000000 {
+ opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <1000000>;
};
- opp@900000000 {
+ opp-900000000 {
opp-hz = /bits/ 64 <900000000>;
opp-microvolt = <1050000>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1075000>;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
opp-microvolt = <1112500>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1112500>;
};
- opp@1300000000 {
+ opp-1300000000 {
opp-hz = /bits/ 64 <1300000000>;
opp-microvolt = <1150000>;
};
@@ -165,63 +165,63 @@
compatible = "operating-points-v2";
opp-shared;
- opp@500000000 {
+ opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <900000>;
};
- opp@600000000 {
+ opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <900000>;
};
- opp@700000000 {
+ opp-700000000 {
opp-hz = /bits/ 64 <700000000>;
opp-microvolt = <912500>;
};
- opp@800000000 {
+ opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <912500>;
};
- opp@900000000 {
+ opp-900000000 {
opp-hz = /bits/ 64 <900000000>;
opp-microvolt = <937500>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <975000>;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
opp-microvolt = <1012500>;
};
- opp@1200000000 {
+ opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1037500>;
};
- opp@1300000000 {
+ opp-1300000000 {
opp-hz = /bits/ 64 <1300000000>;
opp-microvolt = <1062500>;
};
- opp@1400000000 {
+ opp-1400000000 {
opp-hz = /bits/ 64 <1400000000>;
opp-microvolt = <1087500>;
};
- opp@1500000000 {
+ opp-1500000000 {
opp-hz = /bits/ 64 <1500000000>;
opp-microvolt = <1125000>;
};
- opp@1600000000 {
+ opp-1600000000 {
opp-hz = /bits/ 64 <1600000000>;
opp-microvolt = <1137500>;
};
- opp@1700000000 {
+ opp-1700000000 {
opp-hz = /bits/ 64 <1700000000>;
opp-microvolt = <1175000>;
};
- opp@1800000000 {
+ opp-1800000000 {
opp-hz = /bits/ 64 <1800000000>;
opp-microvolt = <1212500>;
};
- opp@1900000000 {
+ opp-1900000000 {
opp-hz = /bits/ 64 <1900000000>;
opp-microvolt = <1262500>;
};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
index da881f5b6ed4..0f2bee028ab0 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
@@ -89,31 +89,31 @@
compatible = "operating-points-v2";
opp-shared;
- opp@245000000 {
+ opp-245000000 {
opp-hz = /bits/ 64 <245000000>;
clock-latency-ns = <300>;
};
- opp@250000000 {
+ opp-250000000 {
opp-hz = /bits/ 64 <250000000>;
clock-latency-ns = <300>;
};
- opp@490000000 {
+ opp-490000000 {
opp-hz = /bits/ 64 <490000000>;
clock-latency-ns = <300>;
};
- opp@500000000 {
+ opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
clock-latency-ns = <300>;
};
- opp@653334000 {
+ opp-653334000 {
opp-hz = /bits/ 64 <653334000>;
clock-latency-ns = <300>;
};
- opp@666667000 {
+ opp-666667000 {
opp-hz = /bits/ 64 <666667000>;
clock-latency-ns = <300>;
};
- opp@980000000 {
+ opp-980000000 {
opp-hz = /bits/ 64 <980000000>;
clock-latency-ns = <300>;
};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
index a6b3a70dae83..19f782408d54 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
@@ -116,35 +116,35 @@
compatible = "operating-points-v2";
opp-shared;
- opp@250000000 {
+ opp-250000000 {
opp-hz = /bits/ 64 <250000000>;
clock-latency-ns = <300>;
};
- opp@275000000 {
+ opp-275000000 {
opp-hz = /bits/ 64 <275000000>;
clock-latency-ns = <300>;
};
- opp@500000000 {
+ opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
clock-latency-ns = <300>;
};
- opp@550000000 {
+ opp-550000000 {
opp-hz = /bits/ 64 <550000000>;
clock-latency-ns = <300>;
};
- opp@666667000 {
+ opp-666667000 {
opp-hz = /bits/ 64 <666667000>;
clock-latency-ns = <300>;
};
- opp@733334000 {
+ opp-733334000 {
opp-hz = /bits/ 64 <733334000>;
clock-latency-ns = <300>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
clock-latency-ns = <300>;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
clock-latency-ns = <300>;
};
@@ -154,35 +154,35 @@
compatible = "operating-points-v2";
opp-shared;
- opp@250000000 {
+ opp-250000000 {
opp-hz = /bits/ 64 <250000000>;
clock-latency-ns = <300>;
};
- opp@275000000 {
+ opp-275000000 {
opp-hz = /bits/ 64 <275000000>;
clock-latency-ns = <300>;
};
- opp@500000000 {
+ opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
clock-latency-ns = <300>;
};
- opp@550000000 {
+ opp-550000000 {
opp-hz = /bits/ 64 <550000000>;
clock-latency-ns = <300>;
};
- opp@666667000 {
+ opp-666667000 {
opp-hz = /bits/ 64 <666667000>;
clock-latency-ns = <300>;
};
- opp@733334000 {
+ opp-733334000 {
opp-hz = /bits/ 64 <733334000>;
clock-latency-ns = <300>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
clock-latency-ns = <300>;
};
- opp@1100000000 {
+ opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
clock-latency-ns = <300>;
};
diff --git a/arch/arm64/boot/dts/zte/zx296718.dtsi b/arch/arm64/boot/dts/zte/zx296718.dtsi
index b850b2cd0adc..2c7dc69987df 100644
--- a/arch/arm64/boot/dts/zte/zx296718.dtsi
+++ b/arch/arm64/boot/dts/zte/zx296718.dtsi
@@ -118,27 +118,27 @@
compatible = "operating-points-v2";
opp-shared;
- opp@500000000 {
+ opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
clock-latency-ns = <500000>;
};
- opp@648000000 {
+ opp-648000000 {
opp-hz = /bits/ 64 <648000000>;
clock-latency-ns = <500000>;
};
- opp@800000000 {
+ opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
clock-latency-ns = <500000>;
};
- opp@1000000000 {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
clock-latency-ns = <500000>;
};
- opp@1188000000 {
+ opp-1188000000 {
opp-hz = /bits/ 64 <1188000000>;
clock-latency-ns = <500000>;
};
--
2.12.0.432.g71c3a4f4ba37
^ permalink raw reply related
* Re: [PATCH v2 5/8] v4l: Switch from V4L2 OF not V4L2 fwnode API
From: Mika Westerberg @ 2017-04-10 9:21 UTC (permalink / raw)
To: Sakari Ailus
Cc: Laurent Pinchart, Sakari Ailus, linux-media, linux-acpi,
devicetree
In-Reply-To: <20170407225515.GM4192@valkosipuli.retiisi.org.uk>
On Sat, Apr 08, 2017 at 01:55:15AM +0300, Sakari Ailus wrote:
> > My ACPI knowledge is limited, but don't ACPI nodes have 4 character names that
> > can be combined in a string to create a full path ?
>
> There is something, yes, but the ACPI framework currently has no such
> functionality. I believe it could be implemented though. Cc Mika.
All ACPI node names are 32-bit integers and those are combined to form a
path, like \_SB.PCI0.I2C0 and so on. A single ACPI node name cannot be
larger than 4 chars, though.
^ permalink raw reply
* Re: [PATCH V4 1/9] PM / OPP: Allow OPP table to be used for power-domains
From: Viresh Kumar @ 2017-04-10 9:25 UTC (permalink / raw)
To: Rob Herring
Cc: Rafael Wysocki, ulf.hansson, Kevin Hilman, Viresh Kumar,
Nishanth Menon, Stephen Boyd, linaro-kernel, linux-pm,
linux-kernel, Vincent Guittot, lina.iyer, rnayak, devicetree
In-Reply-To: <20170324154451.ljszby3mhc4rlgnw@rob-hp-laptop>
On 24-03-17, 10:44, Rob Herring wrote:
> On Mon, Mar 20, 2017 at 03:02:13PM +0530, Viresh Kumar wrote:
> > Power-domains need to express their active states in DT and what's
> > better than OPP table for that.
> >
> > This patch allows power-domains to reuse OPP tables to express their
> > active states. The "opp-hz" property isn't a required property anymore
> > as power-domains may not always use them.
>
> Then maybe you shouldn't be trying to make OPP table work here. At that
> point you just need a table of voltage(s) per performance state?
Because that's what Kevin strongly recommended in the previous
versions.
@Kevin: Would you like to reply here ?
> > Add a new property "domain-performance-state", which will contain
> > positive integer values to represent performance levels of the
> > power-domains as described in this patch.
>
> Why not reference the OPP entries from the domain:
>
> performance-states = <&opp1>, <&opp2>;
Because that would require additional code in the OPP core to parse
these then. Right now it is quite straight forward with the bindings I
presented.
> Just thinking out loud, not saying that is what you should do. The
> continual evolution of power (management) domain, idle state, and OPP
> bindings is getting tiring.
I agree :)
--
viresh
^ permalink raw reply
* Re: [PATCH V4 1/9] PM / OPP: Allow OPP table to be used for power-domains
From: Viresh Kumar @ 2017-04-10 9:50 UTC (permalink / raw)
To: Rob Herring, Kevin Hilman
Cc: Rafael Wysocki, ulf.hansson, Viresh Kumar, Nishanth Menon,
Stephen Boyd, linaro-kernel, linux-pm, linux-kernel,
Vincent Guittot, lina.iyer, rnayak, devicetree
In-Reply-To: <20170410092515.GF24555@vireshk-i7>
Fixing Kevin's email id :(
On 10-04-17, 14:55, Viresh Kumar wrote:
> On 24-03-17, 10:44, Rob Herring wrote:
> > On Mon, Mar 20, 2017 at 03:02:13PM +0530, Viresh Kumar wrote:
> > > Power-domains need to express their active states in DT and what's
> > > better than OPP table for that.
> > >
> > > This patch allows power-domains to reuse OPP tables to express their
> > > active states. The "opp-hz" property isn't a required property anymore
> > > as power-domains may not always use them.
> >
> > Then maybe you shouldn't be trying to make OPP table work here. At that
> > point you just need a table of voltage(s) per performance state?
>
> Because that's what Kevin strongly recommended in the previous
> versions.
>
> @Kevin: Would you like to reply here ?
>
> > > Add a new property "domain-performance-state", which will contain
> > > positive integer values to represent performance levels of the
> > > power-domains as described in this patch.
> >
> > Why not reference the OPP entries from the domain:
> >
> > performance-states = <&opp1>, <&opp2>;
>
> Because that would require additional code in the OPP core to parse
> these then. Right now it is quite straight forward with the bindings I
> presented.
>
> > Just thinking out loud, not saying that is what you should do. The
> > continual evolution of power (management) domain, idle state, and OPP
> > bindings is getting tiring.
>
> I agree :)
--
viresh
^ permalink raw reply
* Re: [PATCH 1/2] leds: Add driver for Qualcomm LPG
From: Pavel Machek @ 2017-04-10 9:52 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Jacek Anaszewski, Rob Herring, Richard Purdie, linux-kernel,
linux-leds, linux-arm-msm, Mark Rutland, devicetree
In-Reply-To: <20170403182158.GV20094@minitux>
Hi!
> > Actually we could achieve the goal by listing all available pattern
> > configurations for given LED class device, so in case of Qualcomm LPG
> > driver we could have transition-pattern-1 to transition-pattern-15
> > listed after executing "cat trigger".
> >
>
> There's a common pattern-table of 24 (or 64) entries, that is shared
> among the 8 LPGs (each LPG simply has to indices pointing into the
> shared table). Each entry in the table holds a value between 0 and 511.
> So that's a lot of "available pattern configurations".
> > I wonder if I'm not missing some vital constraints here that could
> > make this design unfeasible.
> >
>
> Regardless of how we expose RGBs to userspace, the 8 LPG hardware blocks
> are independent of each other. The fact that they end up controlling
> something that is perceived by the human eye as some mixed color is to
> me a matter of system integration, and as such should not convolute the
> implementation of the individual instances.
Well... the 8 LPG blocks share the pattern-table.. and the pattern-table is very
limited. We could statically allocate 3 entries to each LPG block, but that
would not be too useful. And if we dynamically allocate entries depending on
patterns, then the LPG blocks are no longer independent.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Re: [PATCH v2 5/8] v4l: Switch from V4L2 OF not V4L2 fwnode API
From: Sakari Ailus @ 2017-04-10 9:59 UTC (permalink / raw)
To: Mika Westerberg, Sakari Ailus
Cc: Laurent Pinchart, linux-media, linux-acpi, devicetree
In-Reply-To: <20170410092147.GE2957@lahna.fi.intel.com>
Hi Mika and Laurent,
On 04/10/17 12:21, Mika Westerberg wrote:
> On Sat, Apr 08, 2017 at 01:55:15AM +0300, Sakari Ailus wrote:
>>> My ACPI knowledge is limited, but don't ACPI nodes have 4 character names that
>>> can be combined in a string to create a full path ?
>>
>> There is something, yes, but the ACPI framework currently has no such
>> functionality. I believe it could be implemented though. Cc Mika.
>
> All ACPI node names are 32-bit integers and those are combined to form a
> path, like \_SB.PCI0.I2C0 and so on. A single ACPI node name cannot be
> larger than 4 chars, though.
On OF, each node has a full_node string attached to it. You could
produce a similar string on ACPI, it is not currently done. Adding such
a string to each fwnode would require some extra memory as well. I
wonder if that could be a Kconfig option.
It would help debugging though.
Providing this information to the user space has been proposed as well:
Devicetree spec defines the syntax for such strings. The user can use
that information for recognising a particular device in the system.
The ACPI spec does, too, but it is limited to ACPI nodes and does not
address hierarchical data extensions. We'd define the syntax for those
ourselves.
Mika: what do you think?
On omap3isp and other drivers --- I think the solution for now should be
to assume OF instead. These drivers will be used on OF platforms only
anyway.
--
Kind regards,
Sakari Ailus
sakari.ailus@linux.intel.com
^ permalink raw reply
* Re: [PATCH v2 5/8] v4l: Switch from V4L2 OF not V4L2 fwnode API
From: Mika Westerberg @ 2017-04-10 10:11 UTC (permalink / raw)
To: Sakari Ailus
Cc: Sakari Ailus, Laurent Pinchart, linux-media, linux-acpi,
devicetree
In-Reply-To: <3e78d983-86da-3ac8-6c77-0720d8e0f534@linux.intel.com>
On Mon, Apr 10, 2017 at 12:59:36PM +0300, Sakari Ailus wrote:
> Hi Mika and Laurent,
>
> On 04/10/17 12:21, Mika Westerberg wrote:
> > On Sat, Apr 08, 2017 at 01:55:15AM +0300, Sakari Ailus wrote:
> >>> My ACPI knowledge is limited, but don't ACPI nodes have 4 character names that
> >>> can be combined in a string to create a full path ?
> >>
> >> There is something, yes, but the ACPI framework currently has no such
> >> functionality. I believe it could be implemented though. Cc Mika.
> >
> > All ACPI node names are 32-bit integers and those are combined to form a
> > path, like \_SB.PCI0.I2C0 and so on. A single ACPI node name cannot be
> > larger than 4 chars, though.
>
> On OF, each node has a full_node string attached to it. You could
> produce a similar string on ACPI, it is not currently done. Adding such
> a string to each fwnode would require some extra memory as well. I
> wonder if that could be a Kconfig option.
>
> It would help debugging though.
>
> Providing this information to the user space has been proposed as well:
> Devicetree spec defines the syntax for such strings. The user can use
> that information for recognising a particular device in the system.
>
> The ACPI spec does, too, but it is limited to ACPI nodes and does not
> address hierarchical data extensions. We'd define the syntax for those
> ourselves.
>
> Mika: what do you think?
There is a function acpi_get_name() which you can use to extract the
full name of the node. Why not investigate how to use that instead of
duplicating the name in an ACPI node.
^ permalink raw reply
* Re: [PATCH v2 5/8] v4l: Switch from V4L2 OF not V4L2 fwnode API
From: Sakari Ailus @ 2017-04-10 10:17 UTC (permalink / raw)
To: Mika Westerberg
Cc: Sakari Ailus, Laurent Pinchart, linux-media, linux-acpi,
devicetree
In-Reply-To: <20170410101128.GF2957@lahna.fi.intel.com>
Moi,
On 04/10/17 13:11, Mika Westerberg wrote:
> On Mon, Apr 10, 2017 at 12:59:36PM +0300, Sakari Ailus wrote:
>> Hi Mika and Laurent,
>>
>> On 04/10/17 12:21, Mika Westerberg wrote:
>>> On Sat, Apr 08, 2017 at 01:55:15AM +0300, Sakari Ailus wrote:
>>>>> My ACPI knowledge is limited, but don't ACPI nodes have 4 character names that
>>>>> can be combined in a string to create a full path ?
>>>>
>>>> There is something, yes, but the ACPI framework currently has no such
>>>> functionality. I believe it could be implemented though. Cc Mika.
>>>
>>> All ACPI node names are 32-bit integers and those are combined to form a
>>> path, like \_SB.PCI0.I2C0 and so on. A single ACPI node name cannot be
>>> larger than 4 chars, though.
>>
>> On OF, each node has a full_node string attached to it. You could
>> produce a similar string on ACPI, it is not currently done. Adding such
>> a string to each fwnode would require some extra memory as well. I
>> wonder if that could be a Kconfig option.
>>
>> It would help debugging though.
>>
>> Providing this information to the user space has been proposed as well:
>> Devicetree spec defines the syntax for such strings. The user can use
>> that information for recognising a particular device in the system.
>>
>> The ACPI spec does, too, but it is limited to ACPI nodes and does not
>> address hierarchical data extensions. We'd define the syntax for those
>> ourselves.
>>
>> Mika: what do you think?
>
> There is a function acpi_get_name() which you can use to extract the
> full name of the node. Why not investigate how to use that instead of
> duplicating the name in an ACPI node.
>
acpi_get_name() would obviously be needed to produce such a string in
the first place.
acpi_get_name() puts the string to an existing buffer so it cannot be
used as such to return a pointer to a string (e.g. to be used for
snprintf()). Also, it only contains the device path of the device. The
data extension path matters here, too.
--
Regards,
Sakari Ailus
sakari.ailus@linux.intel.com
^ permalink raw reply
* Re: [PATCH 1/2] ARM: dts: at91: sama5d3_xplained: fix ADC vref
From: Alexandre Belloni @ 2017-04-10 10:28 UTC (permalink / raw)
To: Ludovic Desroches
Cc: linux-arm-kernel, devicetree, linux-kernel, nicolas.ferre,
Eugen.Hristev, # 3 . 16+
In-Reply-To: <20170410082517.19628-1-ludovic.desroches@microchip.com>
On 10/04/2017 at 10:25:16 +0200, Ludovic Desroches wrote:
> The voltage reference for the ADC is not 3V but 3.3V since it is connected to
> VDDANA.
>
> Signed-off-by: Ludovic Desroches <ludovic.desroches@microchip.com>
> Cc: <stable@vger.kernel.org> # 3.16+
> ---
> arch/arm/boot/dts/at91-sama5d3_xplained.dts | 1 +
> 1 file changed, 1 insertion(+)
>
Applied, thanks.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: at91: sama5d3_xplained: not all ADC channels are available
From: Alexandre Belloni @ 2017-04-10 10:28 UTC (permalink / raw)
To: Ludovic Desroches
Cc: linux-arm-kernel, devicetree, linux-kernel, nicolas.ferre,
Eugen.Hristev, # 3 . 16+
In-Reply-To: <20170410082517.19628-2-ludovic.desroches@microchip.com>
On 10/04/2017 at 10:25:17 +0200, Ludovic Desroches wrote:
> Remove ADC channels that are not available by default on the sama5d3_xplained
> board (resistor not populated) in order to not create confusion.
>
> Signed-off-by: Ludovic Desroches <ludovic.desroches@microchip.com>
> Cc: <stable@vger.kernel.org> # 3.16+
> ---
> arch/arm/boot/dts/at91-sama5d3_xplained.dts | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
Applied, thanks.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
From: Ulf Hansson @ 2017-04-10 10:48 UTC (permalink / raw)
To: Y.B. Lu
Cc: linux-mmc@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Adrian Hunter, Rob Herring,
Mark Rutland, Catalin Marinas, Will Deacon, Xiaobo Xie
In-Reply-To: <DB6PR0401MB253627A0ABBF6DA9EC063A84F8010@DB6PR0401MB2536.eurprd04.prod.outlook.com>
On 10 April 2017 at 10:20, Y.B. Lu <yangbo.lu@nxp.com> wrote:
> Hi Andrian and Uffe,
>
> Do you have any comments on MMC patches?
> Could you help to merge the mmc patches if there is no changes requested?
I am waiting for Adrian's acks.
>
> Regarding to the dts patches, I have some more platforms to support.
> So I'd like to drop them currently, and send them all to arm mailing list for reviewing.
If it's new bindings/compatibles, the DT doc changes needs to be
discussed and agreed upon first. Actual changes to the DTS files,
should preferably go via the arm soc tree.
Kind regards
Uffe
^ permalink raw reply
* [PATCH V11 00/11] IOMMU probe deferral support
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
catalin.marinas, arnd, linux-arch, gregkh
Cc: sricharan
This series calls the dma ops configuration for the devices
at a generic place so that it works for all busses.
The dma_configure_ops for a device is now called during
the device_attach callback just before the probe of the
bus/driver is called. Similarly dma_deconfigure is called during
device/driver_detach path.
pci_bus_add_devices (platform/amba)(_device_create/driver_register)
| |
pci_bus_add_device (device_add/driver_register)
| |
device_attach device_initial_probe
| |
__device_attach_driver __device_attach_driver
|
driver_probe_device
|
really_probe
|
dma_configure
Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.
Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
against iommu-next and with 3-way merge applies on top of linux-next
as well (patch #8), because of "ACPI platform MSI support" from
Hanjun being merged.
* Tested with platform and pci devices for probe deferral
and reprobe on arm64 based platform.
Previous post of this series [8].
Please note that, i have kept the tested/acked tags intact from V8
because V9/10/11 were for more fixes that was added, so the original
tags that was given for the functional testing remains the same.
[V11]
* No functional changes.
* Rebased on top of 4.11-rc6.
* Dropped patch#3 from V10, as a result have to make
a change in patch#7 to return a 'non-void' to fix a
build warning.
* Added Robin's and Rob's tags.
[V10]
* Rebased on top of 4.11-rc5.
* Fixed coherent_dma_mask 64bit overflow issue [8]
for OF. The fix for OF was added as a separate
patch#6, since the issue is true even without probe deferral,
but gets reproduced with the probe deferral series.
Added Lorenzo's ACPI fix for coherent_dma_mask overflow
and the fix for dma_configure getting called more than
once for the same device.
* Also fixed an build issue caught by kbuild robot for
m68k arch. The issue was dma_(de)configure was not
getting defined for !CONFIG_HAS_DMA, so fixed that as well.
[V9]
* Rebased on top of 4.11-rc1.
* Merged Robin's fixes for legacy binding issue,
pci devices with no iommu-map property and deferencing
of_iommu_table after init.
[V8]
* Picked up all the acks and tested tags from Marek and
Hanjun for DT and ACPI patches respectively, since
no functional changes was done.
* Addressed Minor comments Sinan and Bjorn.
* Added Robin's fix for fixing the deferencing NULL for
of_iommu_table after init in patch #2.
* Rebased it on top of linux-next
[V7]
* Updated the subject and commit log for patch #6 as per
comments from Lorenzo. No functional changes.
[V6]
* Fixed a bug in dma_configure function pointed out by
Robin.
* Reordered the patches as per comments from Robin and
Lorenzo.
* Added Tags.
[V5]
* Reworked the pci configuration code hanging outside and
pushed it to dma_configure as in PATCH#5,6,7.
Also added a couple of patches that Lorenzo provided for
correcting the Probe deferring mechanism in case of
ACPI devices from here [5].
[V4]
* Took the reworked patches [2] from Robin's branch and
rebased on top of Lorenzo's ACPI IORT ARM support series [3].
* Added the patches for moving the dma ops configuration of
acpi based devices to probe time as well.
[V3]
* Removed the patch to split dma_masks/dma_ops configuration
separately based on review comments that both masks and ops are
required only during the device probe time.
* Reworked the series based on Generic DT bindings series.
* Added call to iommu's remove_device in the cleanup path for arm and
arm64.
* Removed the notifier trick in arm64 to handle early device
registration.
* Added reset of dma_ops in cleanup path for arm based on comments.
* Fixed the pci_iommu_configure path and tested with PCI device as
well.
* Fixed a bug to return the correct iommu_ops from patch 7 [4] in
last post.
* Fixed few other cosmetic comments.
[V2]
* Updated the Initial post to call dma_configure/deconfigure from
generic code
* Added iommu add_device callback from of_iommu_configure path
[V1]
* Initial post from Laurent Pinchart [1]
[1] http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013016.html
[2] http://www.linux-arm.org/git?p=linux-rm.git;a=shortlog;h=refs/heads/iommu/defer
[3] https://lkml.org/lkml/2016/11/21/141
[4] https://www.mail-archive.com/iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx/msg13940.html
[5] git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git iommu/probe-deferral
[6] http://www.spinics.net/lists/linux-pci/msg57992.html
[7] https://www.spinics.net/lists/arm-kernel/msg556209.html
[8] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/01557.html
Laurent Pinchart (2):
of: dma: Make of_dma_deconfigure() public
iommu: of: Handle IOMMU lookup failure with deferred probing or error
Lorenzo Pieralisi (2):
ACPI/IORT: Add function to check SMMUs drivers presence
ACPI/IORT: Remove linker section for IORT entries probing
Robin Murphy (3):
iommu/of: Refactor of_iommu_configure() for error handling
iommu/of: Prepare for deferred IOMMU configuration
iommu/arm-smmu: Clean up early-probing workarounds
Sricharan R (4):
of: device: Fix overflow of coherent_dma_mask
of/acpi: Configure dma operations at probe time for platform/amba/pci
bus devices
drivers: acpi: Handle IOMMU lookup failure with deferred probing or
error
arm64: dma-mapping: Remove the notifier trick to handle early setting
of dma_ops
arch/arm64/mm/dma-mapping.c | 142 +++++---------------------------------
drivers/acpi/arm64/iort.c | 48 ++++++++++++-
drivers/acpi/glue.c | 5 --
drivers/acpi/scan.c | 11 ++-
drivers/base/dd.c | 9 +++
drivers/base/dma-mapping.c | 41 +++++++++++
drivers/iommu/arm-smmu-v3.c | 46 +-----------
drivers/iommu/arm-smmu.c | 110 +++++++++++++----------------
drivers/iommu/of_iommu.c | 126 ++++++++++++++++++++++++---------
drivers/of/device.c | 23 +++++-
drivers/of/platform.c | 10 +--
drivers/pci/probe.c | 28 --------
include/acpi/acpi_bus.h | 2 +-
include/asm-generic/vmlinux.lds.h | 1 -
include/linux/acpi.h | 7 +-
include/linux/acpi_iort.h | 3 -
include/linux/dma-mapping.h | 12 ++++
include/linux/of_device.h | 10 ++-
18 files changed, 312 insertions(+), 322 deletions(-)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply
* [PATCH V11 01/11] iommu/of: Refactor of_iommu_configure() for error handling
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
catalin.marinas, arnd, linux-arch, gregkh
Cc: sricharan
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan@codeaurora.org>
From: Robin Murphy <robin.murphy@arm.com>
In preparation for some upcoming cleverness, rework the control flow in
of_iommu_configure() to minimise duplication and improve the propogation
of errors. It's also as good a time as any to switch over from the
now-just-a-compatibility-wrapper of_iommu_get_ops() to using the generic
IOMMU instance interface directly.
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/of_iommu.c | 83 +++++++++++++++++++++++++++++++-----------------
1 file changed, 53 insertions(+), 30 deletions(-)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 2683e9f..8f4e599 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,28 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
}
EXPORT_SYMBOL_GPL(of_get_dma_window);
+static const struct iommu_ops
+*of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
+{
+ const struct iommu_ops *ops;
+ struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
+ int err;
+
+ ops = iommu_ops_from_fwnode(fwnode);
+ if (!ops || !ops->of_xlate)
+ return NULL;
+
+ err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
+ if (err)
+ return ERR_PTR(err);
+
+ err = ops->of_xlate(dev, iommu_spec);
+ if (err)
+ return ERR_PTR(err);
+
+ return ops;
+}
+
static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
{
struct of_phandle_args *iommu_spec = data;
@@ -105,10 +127,11 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
}
static const struct iommu_ops
-*of_pci_iommu_configure(struct pci_dev *pdev, struct device_node *bridge_np)
+*of_pci_iommu_init(struct pci_dev *pdev, struct device_node *bridge_np)
{
const struct iommu_ops *ops;
struct of_phandle_args iommu_spec;
+ int err;
/*
* Start by tracing the RID alias down the PCI topology as
@@ -123,56 +146,56 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
* bus into the system beyond, and which IOMMU it ends up at.
*/
iommu_spec.np = NULL;
- if (of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
- "iommu-map-mask", &iommu_spec.np, iommu_spec.args))
- return NULL;
+ err = of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
+ "iommu-map-mask", &iommu_spec.np,
+ iommu_spec.args);
+ if (err)
+ return err == -ENODEV ? NULL : ERR_PTR(err);
- ops = iommu_ops_from_fwnode(&iommu_spec.np->fwnode);
- if (!ops || !ops->of_xlate ||
- iommu_fwspec_init(&pdev->dev, &iommu_spec.np->fwnode, ops) ||
- ops->of_xlate(&pdev->dev, &iommu_spec))
- ops = NULL;
+ ops = of_iommu_xlate(&pdev->dev, &iommu_spec);
of_node_put(iommu_spec.np);
return ops;
}
-const struct iommu_ops *of_iommu_configure(struct device *dev,
- struct device_node *master_np)
+static const struct iommu_ops
+*of_platform_iommu_init(struct device *dev, struct device_node *np)
{
struct of_phandle_args iommu_spec;
- struct device_node *np;
const struct iommu_ops *ops = NULL;
int idx = 0;
- if (dev_is_pci(dev))
- return of_pci_iommu_configure(to_pci_dev(dev), master_np);
-
/*
* We don't currently walk up the tree looking for a parent IOMMU.
* See the `Notes:' section of
* Documentation/devicetree/bindings/iommu/iommu.txt
*/
- while (!of_parse_phandle_with_args(master_np, "iommus",
- "#iommu-cells", idx,
- &iommu_spec)) {
- np = iommu_spec.np;
- ops = iommu_ops_from_fwnode(&np->fwnode);
-
- if (!ops || !ops->of_xlate ||
- iommu_fwspec_init(dev, &np->fwnode, ops) ||
- ops->of_xlate(dev, &iommu_spec))
- goto err_put_node;
-
- of_node_put(np);
+ while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells",
+ idx, &iommu_spec)) {
+ ops = of_iommu_xlate(dev, &iommu_spec);
+ of_node_put(iommu_spec.np);
idx++;
+ if (IS_ERR_OR_NULL(ops))
+ break;
}
return ops;
+}
+
+const struct iommu_ops *of_iommu_configure(struct device *dev,
+ struct device_node *master_np)
+{
+ const struct iommu_ops *ops;
+
+ if (!master_np)
+ return NULL;
+
+ if (dev_is_pci(dev))
+ ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
+ else
+ ops = of_platform_iommu_init(dev, master_np);
-err_put_node:
- of_node_put(np);
- return NULL;
+ return IS_ERR(ops) ? NULL : ops;
}
static int __init of_iommu_init(void)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH V11 02/11] iommu/of: Prepare for deferred IOMMU configuration
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
catalin.marinas, arnd, linux-arch, gregkh
Cc: sricharan
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan@codeaurora.org>
From: Robin Murphy <robin.murphy@arm.com>
IOMMU configuration represents unchanging properties of the hardware,
and as such should only need happen once in a device's lifetime, but
the necessary interaction with the IOMMU device and driver complicates
exactly when that point should be.
Since the only reasonable tool available for handling the inter-device
dependency is probe deferral, we need to prepare of_iommu_configure()
to run later than it is currently called (i.e. at driver probe rather
than device creation), to handle being retried, and to tell whether a
not-yet present IOMMU should be waited for or skipped (by virtue of
having declared a built-in driver or not).
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/of_iommu.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 8f4e599..c8be889 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,19 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
}
EXPORT_SYMBOL_GPL(of_get_dma_window);
+static bool of_iommu_driver_present(struct device_node *np)
+{
+ /*
+ * If the IOMMU still isn't ready by the time we reach init, assume
+ * it never will be. We don't want to defer indefinitely, nor attempt
+ * to dereference __iommu_of_table after it's been freed.
+ */
+ if (system_state > SYSTEM_BOOTING)
+ return false;
+
+ return of_match_node(&__iommu_of_table, np);
+}
+
static const struct iommu_ops
*of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
{
@@ -104,12 +117,20 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
int err;
ops = iommu_ops_from_fwnode(fwnode);
- if (!ops || !ops->of_xlate)
+ if ((ops && !ops->of_xlate) ||
+ (!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;
err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
if (err)
return ERR_PTR(err);
+ /*
+ * The otherwise-empty fwspec handily serves to indicate the specific
+ * IOMMU device we're waiting for, which will be useful if we ever get
+ * a proper probe-ordering dependency mechanism in future.
+ */
+ if (!ops)
+ return ERR_PTR(-EPROBE_DEFER);
err = ops->of_xlate(dev, iommu_spec);
if (err)
@@ -186,14 +207,34 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
struct device_node *master_np)
{
const struct iommu_ops *ops;
+ struct iommu_fwspec *fwspec = dev->iommu_fwspec;
if (!master_np)
return NULL;
+ if (fwspec) {
+ if (fwspec->ops)
+ return fwspec->ops;
+
+ /* In the deferred case, start again from scratch */
+ iommu_fwspec_free(dev);
+ }
+
if (dev_is_pci(dev))
ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
else
ops = of_platform_iommu_init(dev, master_np);
+ /*
+ * If we have reason to believe the IOMMU driver missed the initial
+ * add_device callback for dev, replay it to get things in order.
+ */
+ if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+ dev->bus && !dev->iommu_group) {
+ int err = ops->add_device(dev);
+
+ if (err)
+ ops = ERR_PTR(err);
+ }
return IS_ERR(ops) ? NULL : ops;
}
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH V11 03/11] of: dma: Make of_dma_deconfigure() public
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
catalin.marinas, arnd, linux-arch, gregkh
Cc: sricharan, Laurent Pinchart
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan@codeaurora.org>
From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
As part of moving DMA initializing to probe time the
of_dma_deconfigure() function will need to be called from different
source files. Make it public and move it to drivers/of/device.c where
the of_dma_configure() function is.
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
drivers/of/device.c | 12 ++++++++++++
drivers/of/platform.c | 5 -----
include/linux/of_device.h | 3 +++
3 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/of/device.c b/drivers/of/device.c
index b1e6beb..0d378c0 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -151,6 +151,18 @@ void of_dma_configure(struct device *dev, struct device_node *np)
}
EXPORT_SYMBOL_GPL(of_dma_configure);
+/**
+ * of_dma_deconfigure - Clean up DMA configuration
+ * @dev: Device for which to clean up DMA configuration
+ *
+ * Clean up all configuration performed by of_dma_configure_ops() and free all
+ * resources that have been allocated.
+ */
+void of_dma_deconfigure(struct device *dev)
+{
+ arch_teardown_dma_ops(dev);
+}
+
int of_device_register(struct platform_device *pdev)
{
device_initialize(&pdev->dev);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5dfcc96..5344db5 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -158,11 +158,6 @@ struct platform_device *of_device_alloc(struct device_node *np,
}
EXPORT_SYMBOL(of_device_alloc);
-static void of_dma_deconfigure(struct device *dev)
-{
- arch_teardown_dma_ops(dev);
-}
-
/**
* of_platform_device_create_pdata - Alloc, initialize and register an of_device
* @np: pointer to node to create device for
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index c12dace..af98455 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -56,6 +56,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
}
void of_dma_configure(struct device *dev, struct device_node *np);
+void of_dma_deconfigure(struct device *dev);
#else /* CONFIG_OF */
static inline int of_driver_match_device(struct device *dev,
@@ -105,6 +106,8 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
}
static inline void of_dma_configure(struct device *dev, struct device_node *np)
{}
+static inline void of_dma_deconfigure(struct device *dev)
+{}
#endif /* CONFIG_OF */
#endif /* _LINUX_OF_DEVICE_H */
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH V11 04/11] ACPI/IORT: Add function to check SMMUs drivers presence
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
catalin.marinas, arnd, linux-arch, gregkh
Cc: sricharan
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan@codeaurora.org>
From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
The IOMMU probe deferral implementation requires a mechanism to detect
if drivers for SMMU components are built-in in the kernel to detect
whether IOMMU configuration for a given device should be deferred (ie
SMMU drivers present but still not probed) or not (drivers not present).
Add a simple function to IORT to detect if SMMU drivers for SMMU
components managed by IORT are built-in in the kernel.
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Cc: Sricharan R <sricharan@codeaurora.org>
---
drivers/acpi/arm64/iort.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 4a5bb96..3dd9ec3 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -523,6 +523,19 @@ static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
return ret;
}
+static inline bool iort_iommu_driver_enabled(u8 type)
+{
+ switch (type) {
+ case ACPI_IORT_NODE_SMMU_V3:
+ return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
+ case ACPI_IORT_NODE_SMMU:
+ return IS_BUILTIN(CONFIG_ARM_SMMU);
+ default:
+ pr_warn("IORT node type %u does not describe an SMMU\n", type);
+ return false;
+ }
+}
+
static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
struct acpi_iort_node *node,
u32 streamid)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH V11 05/11] of: device: Fix overflow of coherent_dma_mask
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
catalin.marinas, arnd, linux-arch, gregkh
Cc: sricharan
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan@codeaurora.org>
Size of the dma-range is calculated as coherent_dma_mask + 1
and passed to arch_setup_dma_ops further. It overflows when
the coherent_dma_mask is set for full 64 bits 0xFFFFFFFFFFFFFFFF,
resulting in size getting passed as 0 wrongly. Fix this by
passsing in max(mask, mask + 1). Note that in this case
when the mask is set to full 64bits, we will be passing the mask
itself to arch_setup_dma_ops instead of the size. The real fix
for this should be to make arch_setup_dma_ops receive the
mask and handle it, to be done in the future.
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
drivers/of/device.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 0d378c0..e1ae9e7 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -107,7 +107,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
- size = dev->coherent_dma_mask + 1;
+ size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
} else {
offset = PFN_DOWN(paddr - dma_addr);
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH V11 06/11] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
linux-arch-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Configuring DMA ops at probe time will allow deferring device probe when
the IOMMU isn't available yet. The dma_configure for the device is
now called from the generic device_attach callback just before the
bus/driver probe is called. This way, configuring the DMA ops for the
device would be called at the same place for all bus_types, hence the
deferred probing mechanism should work for all buses as well.
pci_bus_add_devices (platform/amba)(_device_create/driver_register)
| |
pci_bus_add_device (device_add/driver_register)
| |
device_attach device_initial_probe
| |
__device_attach_driver __device_attach_driver
|
driver_probe_device
|
really_probe
|
dma_configure
Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.
This patch changes the dma ops configuration to probe time for
both OF and ACPI based platform/amba/pci bus devices.
Tested-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Acked-by: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org> (drivers/pci part)
Acked-by: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
drivers/acpi/glue.c | 5 -----
drivers/base/dd.c | 9 +++++++++
drivers/base/dma-mapping.c | 40 ++++++++++++++++++++++++++++++++++++++++
drivers/of/platform.c | 5 +----
drivers/pci/probe.c | 28 ----------------------------
include/linux/dma-mapping.h | 12 ++++++++++++
6 files changed, 62 insertions(+), 37 deletions(-)
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index fb19e1c..c05f241 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -176,7 +176,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
struct list_head *physnode_list;
unsigned int node_id;
int retval = -EINVAL;
- enum dev_dma_attr attr;
if (has_acpi_companion(dev)) {
if (acpi_dev) {
@@ -233,10 +232,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
if (!has_acpi_companion(dev))
ACPI_COMPANION_SET(dev, acpi_dev);
- attr = acpi_get_dma_attr(acpi_dev);
- if (attr != DEV_DMA_NOT_SUPPORTED)
- acpi_dma_configure(dev, attr);
-
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
physical_node_name);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a1fbf55..4882f06 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -19,6 +19,7 @@
#include <linux/device.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/wait.h>
@@ -356,6 +357,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
if (ret)
goto pinctrl_bind_failed;
+ ret = dma_configure(dev);
+ if (ret)
+ goto dma_failed;
+
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev_name(dev));
@@ -417,6 +422,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
goto done;
probe_failed:
+ dma_deconfigure(dev);
+dma_failed:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
@@ -826,6 +833,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
drv->remove(dev);
device_links_driver_cleanup(dev);
+ dma_deconfigure(dev);
+
devres_release_all(dev);
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index efd71cf..449b948 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -7,9 +7,11 @@
* This file is released under the GPLv2.
*/
+#include <linux/acpi.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
#include <linux/gfp.h>
+#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -341,3 +343,41 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
vunmap(cpu_addr);
}
#endif
+
+/*
+ * Common configuration to enable DMA API use for a device
+ */
+#include <linux/pci.h>
+
+int dma_configure(struct device *dev)
+{
+ struct device *bridge = NULL, *dma_dev = dev;
+ enum dev_dma_attr attr;
+
+ if (dev_is_pci(dev)) {
+ bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+ dma_dev = bridge;
+ if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
+ dma_dev->parent->of_node)
+ dma_dev = dma_dev->parent;
+ }
+
+ if (dma_dev->of_node) {
+ of_dma_configure(dev, dma_dev->of_node);
+ } else if (has_acpi_companion(dma_dev)) {
+ attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
+ if (attr != DEV_DMA_NOT_SUPPORTED)
+ acpi_dma_configure(dev, attr);
+ }
+
+ if (bridge)
+ pci_put_host_bridge_device(bridge);
+
+ return 0;
+}
+
+void dma_deconfigure(struct device *dev)
+{
+ of_dma_deconfigure(dev);
+ acpi_dma_deconfigure(dev);
+}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5344db5..2aa4ebb 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
+#include <linux/of_iommu.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
@@ -186,11 +187,9 @@ static struct platform_device *of_platform_device_create_pdata(
dev->dev.bus = &platform_bus_type;
dev->dev.platform_data = platform_data;
- of_dma_configure(&dev->dev, dev->dev.of_node);
of_msi_configure(&dev->dev, dev->dev.of_node);
if (of_device_add(dev) != 0) {
- of_dma_deconfigure(&dev->dev);
platform_device_put(dev);
goto err_clear_flag;
}
@@ -248,7 +247,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
dev_set_name(&dev->dev, "%s", bus_id);
else
of_device_make_bus_id(&dev->dev);
- of_dma_configure(&dev->dev, dev->dev.of_node);
/* Allow the HW Peripheral ID to be overridden */
prop = of_get_property(node, "arm,primecell-periphid", NULL);
@@ -542,7 +540,6 @@ static int of_platform_device_destroy(struct device *dev, void *data)
amba_device_unregister(to_amba_device(dev));
#endif
- of_dma_deconfigure(dev);
of_node_clear_flag(dev->of_node, OF_POPULATED);
of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
return 0;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dfc9a27..5a8dd43 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1893,33 +1893,6 @@ static void pci_set_msi_domain(struct pci_dev *dev)
dev_set_msi_domain(&dev->dev, d);
}
-/**
- * pci_dma_configure - Setup DMA configuration
- * @dev: ptr to pci_dev struct of the PCI device
- *
- * Function to update PCI devices's DMA configuration using the same
- * info from the OF node or ACPI node of host bridge's parent (if any).
- */
-static void pci_dma_configure(struct pci_dev *dev)
-{
- struct device *bridge = pci_get_host_bridge_device(dev);
-
- if (IS_ENABLED(CONFIG_OF) &&
- bridge->parent && bridge->parent->of_node) {
- of_dma_configure(&dev->dev, bridge->parent->of_node);
- } else if (has_acpi_companion(bridge)) {
- struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
- enum dev_dma_attr attr = acpi_get_dma_attr(adev);
-
- if (attr == DEV_DMA_NOT_SUPPORTED)
- dev_warn(&dev->dev, "DMA not supported.\n");
- else
- acpi_dma_configure(&dev->dev, attr);
- }
-
- pci_put_host_bridge_device(bridge);
-}
-
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
{
int ret;
@@ -1933,7 +1906,6 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
dev->dev.dma_mask = &dev->dma_mask;
dev->dev.dma_parms = &dev->dma_parms;
dev->dev.coherent_dma_mask = 0xffffffffull;
- pci_dma_configure(dev);
pci_set_dma_max_seg_size(dev, 65536);
pci_set_dma_seg_boundary(dev, 0xffffffff);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 0977317..4f3eece 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -728,6 +728,18 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
}
#endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
+#ifdef CONFIG_HAS_DMA
+int dma_configure(struct device *dev);
+void dma_deconfigure(struct device *dev);
+#else
+static inline int dma_configure(struct device *dev)
+{
+ return 0;
+}
+
+static inline void dma_deconfigure(struct device *dev) {}
+#endif
+
/*
* Managed DMA API
*/
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH V11 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
linux-arch-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
Cc: Laurent Pinchart
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
From: Laurent Pinchart <laurent.pinchart+renesas-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
Failures to look up an IOMMU when parsing the DT iommus property need to
be handled separately from the .of_xlate() failures to support deferred
probing.
The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.
The first case occurs when the device tree describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.
The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.
The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.
Tested-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Laurent Pichart <laurent.pinchart+renesas-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
[V11] Small change to return non-void value in one of returns
in of_dma_configure, as a result of dropping patch #3 from
previous V10. No functional impact.
drivers/base/dma-mapping.c | 5 +++--
drivers/iommu/of_iommu.c | 4 ++--
drivers/of/device.c | 9 +++++++--
include/linux/of_device.h | 9 ++++++---
4 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 449b948..82bd45c 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -353,6 +353,7 @@ int dma_configure(struct device *dev)
{
struct device *bridge = NULL, *dma_dev = dev;
enum dev_dma_attr attr;
+ int ret = 0;
if (dev_is_pci(dev)) {
bridge = pci_get_host_bridge_device(to_pci_dev(dev));
@@ -363,7 +364,7 @@ int dma_configure(struct device *dev)
}
if (dma_dev->of_node) {
- of_dma_configure(dev, dma_dev->of_node);
+ ret = of_dma_configure(dev, dma_dev->of_node);
} else if (has_acpi_companion(dma_dev)) {
attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
if (attr != DEV_DMA_NOT_SUPPORTED)
@@ -373,7 +374,7 @@ int dma_configure(struct device *dev)
if (bridge)
pci_put_host_bridge_device(bridge);
- return 0;
+ return ret;
}
void dma_deconfigure(struct device *dev)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index c8be889..9f44ee8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -236,7 +236,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
ops = ERR_PTR(err);
}
- return IS_ERR(ops) ? NULL : ops;
+ return ops;
}
static int __init of_iommu_init(void)
@@ -247,7 +247,7 @@ static int __init of_iommu_init(void)
for_each_matching_node_and_match(np, matches, &match) {
const of_iommu_init_fn init_fn = match->data;
- if (init_fn(np))
+ if (init_fn && init_fn(np))
pr_err("Failed to initialise IOMMU %s\n",
of_node_full_name(np));
}
diff --git a/drivers/of/device.c b/drivers/of/device.c
index e1ae9e7..8bd3d8c 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -82,7 +82,7 @@ int of_device_add(struct platform_device *ofdev)
* can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
* to fix up DMA configuration.
*/
-void of_dma_configure(struct device *dev, struct device_node *np)
+int of_dma_configure(struct device *dev, struct device_node *np)
{
u64 dma_addr, paddr, size;
int ret;
@@ -123,7 +123,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
if (!size) {
dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
- return;
+ return -EINVAL;
}
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}
@@ -144,10 +144,15 @@ void of_dma_configure(struct device *dev, struct device_node *np)
coherent ? " " : " not ");
iommu = of_iommu_configure(dev, np);
+ if (IS_ERR(iommu))
+ return PTR_ERR(iommu);
+
dev_dbg(dev, "device is%sbehind an iommu\n",
iommu ? " " : " not ");
arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(of_dma_configure);
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index af98455..2cacdd8 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -55,7 +55,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
return of_node_get(cpu_dev->of_node);
}
-void of_dma_configure(struct device *dev, struct device_node *np);
+int of_dma_configure(struct device *dev, struct device_node *np);
void of_dma_deconfigure(struct device *dev);
#else /* CONFIG_OF */
@@ -104,8 +104,11 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
{
return NULL;
}
-static inline void of_dma_configure(struct device *dev, struct device_node *np)
-{}
+
+static inline int of_dma_configure(struct device *dev, struct device_node *np)
+{
+ return 0;
+}
static inline void of_dma_deconfigure(struct device *dev)
{}
#endif /* CONFIG_OF */
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
linux-arch-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
This is an equivalent to the DT's handling of the iommu master's probe
with deferred probing when the corrsponding iommu is not probed yet.
The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.
The first case occurs when the firmware describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.
The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.
The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.
Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
called multiple times for same device]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
drivers/acpi/arm64/iort.c | 33 ++++++++++++++++++++++++++++++++-
drivers/acpi/scan.c | 11 ++++++++---
drivers/base/dma-mapping.c | 2 +-
include/acpi/acpi_bus.h | 2 +-
include/linux/acpi.h | 7 +++++--
5 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 3dd9ec3..e323ece 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
const struct iommu_ops *ops = NULL;
int ret = -ENODEV;
struct fwnode_handle *iort_fwnode;
+ struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+
+ /*
+ * If we already translated the fwspec there
+ * is nothing left to do, return the iommu_ops.
+ */
+ if (fwspec && fwspec->ops)
+ return fwspec->ops;
if (node) {
iort_fwnode = iort_get_fwnode(node);
@@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
return NULL;
ops = iommu_ops_from_fwnode(iort_fwnode);
+ /*
+ * If the ops look-up fails, this means that either
+ * the SMMU drivers have not been probed yet or that
+ * the SMMU drivers are not built in the kernel;
+ * Depending on whether the SMMU drivers are built-in
+ * in the kernel or not, defer the IOMMU configuration
+ * or just abort it.
+ */
if (!ops)
- return NULL;
+ return iort_iommu_driver_enabled(node->type) ?
+ ERR_PTR(-EPROBE_DEFER) : NULL;
ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
}
@@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
while (parent) {
ops = iort_iommu_xlate(dev, parent, streamid);
+ if (IS_ERR_OR_NULL(ops))
+ return ops;
parent = iort_node_get_id(node, &streamid,
IORT_IOMMU_TYPE, i++);
}
}
+ /*
+ * If we have reason to believe the IOMMU driver missed the initial
+ * add_device callback for dev, replay it to get things in order.
+ */
+ if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+ dev->bus && !dev->iommu_group) {
+ int err = ops->add_device(dev);
+
+ if (err)
+ ops = ERR_PTR(err);
+ }
+
return ops;
}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1926918..2a513cc 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
* @dev: The pointer to the device
* @attr: device dma attributes
*/
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
{
const struct iommu_ops *iommu;
+ u64 size;
iort_set_dma_mask(dev);
iommu = iort_iommu_configure(dev);
+ if (IS_ERR(iommu))
+ return PTR_ERR(iommu);
+ size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
/*
* Assume dma valid range starts at 0 and covers the whole
* coherent_dma_mask.
*/
- arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
- attr == DEV_DMA_COHERENT);
+ arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(acpi_dma_configure);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 82bd45c..755a2b5 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
} else if (has_acpi_companion(dma_dev)) {
attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
if (attr != DEV_DMA_NOT_SUPPORTED)
- acpi_dma_configure(dev, attr);
+ ret = acpi_dma_configure(dev, attr);
}
if (bridge)
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index ef0ae8a..2a9a5de 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -575,7 +575,7 @@ struct acpi_pci_root {
bool acpi_dma_supported(struct acpi_device *adev);
enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
void acpi_dma_deconfigure(struct device *dev);
struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 9b05886..79d06ef6 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
return DEV_DMA_NOT_SUPPORTED;
}
-static inline void acpi_dma_configure(struct device *dev,
- enum dev_dma_attr attr) { }
+static inline int acpi_dma_configure(struct device *dev,
+ enum dev_dma_attr attr)
+{
+ return 0;
+}
static inline void acpi_dma_deconfigure(struct device *dev) { }
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH V11 09/11] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
linux-arch-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
With arch_setup_dma_ops now being called late during device's probe after
the device's iommu is probed, the notifier trick required to handle the
early setup of dma_ops before the iommu group gets created is not
required. So removing the notifier's here.
Tested-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Acked-by: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
[rm: clean up even more]
Signed-off-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
---
arch/arm64/mm/dma-mapping.c | 142 ++++++--------------------------------------
1 file changed, 18 insertions(+), 124 deletions(-)
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 81cdb2e..b465759 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -813,34 +813,26 @@ static void __iommu_unmap_sg_attrs(struct device *dev,
.mapping_error = iommu_dma_mapping_error,
};
-/*
- * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
- * everything it needs to - the device is only partially created and the
- * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
- * need this delayed attachment dance. Once IOMMU probe ordering is sorted
- * to move the arch_setup_dma_ops() call later, all the notifier bits below
- * become unnecessary, and will go away.
- */
-struct iommu_dma_notifier_data {
- struct list_head list;
- struct device *dev;
- const struct iommu_ops *ops;
- u64 dma_base;
- u64 size;
-};
-static LIST_HEAD(iommu_dma_masters);
-static DEFINE_MUTEX(iommu_dma_notifier_lock);
+static int __init __iommu_dma_init(void)
+{
+ return iommu_dma_init();
+}
+arch_initcall(__iommu_dma_init);
-static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
- u64 dma_base, u64 size)
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ const struct iommu_ops *ops)
{
- struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+ struct iommu_domain *domain;
+
+ if (!ops)
+ return;
/*
- * If the IOMMU driver has the DMA domain support that we require,
- * then the IOMMU core will have already configured a group for this
- * device, and allocated the default domain for that group.
+ * The IOMMU core code allocates the default DMA domain, which the
+ * underlying IOMMU driver needs to support via the dma-iommu layer.
*/
+ domain = iommu_get_domain_for_dev(dev);
+
if (!domain)
goto out_err;
@@ -851,109 +843,11 @@ static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
dev->dma_ops = &iommu_dma_ops;
}
- return true;
+ return;
+
out_err:
- pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
+ pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
dev_name(dev));
- return false;
-}
-
-static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
- u64 dma_base, u64 size)
-{
- struct iommu_dma_notifier_data *iommudata;
-
- iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
- if (!iommudata)
- return;
-
- iommudata->dev = dev;
- iommudata->ops = ops;
- iommudata->dma_base = dma_base;
- iommudata->size = size;
-
- mutex_lock(&iommu_dma_notifier_lock);
- list_add(&iommudata->list, &iommu_dma_masters);
- mutex_unlock(&iommu_dma_notifier_lock);
-}
-
-static int __iommu_attach_notifier(struct notifier_block *nb,
- unsigned long action, void *data)
-{
- struct iommu_dma_notifier_data *master, *tmp;
-
- if (action != BUS_NOTIFY_BIND_DRIVER)
- return 0;
-
- mutex_lock(&iommu_dma_notifier_lock);
- list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
- if (data == master->dev && do_iommu_attach(master->dev,
- master->ops, master->dma_base, master->size)) {
- list_del(&master->list);
- kfree(master);
- break;
- }
- }
- mutex_unlock(&iommu_dma_notifier_lock);
- return 0;
-}
-
-static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
-{
- struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
- int ret;
-
- if (!nb)
- return -ENOMEM;
-
- nb->notifier_call = __iommu_attach_notifier;
-
- ret = bus_register_notifier(bus, nb);
- if (ret) {
- pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops unavailable on bus '%s'\n",
- bus->name);
- kfree(nb);
- }
- return ret;
-}
-
-static int __init __iommu_dma_init(void)
-{
- int ret;
-
- ret = iommu_dma_init();
- if (!ret)
- ret = register_iommu_dma_ops_notifier(&platform_bus_type);
- if (!ret)
- ret = register_iommu_dma_ops_notifier(&amba_bustype);
-#ifdef CONFIG_PCI
- if (!ret)
- ret = register_iommu_dma_ops_notifier(&pci_bus_type);
-#endif
- return ret;
-}
-arch_initcall(__iommu_dma_init);
-
-static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
- const struct iommu_ops *ops)
-{
- struct iommu_group *group;
-
- if (!ops)
- return;
- /*
- * TODO: As a concession to the future, we're ready to handle being
- * called both early and late (i.e. after bus_add_device). Once all
- * the platform bus code is reworked to call us late and the notifier
- * junk above goes away, move the body of do_iommu_attach here.
- */
- group = iommu_group_get(dev);
- if (group) {
- do_iommu_attach(dev, ops, dma_base, size);
- iommu_group_put(group);
- } else {
- queue_iommu_attach(dev, ops, dma_base, size);
- }
}
void arch_teardown_dma_ops(struct device *dev)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH V11 10/11] iommu/arm-smmu: Clean up early-probing workarounds
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
linux-arch-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
In-Reply-To: <1491823266-1209-1-git-send-email-sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
From: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Now that the appropriate ordering is enforced via probe-deferral of
masters in core code, rip it all out and bask in the simplicity.
Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Acked-by: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
[Sricharan: Rebased on top of ACPI IORT SMMU series]
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
drivers/iommu/arm-smmu-v3.c | 46 +-----------------
drivers/iommu/arm-smmu.c | 110 +++++++++++++++++++-------------------------
2 files changed, 49 insertions(+), 107 deletions(-)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 5806a6a..9497800 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2761,51 +2761,9 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
.probe = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
};
+module_platform_driver(arm_smmu_driver);
-static int __init arm_smmu_init(void)
-{
- static bool registered;
- int ret = 0;
-
- if (!registered) {
- ret = platform_driver_register(&arm_smmu_driver);
- registered = !ret;
- }
- return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
- return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
- int ret = arm_smmu_init();
-
- if (ret)
- return ret;
-
- if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
- return -ENODEV;
-
- return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init acpi_smmu_v3_init(struct acpi_table_header *table)
-{
- if (iort_node_match(ACPI_IORT_NODE_SMMU_V3))
- return arm_smmu_init();
-
- return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu_v3, ACPI_SIG_IORT, acpi_smmu_v3_init);
-#endif
+IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
MODULE_AUTHOR("Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index abf6496..be53b02 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2075,6 +2075,23 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
return 0;
}
+static void arm_smmu_bus_init(void)
+{
+ /* Oh, for a proper bus abstraction */
+ if (!iommu_present(&platform_bus_type))
+ bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+#ifdef CONFIG_ARM_AMBA
+ if (!iommu_present(&amba_bustype))
+ bus_set_iommu(&amba_bustype, &arm_smmu_ops);
+#endif
+#ifdef CONFIG_PCI
+ if (!iommu_present(&pci_bus_type)) {
+ pci_request_acs();
+ bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
+ }
+#endif
+}
+
static int arm_smmu_device_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -2180,21 +2197,30 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
arm_smmu_device_reset(smmu);
arm_smmu_test_smr_masks(smmu);
- /* Oh, for a proper bus abstraction */
- if (!iommu_present(&platform_bus_type))
- bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
-#ifdef CONFIG_ARM_AMBA
- if (!iommu_present(&amba_bustype))
- bus_set_iommu(&amba_bustype, &arm_smmu_ops);
-#endif
-#ifdef CONFIG_PCI
- if (!iommu_present(&pci_bus_type)) {
- pci_request_acs();
- bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
- }
-#endif
+ /*
+ * For ACPI and generic DT bindings, an SMMU will be probed before
+ * any device which might need it, so we want the bus ops in place
+ * ready to handle default domain setup as soon as any SMMU exists.
+ */
+ if (!using_legacy_binding)
+ arm_smmu_bus_init();
+
+ return 0;
+}
+
+/*
+ * With the legacy DT binding in play, though, we have no guarantees about
+ * probe order, but then we're also not doing default domains, so we can
+ * delay setting bus ops until we're sure every possible SMMU is ready,
+ * and that way ensure that no add_device() calls get missed.
+ */
+static int arm_smmu_legacy_bus_init(void)
+{
+ if (using_legacy_binding)
+ arm_smmu_bus_init();
return 0;
}
+device_initcall_sync(arm_smmu_legacy_bus_init);
static int arm_smmu_device_remove(struct platform_device *pdev)
{
@@ -2219,56 +2245,14 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
.probe = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
};
-
-static int __init arm_smmu_init(void)
-{
- static bool registered;
- int ret = 0;
-
- if (!registered) {
- ret = platform_driver_register(&arm_smmu_driver);
- registered = !ret;
- }
- return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
- return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
- int ret = arm_smmu_init();
-
- if (ret)
- return ret;
-
- if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
- return -ENODEV;
-
- return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", arm_smmu_of_init);
-IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init arm_smmu_acpi_init(struct acpi_table_header *table)
-{
- if (iort_node_match(ACPI_IORT_NODE_SMMU))
- return arm_smmu_init();
-
- return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu, ACPI_SIG_IORT, arm_smmu_acpi_init);
-#endif
+module_platform_driver(arm_smmu_driver);
+
+IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", NULL);
+IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", NULL);
+IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", NULL);
+IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", NULL);
+IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", NULL);
+IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", NULL);
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
MODULE_AUTHOR("Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>");
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox