* [PATCH v2 1/5] i2c: mux: pca954x: Add missing pca9542 definition to chip_desc
From: Phil Reid @ 2017-01-05 4:10 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1483589463-35380-1-git-send-email-preid@electromag.com.au>
The spec for the pca954x was missing. This chip is the same as the pca9540
except that it has interrupt lines. While the i2c_device_id table mapped
the pca9542 to the pca9540 definition the compatible table did not. In
preparation for irq support add the pca9542 definition.
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index dd18b9c..bbf088e 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -84,6 +84,11 @@ struct pca954x {
.enable = 0x4,
.muxtype = pca954x_ismux,
},
+ [pca_9542] = {
+ .nchans = 2,
+ .enable = 0x4,
+ .muxtype = pca954x_ismux,
+ },
[pca_9543] = {
.nchans = 2,
.muxtype = pca954x_isswi,
@@ -110,7 +115,7 @@ struct pca954x {
static const struct i2c_device_id pca954x_id[] = {
{ "pca9540", pca_9540 },
- { "pca9542", pca_9540 },
+ { "pca9542", pca_9542 },
{ "pca9543", pca_9543 },
{ "pca9544", pca_9544 },
{ "pca9545", pca_9545 },
@@ -124,7 +129,7 @@ struct pca954x {
#ifdef CONFIG_ACPI
static const struct acpi_device_id pca954x_acpi_ids[] = {
{ .id = "PCA9540", .driver_data = pca_9540 },
- { .id = "PCA9542", .driver_data = pca_9540 },
+ { .id = "PCA9542", .driver_data = pca_9542 },
{ .id = "PCA9543", .driver_data = pca_9543 },
{ .id = "PCA9544", .driver_data = pca_9544 },
{ .id = "PCA9545", .driver_data = pca_9545 },
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 2/5] dt: bindings: i2c-mux-pca954x: Add documentation for interrupt controller
From: Phil Reid @ 2017-01-05 4:11 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1483589463-35380-1-git-send-email-preid@electromag.com.au>
Various muxes can aggregate multiple irq lines and provide a control
register to determine the active line. Add bindings for interrupt
controller support.
Acked-by: Peter Rosin <peda@axentia.se>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
index cf53d5f..aa09704 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
@@ -19,7 +19,14 @@ Optional Properties:
- i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
children in idle state. This is necessary for example, if there are several
multiplexers on the bus and the devices behind them use same I2C addresses.
-
+ - interrupt-parent: Phandle for the interrupt controller that services
+ interrupts for this device.
+ - interrupts: Interrupt mapping for IRQ.
+ - interrupt-controller: Marks the device node as an interrupt controller.
+ - #interrupt-cells : Should be two.
+ - first cell is the pin number
+ - second cell is used to specify flags.
+ See also Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Example:
@@ -29,6 +36,11 @@ Example:
#size-cells = <0>;
reg = <0x74>;
+ interrupt-parent = <&ipic>;
+ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 3/5] i2c: mux: pca954x: Add interrupt controller support
From: Phil Reid @ 2017-01-05 4:11 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1483589463-35380-1-git-send-email-preid@electromag.com.au>
Various muxes can aggregate multiple interrupts from each i2c bus.
All of the muxes with interrupt support combine the active low irq lines
using an internal 'and' function and generate a combined active low
output. The muxes do provide the ability to read a control register to
determine which irq is active. By making the mux an irq controller isr
latency can potentially be reduced by reading the status register and
then only calling the registered isr on that bus segment.
As there is no irq masking on the mux irq are disabled until irq_unmask is
called at least once.
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 127 +++++++++++++++++++++++++++++++++++-
1 file changed, 125 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index bbf088e..84fc767 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -41,14 +41,19 @@
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/i2c/pca954x.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_irq.h>
#include <linux/pm.h>
#include <linux/slab.h>
#define PCA954X_MAX_NCHANS 8
+#define PCA954X_IRQ_OFFSET 4
+
enum pca_type {
pca_9540,
pca_9542,
@@ -63,6 +68,7 @@ enum pca_type {
struct chip_desc {
u8 nchans;
u8 enable; /* used for muxes only */
+ u8 has_irq;
enum muxtype {
pca954x_ismux = 0,
pca954x_isswi
@@ -75,6 +81,9 @@ struct pca954x {
u8 last_chan; /* last register value */
u8 deselect;
struct i2c_client *client;
+
+ struct irq_domain *irq;
+ unsigned int irq_mask;
};
/* Provide specs for the PCA954x types we know about */
@@ -87,19 +96,23 @@ struct pca954x {
[pca_9542] = {
.nchans = 2,
.enable = 0x4,
+ .has_irq = 1,
.muxtype = pca954x_ismux,
},
[pca_9543] = {
.nchans = 2,
+ .has_irq = 1,
.muxtype = pca954x_isswi,
},
[pca_9544] = {
.nchans = 4,
.enable = 0x4,
+ .has_irq = 1,
.muxtype = pca954x_ismux,
},
[pca_9545] = {
.nchans = 4,
+ .has_irq = 1,
.muxtype = pca954x_isswi,
},
[pca_9547] = {
@@ -222,6 +235,102 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan)
return pca954x_reg_write(muxc->parent, client, data->last_chan);
}
+static irqreturn_t pca954x_irq_handler(int irq, void *dev_id)
+{
+ struct pca954x *data = dev_id;
+ unsigned int child_irq;
+ int ret, i, handled;
+
+ ret = i2c_smbus_read_byte(data->client);
+ if (ret < 0)
+ return IRQ_NONE;
+
+ for (i = 0; i < data->chip->nchans; i++) {
+ if (ret & BIT(PCA954X_IRQ_OFFSET + i)) {
+ child_irq = irq_linear_revmap(data->irq, i);
+ handle_nested_irq(child_irq);
+ handled++;
+ }
+ }
+ return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void pca954x_irq_mask(struct irq_data *idata)
+{
+ struct pca954x *data = irq_data_get_irq_chip_data(idata);
+ unsigned int pos = idata->hwirq;
+
+ data->irq_mask &= ~BIT(pos);
+ if (!data->irq_mask)
+ disable_irq(data->client->irq);
+}
+
+static void pca954x_irq_unmask(struct irq_data *idata)
+{
+ struct pca954x *data = irq_data_get_irq_chip_data(idata);
+ unsigned int pos = idata->hwirq;
+
+ if (!data->irq_mask)
+ enable_irq(data->client->irq);
+ data->irq_mask |= BIT(pos);
+}
+
+static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type)
+{
+ if ((type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_LOW)
+ return -EINVAL;
+ return 0;
+}
+
+static struct irq_chip pca954x_irq_chip = {
+ .name = "i2c-mux-pca954x",
+ .irq_mask = pca954x_irq_mask,
+ .irq_unmask = pca954x_irq_unmask,
+ .irq_set_type = pca954x_irq_set_type,
+};
+
+static int pca954x_irq_setup(struct i2c_mux_core *muxc)
+{
+ struct pca954x *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
+ int c, err, irq;
+
+ if (!data->chip->has_irq || client->irq <= 0)
+ return 0;
+
+ data->irq = irq_domain_add_linear(client->dev.of_node,
+ data->chip->nchans,
+ &irq_domain_simple_ops, data);
+ if (!data->irq)
+ return -ENODEV;
+
+ for (c = 0; c < data->chip->nchans; c++) {
+ irq = irq_create_mapping(data->irq, c);
+ irq_set_chip_data(irq, data);
+ irq_set_chip_and_handler(irq, &pca954x_irq_chip,
+ handle_simple_irq);
+ }
+
+ err = devm_request_threaded_irq(&client->dev, data->client->irq, NULL,
+ pca954x_irq_handler,
+ IRQF_ONESHOT | IRQF_SHARED,
+ "pca954x", data);
+ if (err)
+ goto err_req_irq;
+
+ disable_irq(data->client->irq);
+
+ return 0;
+err_req_irq:
+ for (c = 0; c < data->chip->nchans; c++) {
+ irq = irq_find_mapping(data->irq, c);
+ irq_dispose_mapping(irq);
+ }
+ irq_domain_remove(data->irq);
+
+ return err;
+}
+
/*
* I2C init/probing/exit functions
*/
@@ -286,6 +395,10 @@ static int pca954x_probe(struct i2c_client *client,
idle_disconnect_dt = of_node &&
of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
+ ret = pca954x_irq_setup(muxc);
+ if (ret)
+ goto fail_del_adapters;
+
/* Now create an adapter for each channel */
for (num = 0; num < data->chip->nchans; num++) {
bool idle_disconnect_pd = false;
@@ -311,7 +424,7 @@ static int pca954x_probe(struct i2c_client *client,
dev_err(&client->dev,
"failed to register multiplexed adapter"
" %d as bus %d\n", num, force);
- goto virt_reg_failed;
+ goto fail_del_adapters;
}
}
@@ -322,7 +435,7 @@ static int pca954x_probe(struct i2c_client *client,
return 0;
-virt_reg_failed:
+fail_del_adapters:
i2c_mux_del_adapters(muxc);
return ret;
}
@@ -330,6 +443,16 @@ static int pca954x_probe(struct i2c_client *client,
static int pca954x_remove(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
+ struct pca954x *data = i2c_mux_priv(muxc);
+ int c, irq;
+
+ if (data->irq) {
+ for (c = 0; c < data->chip->nchans; c++) {
+ irq = irq_find_mapping(data->irq, c);
+ irq_dispose_mapping(irq);
+ }
+ irq_domain_remove(data->irq);
+ }
i2c_mux_del_adapters(muxc);
return 0;
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 4/5] dt: bindings: i2c-mux-pca954x: Add documentation for i2c-mux-irq-mask-en
From: Phil Reid @ 2017-01-05 4:11 UTC (permalink / raw)
To: peda-koto5C5qi+TLoDKTGw+V6w, wsa-z923LK4zBo2bacvFa/9K2g,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1483589463-35380-1-git-send-email-preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
Unfortunately some hardware device will assert their irq line immediately
on power on and provide no mechanism to mask the irq. As the i2c muxes
provide no method to mask irq line this provides a work around by keeping
the parent irq masked until enough device drivers have loaded to service
all pending interrupts.
For example the the ltc1760 assert its SMBALERT irq immediately on power
on. With two ltc1760 attached to bus 0 & 1 on a pca954x mux when the first
device is registered irq are enabled and fire continuously as the second
device driver has not yet loaded. Setting this parameter to 0x3 while
delay the irq being enabled until both devices are ready.
Acked-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
Signed-off-by: Phil Reid <preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
---
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
index aa09704..6de1e8e 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
@@ -19,6 +19,8 @@ Optional Properties:
- i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
children in idle state. This is necessary for example, if there are several
multiplexers on the bus and the devices behind them use same I2C addresses.
+ - nxp,irq-mask-enable: BitMask; Defines a mask for which irq lines need to be
+ unmasked before the parent irq line in enabled.
- interrupt-parent: Phandle for the interrupt controller that services
interrupts for this device.
- interrupts: Interrupt mapping for IRQ.
@@ -36,6 +38,7 @@ Example:
#size-cells = <0>;
reg = <0x74>;
+ nxp,irq-mask-enable = <0x3>;
interrupt-parent = <&ipic>;
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
--
1.8.3.1
--
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 related
* [PATCH v2 5/5] i2c: mux: pca954x: Add irq_mask_en to delay enabling irqs
From: Phil Reid @ 2017-01-05 4:11 UTC (permalink / raw)
To: peda-koto5C5qi+TLoDKTGw+V6w, wsa-z923LK4zBo2bacvFa/9K2g,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1483589463-35380-1-git-send-email-preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
Unfortunately some hardware device will assert their irq line immediately
on power on and provide no mechanism to mask the irq. As the i2c muxes
provide no method to mask irq line this provides a work around by keeping
the parent irq masked until enough device drivers have loaded to service
all pending interrupts.
For example the the ltc1760 assert its SMBALERT irq immediately on power
on. With two ltc1760 attached to bus 0 & 1 on a pca954x mux when the first
device is registered irq are enabled and fire continuously as the second
device driver has not yet loaded. Setting this parameter to 0x3 while
delay the irq being enabled until both devices are ready.
Acked-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
Signed-off-by: Phil Reid <preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 84fc767..581a75d 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -75,6 +75,19 @@ struct chip_desc {
} muxtype;
};
+/*
+ * irq_mask_enable: Provides a mechanism to work around hardware that asserts
+ * their irq immediately on power on. It allows the enabling of the irq to be
+ * delayed until the corresponding bits in the the irq_mask are set thru
+ * irq_unmask.
+ * For example the the ltc1760 assert its SMBALERT irq immediately on power
+ * on. With two ltc1760 attached to bus 0 & 1 on a pca954x mux when the first
+ * device is registered irq are enabled and fire continuously as the second
+ * device driver has not yet loaded. Setting this parameter to 0x3 while
+ * delay the irq being enabled until both devices are ready.
+ * This workaround will not work if two devices share an interrupt on the
+ * same bus segment.
+ */
struct pca954x {
const struct chip_desc *chip;
@@ -84,6 +97,7 @@ struct pca954x {
struct irq_domain *irq;
unsigned int irq_mask;
+ unsigned int irq_mask_enable;
};
/* Provide specs for the PCA954x types we know about */
@@ -270,9 +284,12 @@ static void pca954x_irq_unmask(struct irq_data *idata)
struct pca954x *data = irq_data_get_irq_chip_data(idata);
unsigned int pos = idata->hwirq;
- if (!data->irq_mask)
+ if (!data->irq_mask_enable && !data->irq_mask)
enable_irq(data->client->irq);
data->irq_mask |= BIT(pos);
+ if (data->irq_mask_enable &&
+ (data->irq_mask & data->irq_mask) == data->irq_mask_enable)
+ enable_irq(data->client->irq);
}
static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type)
@@ -395,6 +412,9 @@ static int pca954x_probe(struct i2c_client *client,
idle_disconnect_dt = of_node &&
of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
+ of_property_read_u32(of_node, "nxp,irq-mask-enable",
+ &data->irq_mask_enable);
+
ret = pca954x_irq_setup(muxc);
if (ret)
goto fail_del_adapters;
--
1.8.3.1
--
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 related
* Re: [PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X
From: Chen-Yu Tsai @ 2017-01-05 4:12 UTC (permalink / raw)
To: Quentin Schulz
Cc: Mark Rutland, devicetree, Lars-Peter Clausen, open list:THERMAL,
linux-iio, linux-kernel, Sebastian Reichel, Russell King,
Chen-Yu Tsai, Rob Herring, linux-arm-kernel,
Peter Meerwald-Stadler, knaack.h, Maxime Ripard,
Bruno Prémont, Lee Jones, Thomas Petazzoni, Jonathan Cameron,
Icenowy Zheng
In-Reply-To: <20170102163723.7939-3-quentin.schulz@free-electrons.com>
On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> The AXP22X PMICs have multiple ADCs, each one exposing data from the
> different power supplies connected to the PMIC.
>
> This adds the different ADC data registers to the volatile registers of
> the AXP22X PMIC.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
> drivers/mfd/axp20x.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 619a83e..a33db5e 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -100,6 +100,7 @@ static const struct regmap_range axp22x_writeable_ranges[] = {
> static const struct regmap_range axp22x_volatile_ranges[] = {
> regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
> regmap_reg_range(AXP20X_VBUS_IPSOUT_MGMT, AXP20X_VBUS_IPSOUT_MGMT),
> + regmap_reg_range(AXP22X_TEMP_ADC_H, AXP20X_BATT_DISCHRG_I_L),
You added this macro in the next patch. Please move that hunk to this patch.
ChenYu
> regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
> regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
> regmap_reg_range(AXP22X_PMIC_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
> --
> 2.9.3
>
^ permalink raw reply
* Re: [PATCH V2 1/5] Documetation: samsung-phy: add the exynos-pcie-phy binding
From: Alim Akhtar @ 2017-01-05 4:16 UTC (permalink / raw)
To: Jaehoon Chung, linux-pci
Cc: devicetree, linux-kernel, linux-samsung-soc, bhelgaas, robh+dt,
mark.rutland, kgene, krzk, kishon, jingoohan1, vivek.gautam,
pankaj.dubey, cpgs
In-Reply-To: <20170104123435.30740-2-jh80.chung@samsung.com>
Hi Jaehoon,
On 01/04/2017 06:04 PM, Jaehoon Chung wrote:
> Adds the exynos-pcie-phy binding for Exynos PCIe PHY.
> This is for using generic PHY framework.
>
> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
> ---
> Changelog on V2:
> - Remove the child node.
> - Add 2nd address to the parent reg prop.
>
> Documentation/devicetree/bindings/phy/samsung-phy.txt | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
> index 9872ba8..ab80bfe 100644
> --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
> +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
> @@ -191,3 +191,20 @@ Example:
> usbdrdphy0 = &usb3_phy0;
> usbdrdphy1 = &usb3_phy1;
> };
> +
> +Samsung Exynos SoC series PCIe PHY controller
> +--------------------------------------------------
> +Required properties:
> +- compatible : Should be set to "samsung,exynos5440-pcie-phy"
> +- #phy-cells : Must be zero
> +- reg : a register used by phy driver.
> + - First is for phy register, second is for block register.
> +- reg-names : Must be set to "phy" and "block".
> +
In general PHY uses a "reference clock" to work, if that is true for
5440 also, will you consider adding an (may be) optional clock
properties as well?
otherwise this binding looks ok to me.
> +Example:
> + pcie_phy0: pcie-phy@270000 {
> + #phy-cells = <0>;
> + compatible = "samsung,exynos5440-pcie-phy";
> + reg = <0x270000 0x1000>, <0x271000 0x40>;
> + reg-names = "phy", "block";
> + };
>
^ permalink raw reply
* Re: [PATCHv2 0/5] Support for Marvell switches with integrated CPUs
From: Chris Packham @ 2017-01-05 4:24 UTC (permalink / raw)
To: Florian Fainelli, linux-arm-kernel@lists.infradead.org
Cc: Mark Rutland, Andrew Lunn, Geert Uytterhoeven, Michael Turquette,
Laxman Dewangan, linux-clk@vger.kernel.org, Juri Lelli,
Russell King, Thierry Reding, Linus Walleij,
Sebastian Hesselbarth, devicetree@vger.kernel.org, Jason Cooper,
Arnd Bergmann, Kalyan Kinthada, Rob Herring, Gregory Clement,
Thomas Petazzoni, linux-gpio@vger.kernel.org, Stephen Boyd
In-Reply-To: <6c6795d3-06ab-a4f0-78ad-5ecc78c1aa2f@gmail.com>
On 05/01/17 17:07, Florian Fainelli wrote:
> Le 01/04/17 à 19:36, Chris Packham a écrit :
>> The 98DX3236, 98DX3336 and 98DX4251 are a set of switch ASICs with
>> integrated CPUs. They CPU block is common within these product lines and
>> (as far as I can tell/have been told) is based on the Armada XP. There
>> are a few differences due to the fact they have to squeeze the CPU into
>> the same package as the switch.
>
> It's really great to see these changes, do you have a plan to also add
> support for the integrated switch using a DSA/switchdev driver?
I'd love to see a switchdev driver but it's a huge task (and no I'm not
committing to writing it). As it stands Marvell ship a switch SDK
largely executes in userspace with a small kernel module providing some
linkage to the underlying hardware.
We (a few of us here at Allied Telesis NZ) have discussed switchdev and
how we get from using Marvell's SDK in our products to using switchdev
proper.
The first step would probably be some kind of trampoline driver which
communicates with a userspace helper to do the actual work.
Alternatively there is some support in Marvell's SDK for compilation as
a binary blob so a proprietary kernel module is another option. Neither
of these are particularly nice in a free software world.
A full "free" implementation would be a large undertaking. Ideally I'd
like to see Marvell involved with producing one but so far they've not
been interested whenever I've brought it up.
^ permalink raw reply
* Re: [PATCHv2 4/5] arm: mvebu: Add device tree for 98DX3236 SoCs
From: Chris Packham @ 2017-01-05 4:34 UTC (permalink / raw)
To: Florian Fainelli, linux-arm-kernel@lists.infradead.org
Cc: Mark Rutland, Andrew Lunn, Jason Cooper,
devicetree@vger.kernel.org, Russell King,
linux-kernel@vger.kernel.org, Rob Herring, Gregory Clement,
Sebastian Hesselbarth
In-Reply-To: <1ee850ee-f771-1aeb-6b96-dfbe3118f2fc@gmail.com>
On 05/01/17 17:06, Florian Fainelli wrote:
> Le 01/04/17 à 19:36, Chris Packham a écrit :
>> The Marvell 98DX3236, 98DX3336, 98DX4521 and variants are switch ASICs
>> with integrated CPUs. They are similar to the Armada XP SoCs but have
>> different I/O interfaces.
>>
>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>> ---
>> +
>> + switch {
>> + packet-processor@0 {
>> + compatible = "marvell,prestera-98dx4521";
>> + };
>> + };
>
> This may be a bit premature if you are not providing a binding document
> for this sub-node, you might as well add it once you also add a
> corresponding driver (or if this will remain out of tree, at least
> submitting a separate binding document).
I also see that I made a typo 4521 should be 4251.
The driver that uses this is an out of tree one so I will add a binding
document for it for now.
It wouldn't he hard to whip up a simple uio based driver that provides
mmap access to the switch register space so I might look at that if I
get time. It would be useful for testing if nothing else.
>
> Also, if this node's unit address is 0, you would expect at least a reg
> property whose address cell is 0 to be present.
>
The reg property is in the base 98dx3236 dsti file. The 3 devices have
the same IO footprint but the switching functionality is quite different
between them hence the different compatible strings (all of which I need
to add binding documentation for). I guess I could make the 3236 entry
pp0: packet-processor@0 {
compatible = "marvell,prestera-98dx3236";
reg = <0 0x4000000>;
...
}
Then the 3336 and 4251 could just override the compatible string
&pp0 {
compatible = "marvell,prestera-98dx4251";
};
Would that be clearer?
^ permalink raw reply
* Re: [PATCHv2 2/5] arm: mvebu: support for SMP on 98DX3336 SoC
From: Chris Packham @ 2017-01-05 4:46 UTC (permalink / raw)
To: Florian Fainelli,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Cc: Rob Herring, Mark Rutland, Jason Cooper, Andrew Lunn,
Gregory Clement, Sebastian Hesselbarth, Russell King,
Geert Uytterhoeven, Chris Brand, Sudeep Holla, Jayachandran C,
Juri Lelli, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <5edb6751-d15b-6654-f4ae-adf38fafb8a4@gmail.com>
On 05/01/17 17:04, Florian Fainelli wrote:
> Le 01/04/17 à 19:36, Chris Packham a écrit :
>> Compared to the armada-xp the 98DX3336 uses different registers to set
>> the boot address for the secondary CPU so a new enable-method is needed.
>> This will only work if the machine definition doesn't define an overall
>> smp_ops because there is not currently a way of overriding this from the
>> device tree if it is set in the machine definition.
>
> Not sure I follow you here, in theory, each individual CPU could have a
> different enable-method property, and considering how you leverage
> existing DTS include files, you should be able to override the DTS with
> the appropriate enable-method, or do you have a different problem?
>
The problem is I can't override the enable method if it's set in the
machine definition. It's because the devicetree is looked up first then
the machine definition overrides it.
Heres an old thread that basically outlines the problem.
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/300371.html
I posted a few attempts to work around it but there never really was any
consensus reached.
> mv98dx3236_resume_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
>> +{
>> + WARN_ON(hw_cpu != 1);
>> +
>> + writel(0, mv98dx3236_resume_base + MV98DX3236_CPU_RESUME_CTRL_OFFSET);
>> + writel(virt_to_phys(boot_addr), mv98dx3236_resume_base +
>> + MV98DX3236_CPU_RESUME_ADDR_OFFSET);
>
> I just submitted a patch series that switches such users to
> __pa_symbol() instead of virt_to_phys() because this is a kernel image
> symbol. For now this will work as-is, but depending on which patch
> series makes it first, it may be a good idea to keep this on someone's
> TODO list (yours or mine). I do expect having to make a second pass of
> conversions anyway.
>
> [1]: https://lkml.org/lkml/2017/1/4/1101
OK I'll keep that in mind.
>
>> +}
>> +
>> +static int __init mv98dx3236_resume_init(void)
>> +{
>> + struct device_node *np;
>> + struct resource res;
>> + int ret = 0;
>> +
>> + np = of_find_matching_node(NULL, of_mv98dx3236_resume_table);
>> + if (!np)
>> + return 0;
>> +
>> + pr_info("Initializing 98DX3236 Resume\n");
>
> This can be probably be dropped, you should know fairly quickly if this
> succeeded or not.
Will do.
>
> Can't this function be implemented as a smp_ops::smp_init_cpus instead
> of having this initialization done at arch_initcall time?
>
I'll look into it. My initial reaction is no because I still need
armada_xp_smp_init_cpus().
>> +
>> + if (of_address_to_resource(np, 0, &res)) {
>> + pr_err("unable to get resource\n");
>> + ret = -ENOENT;
>> + goto out;
>> + }
>> +
>> + if (!request_mem_region(res.start, resource_size(&res),
>> + np->full_name)) {
>> + pr_err("unable to request region\n");
>> + ret = -EBUSY;
>> + goto out;
>> + }
>
> You should be able to use of_io_request_and_map() and here.
>
Will do.
--
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 v2] i2c: do not enable fall back to Host Notify by default
From: Dmitry Torokhov @ 2017-01-05 4:57 UTC (permalink / raw)
To: Wolfram Sang
Cc: Rob Herring, Benjamin Tissoires, Pali Rohár,
Michał Kępień, Jean Delvare, Takashi Iwai,
linux-i2c, devicetree, linux-kernel
Falling back unconditionally to HostNotify as primary client's interrupt
breaks some drivers which alter their functionality depending on whether
interrupt is present or not, so let's introduce a board flag telling I2C
core explicitly if we want wired interrupt or HostNotify-based one:
I2C_CLIENT_HOST_NOTIFY.
For DT-based systems we introduce "host-notify" property that we convert
to I2C_CLIENT_HOST_NOTIFY board flag.
Tested-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
v1->v2:
- of_read_property_bool -> of_property_read_bool
- did not change binding wording to avoit mentioning I2C core because we
use the same wording (mentioning I2C core) for wired interrupts
Documentation/devicetree/bindings/i2c/i2c.txt | 8 ++++++++
drivers/i2c/i2c-core.c | 17 ++++++++---------
include/linux/i2c.h | 1 +
3 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt
index 5fa691e6f638..cee9d5055fa2 100644
--- a/Documentation/devicetree/bindings/i2c/i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c.txt
@@ -62,6 +62,9 @@ wants to support one of the below features, it should adapt the bindings below.
"irq" and "wakeup" names are recognized by I2C core, other names are
left to individual drivers.
+- host-notify
+ device uses SMBus host notify protocol instead of interrupt line.
+
- multi-master
states that there is another master active on this bus. The OS can use
this information to adapt power management to keep the arbitration awake
@@ -81,6 +84,11 @@ Binding may contain optional "interrupts" property, describing interrupts
used by the device. I2C core will assign "irq" interrupt (or the very first
interrupt if not using interrupt names) as primary interrupt for the slave.
+Alternatively, devices supporting SMbus Host Notify, and connected to
+adapters that support this feature, may use "host-notify" property. I2C
+core will create a virtual interrupt for Host Notify and assign it as
+primary interrupt for the slave.
+
Also, if device is marked as a wakeup source, I2C core will set up "wakeup"
interrupt for the device. If "wakeup" interrupt name is not present in the
binding, then primary interrupt will be used as wakeup interrupt.
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index cf9e396d7702..7b117240f1ea 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -931,7 +931,10 @@ static int i2c_device_probe(struct device *dev)
if (!client->irq) {
int irq = -ENOENT;
- if (dev->of_node) {
+ if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
+ dev_dbg(dev, "Using Host Notify IRQ\n");
+ irq = i2c_smbus_host_notify_to_irq(client);
+ } else if (dev->of_node) {
irq = of_irq_get_byname(dev->of_node, "irq");
if (irq == -EINVAL || irq == -ENODATA)
irq = of_irq_get(dev->of_node, 0);
@@ -940,14 +943,7 @@ static int i2c_device_probe(struct device *dev)
}
if (irq == -EPROBE_DEFER)
return irq;
- /*
- * ACPI and OF did not find any useful IRQ, try to see
- * if Host Notify can be used.
- */
- if (irq < 0) {
- dev_dbg(dev, "Using Host Notify IRQ\n");
- irq = i2c_smbus_host_notify_to_irq(client);
- }
+
if (irq < 0)
irq = 0;
@@ -1716,6 +1712,9 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
info.of_node = of_node_get(node);
info.archdata = &dev_ad;
+ if (of_property_read_bool(node, "host-notify"))
+ info.flags |= I2C_CLIENT_HOST_NOTIFY;
+
if (of_get_property(node, "wakeup-source", NULL))
info.flags |= I2C_CLIENT_WAKE;
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index b2109c522dec..4b45ec46161f 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -665,6 +665,7 @@ i2c_unlock_adapter(struct i2c_adapter *adapter)
#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
/* Must equal I2C_M_TEN below */
#define I2C_CLIENT_SLAVE 0x20 /* we are the slave */
+#define I2C_CLIENT_HOST_NOTIFY 0x40 /* We want to use I2C host notify */
#define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */
#define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */
/* Must match I2C_M_STOP|IGNORE_NAK */
--
2.11.0.390.gc69c2f50cf-goog
--
Dmitry
^ permalink raw reply related
* Re: [PATCH v3 02/10] dt-bindings: hisi: Add Hisilicon HiP05/06/07 Djtag dts bindings
From: Anurup M @ 2017-01-05 4:58 UTC (permalink / raw)
To: Rob Herring
Cc: mark.rutland-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
anurup.m-hv44wF8Li93QT0dZR+AlfA,
zhangshaokun-C8/M+/jPZTeaMJb+Lgu22Q,
tanxiaojun-hv44wF8Li93QT0dZR+AlfA, xuwei5-C8/M+/jPZTeaMJb+Lgu22Q,
sanil.kumar-C8/M+/jPZTeaMJb+Lgu22Q,
john.garry-hv44wF8Li93QT0dZR+AlfA,
gabriele.paoloni-hv44wF8Li93QT0dZR+AlfA,
shiju.jose-hv44wF8Li93QT0dZR+AlfA,
wangkefeng.wang-hv44wF8Li93QT0dZR+AlfA,
linuxarm-hv44wF8Li93QT0dZR+AlfA, shyju.pv-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <20170103225623.ynhc7n267jpzu44z@rob-hp-laptop>
On Wednesday 04 January 2017 04:26 AM, Rob Herring wrote:
> On Mon, Jan 02, 2017 at 01:49:03AM -0500, Anurup M wrote:
>> From: Tan Xiaojun <tanxiaojun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>>
>> Add Hisilicon HiP05/06/07 Djtag dts bindings for CPU and IO Die
>>
>> Signed-off-by: Tan Xiaojun <tanxiaojun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> Signed-off-by: Anurup M <anurup.m-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> ---
>> .../devicetree/bindings/arm/hisilicon/djtag.txt | 41 ++++++++++++++++++++++
>> 1 file changed, 41 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
>>
>> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt b/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
>> new file mode 100644
>> index 0000000..bbe8b45
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
>> @@ -0,0 +1,41 @@
>> +The Hisilicon Djtag is an independent component which connects with some other
>> +components in the SoC by Debug Bus. The djtag is available in CPU and IO dies
>> +in the chip. The djtag controls access to connecting modules of CPU and IO
>> +dies.
>> +The various connecting components in CPU die (like L3 cache, L3 cache PMU etc.)
>> +are accessed by djtag during real time debugging. In IO die there are connecting
>> +components like RSA. These components appear as devices attached to djtag bus.
>> +
>> +Hisilicon HiP05/06/07 djtag for CPU and IO die
>> +Required properties:
>> + - compatible : The value should be as follows
>> + (a) "hisilicon,hip05-djtag-v1" for CPU and IO die which use v1 hw in
>> + HiP05 chipset.
> You don't need to distinguish the CPU and IO blocks?
The CPU and IO djtag nodes will have different base address(in reg
property).
There is no difference in handling of CPU and IO dies in the djtag driver.
So there is currently no need to distinguish them.
>> + (b) "hisilicon,hip06-djtag-v1" for CPU die which use v1 hw in HiP06 chipset.
>> + (c) "hisilicon,hip06-djtag-v2" for IO die which use v2 hw in HiP06 chipset.
>> + (d) "hisilicon,hip07-djtag-v2" for CPU and IO die which use v2 hw in
>> + HiP07 chipset.
>> + - reg : Register address and size
>> + - hisi-scl-id : The Super Cluster ID for CPU or IO die
> Still needs a vendor prefix. i.e. hisilicon,scl-id
>
Ok. I shall modify it.
Thanks,
Anurup
>> +
>> +Example 1: Djtag for CPU die
>> +
>> + /* for Hisilicon HiP05 djtag for CPU Die */
>> + djtag0: djtag@80010000 {
>> + compatible = "hisilicon,hip05-djtag-v1";
>> + reg = <0x0 0x80010000 0x0 0x10000>;
>> + hisi-scl-id = <0x02>;
>> +
>> + /* All connecting components will appear as child nodes */
>> + };
>> +
>> +Example 2: Djtag for IO die
>> +
>> + /* for Hisilicon HiP05 djtag for IO Die */
>> + djtag1: djtag@d0000000 {
>> + compatible = "hisilicon,hip05-djtag-v1";
>> + reg = <0x0 0xd0000000 0x0 0x10000>;
>> + hisi-scl-id = <0x01>;
>> +
>> + /* All connecting components will appear as child nodes */
>> + };
>> --
>> 2.1.4
>>
--
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
* Re: [PATCH v3 03/10] dt-bindings: perf: hisi: Add Devicetree bindings for Hisilicon SoC PMU
From: Anurup M @ 2017-01-05 5:00 UTC (permalink / raw)
To: Rob Herring
Cc: mark.rutland-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
anurup.m-hv44wF8Li93QT0dZR+AlfA,
zhangshaokun-C8/M+/jPZTeaMJb+Lgu22Q,
tanxiaojun-hv44wF8Li93QT0dZR+AlfA, xuwei5-C8/M+/jPZTeaMJb+Lgu22Q,
sanil.kumar-C8/M+/jPZTeaMJb+Lgu22Q,
john.garry-hv44wF8Li93QT0dZR+AlfA,
gabriele.paoloni-hv44wF8Li93QT0dZR+AlfA,
shiju.jose-hv44wF8Li93QT0dZR+AlfA,
wangkefeng.wang-hv44wF8Li93QT0dZR+AlfA,
linuxarm-hv44wF8Li93QT0dZR+AlfA, shyju.pv-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <20170103225914.w3drvtpvupnpfa4x@rob-hp-laptop>
On Wednesday 04 January 2017 04:29 AM, Rob Herring wrote:
> On Mon, Jan 02, 2017 at 01:49:21AM -0500, Anurup M wrote:
>> 1) Device tree bindings for Hisilicon SoC PMU.
>> 2) Add example for Hisilicon L3 cache and MN PMU.
>> 3) Add child nodes of L3C and MN in djtag bindings example.
>>
>> Signed-off-by: Anurup M <anurup.m-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> Signed-off-by: Shaokun Zhang <zhangshaokun-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
>> ---
>> .../devicetree/bindings/arm/hisilicon/djtag.txt | 25 ++++++
>> .../devicetree/bindings/arm/hisilicon/pmu.txt | 100 +++++++++++++++++++++
>> 2 files changed, 125 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
>>
>> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt b/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
>> index bbe8b45..653fdb7 100644
>> --- a/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
>> +++ b/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
>> @@ -27,6 +27,31 @@ Example 1: Djtag for CPU die
>> hisi-scl-id = <0x02>;
>>
>> /* All connecting components will appear as child nodes */
>> +
>> + pmul3c0 {
>> + compatible = "hisilicon,hip05-pmu-l3c-v1";
>> + hisi-module-id = <0x04 0x02>;
>> + };
>> +
>> + pmul3c1 {
>> + compatible = "hisilicon,hip05-pmu-l3c-v1";
>> + hisi-module-id = <0x04 0x04>;
>> + };
>> +
>> + pmul3c2 {
>> + compatible = "hisilicon,hip05-pmu-l3c-v1";
>> + hisi-module-id = <0x04 0x01>;
>> + };
>> +
>> + pmul3c3 {
>> + compatible = "hisilicon,hip05-pmu-l3c-v1";
>> + hisi-module-id = <0x04 0x08>;
>> + };
>> +
>> + pmumn0 {
>> + compatible = "hisilicon,hip05-pmu-mn-v1";
>> + hisi-module-id = <0x0b>;
>> + };
>> };
>>
>> Example 2: Djtag for IO die
>> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
>> new file mode 100644
>> index 0000000..fceef8d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
>> @@ -0,0 +1,100 @@
>> +Hisilicon SoC HiP05/06/07 ARMv8 PMU
>> +===================================
>> +
>> +The Hisilicon SoC chips like HiP05/06/07 etc. consist of various independent
>> +system device PMUs such as L3 cache (L3C) and Miscellaneous Nodes(MN). These
>> +PMU devices are independent and have hardware logic to gather statistics and
>> +performance information.
>> +
>> +HiSilicon SoC chip is encapsulated by multiple CPU and IO dies. The CPU die
>> +is called as Super CPU cluster (SCCL) which includes 16 cpu-cores. Every SCCL
>> +in HiP05/06/07 chips are further grouped as CPU clusters (CCL) which includes
>> +4 cpu-cores each.
>> +e.g. In the case of HiP05/06/07, each SCCL has 1 L3 cache and 1 MN PMU device.
>> +The L3 cache is further grouped as 4 L3 cache banks in a SCCL.
>> +
>> +The Hisilicon SoC PMU DT node bindings for uncore PMU devices are as below.
>> +For PMU devices like L3 cache. MN etc. which are accessed using the djtag,
>> +the parent node will be the djtag node of the corresponding CPU die (SCCL).
>> +
>> +L3 cache
>> +---------
>> +The L3 cache is dedicated for each SCCL. Each SCCL in HiP05/06/07 chips have 4
>> +L3 cache banks. Each L3 cache bank have separate DT nodes.
>> +
>> +Required properties:
>> +
>> + - compatible : This value should be as follows
>> + (a) "hisilicon,hip05-pmu-l3c-v1" for v1 hw in HiP05 chipset
>> + (b) "hisilicon,hip06-pmu-l3c-v1" for v1 hw in HiP06 chipset
>> + (c) "hisilicon,hip07-pmu-l3c-v2" for v2 hw in HiP07 chipset
>> +
>> + - hisi-module-id : This property is a combination of two values in the below order.
> Vendor prefix: hisilicon,module-id
Ok. I shall modify it.
>> + a) Module ID: The module identifier for djtag.
>> + b) Instance or Bank ID: This will identify the L3 cache bank
>> + or instance.
>> +
>> +Optional properties:
>> +
>> + - interrupt-parent : A phandle indicating which interrupt controller
>> + this PMU signals interrupts to.
>> +
>> + - interrupts : Interrupt line used by this L3 cache bank.
>> +
>> + *The counter overflow IRQ is not supported in v1 hardware (HiP05/06).
>> +
>> +Miscellaneous Node
>> +------------------
>> +The MN is dedicated for each SCCL and hence there are separate DT nodes for MN
>> +for each SCCL.
>> +
>> +Required properties:
>> +
>> + - compatible : This value should be as follows
>> + (a) "hisilicon,hip05-pmu-mn-v1" for v1 hw in HiP05 chipset
>> + (b) "hisilicon,hip06-pmu-mn-v1" for v1 hw in HiP06 chipset
>> + (c) "hisilicon,hip07-pmu-mn-v2" for v2 hw in HiP07 chipset
>> +
>> + - hisi-module-id : Module ID to input for djtag.
> ditto
Ok. I shall modify it.
Thanks,
Anurup
>> +
>> +Optional properties:
>> +
>> + - interrupt-parent : A phandle indicating which interrupt controller
>> + this PMU signals interrupts to.
>> +
>> + - interrupts : Interrupt line used by this PMU.
>> +
>> + *The counter overflow IRQ is not supported in v1 hardware (HiP05/06).
>> +
>> +Example:
>> +
>> + djtag0: djtag@80010000 {
>> + compatible = "hisilicon,hip05-djtag-v1";
>> + reg = <0x0 0x80010000 0x0 0x10000>;
>> + scl-id = <0x02>;
>> +
>> + pmul3c0 {
>> + compatible = "hisilicon,hip05-pmu-l3c-v1";
>> + hisi-module-id = <0x04 0x02>;
>> + };
>> +
>> + pmul3c1 {
>> + compatible = "hisilicon,hip05-pmu-l3c-v1";
>> + hisi-module-id = <0x04 0x04>;
>> + };
>> +
>> + pmul3c2 {
>> + compatible = "hisilicon,hip05-pmu-l3c-v1";
>> + hisi-module-id = <0x04 0x01>;
>> + };
>> +
>> + pmul3c3 {
>> + compatible = "hisilicon,hip05-pmu-l3c-v1";
>> + hisi-module-id = <0x04 0x08>;
>> + };
>> +
>> + pmumn0 {
>> + compatible = "hisilicon,hip05-pmu-mn-v1";
>> + hisi-module-id = <0x0b>;
>> + };
>> + };
>> --
>> 2.1.4
>>
--
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
* RE: [RFC PATCH] usb: dwc3: add support for OTG driver compilation
From: Manish Narani @ 2017-01-05 5:27 UTC (permalink / raw)
To: Felipe Balbi, robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org,
catalin.marinas-5wv7dgnIgG8@public.gmane.org,
will.deacon-5wv7dgnIgG8@public.gmane.org,
michal.simek-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org,
Soren Brinkmann,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org,
mathias.nyman-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org,
agraf-l3A5Bk7waGM@public.gmane.org, Bharat Kumar Gogada,
Punnaiah Choudary Kalluri, dhdang-qTEPVZfXA3Y@public.gmane.org,
marc.zyngier-5wv7dgnIgG8@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Cc: Anirudha Sarangi, Anurag Kumar Vulisha
In-Reply-To: <87r34jvtn5.fsf-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Hi Felipe,
> From: Felipe Balbi [mailto:balbi-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org]
> Sent: Wednesday, January 04, 2017 7:01 PM
> Hi,
>
> Manish Narani <manish.narani-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org> writes:
> > This patch adds support for OTG driver compilation and object file
> > creation
> >
> > Signed-off-by: Manish Narani <mnarani-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> > ---
> > drivers/usb/dwc3/Makefile | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
> > index ffca340..2d269ad 100644
> > --- a/drivers/usb/dwc3/Makefile
> > +++ b/drivers/usb/dwc3/Makefile
> > @@ -17,6 +17,10 @@ ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET)
> $(CONFIG_USB_DWC3_DUAL_ROLE)),)
> > dwc3-y += gadget.o ep0.o
> > endif
> >
> > +ifneq ($(CONFIG_USB_DWC3_DUAL_ROLE),)
> > + dwc3-y += otg.o
> > +endif
>
> you just broke compilation
Should I add new USB_DWC3_OTG macro in Kconfig?
Thanks,
Manish
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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 v6 0/4] arm64: arch_timer: Add workaround for hisilicon-161601 erratum
From: Ding Tianhong @ 2017-01-05 5:31 UTC (permalink / raw)
To: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
marc.zyngier-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
oss-fOR+EgIDQEHk1uMJSBkQmQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A, stuart.yoder-3arQi8VN3Tc,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxarm-hv44wF8Li93QT0dZR+AlfA
Cc: Ding Tianhong
Erratum Hisilicon-161601 says that the ARM generic timer counter "has the
potential to contain an erroneous value when the timer value changes".
Accesses to TVAL (both read and write) are also affected due to the implicit counter
read. Accesses to CVAL are not affected.
The workaround is to reread the system count registers until the value of the second
read is larger than the first one by less than 32, the system counter can be guaranteed
not to return wrong value twice by back-to-back read and the error value is always larger
than the correct one by 32. Writes to TVAL are replaced with an equivalent write to CVAL.
v2: Introducing a new generic erratum handling mechanism for fsl,a008585 and hisilicon,161601.
Significant rework based on feedback, including seperate the fsl erratum a008585
to another patch, update the erratum name and remove unwanted code.
v3: Introducing the erratum_workaround_set_sne generic function for fsl erratum a008585
and make the #define __fsl_a008585_read_reg to be private to the .c file instead of
being globally visible. After discussion with Marc and Will, a consensus decision was
made to remove the commandline parameter for enabling fsl,erratum-a008585 erratum,
and make some generic name more specific, export timer_unstable_counter_workaround
for module access.
Significant rework based on feedback, including fix some alignment problem, make the
#define __hisi_161601_read_reg to be private to the .c file instead of being globally
visible, add more accurate annotation and modify a bit of logical format to enable
arch_timer_read_ool_enabled, remove the kernel commandline parameter
clocksource.arm_arch_timer.hisilicon-161601.
Introduce a generic aquick framework for erratum in ACPI mode.
v4: rename the quirk handler parameter to make it more generic, and
avoid break loop when handling the quirk becasue it need to
support multi quirks handler.
update some data structures for acpi mode.
v5: Adapt the new kernel-parameters.txt for latest kernel version.
Set the retries of reread system counter to 50, because it is possible
that some interrupts may lead to more than twice read errors and break the loop,
it will trigger the warning, so we set the number of retries far beyond the number of
iterations the loop has been observed to take.
v6: The last 2 patches in the previous version about the ACPI mode will conflict witch Fuwei's
GTDT patches, so remove the ACPI part and only support the DT base code for this patch set.
We have trigger a bug when select the CONFIG_FUNCTION_GRAPH_TRACER and enable function_graph
to /sys/kernel/debug/tracing/current_tracer, the system will stall into an endless loop, it looks
like that the ftrace_graph_caller will be related to xxx.read_cntvct_el0 and read the system counter
again, so mark the xxx.read_cntvct_el0 with notrace to fix the problem.
Ding Tianhong (4):
arm64: arch_timer: Add device tree binding for hisilicon-161601
erratum
arm64: arch_timer: Introduce a generic erratum handing mechanism for
fsl-a008585
arm64: arch_timer: Work around Erratum Hisilicon-161601
arm64: arch timer: Add timer erratum property for Hip05-d02 and
Hip06-d03
Documentation/admin-guide/kernel-parameters.txt | 9 --
Documentation/arm64/silicon-errata.txt | 1 +
.../devicetree/bindings/arm/arch_timer.txt | 8 ++
arch/arm64/boot/dts/hisilicon/hip05.dtsi | 1 +
arch/arm64/boot/dts/hisilicon/hip06.dtsi | 1 +
arch/arm64/include/asm/arch_timer.h | 38 ++----
drivers/clocksource/Kconfig | 9 ++
drivers/clocksource/arm_arch_timer.c | 146 ++++++++++++++++-----
8 files changed, 143 insertions(+), 70 deletions(-)
--
1.9.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 v6 1/4] arm64: arch_timer: Add device tree binding for hisilicon-161601 erratum
From: Ding Tianhong @ 2017-01-05 5:31 UTC (permalink / raw)
To: catalin.marinas, will.deacon, marc.zyngier, mark.rutland, oss,
devicetree, shawnguo, stuart.yoder, linux-arm-kernel, linuxarm
Cc: Ding Tianhong
In-Reply-To: <1483594317-10732-1-git-send-email-dingtianhong@huawei.com>
This erratum describes a bug in logic outside the core, so MIDR can't be
used to identify its presence, and reading an SoC-specific revision
register from common arch timer code would be awkward. So, describe it
in the device tree.
v2: Use the new erratum name and update the description.
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Acked-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/arm/arch_timer.txt | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt
index ad440a2..935f142 100644
--- a/Documentation/devicetree/bindings/arm/arch_timer.txt
+++ b/Documentation/devicetree/bindings/arm/arch_timer.txt
@@ -31,6 +31,14 @@ to deliver its interrupts via SPIs.
This also affects writes to the tval register, due to the implicit
counter read.
+- hisilicon,erratum-161601 : A boolean property. Indicates the presence of
+ erratum 161601, which says that reading the counter is unreliable unless
+ reading twice on the register and the value of the second read is larger
+ than the first by less than 32. If the verification is unsuccessful, then
+ discard the value of this read and repeat this procedure until the verification
+ is successful. This also affects writes to the tval register, due to the
+ implicit counter read.
+
** Optional properties:
- arm,cpu-registers-not-fw-configured : Firmware does not initialize
--
1.9.0
^ permalink raw reply related
* [PATCH v6 2/4] arm64: arch_timer: Introduce a generic erratum handing mechanism for fsl-a008585
From: Ding Tianhong @ 2017-01-05 5:31 UTC (permalink / raw)
To: catalin.marinas, will.deacon, marc.zyngier, mark.rutland, oss,
devicetree, shawnguo, stuart.yoder, linux-arm-kernel, linuxarm
Cc: Ding Tianhong
In-Reply-To: <1483594317-10732-1-git-send-email-dingtianhong@huawei.com>
The workaround for hisilicon,161601 will check the return value of the system counter
by different way, in order to distinguish with the fsl-a008585 workaround, introduce
a new generic erratum handing mechanism for fsl-a008585 and rename some functions.
v2: Introducing a new generic erratum handling mechanism for fsl erratum a008585.
v3: Introducing the erratum_workaround_set_sne generic function for fsl erratum a008585
and make the #define __fsl_a008585_read_reg to be private to the .c file instead of
being globally visible. After discussion with Marc and Will, a consensus decision was
made to remove the commandline parameter for enabling fsl,erratum-a008585 erratum,
and make some generic name more specific, export timer_unstable_counter_workaround
for module access.
v5: Adapt the new documentation for kernel-parameters.txt.
v6: Mark the fsl_a008585_read_xxx_el0 with notrace, if CONFIG_FUNCTION_GRAPH_TRACER selected,
fsl_a008585_read_xxx_el0 will be related to ftrace_graph_caller which will calling sched_clock
to read system counter again, it will cause the system stall into an endless loop.
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
Documentation/admin-guide/kernel-parameters.txt | 9 ---
arch/arm64/include/asm/arch_timer.h | 36 ++++--------
drivers/clocksource/arm_arch_timer.c | 78 +++++++++++++++----------
3 files changed, 58 insertions(+), 65 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 21e2d88..76437ad 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -539,15 +539,6 @@
loops can be debugged more effectively on production
systems.
- clocksource.arm_arch_timer.fsl-a008585=
- [ARM64]
- Format: <bool>
- Enable/disable the workaround of Freescale/NXP
- erratum A-008585. This can be useful for KVM
- guests, if the guest device tree doesn't show the
- erratum. If unspecified, the workaround is
- enabled based on the device tree.
-
clearcpuid=BITNUM [X86]
Disable CPUID feature X for the kernel. See
arch/x86/include/asm/cpufeatures.h for the valid bit
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index eaa5bbe..f882c7c 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -31,39 +31,27 @@
#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
extern struct static_key_false arch_timer_read_ool_enabled;
-#define needs_fsl_a008585_workaround() \
+#define needs_unstable_timer_counter_workaround() \
static_branch_unlikely(&arch_timer_read_ool_enabled)
#else
-#define needs_fsl_a008585_workaround() false
+#define needs_unstable_timer_counter_workaround() false
#endif
-u32 __fsl_a008585_read_cntp_tval_el0(void);
-u32 __fsl_a008585_read_cntv_tval_el0(void);
-u64 __fsl_a008585_read_cntvct_el0(void);
-/*
- * The number of retries is an arbitrary value well beyond the highest number
- * of iterations the loop has been observed to take.
- */
-#define __fsl_a008585_read_reg(reg) ({ \
- u64 _old, _new; \
- int _retries = 200; \
- \
- do { \
- _old = read_sysreg(reg); \
- _new = read_sysreg(reg); \
- _retries--; \
- } while (unlikely(_old != _new) && _retries); \
- \
- WARN_ON_ONCE(!_retries); \
- _new; \
-})
+struct arch_timer_erratum_workaround {
+ int erratum; /* Indicate the Erratum ID */
+ u32 (*read_cntp_tval_el0)(void);
+ u32 (*read_cntv_tval_el0)(void);
+ u64 (*read_cntvct_el0)(void);
+};
+
+extern struct arch_timer_erratum_workaround *timer_unstable_counter_workaround;
#define arch_timer_reg_read_stable(reg) \
({ \
u64 _val; \
- if (needs_fsl_a008585_workaround()) \
- _val = __fsl_a008585_read_##reg(); \
+ if (needs_unstable_timer_counter_workaround()) \
+ _val = timer_unstable_counter_workaround->read_##reg();\
else \
_val = read_sysreg(reg); \
_val; \
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 02fef68..f9097b6 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -96,40 +96,53 @@ static int __init early_evtstrm_cfg(char *buf)
*/
#ifdef CONFIG_FSL_ERRATUM_A008585
-DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
-EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
-
-static int fsl_a008585_enable = -1;
+struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
+EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
-static int __init early_fsl_a008585_cfg(char *buf)
-{
- int ret;
- bool val;
+#define FSL_A008585 0x0001
- ret = strtobool(buf, &val);
- if (ret)
- return ret;
-
- fsl_a008585_enable = val;
- return 0;
-}
-early_param("clocksource.arm_arch_timer.fsl-a008585", early_fsl_a008585_cfg);
+DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
+EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
-u32 __fsl_a008585_read_cntp_tval_el0(void)
+/*
+ * The number of retries is an arbitrary value well beyond the highest number
+ * of iterations the loop has been observed to take.
+ */
+#define __fsl_a008585_read_reg(reg) ({ \
+ u64 _old, _new; \
+ int _retries = 200; \
+ \
+ do { \
+ _old = read_sysreg(reg); \
+ _new = read_sysreg(reg); \
+ _retries--; \
+ } while (unlikely(_old != _new) && _retries); \
+ \
+ WARN_ON_ONCE(!_retries); \
+ _new; \
+})
+
+static u32 notrace fsl_a008585_read_cntp_tval_el0(void)
{
return __fsl_a008585_read_reg(cntp_tval_el0);
}
-u32 __fsl_a008585_read_cntv_tval_el0(void)
+static u32 notrace fsl_a008585_read_cntv_tval_el0(void)
{
return __fsl_a008585_read_reg(cntv_tval_el0);
}
-u64 __fsl_a008585_read_cntvct_el0(void)
+static u64 notrace fsl_a008585_read_cntvct_el0(void)
{
return __fsl_a008585_read_reg(cntvct_el0);
}
-EXPORT_SYMBOL(__fsl_a008585_read_cntvct_el0);
+
+static struct arch_timer_erratum_workaround arch_timer_fsl_a008585 = {
+ .erratum = FSL_A008585,
+ .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
+ .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
+ .read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
+};
#endif /* CONFIG_FSL_ERRATUM_A008585 */
static __always_inline
@@ -282,7 +295,7 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
}
#ifdef CONFIG_FSL_ERRATUM_A008585
-static __always_inline void fsl_a008585_set_next_event(const int access,
+static __always_inline void erratum_set_next_event_generic(const int access,
unsigned long evt, struct clock_event_device *clk)
{
unsigned long ctrl;
@@ -300,17 +313,17 @@ static __always_inline void fsl_a008585_set_next_event(const int access,
arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
}
-static int fsl_a008585_set_next_event_virt(unsigned long evt,
+static int erratum_set_next_event_virt(unsigned long evt,
struct clock_event_device *clk)
{
- fsl_a008585_set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
+ erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
return 0;
}
-static int fsl_a008585_set_next_event_phys(unsigned long evt,
+static int erratum_set_next_event_phys(unsigned long evt,
struct clock_event_device *clk)
{
- fsl_a008585_set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
+ erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
return 0;
}
#endif /* CONFIG_FSL_ERRATUM_A008585 */
@@ -343,16 +356,16 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
return 0;
}
-static void fsl_a008585_set_sne(struct clock_event_device *clk)
+static void erratum_workaround_set_sne(struct clock_event_device *clk)
{
#ifdef CONFIG_FSL_ERRATUM_A008585
if (!static_branch_unlikely(&arch_timer_read_ool_enabled))
return;
if (arch_timer_uses_ppi == VIRT_PPI)
- clk->set_next_event = fsl_a008585_set_next_event_virt;
+ clk->set_next_event = erratum_set_next_event_virt;
else
- clk->set_next_event = fsl_a008585_set_next_event_phys;
+ clk->set_next_event = erratum_set_next_event_phys;
#endif
}
@@ -385,7 +398,7 @@ static void __arch_timer_setup(unsigned type,
BUG();
}
- fsl_a008585_set_sne(clk);
+ erratum_workaround_set_sne(clk);
} else {
clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
clk->name = "arch_mem_timer";
@@ -894,9 +907,10 @@ static int __init arch_timer_of_init(struct device_node *np)
arch_timer_c3stop = !of_property_read_bool(np, "always-on");
#ifdef CONFIG_FSL_ERRATUM_A008585
- if (fsl_a008585_enable < 0)
- fsl_a008585_enable = of_property_read_bool(np, "fsl,erratum-a008585");
- if (fsl_a008585_enable) {
+ if (!timer_unstable_counter_workaround && of_property_read_bool(np, "fsl,erratum-a008585"))
+ timer_unstable_counter_workaround = &arch_timer_fsl_a008585;
+
+ if (timer_unstable_counter_workaround) {
static_branch_enable(&arch_timer_read_ool_enabled);
pr_info("Enabling workaround for FSL erratum A-008585\n");
}
--
1.9.0
^ permalink raw reply related
* [PATCH v6 3/4] arm64: arch_timer: Work around Erratum Hisilicon-161601
From: Ding Tianhong @ 2017-01-05 5:31 UTC (permalink / raw)
To: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
marc.zyngier-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
oss-fOR+EgIDQEHk1uMJSBkQmQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A, stuart.yoder-3arQi8VN3Tc,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxarm-hv44wF8Li93QT0dZR+AlfA
Cc: Ding Tianhong
In-Reply-To: <1483594317-10732-1-git-send-email-dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Erratum Hisilicon-161601 says that the ARM generic timer counter "has the
potential to contain an erroneous value when the timer value changes".
Accesses to TVAL (both read and write) are also affected due to the implicit counter
read. Accesses to CVAL are not affected.
The workaround is to reread the system count registers until the value of the second
read is larger than the first one by less than 32, the system counter can be guaranteed
not to return wrong value twice by back-to-back read and the error value is always larger
than the correct one by 32. Writes to TVAL are replaced with an equivalent write to CVAL.
The workaround is enabled if the hisilicon,erratum-161601 property is found in
the timer node in the device tree. This can be overridden with the
clocksource.arm_arch_timer.hisilicon-161601 boot parameter, which allows KVM
users to enable the workaround until a mechanism is implemented to
automatically communicate this information.
Fix some description for fsl erratum a008585.
v2: Significant rework based on feedback, including seperate the fsl erratum a008585
to another patch, update the erratum name and remove unwanted code.
v3: Significant rework based on feedback, including fix some alignment problem, make the
#define __hisi_161601_read_reg to be private to the .c file instead of being globally
visible, add more accurate annotation and modify a bit of logical format to enable
arch_timer_read_ool_enabled, remove the kernel commandline parameter
clocksource.arm_arch_timer.hisilicon-161601.
v5: Theoretically the erratum should not occur more than twice in succession when reading
the system counter, but it is possible that some interrupts may lead to more than twice
read errors, triggering the warning, so setting the number of retries to 50 which is far
beyond the number of iterations the loop has been observed to take.
v6: Mark the hisi_161601_read_xxx_el0 with notrace, if CONFIG_FUNCTION_GRAPH_TRACER selected,
hisi_161601_read_xxx_el0 will be related to ftrace_graph_caller which will calling sched_clock
to read system counter again, it will cause the system stall into an endless loop.
Signed-off-by: Ding Tianhong <dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
Documentation/arm64/silicon-errata.txt | 1 +
arch/arm64/include/asm/arch_timer.h | 2 +-
drivers/clocksource/Kconfig | 9 +++++
drivers/clocksource/arm_arch_timer.c | 70 +++++++++++++++++++++++++++++++---
4 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 405da11..1c1a95f 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -63,3 +63,4 @@ stable kernels.
| Cavium | ThunderX SMMUv2 | #27704 | N/A |
| | | | |
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
+| Hisilicon | Hip0{5,6,7} | #161601 | HISILICON_ERRATUM_161601|
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index f882c7c..ebf4cde 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -29,7 +29,7 @@
#include <clocksource/arm_arch_timer.h>
-#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
extern struct static_key_false arch_timer_read_ool_enabled;
#define needs_unstable_timer_counter_workaround() \
static_branch_unlikely(&arch_timer_read_ool_enabled)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 4866f7a..162d820 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -335,6 +335,15 @@ config FSL_ERRATUM_A008585
value"). The workaround will only be active if the
fsl,erratum-a008585 property is found in the timer node.
+config HISILICON_ERRATUM_161601
+ bool "Workaround for Hisilicon Erratum 161601"
+ default y
+ depends on ARM_ARCH_TIMER && ARM64
+ help
+ This option enables a workaround for Hisilicon Erratum
+ 161601. The workaround will be active if the hisilicon,erratum-161601
+ property is found in the timer node.
+
config ARM_GLOBAL_TIMER
bool "Support for the ARM global timer" if COMPILE_TEST
select CLKSRC_OF if OF
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index f9097b6..078d38f 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -95,15 +95,18 @@ static int __init early_evtstrm_cfg(char *buf)
* Architected system timer support.
*/
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#if CONFIG_FSL_ERRATUM_A008585 || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
#define FSL_A008585 0x0001
+#define HISILICON_161601 0x0002
DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
+#endif
+#ifdef CONFIG_FSL_ERRATUM_A008585
/*
* The number of retries is an arbitrary value well beyond the highest number
* of iterations the loop has been observed to take.
@@ -145,6 +148,54 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void)
};
#endif /* CONFIG_FSL_ERRATUM_A008585 */
+#ifdef CONFIG_HISILICON_ERRATUM_161601
+/*
+ * Verify whether the value of the second read is larger than the first by
+ * less than 32 is the only way to confirm the value is correct, so clear the
+ * lower 5 bits to check whether the difference is greater than 32 or not.
+ * Theoretically the erratum should not occur more than twice in succession
+ * when reading the system counter, but it is possible that some interrupts
+ * may lead to more than twice read errors, triggering the warning, so setting
+ * the number of retries far beyond the number of iterations the loop has been
+ * observed to take.
+ */
+#define __hisi_161601_read_reg(reg) ({ \
+ u64 _old, _new; \
+ int _retries = 50; \
+ \
+ do { \
+ _old = read_sysreg(reg); \
+ _new = read_sysreg(reg); \
+ _retries--; \
+ } while (unlikely((_new - _old) >> 5) && _retries); \
+ \
+ WARN_ON_ONCE(!_retries); \
+ _new; \
+})
+
+static u32 notrace hisi_161601_read_cntp_tval_el0(void)
+{
+ return __hisi_161601_read_reg(cntp_tval_el0);
+}
+
+static u32 notrace hisi_161601_read_cntv_tval_el0(void)
+{
+ return __hisi_161601_read_reg(cntv_tval_el0);
+}
+
+static u64 notrace hisi_161601_read_cntvct_el0(void)
+{
+ return __hisi_161601_read_reg(cntvct_el0);
+}
+
+static struct arch_timer_erratum_workaround arch_timer_hisi_161601 = {
+ .erratum = HISILICON_161601,
+ .read_cntp_tval_el0 = hisi_161601_read_cntp_tval_el0,
+ .read_cntv_tval_el0 = hisi_161601_read_cntv_tval_el0,
+ .read_cntvct_el0 = hisi_161601_read_cntvct_el0,
+};
+#endif /* CONFIG_HISILICON_ERRATUM_161601 */
+
static __always_inline
void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
struct clock_event_device *clk)
@@ -294,7 +345,7 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
}
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
static __always_inline void erratum_set_next_event_generic(const int access,
unsigned long evt, struct clock_event_device *clk)
{
@@ -358,7 +409,7 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
static void erratum_workaround_set_sne(struct clock_event_device *clk)
{
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
if (!static_branch_unlikely(&arch_timer_read_ool_enabled))
return;
@@ -618,7 +669,7 @@ static void __init arch_counter_register(unsigned type)
clocksource_counter.archdata.vdso_direct = true;
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
/*
* Don't use the vdso fastpath if errata require using
* the out-of-line counter accessor.
@@ -909,10 +960,19 @@ static int __init arch_timer_of_init(struct device_node *np)
#ifdef CONFIG_FSL_ERRATUM_A008585
if (!timer_unstable_counter_workaround && of_property_read_bool(np, "fsl,erratum-a008585"))
timer_unstable_counter_workaround = &arch_timer_fsl_a008585;
+#endif
+
+#ifdef CONFIG_HISILICON_ERRATUM_161601
+ if (!timer_unstable_counter_workaround && of_property_read_bool(np, "hisilicon,erratum-161601"))
+ timer_unstable_counter_workaround = &arch_timer_hisi_161601;
+#endif
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
if (timer_unstable_counter_workaround) {
static_branch_enable(&arch_timer_read_ool_enabled);
- pr_info("Enabling workaround for FSL erratum A-008585\n");
+ pr_info("Enabling workaround for %s\n",
+ timer_unstable_counter_workaround->erratum == FSL_A008585 ?
+ "FSL ERRATUM A-008585" : "HISILICON ERRATUM 161601");
}
#endif
--
1.9.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 related
* [PATCH v6 4/4] arm64: arch timer: Add timer erratum property for Hip05-d02 and Hip06-d03
From: Ding Tianhong @ 2017-01-05 5:31 UTC (permalink / raw)
To: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
marc.zyngier-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
oss-fOR+EgIDQEHk1uMJSBkQmQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A, stuart.yoder-3arQi8VN3Tc,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxarm-hv44wF8Li93QT0dZR+AlfA
Cc: Ding Tianhong
In-Reply-To: <1483594317-10732-1-git-send-email-dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Enable workaround for hisilicon erratum 161601 on Hip05-d02 and Hip06-d03 board.
Signed-off-by: Ding Tianhong <dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
arch/arm64/boot/dts/hisilicon/hip05.dtsi | 1 +
arch/arm64/boot/dts/hisilicon/hip06.dtsi | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
index 4b472a3..a8e9969 100644
--- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
@@ -281,6 +281,7 @@
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ hisilicon,erratum-161601;
};
pmu {
diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
index a049b64..344e0f0 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
@@ -260,6 +260,7 @@
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ hisilicon,erratum-161601;
};
pmu {
--
1.9.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 related
* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
From: Chen-Yu Tsai @ 2017-01-05 5:42 UTC (permalink / raw)
To: Quentin Schulz
Cc: Mark Rutland, devicetree, Lars-Peter Clausen, open list:THERMAL,
linux-iio, linux-kernel, Sebastian Reichel, Russell King,
Chen-Yu Tsai, Rob Herring, linux-arm-kernel,
Peter Meerwald-Stadler, knaack.h, Maxime Ripard,
Bruno Prémont, Lee Jones, Thomas Petazzoni, Jonathan Cameron,
Icenowy Zheng
In-Reply-To: <20170102163723.7939-4-quentin.schulz@free-electrons.com>
On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> 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@free-electrons.com>
> ---
> drivers/iio/adc/Kconfig | 10 +
> drivers/iio/adc/Makefile | 1 +
> drivers/iio/adc/axp20x_adc.c | 490 +++++++++++++++++++++++++++++++++++++++++++
> include/linux/mfd/axp20x.h | 4 +
> 4 files changed, 505 insertions(+)
> create mode 100644 drivers/iio/adc/axp20x_adc.c
>
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 38bc319..5c5b51f 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 d36c4be..f5c28a5 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..8df972a
> --- /dev/null
> +++ b/drivers/iio/adc/axp20x_adc.c
> @@ -0,0 +1,490 @@
> +/* ADC driver for AXP20X and AXP22X PMICs
> + *
> + * Copyright (c) 2016 Free Electrons NextThing Co.
> + * Quentin Schulz <quentin.schulz@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it under
> + * the terms of the GNU General Public License version 2 as published by the
> + * Free Software Foundation.
> + *
> + */
> +
> +#include <linux/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/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_ADC_EN2_TEMP_ADC BIT(7)
> +#define AXP20X_ADC_EN2_GPIO0_ADC BIT(3)
> +#define AXP20X_ADC_EN2_GPIO1_ADC BIT(2)
The latter 3 individual bits aren't used anywhere.
Please remove them for now.
> +
> +#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 (3 << 6)
> +#define AXP20X_ADC_RATE_25HZ (0 << 6)
> +#define AXP20X_ADC_RATE_50HZ BIT(6)
Please be consistent with the format.
> +#define AXP20X_ADC_RATE_100HZ (2 << 6)
> +#define AXP20X_ADC_RATE_200HZ (3 << 6)
> +
> +#define AXP22X_ADC_RATE_100HZ (0 << 6)
> +#define AXP22X_ADC_RATE_200HZ BIT(6)
> +#define AXP22X_ADC_RATE_400HZ (2 << 6)
> +#define AXP22X_ADC_RATE_800HZ (3 << 6)
These are power-of-2 multiples of some base rate. May I suggest
a formula macro instead. Either way, you seem to be using only
one value. Will this be made configurable in the future?
> +
> +#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 axp20x_adc_iio {
> + struct iio_dev *indio_dev;
> + struct regmap *regmap;
> +};
> +
> +enum axp20x_adc_channel {
> + AXP20X_ACIN_V = 0,
> + AXP20X_ACIN_I,
> + AXP20X_VBUS_V,
> + AXP20X_VBUS_I,
> + AXP20X_TEMP_ADC,
PMIC_TEMP would be better. And please save a slot for TS input.
> + AXP20X_GPIO0_V,
> + AXP20X_GPIO1_V,
Please skip a slot for "battery instantaneous power".
> + AXP20X_BATT_V,
> + AXP20X_BATT_CHRG_I,
> + AXP20X_BATT_DISCHRG_I,
> + AXP20X_IPSOUT_V,
> +};
> +
> +enum axp22x_adc_channel {
> + AXP22X_TEMP_ADC = 0,
Same comments as AXP20X_TEMP_ADC.
> + AXP22X_BATT_V,
> + AXP22X_BATT_CHRG_I,
> + AXP22X_BATT_DISCHRG_I,
> +};
Shouldn't these channel numbers be exported as part of the device tree
bindings? At the very least, they shouldn't be changed.
Also please add a comment saying that the channels are numbered
in the order of their respective registers, and not the table
describing the ADCs in the datasheet (9.7 Signal Capture for AXP209
and 9.5 E-Gauge for AXP221).
> +
> +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),
> + AXP20X_ADC_CHANNEL_OFFSET(AXP20X_TEMP_ADC, "temp_adc", IIO_TEMP,
> + AXP20X_TEMP_ADC_H),
> + 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_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),
> + AXP20X_ADC_CHANNEL(AXP20X_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,
> + AXP20X_IPSOUT_V_HIGH_H),
> +};
> +
> +static const struct iio_chan_spec axp22x_adc_channels[] = {
> + AXP20X_ADC_CHANNEL_OFFSET(AXP22X_TEMP_ADC, "temp_adc", IIO_TEMP,
> + AXP22X_TEMP_ADC_H),
> + 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_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *channel, int *val,
> + int *val2)
> +{
> + struct axp20x_adc_iio *info = iio_priv(indio_dev);
> + int size = 12, ret;
> +
> + switch (channel->channel) {
> + case AXP20X_BATT_DISCHRG_I:
> + size = 13;
> + case AXP20X_ACIN_V:
> + case AXP20X_ACIN_I:
> + case AXP20X_VBUS_V:
> + case AXP20X_VBUS_I:
> + case AXP20X_TEMP_ADC:
> + case AXP20X_BATT_V:
> + case AXP20X_BATT_CHRG_I:
> + case AXP20X_IPSOUT_V:
> + case AXP20X_GPIO0_V:
> + case AXP20X_GPIO1_V:
> + ret = axp20x_read_variable_width(info->regmap, channel->address,
> + size);
> + if (ret < 0)
> + return ret;
> + *val = ret;
> + return IIO_VAL_INT;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *channel, int *val,
> + int *val2)
> +{
> + struct axp20x_adc_iio *info = iio_priv(indio_dev);
> + int size = 12, ret;
> +
> + switch (channel->channel) {
> + case AXP22X_BATT_DISCHRG_I:
> + size = 13;
> + case AXP22X_TEMP_ADC:
> + case AXP22X_BATT_V:
> + case AXP22X_BATT_CHRG_I:
According to the datasheet, AXP22X_BATT_CHRG_I is also 13 bits wide.
> + ret = axp20x_read_variable_width(info->regmap, channel->address,
> + size);
> + if (ret < 0)
> + return ret;
> + *val = ret;
> + return IIO_VAL_INT;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static int axp20x_adc_scale(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_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_TEMP_ADC:
> + *val = 100;
> + return IIO_VAL_INT;
> +
> + 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_BATT_DISCHRG_I:
> + case AXP20X_BATT_CHRG_I:
> + *val = 0;
> + *val2 = 500000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case AXP20X_IPSOUT_V:
> + *val = 1;
> + *val2 = 400000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static int axp22x_adc_scale(int channel, int *val, int *val2)
> +{
> + switch (channel) {
> + case AXP22X_TEMP_ADC:
> + *val = 100;
> + return IIO_VAL_INT;
> +
> + case AXP22X_BATT_V:
> + *val = 1;
> + *val2 = 100000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + case AXP22X_BATT_DISCHRG_I:
> + case AXP22X_BATT_CHRG_I:
> + *val = 0;
> + *val2 = 500000;
> + return IIO_VAL_INT_PLUS_MICRO;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static int axp20x_adc_offset(struct iio_dev *indio_dev, int channel, int *val)
> +{
> + struct axp20x_adc_iio *info = iio_priv(indio_dev);
> + int ret, reg;
> +
> + switch (channel) {
> + case AXP20X_TEMP_ADC:
> + *val = -1447;
> + return IIO_VAL_INT;
> +
> + case AXP20X_GPIO0_V:
> + case AXP20X_GPIO1_V:
> + ret = regmap_read(info->regmap, AXP20X_GPIO10_IN_RANGE, ®);
> + if (ret < 0)
> + return ret;
> +
> + if (channel == AXP20X_GPIO0_V)
> + *val = reg & AXP20X_GPIO10_IN_RANGE_GPIO0;
> + else
> + *val = reg & AXP20X_GPIO10_IN_RANGE_GPIO1;
> +
> + *val = !!(*val) * 700000;
> +
> + return IIO_VAL_INT;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + 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->channel, val);
> +
> + case IIO_CHAN_INFO_SCALE:
> + return axp20x_adc_scale(chan->channel, val, val2);
> +
> + case IIO_CHAN_INFO_RAW:
> + return axp20x_adc_read_raw(indio_dev, chan, val, val2);
> +
> + default:
> + return -EINVAL;
> + }
> +
> + 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 = -2667;
Datasheet says -267.7 C, or -2677 here.
> + return IIO_VAL_INT;
> +
> + case IIO_CHAN_INFO_SCALE:
> + return axp22x_adc_scale(chan->channel, val, val2);
> +
> + case IIO_CHAN_INFO_RAW:
> + return axp22x_adc_read_raw(indio_dev, chan, val, val2);
> +
> + default:
> + return -EINVAL;
> + }
> +
> + 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);
> +
> + /*
> + * 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 (chan->channel != AXP20X_GPIO0_V && chan->channel != AXP20X_GPIO1_V)
> + return -EINVAL;
> +
> + if (val != 0 && val != 700000)
> + return -EINVAL;
> +
> + if (chan->channel == AXP20X_GPIO0_V)
> + return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE,
> + AXP20X_GPIO10_IN_RANGE_GPIO0,
> + AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(!!val));
> +
> + return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE,
> + AXP20X_GPIO10_IN_RANGE_GPIO1,
> + AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(!!val));
> +}
> +
> +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 const struct of_device_id axp20x_adc_of_match[] = {
> + { .compatible = "x-powers,axp209-adc", .data = (void *)AXP209_ID, },
> + { .compatible = "x-powers,axp221-adc", .data = (void *)AXP221_ID, },
> + { /* sentinel */ },
> +};
> +
> +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_id;
> +
> + 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;
> + info->indio_dev = indio_dev;
> + indio_dev->name = dev_name(&pdev->dev);
> + indio_dev->dev.parent = &pdev->dev;
> + indio_dev->dev.of_node = pdev->dev.of_node;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> +
> + axp20x_id = (int)of_device_get_match_data(&pdev->dev);
> +
> + switch (axp20x_id) {
> + case AXP209_ID:
> + indio_dev->info = &axp20x_adc_iio_info;
> + indio_dev->num_channels = ARRAY_SIZE(axp20x_adc_channels);
> + indio_dev->channels = axp20x_adc_channels;
> +
> + /* Enable the ADCs on IP */
> + regmap_write(info->regmap, AXP20X_ADC_EN1, AXP20X_ADC_EN1_MASK);
> +
> + /* 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, AXP20X_ADC_RATE_50HZ);
> + break;
> +
> + case AXP221_ID:
> + indio_dev->info = &axp22x_adc_iio_info;
> + indio_dev->num_channels = ARRAY_SIZE(axp22x_adc_channels);
> + indio_dev->channels = axp22x_adc_channels;
> +
> + /* Enable the ADCs on IP */
> + regmap_write(info->regmap, AXP20X_ADC_EN1, AXP22X_ADC_EN1_MASK);
> +
> + /* Configure ADCs rate */
> + regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> + AXP20X_ADC_RATE_MASK, AXP22X_ADC_RATE_200HZ);
> + break;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + ret = devm_iio_device_register(&pdev->dev, indio_dev);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "could not register the device\n");
> + regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> + regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int axp20x_remove(struct platform_device *pdev)
> +{
> + struct axp20x_adc_iio *info;
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> + info = iio_priv(indio_dev);
Nit: you could just reverse the 2 declarations above and join this
line after struct axp20x_adc_iio *info;
> + regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> + regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
The existing VBUS power supply driver enables the VBUS ADC bits itself,
and does not check them later on. This means if one were to remove this
axp20x-adc module, the voltage/current readings in the VBUS power supply
would be invalid. Some sort of workaround would be needed here in this
driver of the VBUS driver.
> +
> + return 0;
> +}
> +
> +static struct platform_driver axp20x_adc_driver = {
> + .driver = {
> + .name = "axp20x-adc",
> + .of_match_table = axp20x_adc_of_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@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index a4860bc..650c6f6 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -150,6 +150,10 @@ enum {
> #define AXP20X_VBUS_I_ADC_L 0x5d
> #define AXP20X_TEMP_ADC_H 0x5e
> #define AXP20X_TEMP_ADC_L 0x5f
> +
> +#define AXP22X_TEMP_ADC_H 0x56
> +#define AXP22X_TEMP_ADC_L 0x57
> +
This is in the wrong patch. Also we already have
/* AXP22X specific registers */
#define AXP22X_PMIC_ADC_H 0x56
#define AXP22X_PMIC_ADC_L 0x57
#define AXP22X_TS_ADC_H 0x58
#define AXP22X_TS_ADC_L 0x59
If you want, you could just rename them to be consistent.
Regards
ChenYu
> #define AXP20X_TS_IN_H 0x62
> #define AXP20X_TS_IN_L 0x63
> #define AXP20X_GPIO0_V_ADC_H 0x64
> --
> 2.9.3
>
^ permalink raw reply
* Re: [PATCH 04/22] mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs
From: Chen-Yu Tsai @ 2017-01-05 5:51 UTC (permalink / raw)
To: Lee Jones
Cc: Mark Rutland, devicetree, Lars-Peter Clausen, open list:THERMAL,
linux-iio, linux-kernel, Sebastian Reichel, Russell King,
Quentin Schulz, Chen-Yu Tsai, Rob Herring, linux-arm-kernel,
Peter Meerwald-Stadler, knaack.h, Maxime Ripard,
Bruno Prémont, Thomas Petazzoni, Jonathan Cameron,
Icenowy Zheng
In-Reply-To: <20170104115637.GC24058@dell>
On Wed, Jan 4, 2017 at 7:56 PM, Lee Jones <lee.jones@linaro.org> wrote:
> On Wed, 04 Jan 2017, Lee Jones wrote:
>
>> On Mon, 02 Jan 2017, Quentin Schulz wrote:
>>
>> > This adds the AXP20X/AXP22x ADCs driver to the mfd cells of the AXP209,
>> > AXP221 and AXP223 MFD.
>> >
>> > Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
>> > ---
>> > drivers/mfd/axp20x.c | 9 +++++++++
>> > 1 file changed, 9 insertions(+)
>>
>> Applied, thanks.
>
> Whoops, wrong key combo! Should have been:
>
> For my own reference:
> Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
Acked-by: Chen-Yu Tsai <wens@csie.org>
>
>> > diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
>> > index a33db5e..31a84d81 100644
>> > --- a/drivers/mfd/axp20x.c
>> > +++ b/drivers/mfd/axp20x.c
>> > @@ -582,6 +582,9 @@ static struct mfd_cell axp20x_cells[] = {
>> > }, {
>> > .name = "axp20x-regulator",
>> > }, {
>> > + .name = "axp20x-adc",
>> > + .of_compatible = "x-powers,axp209-adc",
>> > + }, {
>> > .name = "axp20x-ac-power-supply",
>> > .of_compatible = "x-powers,axp202-ac-power-supply",
>> > .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
>> > @@ -602,6 +605,9 @@ static struct mfd_cell axp221_cells[] = {
>> > }, {
>> > .name = "axp20x-regulator",
>> > }, {
>> > + .name = "axp20x-adc",
>> > + .of_compatible = "x-powers,axp221-adc"
>> > + }, {
>> > .name = "axp20x-usb-power-supply",
>> > .of_compatible = "x-powers,axp221-usb-power-supply",
>> > .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
>> > @@ -615,6 +621,9 @@ static struct mfd_cell axp223_cells[] = {
>> > .num_resources = ARRAY_SIZE(axp22x_pek_resources),
>> > .resources = axp22x_pek_resources,
>> > }, {
>> > + .name = "axp20x-adc",
>> > + .of_compatible = "x-powers,axp221-adc"
>> > + }, {
>> > .name = "axp20x-regulator",
>> > }, {
>> > .name = "axp20x-usb-power-supply",
>>
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode
From: Chen-Yu Tsai @ 2017-01-05 5:51 UTC (permalink / raw)
To: Quentin Schulz
Cc: Mark Rutland, devicetree, Lars-Peter Clausen, open list:THERMAL,
linux-iio, linux-kernel, Sebastian Reichel, Russell King,
Chen-Yu Tsai, Rob Herring, linux-arm-kernel,
Peter Meerwald-Stadler, knaack.h, Maxime Ripard,
Bruno Prémont, Lee Jones, Thomas Petazzoni, Jonathan Cameron,
Icenowy Zheng
In-Reply-To: <20170102163723.7939-6-quentin.schulz@free-electrons.com>
On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> X-Powers AXP209 PMIC has multiple ADCs, each one exposing data from the
> different power supplies connected to the PMIC.
>
> This adds the ADC subnode for AXP20X PMIC.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
> arch/arm/boot/dts/axp209.dtsi | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
> index 675bb0f..2a4e8ee 100644
> --- a/arch/arm/boot/dts/axp209.dtsi
> +++ b/arch/arm/boot/dts/axp209.dtsi
> @@ -53,6 +53,11 @@
> interrupt-controller;
> #interrupt-cells = <1>;
>
> + axp209_adc: axp209_adc {
Node name should be generic. Please change it to "adc".
ChenYu
> + compatible = "x-powers,axp209-adc";
> + #io-channel-cells = <1>;
> + };
> +
> axp_gpio: gpio {
> compatible = "x-powers,axp209-gpio";
> gpio-controller;
> --
> 2.9.3
>
^ permalink raw reply
* Re: [PATCH 06/22] ARM: dtsi: axp22x: add AXP22X ADC subnode
From: Chen-Yu Tsai @ 2017-01-05 5:52 UTC (permalink / raw)
To: Quentin Schulz
Cc: Mark Rutland, devicetree, Lars-Peter Clausen, open list:THERMAL,
linux-iio, linux-kernel, Sebastian Reichel, Russell King,
Chen-Yu Tsai, Rob Herring, linux-arm-kernel,
Peter Meerwald-Stadler, knaack.h, Maxime Ripard,
Bruno Prémont, Lee Jones, Thomas Petazzoni, Jonathan Cameron,
Icenowy Zheng
In-Reply-To: <20170102163723.7939-7-quentin.schulz@free-electrons.com>
On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> X-Powers AXP22X PMIC has multiple ADCs, each one exposing data from the
> different power supplies connected to the PMIC.
>
> This adds the ADC subnode for AXP22X PMIC.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
> arch/arm/boot/dts/axp22x.dtsi | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi
> index 458b668..a2c4401 100644
> --- a/arch/arm/boot/dts/axp22x.dtsi
> +++ b/arch/arm/boot/dts/axp22x.dtsi
> @@ -52,6 +52,11 @@
> interrupt-controller;
> #interrupt-cells = <1>;
>
> + axp221_adc: axp221_adc {
Same as the last patch. Please change to "adc".
ChenYu
> + compatible = "x-powers,axp221-adc";
> + #io-channel-cells = <1>;
> + };
> +
> regulators {
> /* Default work frequency for buck regulators */
> x-powers,dcdc-freq = <3000>;
> --
> 2.9.3
>
^ permalink raw reply
* [PATCH v11 0/8] power: add power sequence library
From: Peter Chen @ 2017-01-05 6:01 UTC (permalink / raw)
To: gregkh, stern, ulf.hansson, broonie, sre, robh+dt, shawnguo, rjw,
dbaryshkov
Cc: mark.rutland, Peter Chen, heiko, stephen.boyd, gary.bisson,
festevam, stillcompiling, arnd, vaibhav.hiremath, krzk, mka,
devicetree, mail, pawel.moll, linux-pm, s.hauer, troy.kisky,
linux-arm-kernel, hverkuil, oscar, linux-usb, linux-kernel,
p.zabel
Hi all,
This is a follow-up for my last power sequence framework patch set [1].
According to Rob Herring and Ulf Hansson's comments[2]. The kinds of
power sequence instances will be added at postcore_initcall, the match
criteria is compatible string first, if the compatible string is not
matched between dts and library, it will try to use generic power sequence.
The host driver just needs to call of_pwrseq_on/of_pwrseq_off
if only one power sequence instance is needed, for more power sequences
are used, using of_pwrseq_on_list/of_pwrseq_off_list instead (eg, USB hub driver).
In future, if there are special power sequence requirements, the special
power sequence library can be created.
This patch set is tested on i.mx6 sabresx evk using a dts change, I use
two hot-plug devices to simulate this use case, the related binding
change is updated at patch [1/6], The udoo board changes were tested
using my last power sequence patch set.[3]
Except for hard-wired MMC and USB devices, I find the USB ULPI PHY also
need to power on itself before it can be found by ULPI bus.
[1] http://www.spinics.net/lists/linux-usb/msg142755.html
[2] http://www.spinics.net/lists/linux-usb/msg143106.html
[3] http://www.spinics.net/lists/linux-usb/msg142815.html
Changes for v11:
- Fix warning: (USB) selects POWER_SEQUENCE which has unmet direct dependencies (OF)
- Delete redundant copyright statement.
- Change pr_warn to pr_debug at wrseq_find_available_instance
- Refine kerneldoc
- %s/ENONET/ENOENT
- Allocate pwrseq list node before than carry out power sequence on
- Add mutex_lock/mutex_lock for pwrseq node browse at pwrseq_find_available_instance
- Add pwrseq_suspend/resume for API both single instance and list
- Add .pwrseq_suspend/resume for pwrseq_generic.c
- Add pwrseq_suspend_list and pwrseq_resume_list for USB hub suspend
and resume routine
Changes for v10:
- Improve the kernel-doc for power sequence core, including exported APIs and
main structure. [Patch 2/8]
- Change Kconfig, and let the user choose power sequence. [Patch 2/8]
- Delete EXPORT_SYMBOL and change related APIs as local, these APIs do not
be intended to export currently. [Patch 2/8]
- Selete POWER_SEQUENCE at USB core's Kconfig. [Patch 4/8]
Changes for v9:
- Add Vaibhav Hiremath's reviewed-by [Patch 4/8]
- Rebase to v4.9-rc1
Changes for v8:
- Allocate one extra pwrseq instance if pwrseq_get has succeed, it can avoid
preallocate instances problem which the number of instance is decided at
compile time, thanks for Heiko Stuebner's suggestion [Patch 2/8]
- Delete pwrseq_compatible_sample.c which is the demo purpose to show compatible
match method. [Patch 2/8]
- Add Maciej S. Szmigiero's tested-by. [Patch 7/8]
Changes for v7:
- Create kinds of power sequence instance at postcore_initcall, and match
the instance with node using compatible string, the beneit of this is
the host driver doesn't need to consider which pwrseq instance needs
to be used, and pwrseq core will match it, however, it eats some memories
if less power sequence instances are used. [Patch 2/8]
- Add pwrseq_compatible_sample.c to test match pwrseq using device_id. [Patch 2/8]
- Fix the comments Vaibhav Hiremath adds for error path for clock and do not
use device_node for parameters at pwrseq_on. [Patch 2/8]
- Simplify the caller to use power sequence, follows Alan's commnets [Patch 4/8]
- Tested three pwrseq instances together using both specific compatible string and
generic libraries.
Changes for v6:
- Add Matthias Kaehlcke's Reviewed-by and Tested-by. (patch [2/6])
- Change chipidea core of_node assignment for coming user. (patch [5/6])
- Applies Joshua Clayton's three dts changes for two boards,
the USB device's reg has only #address-cells, but without #size-cells.
Changes for v5:
- Delete pwrseq_register/pwrseq_unregister, which is useless currently
- Fix the linker error when the pwrseq user is compiled as module
Changes for v4:
- Create the patch on next-20160722
- Fix the of_node is not NULL after chipidea driver is unbinded [Patch 5/6]
- Using more friendly wait method for reset gpio [Patch 2/6]
- Support multiple input clocks [Patch 2/6]
- Add Rob Herring's ack for DT changes
- Add Joshua Clayton's Tested-by
Changes for v3:
- Delete "power-sequence" property at binding-doc, and change related code
at both library and user code.
- Change binding-doc example node name with Rob's comments
- of_get_named_gpio_flags only gets the gpio, but without setting gpio flags,
add additional code request gpio with proper gpio flags
- Add Philipp Zabel's Ack and MAINTAINER's entry
Changes for v2:
- Delete "pwrseq" prefix and clock-names for properties at dt binding
- Should use structure not but its pointer for kzalloc
- Since chipidea core has no of_node, let core's of_node equals glue
layer's at core's probe
Joshua Clayton (2):
ARM: dts: imx6qdl: Enable usb node children with <reg>
ARM: dts: imx6q-evi: Fix onboard hub reset line
Peter Chen (6):
binding-doc: power: pwrseq-generic: add binding doc for generic power
sequence library
power: add power sequence library
binding-doc: usb: usb-device: add optional properties for power
sequence
usb: core: add power sequence handling for USB devices
usb: chipidea: let chipidea core device of_node equal's glue layer
device of_node
ARM: dts: imx6qdl-udoo.dtsi: fix onboard USB HUB property
.../bindings/power/pwrseq/pwrseq-generic.txt | 48 +++
.../devicetree/bindings/usb/usb-device.txt | 10 +-
MAINTAINERS | 9 +
arch/arm/boot/dts/imx6q-evi.dts | 25 +-
arch/arm/boot/dts/imx6qdl-udoo.dtsi | 26 +-
arch/arm/boot/dts/imx6qdl.dtsi | 6 +
drivers/power/Kconfig | 1 +
drivers/power/Makefile | 1 +
drivers/power/pwrseq/Kconfig | 20 ++
drivers/power/pwrseq/Makefile | 2 +
drivers/power/pwrseq/core.c | 335 +++++++++++++++++++++
drivers/power/pwrseq/pwrseq_generic.c | 224 ++++++++++++++
drivers/usb/Kconfig | 1 +
drivers/usb/chipidea/core.c | 27 +-
drivers/usb/core/hub.c | 48 ++-
drivers/usb/core/hub.h | 1 +
include/linux/power/pwrseq.h | 81 +++++
17 files changed, 823 insertions(+), 42 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
create mode 100644 drivers/power/pwrseq/Kconfig
create mode 100644 drivers/power/pwrseq/Makefile
create mode 100644 drivers/power/pwrseq/core.c
create mode 100644 drivers/power/pwrseq/pwrseq_generic.c
create mode 100644 include/linux/power/pwrseq.h
--
2.7.4
^ permalink raw reply
* [PATCH v11 1/8] binding-doc: power: pwrseq-generic: add binding doc for generic power sequence library
From: Peter Chen @ 2017-01-05 6:01 UTC (permalink / raw)
To: gregkh, stern, ulf.hansson, broonie, sre, robh+dt, shawnguo, rjw,
dbaryshkov
Cc: mark.rutland, Peter Chen, heiko, stephen.boyd, gary.bisson,
festevam, stillcompiling, arnd, vaibhav.hiremath, krzk, mka,
devicetree, mail, pawel.moll, linux-pm, s.hauer, troy.kisky,
linux-arm-kernel, hverkuil, oscar, linux-usb, linux-kernel,
p.zabel
In-Reply-To: <1483596119-27508-1-git-send-email-peter.chen@nxp.com>
Add binding doc for generic power sequence library.
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Rob Herring <robh@kernel.org>
---
.../bindings/power/pwrseq/pwrseq-generic.txt | 48 ++++++++++++++++++++++
1 file changed, 48 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
diff --git a/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
new file mode 100644
index 0000000..ebf0d47
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
@@ -0,0 +1,48 @@
+The generic power sequence library
+
+Some hard-wired devices (eg USB/MMC) need to do power sequence before
+the device can be enumerated on the bus, the typical power sequence
+like: enable USB PHY clock, toggle reset pin, etc. But current
+Linux device driver lacks of such code to do it, it may cause some
+hard-wired devices works abnormal or can't be recognized by
+controller at all. The power sequence will be done before this device
+can be found at the bus.
+
+The power sequence properties is under the device node.
+
+Optional properties:
+- clocks: the input clocks for device.
+- reset-gpios: Should specify the GPIO for reset.
+- reset-duration-us: the duration in microsecond for assert reset signal.
+
+Below is the example of USB power sequence properties on USB device
+nodes which have two level USB hubs.
+
+&usbotg1 {
+ vbus-supply = <®_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ genesys: hub@1 {
+ compatible = "usb5e3,608";
+ reg = <1>;
+
+ clocks = <&clks IMX6SX_CLK_CKO>;
+ reset-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* hub reset pin */
+ reset-duration-us = <10>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ asix: ethernet@1 {
+ compatible = "usbb95,1708";
+ reg = <1>;
+
+ clocks = <&clks IMX6SX_CLK_IPG>;
+ reset-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; /* ethernet_rst */
+ reset-duration-us = <15>;
+ };
+ };
+};
--
2.7.4
^ 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