Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 3/4] ARM: dts: imx7s: add i.MX7 messaging unit support
From: Oleksij Rempel @ 2018-06-15  9:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615095107.24610-1-o.rempel@pengutronix.de>

Define the Messaging Unit (MU) for i.MX7 in the processor's dtsi.
The respective driver is added in the next commit.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 arch/arm/boot/dts/imx7s.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index d9437e773b37..87a82c1f4dfd 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -1008,6 +1008,24 @@
 				status = "disabled";
 			};
 
+			mu0a: mailbox at 30aa0000 {
+				compatible = "fsl,imx7s-mu-a";
+				reg = <0x30aa0000 0x10000>;
+				interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_MU_ROOT_CLK>;
+				#mbox-cells = <1>;
+				status = "disabled";
+			};
+
+			mu0b: mailbox at 30ab0000 {
+				compatible = "fsl,imx7s-mu-b";
+				reg = <0x30ab0000 0x10000>;
+				interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_MU_ROOT_CLK>;
+				#mbox-cells = <1>;
+				status = "disabled";
+			};
+
 			usbotg1: usb at 30b10000 {
 				compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
 				reg = <0x30b10000 0x200>;
-- 
2.17.1

^ permalink raw reply related

* [PATCH v2 4/4] mailbox: Add support for i.MX7D messaging unit
From: Oleksij Rempel @ 2018-06-15  9:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615095107.24610-1-o.rempel@pengutronix.de>

The Mailbox controller is able to send messages (up to 4 32 bit words)
between the endpoints.

This driver was tested using the mailbox-test driver sending messages
between the Cortex-A7 and the Cortex-M4.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/mailbox/Kconfig       |   6 +
 drivers/mailbox/Makefile      |   2 +
 drivers/mailbox/imx-mailbox.c | 288 ++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/mailbox/imx-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index a2bb27446dce..e1d2738a2e4c 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -15,6 +15,12 @@ config ARM_MHU
 	  The controller has 3 mailbox channels, the last of which can be
 	  used in Secure mode only.
 
+config IMX_MBOX
+	tristate "iMX Mailbox"
+	depends on SOC_IMX7D || COMPILE_TEST
+	help
+	  Mailbox implementation for iMX7D Messaging Unit (MU).
+
 config PLATFORM_MHU
 	tristate "Platform MHU Mailbox"
 	depends on OF
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index cc23c3a43fcd..ba2fe1b6dd62 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_MAILBOX_TEST)	+= mailbox-test.o
 
 obj-$(CONFIG_ARM_MHU)	+= arm_mhu.o
 
+obj-$(CONFIG_IMX_MBOX)	+= imx-mailbox.o
+
 obj-$(CONFIG_PLATFORM_MHU)	+= platform_mhu.o
 
 obj-$(CONFIG_PL320_MBOX)	+= pl320-ipc.o
diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
new file mode 100644
index 000000000000..e3f621cb1d30
--- /dev/null
+++ b/drivers/mailbox/imx-mailbox.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+
+/* Transmit Register */
+#define IMX_MU_xTRn(x)		(0x00 + 4 * (x))
+/* Receive Register */
+#define IMX_MU_xRRn(x)		(0x10 + 4 * (x))
+/* Status Register */
+#define IMX_MU_xSR		0x20
+#define IMX_MU_xSR_TEn(x)	BIT(20 + (x))
+#define IMX_MU_xSR_RFn(x)	BIT(24 + (x))
+#define IMX_MU_xSR_BRDIP	BIT(9)
+
+/* Control Register */
+#define IMX_MU_xCR		0x24
+/* Transmit Interrupt Enable */
+#define IMX_MU_xCR_TIEn(x)	BIT(20 + (x))
+/* Receive Interrupt Enable */
+#define IMX_MU_xCR_RIEn(x)	BIT(24 + (x))
+
+#define IMX_MU_MAX_CHANS	4u
+
+struct imx_mu_priv;
+
+struct imx_mu_cfg {
+	unsigned int		chans;
+	void (*init_hw)(struct imx_mu_priv *priv);
+};
+
+struct imx_mu_con_priv {
+	int			irq;
+	unsigned int		bidx;
+	unsigned int		idx;
+};
+
+struct imx_mu_priv {
+	struct device		*dev;
+	const struct imx_mu_cfg	*dcfg;
+	void __iomem		*base;
+
+	struct mbox_controller	mbox;
+	struct mbox_chan	mbox_chans[IMX_MU_MAX_CHANS];
+
+	struct imx_mu_con_priv  con_priv[IMX_MU_MAX_CHANS];
+	struct clk		*clk;
+};
+
+static struct imx_mu_priv *to_imx_mu_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct imx_mu_priv, mbox);
+}
+
+static void imx_mu_write(struct imx_mu_priv *priv, u32 val, u32 offs)
+{
+	iowrite32(val, priv->base + offs);
+}
+
+static u32 imx_mu_read(struct imx_mu_priv *priv, u32 offs)
+{
+	return ioread32(priv->base + offs);
+}
+
+static u32 imx_mu_rmw(struct imx_mu_priv *priv, u32 offs, u32 set, u32 clr)
+{
+	u32 val;
+
+	val = imx_mu_read(priv, offs);
+	val &= ~clr;
+	val |= set;
+	imx_mu_write(priv, val, offs);
+
+	return val;
+}
+
+static irqreturn_t imx_mu_isr(int irq, void *p)
+{
+	struct mbox_chan *chan = p;
+	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
+	struct imx_mu_con_priv *cp = chan->con_priv;
+
+	u32 val, dat;
+
+	val = imx_mu_read(priv, IMX_MU_xSR);
+	val &= IMX_MU_xSR_TEn(cp->bidx) | IMX_MU_xSR_RFn(cp->bidx);
+	if (!val)
+		return IRQ_NONE;
+
+	if (val & IMX_MU_xSR_TEn(cp->bidx)) {
+		imx_mu_rmw(priv, IMX_MU_xCR, 0, IMX_MU_xCR_TIEn(cp->bidx));
+		mbox_chan_txdone(chan, 0);
+	}
+
+	if (val & IMX_MU_xSR_RFn(cp->bidx)) {
+		dat = imx_mu_read(priv, IMX_MU_xRRn(cp->idx));
+		mbox_chan_received_data(chan, (void *)&dat);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static bool imx_mu_last_tx_done(struct mbox_chan *chan)
+{
+	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
+	struct imx_mu_con_priv *cp = chan->con_priv;
+	u32 val;
+
+	val = imx_mu_read(priv, IMX_MU_xSR);
+	/* test if transmit register is empty */
+	return (!!(val & IMX_MU_xSR_TEn(cp->bidx)));
+}
+
+static int imx_mu_send_data(struct mbox_chan *chan, void *data)
+{
+	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
+	struct imx_mu_con_priv *cp = chan->con_priv;
+	u32 *arg = data;
+
+	if (!imx_mu_last_tx_done(chan))
+		return -EBUSY;
+
+	imx_mu_write(priv, *arg, IMX_MU_xTRn(cp->idx));
+	imx_mu_rmw(priv, IMX_MU_xCR, IMX_MU_xSR_TEn(cp->bidx), 0);
+
+	return 0;
+}
+
+static int imx_mu_startup(struct mbox_chan *chan)
+{
+	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
+	struct imx_mu_con_priv *cp = chan->con_priv;
+	int ret;
+
+	ret = request_irq(cp->irq, imx_mu_isr,
+			  IRQF_SHARED, "imx_mu_chan", chan);
+	if (ret) {
+		dev_err(chan->mbox->dev,
+			"Unable to acquire IRQ %d\n", cp->irq);
+		return ret;
+	}
+
+	imx_mu_rmw(priv, IMX_MU_xCR, IMX_MU_xCR_RIEn(cp->bidx), 0);
+
+	return 0;
+}
+
+static void imx_mu_shutdown(struct mbox_chan *chan)
+{
+	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
+	struct imx_mu_con_priv *cp = chan->con_priv;
+
+	imx_mu_rmw(priv, IMX_MU_xCR, 0,
+		   IMX_MU_xCR_TIEn(cp->bidx) | IMX_MU_xCR_RIEn(cp->bidx));
+
+	free_irq(cp->irq, chan);
+}
+
+static const struct mbox_chan_ops imx_mu_ops = {
+	.send_data = imx_mu_send_data,
+	.startup = imx_mu_startup,
+	.shutdown = imx_mu_shutdown,
+};
+
+static int imx_mu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *iomem;
+	struct imx_mu_priv *priv;
+	const struct imx_mu_cfg *dcfg;
+	unsigned int i, chans;
+	int irq, ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dcfg = of_device_get_match_data(dev);
+	if (!dcfg)
+		return -EINVAL;
+
+	priv->dcfg = dcfg;
+	priv->dev = dev;
+
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->base = devm_ioremap_resource(&pdev->dev, iomem);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0)
+		return irq < 0 ? irq : -EINVAL;
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		if (PTR_ERR(priv->clk) == -ENOENT) {
+			priv->clk = NULL;
+		} else {
+			dev_err(dev, "Failed to get clock\n");
+			return PTR_ERR(priv->clk);
+		}
+	}
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(dev, "Failed to enable clock\n");
+		return ret;
+	}
+
+	chans = min(dcfg->chans, IMX_MU_MAX_CHANS);
+	/* Initialize channel identifiers */
+	for (i = 0; i < chans; i++) {
+		struct imx_mu_con_priv *cp = &priv->con_priv[i];
+
+		cp->bidx = 3 - i;
+		cp->idx = i;
+		cp->irq = irq;
+		priv->mbox_chans[i].con_priv = cp;
+	}
+
+	priv->mbox.dev = dev;
+	priv->mbox.ops = &imx_mu_ops;
+	priv->mbox.chans = priv->mbox_chans;
+	priv->mbox.num_chans = chans;
+	priv->mbox.txdone_irq = true;
+
+	platform_set_drvdata(pdev, priv);
+
+	if (priv->dcfg->init_hw)
+		priv->dcfg->init_hw(priv);
+
+	return mbox_controller_register(&priv->mbox);
+}
+
+static int imx_mu_remove(struct platform_device *pdev)
+{
+	struct imx_mu_priv *priv = platform_get_drvdata(pdev);
+
+	mbox_controller_unregister(&priv->mbox);
+	clk_disable_unprepare(priv->clk);
+
+	return 0;
+}
+
+
+static void imx_mu_init_imx7d_a(struct imx_mu_priv *priv)
+{
+	/* Set default config */
+	imx_mu_write(priv, 0, IMX_MU_xCR);
+}
+
+static const struct imx_mu_cfg imx_mu_cfg_imx7d_a = {
+	.chans = IMX_MU_MAX_CHANS,
+	.init_hw = imx_mu_init_imx7d_a,
+};
+
+static const struct imx_mu_cfg imx_mu_cfg_imx7d_b = {
+	.chans = IMX_MU_MAX_CHANS,
+};
+
+static const struct of_device_id imx_mu_dt_ids[] = {
+	{ .compatible = "fsl,imx7s-mu-a", .data = &imx_mu_cfg_imx7d_a },
+	{ .compatible = "fsl,imx7s-mu-b", .data = &imx_mu_cfg_imx7d_b },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, imx_mu_dt_ids);
+
+static struct platform_driver imx_mu_driver = {
+	.probe		= imx_mu_probe,
+	.remove		= imx_mu_remove,
+	.driver = {
+		.name	= "imx_mu",
+		.of_match_table = imx_mu_dt_ids,
+	},
+};
+module_platform_driver(imx_mu_driver);
+
+MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
+MODULE_DESCRIPTION("Message Unit driver for i.MX");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1

^ permalink raw reply related

* [PATCH] arm64/acpi: Add fixup for HPE m400 quirks
From: Graeme Gregory @ 2018-06-15  9:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <51d3d738-cdf5-2992-bba5-c3e1f34096c2@infradead.org>

On Wed, Jun 13, 2018 at 11:22:30AM -0700, Geoff Levand wrote:
> Adds a new ACPI init routine acpi_fixup_m400_quirks that adds
> a work-around for HPE ProLiant m400 APEI firmware problems.
> 
> The work-around disables APEI when CONFIG_ACPI_APEI is set and
> m400 firmware is detected.  Without this fixup m400 systems
> experience errors like these on startup:
> 
>   [Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 2
>   [Hardware Error]: event severity: fatal
>   [Hardware Error]:  Error 0, type: fatal
>   [Hardware Error]:   section_type: memory error
>   [Hardware Error]:   error_status: 0x0000000000001300
>   [Hardware Error]:   error_type: 10, invalid address
>   Kernel panic - not syncing: Fatal hardware error!
> 
> Signed-off-by: Geoff Levand <geoff@infradead.org>
> ---
> Hi,
> 
> It seems unlikely there will be any m400 firmware updates to fix
> this problem.  APEI support is desired for new ARM64 servers coming
> to market.  Distros are now forced to have their own fixes, not
> enable APEI, or let m400 users fend for themselves.
> 
> Please consider.
> 
> -Geoff
> 
>  arch/arm64/kernel/acpi.c | 40 ++++++++++++++++++++++++++++++++++++----
>  1 file changed, 36 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 7b09487ff8fb..3c315c2c7476 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -31,6 +31,8 @@
>  #include <asm/cpu_ops.h>
>  #include <asm/smp_plat.h>
>  
> +#include <acpi/apei.h>
> +
>  #ifdef CONFIG_ACPI_APEI
>  # include <linux/efi.h>
>  # include <asm/pgtable.h>
> @@ -177,6 +179,33 @@ static int __init acpi_fadt_sanity_check(void)
>  	return ret;
>  }
>  
> +/*
> + * acpi_fixup_m400_quirks - Work-around for HPE ProLiant m400 APEI firmware
> + * problems.
> + */
> +static void __init acpi_fixup_m400_quirks(void)
> +{
> +	acpi_status status;
> +	struct acpi_table_header *header;
> +#if !defined(CONFIG_ACPI_APEI)
> +	int hest_disable = HEST_DISABLED;
> +#endif
> +
> +	if (!IS_ENABLED(CONFIG_ACPI_APEI) || hest_disable != HEST_ENABLED)
> +		return;
> +
> +	status = acpi_get_table(ACPI_SIG_HEST, 0, &header);
> +
> +	if (ACPI_SUCCESS(status) && !strncmp(header->oem_id, "HPE   ", 6) &&
> +		!strncmp(header->oem_table_id, "ProLiant", 8) &&
> +		MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM) {
> +		hest_disable = HEST_DISABLED;
> +		pr_info("Disabled APEI for m400.\n");
> +	}
> +
> +	acpi_put_table(header);
> +}
> +
>  /*
>   * acpi_boot_table_init() called from setup_arch(), always.
>   *	1. find RSDP and get its address, and then find XSDT
> @@ -232,11 +261,14 @@ void __init acpi_boot_table_init(void)
>  	if (acpi_disabled) {
>  		if (earlycon_acpi_spcr_enable)
>  			early_init_dt_scan_chosen_stdout();
> -	} else {
> -		acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
> -		if (IS_ENABLED(CONFIG_ACPI_BGRT))
> -			acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
> +		return;
>  	}
> +
> +	acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
> +	if (IS_ENABLED(CONFIG_ACPI_BGRT))
> +		acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
> +
> +	acpi_fixup_m400_quirks();
>  }
>  
>  #ifdef CONFIG_ACPI_APEI

Quirk actually make code nicer to read.

Reviewed-by: Graeme Gregory <graeme.gregory@linaro.org>

Thanks we needed this having 90+ m400s

Graeme

^ permalink raw reply

* [RFC PATCH 6/8] dts: coresight: Clean up the device tree graph bindings
From: Suzuki K Poulose @ 2018-06-15  9:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAL_Jsq+0kExVY33kdDoR6bAxbr2VzRUzW2j0k+2wmv4CSNVnpQ@mail.gmail.com>

On 14/06/18 14:59, Rob Herring wrote:
> On Thu, Jun 14, 2018 at 2:53 AM, Suzuki K Poulose
> <Suzuki.Poulose@arm.com> wrote:
>> On 13/06/18 22:07, Matt Sealey wrote:
>>>
>>>
>>>
>>>> -----Original Message-----
>>>> From: Mathieu Poirier <mathieu.poirier@linaro.org>
>>>>
>>>>> So, if the suggestion is to use an existing property "unit", I am fine
>>>>> with it, if people agree to it.
>>>>
>>>>
>>>> If we're going to have something sharply different than ACPI I prefer
>>>> Rob's idea.
>>
>>
>> No, the above comment is about using "unit" ( if it is a standard property
>> for specifying something specific to hardware) instead of "coresight,hwid".
>> I would prefer to stick to the DT graph bindings, because :
> 
> "unit" is not a standard property and I don't like it either.
> 
>>
>> 1) The connections are bi-directional => Well, not necessarily
>> bi-directional
>> in terms of the data flow. But the connection information is critical. i.e,
>> we need information about both the end-points of a connection, which the DT
>> graph bindings solves.
>>
>> All we are missing is a way for specifying the "hardware port" number and
>> the
>> direction of flow. I don't see why do we need to create something new just
>> for
>> these two properties for something that exists today and works reasonably
>> well
>> for the usecase.

Rob,

> 
> If you have "in-ports" and "out-ports" nodes, then that gives you
> direction and you can use reg for the "hardware port".
> 
> in-ports {
>    port at 0 {
>      reg = <0>;
>      endpoint {...};
>    };
>    port at 1 {
>      reg = <1>;
>      endpoint {...};
>    };
> };
> out-ports {
>    port at 0 {
>      reg = <0>;
>      endpoint {...};
>    };
> };
> 
> I'll need to check, but dtc may need an update to not warn about this.

Ok, that looks good.

> 
>>
>>>
>>> What are you trying to say about being sharply different than ACPI?
>>
>>
>> The proposed Coresight ACPI draft bindings are based on the ACPI Graph
>> bindings
>> (just like the DT graph bindings and is compatible with it, in terms of the
>> APIs.
>> i.e, fwnode_graph_* operations work for both ACPI and DT  alike).
>>
>> So, what Mathieu, in turn means is, if we depart from the DT Graph bindings,
>> which
>> I personally don't see any benefit in.
> 
> If DT bindings can be reused for ACPI, that's fine, but don't expect
> any DT bindings to be accepted simply because they match ACPI
> bindings.

The proposed bindings are not making it compatible with the ACPI. In fact,
the ACPI bindings do need something similar to give us an explicit hardware
port number, which needs to be worked out. The only common theme shared
between the proposed ACPI and current DT bindings are the Generic Graph
bindings for describing the connections, which allows sharing the parsing
code independent of the platform, using fwnode_ops.

Suzuki

^ permalink raw reply

* [PATCH 1/4] arm: dts: add support for Laird WB45N cpu module and DVK
From: Ben Whitten @ 2018-06-15 10:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <03f0f635-3fc2-085b-20e0-e1fcaa9e8062@microchip.com>

> On 14/06/2018 at 10:51, Ben Whitten wrote:
> > Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
> > ---
> >   arch/arm/boot/dts/Makefile        |   3 +-
> >   arch/arm/boot/dts/at91-wb45n.dts  |  66 +++++++++++++++
> >   arch/arm/boot/dts/at91-wb45n.dtsi | 169
> ++++++++++++++++++++++++++++++++++++++
> >   3 files changed, 237 insertions(+), 1 deletion(-)
> >   create mode 100644 arch/arm/boot/dts/at91-wb45n.dts
> >   create mode 100644 arch/arm/boot/dts/at91-wb45n.dtsi
> >
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index 7e24249..1ee94ee 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -42,7 +42,8 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
> >   	at91sam9g25ek.dtb \
> >   	at91sam9g35ek.dtb \
> >   	at91sam9x25ek.dtb \
> > -	at91sam9x35ek.dtb
> > +	at91sam9x35ek.dtb \
> > +	at91-wb45n.dtb
> >   dtb-$(CONFIG_SOC_SAM_V7) += \
> >   	at91-kizbox2.dtb \
> >   	at91-nattis-2-natte-2.dtb \
> > diff --git a/arch/arm/boot/dts/at91-wb45n.dts b/arch/arm/boot/dts/at91-
> wb45n.dts
> > new file mode 100644
> > index 0000000..4e88815
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/at91-wb45n.dts
> > @@ -0,0 +1,66 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * at91-wb45n.dts - Device Tree file for WB45NBT board
> > + *
> > + *  Copyright (C) 2018 Laird
> > + *
> > +*/
> > +/dts-v1/;
> > +#include "at91-wb45n.dtsi"
> > +
> > +/ {
> > +	model = "Laird Workgroup Bridge 45N - Atmel AT91SAM (dt)";
> > +	compatible = "laird,wb45n", "laird,wbxx", "atmel,at91sam9x5",
> "atmel,at91sam9";
> 
> "laird" prefix must be added to
> Documentation/devicetree/bindings/vendor-prefixes.txt before using it:
> you can do a little patch as a first patch of this series.
> Otherwise it will trigger a warning message while running
> scripts/checkpatch.pl on top of your patch.
> 
> 
> > +
> > +	ahb {
> > +		apb {
> > +			watchdog at fffffe40 {
> > +				status = "okay";
> > +			};
> > +		};
> > +	};
> > +
> > +	gpio_keys {
> > +		compatible = "gpio-keys";
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		irqbtn at pb18 {
> 
> I'm not sure that the @pb18 can be used like this. This address
> extension must be used in a "reg" property in the node. dtc used with
> warning switch on might trigger an error for this.
> 
> > +			label = "IRQBTN";
> > +			linux,code = <99>;
> > +			gpios = <&pioB 18 GPIO_ACTIVE_LOW>;
> > +			gpio-key,wakeup = <1>;
> > +		};
> > +	};
> > +};
> > +
> > +&usb0 {
> > +	status = "okay";
> > +};
> > +
> > +&mmc0 {
> > +	status = "okay";
> > +};
> > +
> > +&spi0 {
> > +	status = "okay";
> > +};
> > +
> > +&macb0 {
> > +	status = "okay";
> > +};
> > +
> > +&dbgu {
> > +	status = "okay";
> > +};
> > +
> > +&usart0 {
> > +	status = "okay";
> > +};
> > +
> > +&usart3 {
> > +	status = "okay";
> > +};
> > +
> > +&i2c1 {
> > +	status = "okay";
> > +};
> > diff --git a/arch/arm/boot/dts/at91-wb45n.dtsi b/arch/arm/boot/dts/at91-
> wb45n.dtsi
> > new file mode 100644
> > index 0000000..2fa58e2
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/at91-wb45n.dtsi
> > @@ -0,0 +1,169 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * at91-wb45n.dtsi - Device Tree file for WB45NBT board
> > + *
> > + *  Copyright (C) 2018 Laird
> > + *
> > + */
> > +
> > +#include "at91sam9g25.dtsi"
> > +
> > +/ {
> > +	model = "Laird Workgroup Bridge 45N - Atmel AT91SAM (dt)";
> > +	compatible = "laird,wb45n", "laird,wbxx", "atmel,at91sam9x5",
> "atmel,at91sam9";
> > +
> > +	chosen {
> > +		bootargs = "ubi.mtd=6 root=ubi0:rootfs rootfstype=ubifs
> rw";
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	memory {
> > +		reg = <0x20000000 0x4000000>;
> > +	};
> > +
> > +	ahb {
> > +		apb {
> > +			shdwc at fffffe10 {
> 
> I would advice you to take exactly the node name:
> "shutdown-controller at fffffe10"; Anyway, it will go away after you use
> the label notation as advised by Alexandre.
> 
> > +				atmel,wakeup-mode = "low";
> > +			};
> > +
> > +			pinctrl at fffff400 {
> > +				usb2 {
> > +					pinctrl_board_usb2: usb2-board {
> > +						atmel,pins =
> > +							<AT91_PIOB 11
> AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;		/* PB11 gpio
> vbus sense, deglitch */
> > +					};
> > +				};
> > +			};
> > +
> > +			rstc at fffffe00 {
> > +				compatible = "atmel,sama5d3-rstc";
> > +			};
> 
> I don't think this node is needed.

I dug through our old code reviews and found this message relating to testing
reboot over several thousand times in our testbed:
After the slow clock has been enabled on the reset controller via upstream
changes, the dram disable access and power down code is causing the SAM9G25
to hang occasionally on reboot.  Using the simple reset function provided
for SAMA5D3 instead.

So it appears to be a workaround for a bug that existed ~2 years ago, may still be
relevant as there haven't been many changes to the reset code in that time.

> > +
> > +		};
> > +	};
> > +
> > +	atheros {
> > +		compatible = "atheros,ath6kl";
> > +		atheros,board-id = "SD32";
> > +	};
> > +};
> > +
> > +&slow_xtal {
> > +	clock-frequency = <32768>;
> > +};
> > +
> > +&main_xtal {
> > +	clock-frequency = <12000000>;
> > +};
> > +
> > +&ebi {
> > +	status = "okay";
> > +	nand_controller: nand-controller {
> > +		pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb
> &pinctrl_nand_oe_we>;
> > +		pinctrl-names = "default";
> > +		status = "okay";
> > +
> > +		nand at 3 {
> > +			reg = <0x3 0x0 0x800000>;
> > +			rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
> > +			cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>;
> > +			nand-bus-width = <8>;
> > +			nand-ecc-mode = "hw";
> > +			nand-ecc-strength = <4>;
> > +			nand-ecc-step-size = <512>;
> > +			nand-on-flash-bbt;
> > +			label = "atmel_nand";
> > +
> > +			partitions {
> > +				compatible = "fixed-partitions";
> > +				#address-cells = <1>;
> > +				#size-cells = <1>;
> > +
> > +				at91bootstrap at 0 {
> > +					label = "at91bs";
> > +					reg = <0x0 0x20000>;
> > +				};
> > +
> > +				uboot at 20000 {
> > +					label = "u-boot";
> > +					reg = <0x20000 0x80000>;
> > +				};
> > +
> > +				ubootenv at a0000 {
> > +					label = "u-boot-env";
> > +					reg = <0xa0000 0x20000>;
> > +				};
> > +
> > +				ubootenv at c0000 {
> > +					label = "redund-env";
> > +					reg = <0xc0000 0x20000>;
> > +				};
> > +
> > +				kernel-a at e0000 {
> > +					label = "kernel-a";
> > +					reg = <0xe0000 0x280000>;
> > +				};
> > +
> > +				kernel-b at 360000 {
> > +					label = "kernel-b";
> > +					reg = <0x360000 0x280000>;
> > +				};
> > +
> > +				rootfs-a at 5e0000 {
> > +					label = "rootfs-a";
> > +					reg = <0x5e0000 0x2600000>;
> > +				};
> > +
> > +				rootfs-b at 2be0000 {
> > +					label = "rootfs-b";
> > +					reg = <0x2be0000 0x2600000>;
> > +				};
> > +
> > +				user at 51e0000 {
> > +					label = "user";
> > +					reg = <0x51e0000 0x2dc0000>;
> > +				};
> > +
> > +				logs at 7fa0000 {
> > +					label = "logs";
> > +					reg = <0x7fa0000 0x60000>;
> > +				};
> > +
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&usb0 {
> 
> This must be &usb1 label, isn't it?
> Because you are referring to ohci binding I suspect (found by having a
> look at: atmel,oc-gpio property...).

I believe usb0 is correct, as this is a at91sam9x5 part, the node in dtsi is -ohci.
sama5d3 is usb1 for -ohci.

> > +	num-ports = <2>;
> > +	atmel,vbus-gpio = <
> > +		&pioB 12 GPIO_ACTIVE_HIGH
> > +		&pioA 31 GPIO_ACTIVE_HIGH
> > +		>;
> > +	atmel,oc-gpio = <&pioB 13 GPIO_ACTIVE_LOW>;
> > +};
> > +
> > +&macb0 {
> > +	phy-mode = "rmii";
> > +};
> > +
> > +&spi0 {
> > +	cs-gpios = <&pioA 14 0>, <&pioA 7 0>, <0>, <0>;
> > +};
> > +
> > +&usb2 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_board_usb2>;
> > +	atmel,vbus-gpio = <&pioB 11 GPIO_ACTIVE_HIGH>;
> > +};
> > +
> > +&mmc0 {
> > +	pinctrl-0 = <
> > +		&pinctrl_mmc0_slot0_clk_cmd_dat0
> > +		&pinctrl_mmc0_slot0_dat1_3>;
> > +	slot at 0 {
> > +		reg = <0>;
> > +		bus-width = <4>;
> > +	};
> > +};
> >
> 
> 
> --
> Nicolas Ferre

^ permalink raw reply

* [PATCH 00/11] Split i2c_lock_adapter into i2c_lock_root and i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

With the introduction of mux-locked I2C muxes, the concept of
locking only a segment of the I2C adapter tree was added. At the
time, I did not want to cause a lot of extra churn, so left most
users of i2c_lock_adapter alone and aparently didn't think enough
about it; they simply continued to lock the whole adapter tree.
However, i2c_lock_adapter is in fact wrong for almost every caller
(there are naturally exceptions) that is itself not a driver for
a root adapter. What normal drivers generally want is to only
lock the segment of the adapter tree that their device sits on.

In fact, if a device sits behind a mux-locked I2C mux, and its
driver calls i2c_lock_adapter followed by an unlocked I2C transfer,
things will deadlock (since even a mux-locked I2C adapter will lock
its parent at some point). If the device is not sitting behind a
mux-locked I2C mux (i.e. either directly on the root adapter or
behind a (chain of) parent-locked I2C muxes) the root/segment
distinction is of no consequence; the root adapter is locked either
way.

Mux-locked I2C muxes are probably not that common, and putting any
of the affected devices behind one is probably even rarer, which
is why we have not seen any deadlocks. At least not that I know
of...

Since silently changing the semantics of i2c_lock_adapter might
be quite a surprise, especially for out-of-tree users, this
series instead introduces new helpers to make it easier to only
lock the I2C segment, then converts drivers over and finally
renames the remaining i2c_lock_adapter instances to i2c_lock_root.

I suggest that Wolfram takes this series through the I2C tree
and creates an immutable branch for the other subsystems. The
series is based on v4.17, but I did not find any new instances in
neither linus-master nor linux-next and the series still applies
cleanly to linus-master for me. linux-next has removed suspend
support from the i2c-tegra driver. A bit strange, I thought the
I2C changes was merged for this window? Anyway, the resolution
for that conflict is trivial, just remove the i2c-tegra hunk from
patch 11.

I do not have *any* of the affected devices, and have thus only
done build tests.

Cheers,
Peter

Peter Rosin (11):
  i2c: add helpers for locking the I2C segment
  tpm/tpm_i2c_infineon: switch to i2c_lock_segment
  i2c: mux: pca9541: switch to i2c_lock_segment
  input: rohm_bu21023: switch to i2c_lock_segment
  media: af9013: switch to i2c_lock_segment
  media: drxk_hard: switch to i2c_lock_segment
  media: rtl2830: switch to i2c_lock_segment
  media: tda1004x: switch to i2c_lock_segment
  media: tda18271: switch to i2c_lock_segment
  mfd: 88pm860x-i2c: switch to i2c_lock_segment
  i2c: rename i2c_lock_adapter to i2c_lock_root

 drivers/char/tpm/tpm_i2c_infineon.c      |  8 ++++----
 drivers/i2c/busses/i2c-brcmstb.c         |  8 ++++----
 drivers/i2c/busses/i2c-davinci.c         |  4 ++--
 drivers/i2c/busses/i2c-gpio.c            | 12 ++++++------
 drivers/i2c/busses/i2c-s3c2410.c         |  4 ++--
 drivers/i2c/busses/i2c-sprd.c            |  8 ++++----
 drivers/i2c/busses/i2c-tegra.c           |  8 ++++----
 drivers/i2c/i2c-core-base.c              |  6 +++---
 drivers/i2c/i2c-core-slave.c             |  8 ++++----
 drivers/i2c/i2c-core-smbus.c             |  4 ++--
 drivers/i2c/muxes/i2c-mux-pca9541.c      |  6 +++---
 drivers/iio/temperature/mlx90614.c       |  4 ++--
 drivers/input/touchscreen/rohm_bu21023.c |  4 ++--
 drivers/media/dvb-frontends/af9013.c     |  8 ++++----
 drivers/media/dvb-frontends/drxk_hard.c  |  4 ++--
 drivers/media/dvb-frontends/rtl2830.c    | 12 ++++++------
 drivers/media/dvb-frontends/tda1004x.c   |  6 +++---
 drivers/media/tuners/tda18271-common.c   |  8 ++++----
 drivers/mfd/88pm860x-i2c.c               |  8 ++++----
 include/linux/i2c.h                      | 22 ++++++++++++++++++++--
 20 files changed, 85 insertions(+), 67 deletions(-)

-- 
2.11.0

^ permalink raw reply

* [PATCH 01/11] i2c: add helpers for locking the I2C segment
From: Peter Rosin @ 2018-06-15 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

This is what almost all drivers want to do. By only advertising
i2c_lock_adapter, they are tricked into locking the root adapter
which is too big of a hammer in most cases.

While at it, convert all open-coded locking of the I2C segment.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/i2c/i2c-core-base.c  |  6 +++---
 drivers/i2c/i2c-core-smbus.c |  4 ++--
 include/linux/i2c.h          | 18 ++++++++++++++++++
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 1ba40bb2b966..3eb09dc20573 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1932,16 +1932,16 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 #endif
 
 		if (in_atomic() || irqs_disabled()) {
-			ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT);
+			ret = i2c_trylock_segment(adap);
 			if (!ret)
 				/* I2C activity is ongoing. */
 				return -EAGAIN;
 		} else {
-			i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
+			i2c_lock_segment(adap);
 		}
 
 		ret = __i2c_transfer(adap, msgs, num);
-		i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
+		i2c_unlock_segment(adap);
 
 		return ret;
 	} else {
diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c
index b5aec33002c3..8a820fdef3e0 100644
--- a/drivers/i2c/i2c-core-smbus.c
+++ b/drivers/i2c/i2c-core-smbus.c
@@ -537,7 +537,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
 	flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;
 
 	if (adapter->algo->smbus_xfer) {
-		i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);
+		i2c_lock_segment(adapter);
 
 		/* Retry automatically on arbitration loss */
 		orig_jiffies = jiffies;
@@ -551,7 +551,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
 				       orig_jiffies + adapter->timeout))
 				break;
 		}
-		i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);
+		i2c_unlock_segment(adapter);
 
 		if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)
 			goto trace;
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 44ad14e016b5..c9080d49e988 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -768,6 +768,24 @@ i2c_unlock_adapter(struct i2c_adapter *adapter)
 	i2c_unlock_bus(adapter, I2C_LOCK_ROOT_ADAPTER);
 }
 
+static inline void
+i2c_lock_segment(struct i2c_adapter *adapter)
+{
+	i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);
+}
+
+static inline int
+i2c_trylock_segment(struct i2c_adapter *adapter)
+{
+	return i2c_trylock_bus(adapter, I2C_LOCK_SEGMENT);
+}
+
+static inline void
+i2c_unlock_segment(struct i2c_adapter *adapter)
+{
+	i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);
+}
+
 /*flags for the client struct: */
 #define I2C_CLIENT_PEC		0x04	/* Use Packet Error Checking */
 #define I2C_CLIENT_TEN		0x10	/* we have a ten bit chip address */
-- 
2.11.0

^ permalink raw reply related

* [PATCH 02/11] tpm/tpm_i2c_infineon: switch to i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

Locking the root adapter for __i2c_transfer will deadlock if the
device sits behind a mux-locked I2C mux. Switch to the finer-grained
i2c_lock_segment. If the device does not sit behind a mux-locked mux,
the two locking variants are equivalent.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/char/tpm/tpm_i2c_infineon.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
index 6116cd05e228..b2889405b4fa 100644
--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -117,7 +117,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 	/* Lock the adapter for the duration of the whole sequence. */
 	if (!tpm_dev.client->adapter->algo->master_xfer)
 		return -EOPNOTSUPP;
-	i2c_lock_adapter(tpm_dev.client->adapter);
+	i2c_lock_segment(tpm_dev.client->adapter);
 
 	if (tpm_dev.chip_type == SLB9645) {
 		/* use a combined read for newer chips
@@ -192,7 +192,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 	}
 
 out:
-	i2c_unlock_adapter(tpm_dev.client->adapter);
+	i2c_unlock_segment(tpm_dev.client->adapter);
 	/* take care of 'guard time' */
 	usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
 
@@ -224,7 +224,7 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
 
 	if (!tpm_dev.client->adapter->algo->master_xfer)
 		return -EOPNOTSUPP;
-	i2c_lock_adapter(tpm_dev.client->adapter);
+	i2c_lock_segment(tpm_dev.client->adapter);
 
 	/* prepend the 'register address' to the buffer */
 	tpm_dev.buf[0] = addr;
@@ -243,7 +243,7 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
 		usleep_range(sleep_low, sleep_hi);
 	}
 
-	i2c_unlock_adapter(tpm_dev.client->adapter);
+	i2c_unlock_segment(tpm_dev.client->adapter);
 	/* take care of 'guard time' */
 	usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH 03/11] i2c: mux: pca9541: switch to i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

Locking the root adapter for __i2c_transfer will deadlock if the
device sits behind a mux-locked I2C mux. Switch to the finer-grained
i2c_lock_segment. If the device does not sit behind a mux-locked mux,
the two locking variants are equivalent.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/i2c/muxes/i2c-mux-pca9541.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c
index 6a39adaf433f..74c560ed44cc 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
@@ -345,11 +345,11 @@ static int pca9541_probe(struct i2c_client *client,
 
 	/*
 	 * I2C accesses are unprotected here.
-	 * We have to lock the adapter before releasing the bus.
+	 * We have to lock the I2C segment before releasing the bus.
 	 */
-	i2c_lock_adapter(adap);
+	i2c_lock_segment(adap);
 	pca9541_release_bus(client);
-	i2c_unlock_adapter(adap);
+	i2c_unlock_segment(adap);
 
 	/* Create mux adapter */
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH 04/11] input: rohm_bu21023: switch to i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

Locking the root adapter for __i2c_transfer will deadlock if the
device sits behind a mux-locked I2C mux. Switch to the finer-grained
i2c_lock_segment. If the device does not sit behind a mux-locked mux,
the two locking variants are equivalent.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/input/touchscreen/rohm_bu21023.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c
index bda0500c9b57..22d79db07234 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -304,7 +304,7 @@ static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf,
 	msg[1].len = len;
 	msg[1].buf = buf;
 
-	i2c_lock_adapter(adap);
+	i2c_lock_segment(adap);
 
 	for (i = 0; i < 2; i++) {
 		if (__i2c_transfer(adap, &msg[i], 1) < 0) {
@@ -313,7 +313,7 @@ static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf,
 		}
 	}
 
-	i2c_unlock_adapter(adap);
+	i2c_unlock_segment(adap);
 
 	return ret;
 }
-- 
2.11.0

^ permalink raw reply related

* [PATCH 05/11] media: af9013: switch to i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

Locking the root adapter for __i2c_transfer will deadlock if the
device sits behind a mux-locked I2C mux. Switch to the finer-grained
i2c_lock_segment. If the device does not sit behind a mux-locked mux,
the two locking variants are equivalent.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/media/dvb-frontends/af9013.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c
index 482bce49819a..a504697ff557 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -1312,10 +1312,10 @@ static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg,
 	memcpy(&buf[3], val, len);
 
 	if (lock)
-		i2c_lock_adapter(client->adapter);
+		i2c_lock_segment(client->adapter);
 	ret = __i2c_transfer(client->adapter, msg, 1);
 	if (lock)
-		i2c_unlock_adapter(client->adapter);
+		i2c_unlock_segment(client->adapter);
 	if (ret < 0) {
 		goto err;
 	} else if (ret != 1) {
@@ -1353,10 +1353,10 @@ static int af9013_rregs(struct i2c_client *client, u8 cmd, u16 reg,
 	buf[2] = cmd;
 
 	if (lock)
-		i2c_lock_adapter(client->adapter);
+		i2c_lock_segment(client->adapter);
 	ret = __i2c_transfer(client->adapter, msg, 2);
 	if (lock)
-		i2c_unlock_adapter(client->adapter);
+		i2c_unlock_segment(client->adapter);
 	if (ret < 0) {
 		goto err;
 	} else if (ret != 2) {
-- 
2.11.0

^ permalink raw reply related

* [PATCH 06/11] media: drxk_hard: switch to i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

Locking the root adapter for __i2c_transfer will deadlock if the
device sits behind a mux-locked I2C mux. Switch to the finer-grained
i2c_lock_segment. If the device does not sit behind a mux-locked mux,
the two locking variants are equivalent.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/media/dvb-frontends/drxk_hard.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index 5a26ad93be10..10e6bb158712 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -213,7 +213,7 @@ static inline u32 log10times100(u32 value)
 
 static int drxk_i2c_lock(struct drxk_state *state)
 {
-	i2c_lock_adapter(state->i2c);
+	i2c_lock_segment(state->i2c);
 	state->drxk_i2c_exclusive_lock = true;
 
 	return 0;
@@ -224,7 +224,7 @@ static void drxk_i2c_unlock(struct drxk_state *state)
 	if (!state->drxk_i2c_exclusive_lock)
 		return;
 
-	i2c_unlock_adapter(state->i2c);
+	i2c_unlock_segment(state->i2c);
 	state->drxk_i2c_exclusive_lock = false;
 }
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH 07/11] media: rtl2830: switch to i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

Locking the root adapter for __i2c_transfer will deadlock if the
device sits behind a mux-locked I2C mux. Switch to the finer-grained
i2c_lock_segment. If the device does not sit behind a mux-locked mux,
the two locking variants are equivalent.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/media/dvb-frontends/rtl2830.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c
index 7bbfe11d11ed..85a8a9c4d020 100644
--- a/drivers/media/dvb-frontends/rtl2830.c
+++ b/drivers/media/dvb-frontends/rtl2830.c
@@ -24,9 +24,9 @@ static int rtl2830_bulk_write(struct i2c_client *client, unsigned int reg,
 	struct rtl2830_dev *dev = i2c_get_clientdata(client);
 	int ret;
 
-	i2c_lock_adapter(client->adapter);
+	i2c_lock_segment(client->adapter);
 	ret = regmap_bulk_write(dev->regmap, reg, val, val_count);
-	i2c_unlock_adapter(client->adapter);
+	i2c_unlock_segment(client->adapter);
 	return ret;
 }
 
@@ -36,9 +36,9 @@ static int rtl2830_update_bits(struct i2c_client *client, unsigned int reg,
 	struct rtl2830_dev *dev = i2c_get_clientdata(client);
 	int ret;
 
-	i2c_lock_adapter(client->adapter);
+	i2c_lock_segment(client->adapter);
 	ret = regmap_update_bits(dev->regmap, reg, mask, val);
-	i2c_unlock_adapter(client->adapter);
+	i2c_unlock_segment(client->adapter);
 	return ret;
 }
 
@@ -48,9 +48,9 @@ static int rtl2830_bulk_read(struct i2c_client *client, unsigned int reg,
 	struct rtl2830_dev *dev = i2c_get_clientdata(client);
 	int ret;
 
-	i2c_lock_adapter(client->adapter);
+	i2c_lock_segment(client->adapter);
 	ret = regmap_bulk_read(dev->regmap, reg, val, val_count);
-	i2c_unlock_adapter(client->adapter);
+	i2c_unlock_segment(client->adapter);
 	return ret;
 }
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH 08/11] media: tda1004x: switch to i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

Locking the root adapter for __i2c_transfer will deadlock if the
device sits behind a mux-locked I2C mux. Switch to the finer-grained
i2c_lock_segment. If the device does not sit behind a mux-locked mux,
the two locking variants are equivalent.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/media/dvb-frontends/tda1004x.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c
index 58e3beff5adc..1e5c183cdd86 100644
--- a/drivers/media/dvb-frontends/tda1004x.c
+++ b/drivers/media/dvb-frontends/tda1004x.c
@@ -329,7 +329,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
 	tda1004x_write_byteI(state, dspCodeCounterReg, 0);
 	fw_msg.addr = state->config->demod_address;
 
-	i2c_lock_adapter(state->i2c);
+	i2c_lock_segment(state->i2c);
 	buf[0] = dspCodeInReg;
 	while (pos != len) {
 		// work out how much to send this time
@@ -342,14 +342,14 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
 		fw_msg.len = tx_size + 1;
 		if (__i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
 			printk(KERN_ERR "tda1004x: Error during firmware upload\n");
-			i2c_unlock_adapter(state->i2c);
+			i2c_unlock_segment(state->i2c);
 			return -EIO;
 		}
 		pos += tx_size;
 
 		dprintk("%s: fw_pos=0x%x\n", __func__, pos);
 	}
-	i2c_unlock_adapter(state->i2c);
+	i2c_unlock_segment(state->i2c);
 
 	/* give the DSP a chance to settle 03/10/05 Hac */
 	msleep(100);
-- 
2.11.0

^ permalink raw reply related

* [PATCH 09/11] media: tda18271: switch to i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

Locking the root adapter for __i2c_transfer will deadlock if the
device sits behind a mux-locked I2C mux. Switch to the finer-grained
i2c_lock_segment. If the device does not sit behind a mux-locked mux,
the two locking variants are equivalent.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/media/tuners/tda18271-common.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/tuners/tda18271-common.c b/drivers/media/tuners/tda18271-common.c
index 7e81cd887c13..93cce2bcd601 100644
--- a/drivers/media/tuners/tda18271-common.c
+++ b/drivers/media/tuners/tda18271-common.c
@@ -225,7 +225,7 @@ static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len,
 	 */
 	if (lock_i2c) {
 		tda18271_i2c_gate_ctrl(fe, 1);
-		i2c_lock_adapter(priv->i2c_props.adap);
+		i2c_lock_segment(priv->i2c_props.adap);
 	}
 	while (len) {
 		if (max > len)
@@ -246,7 +246,7 @@ static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len,
 		len -= max;
 	}
 	if (lock_i2c) {
-		i2c_unlock_adapter(priv->i2c_props.adap);
+		i2c_unlock_segment(priv->i2c_props.adap);
 		tda18271_i2c_gate_ctrl(fe, 0);
 	}
 
@@ -300,7 +300,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
 	 * as those could cause bad things
 	 */
 	tda18271_i2c_gate_ctrl(fe, 1);
-	i2c_lock_adapter(priv->i2c_props.adap);
+	i2c_lock_segment(priv->i2c_props.adap);
 
 	/* initialize registers */
 	switch (priv->id) {
@@ -516,7 +516,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
 	/* synchronize */
 	__tda18271_write_regs(fe, R_EP1, 1, false);
 
-	i2c_unlock_adapter(priv->i2c_props.adap);
+	i2c_unlock_segment(priv->i2c_props.adap);
 	tda18271_i2c_gate_ctrl(fe, 0);
 
 	return 0;
-- 
2.11.0

^ permalink raw reply related

* [PATCH 10/11] mfd: 88pm860x-i2c: switch to i2c_lock_segment
From: Peter Rosin @ 2018-06-15 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

Locking the root adapter for __i2c_transfer will deadlock if the
device sits behind a mux-locked I2C mux. Switch to the finer-grained
i2c_lock_segment. If the device does not sit behind a mux-locked mux,
the two locking variants are equivalent.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/mfd/88pm860x-i2c.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index 84e313107233..8e54fc2dc29c 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -146,14 +146,14 @@ int pm860x_page_reg_write(struct i2c_client *i2c, int reg,
 	unsigned char zero;
 	int ret;
 
-	i2c_lock_adapter(i2c->adapter);
+	i2c_lock_segment(i2c->adapter);
 	read_device(i2c, 0xFA, 0, &zero);
 	read_device(i2c, 0xFB, 0, &zero);
 	read_device(i2c, 0xFF, 0, &zero);
 	ret = write_device(i2c, reg, 1, &data);
 	read_device(i2c, 0xFE, 0, &zero);
 	read_device(i2c, 0xFC, 0, &zero);
-	i2c_unlock_adapter(i2c->adapter);
+	i2c_unlock_segment(i2c->adapter);
 	return ret;
 }
 EXPORT_SYMBOL(pm860x_page_reg_write);
@@ -164,14 +164,14 @@ int pm860x_page_bulk_read(struct i2c_client *i2c, int reg,
 	unsigned char zero = 0;
 	int ret;
 
-	i2c_lock_adapter(i2c->adapter);
+	i2c_lock_segment(i2c->adapter);
 	read_device(i2c, 0xfa, 0, &zero);
 	read_device(i2c, 0xfb, 0, &zero);
 	read_device(i2c, 0xff, 0, &zero);
 	ret = read_device(i2c, reg, count, buf);
 	read_device(i2c, 0xFE, 0, &zero);
 	read_device(i2c, 0xFC, 0, &zero);
-	i2c_unlock_adapter(i2c->adapter);
+	i2c_unlock_segment(i2c->adapter);
 	return ret;
 }
 EXPORT_SYMBOL(pm860x_page_bulk_read);
-- 
2.11.0

^ permalink raw reply related

* [PATCH 11/11] i2c: rename i2c_lock_adapter to i2c_lock_root
From: Peter Rosin @ 2018-06-15 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615101506.8012-1-peda@axentia.se>

The i2c_lock_adapter name is ambiguous since it is unclear if it
refers to the root adapter or the adapter you name in the argument.
The natural interpretation is the adapter you name in the argument,
but there are historical reasons for that not being the case; it
in fact locks the root adapter. Rename the function to indicate
what is really going on. Also rename i2c_unlock_adapter, of course.

This patch was generated with

  grep -rlI --exclude-dir=.git 'i2c_\(un\)\?lock_adapter' \
    | xargs sed -i 's/i2c_\(un\)\?lock_adapter/i2c_\1lock_root/g'

followed by some minor white-space touch-up.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/i2c/busses/i2c-brcmstb.c   |  8 ++++----
 drivers/i2c/busses/i2c-davinci.c   |  4 ++--
 drivers/i2c/busses/i2c-gpio.c      | 12 ++++++------
 drivers/i2c/busses/i2c-s3c2410.c   |  4 ++--
 drivers/i2c/busses/i2c-sprd.c      |  8 ++++----
 drivers/i2c/busses/i2c-tegra.c     |  8 ++++----
 drivers/i2c/i2c-core-slave.c       |  8 ++++----
 drivers/iio/temperature/mlx90614.c |  4 ++--
 include/linux/i2c.h                |  4 ++--
 9 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c
index 78792b4d6437..c42e14d4a127 100644
--- a/drivers/i2c/busses/i2c-brcmstb.c
+++ b/drivers/i2c/busses/i2c-brcmstb.c
@@ -689,9 +689,9 @@ static int brcmstb_i2c_suspend(struct device *dev)
 {
 	struct brcmstb_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
-	i2c_lock_adapter(&i2c_dev->adapter);
+	i2c_lock_root(&i2c_dev->adapter);
 	i2c_dev->is_suspended = true;
-	i2c_unlock_adapter(&i2c_dev->adapter);
+	i2c_unlock_root(&i2c_dev->adapter);
 
 	return 0;
 }
@@ -700,10 +700,10 @@ static int brcmstb_i2c_resume(struct device *dev)
 {
 	struct brcmstb_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
-	i2c_lock_adapter(&i2c_dev->adapter);
+	i2c_lock_root(&i2c_dev->adapter);
 	brcmstb_i2c_set_bsc_reg_defaults(i2c_dev);
 	i2c_dev->is_suspended = false;
-	i2c_unlock_adapter(&i2c_dev->adapter);
+	i2c_unlock_root(&i2c_dev->adapter);
 
 	return 0;
 }
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 75d6ab177055..9139d8da29ae 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -714,14 +714,14 @@ static int i2c_davinci_cpufreq_transition(struct notifier_block *nb,
 
 	dev = container_of(nb, struct davinci_i2c_dev, freq_transition);
 
-	i2c_lock_adapter(&dev->adapter);
+	i2c_lock_root(&dev->adapter);
 	if (val == CPUFREQ_PRECHANGE) {
 		davinci_i2c_reset_ctrl(dev, 0);
 	} else if (val == CPUFREQ_POSTCHANGE) {
 		i2c_davinci_calc_clk_dividers(dev);
 		davinci_i2c_reset_ctrl(dev, 1);
 	}
-	i2c_unlock_adapter(&dev->adapter);
+	i2c_unlock_root(&dev->adapter);
 
 	return 0;
 }
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 58abb3eced58..6983968735ca 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -82,18 +82,18 @@ static int fops_##wire##_get(void *data, u64 *val)	\
 {							\
 	struct i2c_gpio_private_data *priv = data;	\
 							\
-	i2c_lock_adapter(&priv->adap);			\
+	i2c_lock_root(&priv->adap);			\
 	*val = get##wire(&priv->bit_data);		\
-	i2c_unlock_adapter(&priv->adap);		\
+	i2c_unlock_root(&priv->adap);			\
 	return 0;					\
 }							\
 static int fops_##wire##_set(void *data, u64 val)	\
 {							\
 	struct i2c_gpio_private_data *priv = data;	\
 							\
-	i2c_lock_adapter(&priv->adap);			\
+	i2c_lock_root(&priv->adap);			\
 	set##wire(&priv->bit_data, val);		\
-	i2c_unlock_adapter(&priv->adap);		\
+	i2c_unlock_root(&priv->adap);			\
 	return 0;					\
 }							\
 DEFINE_DEBUGFS_ATTRIBUTE(fops_##wire, fops_##wire##_get, fops_##wire##_set, "%llu\n")
@@ -113,7 +113,7 @@ static int fops_incomplete_transfer_set(void *data, u64 addr)
 	/* ADDR (7 bit) + RD (1 bit) + SDA hi (1 bit) */
 	pattern = (addr << 2) | 3;
 
-	i2c_lock_adapter(&priv->adap);
+	i2c_lock_root(&priv->adap);
 
 	/* START condition */
 	setsda(bit_data, 0);
@@ -129,7 +129,7 @@ static int fops_incomplete_transfer_set(void *data, u64 addr)
 		udelay(bit_data->udelay);
 	}
 
-	i2c_unlock_adapter(&priv->adap);
+	i2c_unlock_root(&priv->adap);
 
 	return 0;
 }
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 5d97510ee48b..6e8f8d2e847c 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -921,9 +921,9 @@ static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
 
 	if ((val == CPUFREQ_POSTCHANGE && delta_f < 0) ||
 	    (val == CPUFREQ_PRECHANGE && delta_f > 0)) {
-		i2c_lock_adapter(&i2c->adap);
+		i2c_lock_root(&i2c->adap);
 		ret = s3c24xx_i2c_clockrate(i2c, &got);
-		i2c_unlock_adapter(&i2c->adap);
+		i2c_unlock_root(&i2c->adap);
 
 		if (ret < 0)
 			dev_err(i2c->dev, "cannot find frequency (%d)\n", ret);
diff --git a/drivers/i2c/busses/i2c-sprd.c b/drivers/i2c/busses/i2c-sprd.c
index 4053259bccb8..58a4a263984f 100644
--- a/drivers/i2c/busses/i2c-sprd.c
+++ b/drivers/i2c/busses/i2c-sprd.c
@@ -590,9 +590,9 @@ static int __maybe_unused sprd_i2c_suspend_noirq(struct device *pdev)
 {
 	struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
 
-	i2c_lock_adapter(&i2c_dev->adap);
+	i2c_lock_root(&i2c_dev->adap);
 	i2c_dev->is_suspended = true;
-	i2c_unlock_adapter(&i2c_dev->adap);
+	i2c_unlock_root(&i2c_dev->adap);
 
 	return pm_runtime_force_suspend(pdev);
 }
@@ -601,9 +601,9 @@ static int __maybe_unused sprd_i2c_resume_noirq(struct device *pdev)
 {
 	struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
 
-	i2c_lock_adapter(&i2c_dev->adap);
+	i2c_lock_root(&i2c_dev->adap);
 	i2c_dev->is_suspended = false;
-	i2c_unlock_adapter(&i2c_dev->adap);
+	i2c_unlock_root(&i2c_dev->adap);
 
 	return pm_runtime_force_resume(pdev);
 }
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 60292d243e24..1f2ed0dfbbaf 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1055,9 +1055,9 @@ static int tegra_i2c_suspend(struct device *dev)
 {
 	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
-	i2c_lock_adapter(&i2c_dev->adapter);
+	i2c_lock_root(&i2c_dev->adapter);
 	i2c_dev->is_suspended = true;
-	i2c_unlock_adapter(&i2c_dev->adapter);
+	i2c_unlock_root(&i2c_dev->adapter);
 
 	return 0;
 }
@@ -1067,13 +1067,13 @@ static int tegra_i2c_resume(struct device *dev)
 	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 	int ret;
 
-	i2c_lock_adapter(&i2c_dev->adapter);
+	i2c_lock_root(&i2c_dev->adapter);
 
 	ret = tegra_i2c_init(i2c_dev);
 	if (!ret)
 		i2c_dev->is_suspended = false;
 
-	i2c_unlock_adapter(&i2c_dev->adapter);
+	i2c_unlock_root(&i2c_dev->adapter);
 
 	return ret;
 }
diff --git a/drivers/i2c/i2c-core-slave.c b/drivers/i2c/i2c-core-slave.c
index 4a78c65e9971..fd68678f31c2 100644
--- a/drivers/i2c/i2c-core-slave.c
+++ b/drivers/i2c/i2c-core-slave.c
@@ -47,9 +47,9 @@ int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb)
 
 	client->slave_cb = slave_cb;
 
-	i2c_lock_adapter(client->adapter);
+	i2c_lock_root(client->adapter);
 	ret = client->adapter->algo->reg_slave(client);
-	i2c_unlock_adapter(client->adapter);
+	i2c_unlock_root(client->adapter);
 
 	if (ret) {
 		client->slave_cb = NULL;
@@ -69,9 +69,9 @@ int i2c_slave_unregister(struct i2c_client *client)
 		return -EOPNOTSUPP;
 	}
 
-	i2c_lock_adapter(client->adapter);
+	i2c_lock_root(client->adapter);
 	ret = client->adapter->algo->unreg_slave(client);
-	i2c_unlock_adapter(client->adapter);
+	i2c_unlock_root(client->adapter);
 
 	if (ret == 0)
 		client->slave_cb = NULL;
diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c
index d619e8634a00..15e7b2c3e7d7 100644
--- a/drivers/iio/temperature/mlx90614.c
+++ b/drivers/iio/temperature/mlx90614.c
@@ -433,11 +433,11 @@ static int mlx90614_wakeup(struct mlx90614_data *data)
 
 	dev_dbg(&data->client->dev, "Requesting wake-up");
 
-	i2c_lock_adapter(data->client->adapter);
+	i2c_lock_root(data->client->adapter);
 	gpiod_direction_output(data->wakeup_gpio, 0);
 	msleep(MLX90614_TIMING_WAKEUP);
 	gpiod_direction_input(data->wakeup_gpio);
-	i2c_unlock_adapter(data->client->adapter);
+	i2c_unlock_root(data->client->adapter);
 
 	data->ready_timestamp = jiffies +
 			msecs_to_jiffies(MLX90614_TIMING_STARTUP);
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index c9080d49e988..40db4b0accb8 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -757,13 +757,13 @@ i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags)
 }
 
 static inline void
-i2c_lock_adapter(struct i2c_adapter *adapter)
+i2c_lock_root(struct i2c_adapter *adapter)
 {
 	i2c_lock_bus(adapter, I2C_LOCK_ROOT_ADAPTER);
 }
 
 static inline void
-i2c_unlock_adapter(struct i2c_adapter *adapter)
+i2c_unlock_root(struct i2c_adapter *adapter)
 {
 	i2c_unlock_bus(adapter, I2C_LOCK_ROOT_ADAPTER);
 }
-- 
2.11.0

^ permalink raw reply related

* [PATCH v4 02/26] arm64: cpufeature: Add cpufeature for IRQ priority masking
From: Suzuki K Poulose @ 2018-06-15 10:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <bc8bb69d-8db4-87b7-adfb-589e1dd905c0@arm.com>

On 12/06/18 14:46, Julien Thierry wrote:
> 
> 
> On 25/05/18 11:48, Julien Thierry wrote:
>>
>>
>> On 25/05/18 11:41, Suzuki K Poulose wrote:
>>> On 25/05/18 11:39, Julien Thierry wrote:
>>>>
>>>>
>>>> On 25/05/18 11:36, Suzuki K Poulose wrote:
>>>>> On 25/05/18 11:17, Julien Thierry wrote:
>>>>>>
>>>>>>
>>>>>> On 25/05/18 11:04, Suzuki K Poulose wrote:
>>>>>>> On 25/05/18 10:49, Julien Thierry wrote:
>>>>>>>> Add a cpufeature indicating whether a cpu supports masking interrupts
>>>>>>>> by priority.
>>>>>>>
>>>>>>> How is this different from the SYSREG_GIC_CPUIF cap ? Is it just
>>>>>>> the description ?
>>>>>>
>>>>>> More or less.
>>>>>>
>>>>>> It is just to have an easier condition in the rest of the series. Basically the PRIO masking feature is enabled if we have a GICv3 CPUIF working *and* the option was selected at build time. Before this meant that I was checking for the GIC_CPUIF cap inside #ifdefs (and putting alternatives depending on that inside #ifdefs as well).
>>>>>>
>>>>>> Having this as a separate feature feels easier to manage in the code. It also makes it clearer at boot time that the kernel will be using irq priorities (although I admit it was not the initial intention):
>>>>>>
>>>>>> [??? 0.000000] CPU features: detected: IRQ priority masking
>>>>>>
>>>>>>
>>>>>> But yes that new feature will be detected only if SYSREG_GIC_CPUIF gets detected as well.
>>>>>
>>>>> Well, you could always wrap the check like :
>>>>>
>>>>> static inline bool system_has_irq_priority_masking(void)
>>>>> {
>>>>> ?????return (IS_ENABLED(CONFIG_YOUR_CONFIG) && cpus_have_const_cap(HWCAP_SYSREG_GIC_CPUIF));
>>>>> }
>>>>>
>>>>> and use it everywhere.
>>>>>
>>>>
>>>> Yes, but I can't use that in the asm parts that use alternatives and would need to surround them in #ifdef... :\
>>>
>>> I thought there is _ALTERNATIVE_CFG() to base the alternative depend on a CONFIG_xxx ?
>>> Doesn't that solve the problem ?
>>
>> Right, I didn't see that one. It should work yes.
>>
>> I'll try that when working on the next version.
> 
> I've been trying to use this now, but I can't figure out how.
> 
> The _ALTERNATIVE_CFG does not seem to work in assembly code (despite having its own definition for __ASSEMBLY__), and the alternative_insn does not seem to be suited for instructions that take operands (or more than one operand)
> 
> If I am mistaken, can you provide an example of how to use this in assembly with instructions having more than 1 operand?

I am sorry, but I think the ALTERNATIVE_CFG is not the right one, as it
omits the entire block, if the CONFIG is not enabled. So you are left with
only three choices :

1) Use alternative call back
2) Stick to two separate caps.
3) Use #ifdef

Cheers
Suzuki

^ permalink raw reply

* [PATCH 1/1] iommu/arm-smmu: Add support to use Last level cache
From: Vivek Gautam @ 2018-06-15 10:53 UTC (permalink / raw)
  To: linux-arm-kernel

Qualcomm SoCs have an additional level of cache called as
System cache or Last level cache[1]. This cache sits right
before the DDR, and is tightly coupled with the memory
controller.
The cache is available to all the clients present in the
SoC system. The clients request their slices from this system
cache, make it active, and can then start using it. For these
clients with smmu, to start using the system cache for
dma buffers and related page tables [2], few of the memory
attributes need to be set accordingly.
This change makes the related memory Outer-Shareable, and
updates the MAIR with necessary protection.

The MAIR attribute requirements are:
    Inner Cacheablity = 0
    Outer Cacheablity = 1, Write-Back Write Allocate
    Outer Shareablity = 1

This change is a realisation of following changes
from downstream msm-4.9:
iommu: io-pgtable-arm: Support DOMAIN_ATTRIBUTE_USE_UPSTREAM_HINT
iommu: io-pgtable-arm: Implement IOMMU_USE_UPSTREAM_HINT

[1] https://patchwork.kernel.org/patch/10422531/
[2] https://patchwork.kernel.org/patch/10302791/

Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
---
 drivers/iommu/arm-smmu.c       | 14 ++++++++++++++
 drivers/iommu/io-pgtable-arm.c | 24 +++++++++++++++++++-----
 drivers/iommu/io-pgtable.h     |  4 ++++
 include/linux/iommu.h          |  4 ++++
 4 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index f7a96bcf94a6..8058e7205034 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -249,6 +249,7 @@ struct arm_smmu_domain {
 	struct mutex			init_mutex; /* Protects smmu pointer */
 	spinlock_t			cb_lock; /* Serialises ATS1* ops and TLB syncs */
 	struct iommu_domain		domain;
+	bool				has_sys_cache;
 };
 
 struct arm_smmu_option_prop {
@@ -862,6 +863,8 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
 
 	if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
 		pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_NO_DMA;
+	if (smmu_domain->has_sys_cache)
+		pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_SYS_CACHE;
 
 	smmu_domain->smmu = smmu;
 	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
@@ -1477,6 +1480,9 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
 	case DOMAIN_ATTR_NESTING:
 		*(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED);
 		return 0;
+	case DOMAIN_ATTR_USE_SYS_CACHE:
+		*((int *)data) = smmu_domain->has_sys_cache;
+		return 0;
 	default:
 		return -ENODEV;
 	}
@@ -1506,6 +1512,14 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
 			smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
 
 		break;
+	case DOMAIN_ATTR_USE_SYS_CACHE:
+		if (smmu_domain->smmu) {
+			ret = -EPERM;
+			goto out_unlock;
+		}
+		if (*((int *)data))
+			smmu_domain->has_sys_cache = true;
+		break;
 	default:
 		ret = -ENODEV;
 	}
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 010a254305dd..b2aee1828524 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -169,9 +169,11 @@
 #define ARM_LPAE_MAIR_ATTR_DEVICE	0x04
 #define ARM_LPAE_MAIR_ATTR_NC		0x44
 #define ARM_LPAE_MAIR_ATTR_WBRWA	0xff
+#define ARM_LPAE_MAIR_ATTR_SYS_CACHE	0xf4
 #define ARM_LPAE_MAIR_ATTR_IDX_NC	0
 #define ARM_LPAE_MAIR_ATTR_IDX_CACHE	1
 #define ARM_LPAE_MAIR_ATTR_IDX_DEV	2
+#define ARM_LPAE_MAIR_ATTR_IDX_SYS_CACHE	3
 
 /* IOPTE accessors */
 #define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d))
@@ -442,6 +444,10 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
 		else if (prot & IOMMU_CACHE)
 			pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE
 				<< ARM_LPAE_PTE_ATTRINDX_SHIFT);
+		else if (prot & IOMMU_SYS_CACHE)
+			pte |= (ARM_LPAE_MAIR_ATTR_IDX_SYS_CACHE
+				<< ARM_LPAE_PTE_ATTRINDX_SHIFT);
+
 	} else {
 		pte = ARM_LPAE_PTE_HAP_FAULT;
 		if (prot & IOMMU_READ)
@@ -771,7 +777,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 	u64 reg;
 	struct arm_lpae_io_pgtable *data;
 
-	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_DMA))
+	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_DMA |
+			    IO_PGTABLE_QUIRK_SYS_CACHE))
 		return NULL;
 
 	data = arm_lpae_alloc_pgtable(cfg);
@@ -779,9 +786,14 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 		return NULL;
 
 	/* TCR */
-	reg = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
-	      (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
-	      (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
+	if (cfg->quirks & IO_PGTABLE_QUIRK_SYS_CACHE) {
+		reg = (ARM_LPAE_TCR_SH_OS << ARM_LPAE_TCR_SH0_SHIFT) |
+		      (ARM_LPAE_TCR_RGN_NC << ARM_LPAE_TCR_IRGN0_SHIFT);
+	} else {
+		reg = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
+		      (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT);
+	}
+	reg |= (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
 
 	switch (ARM_LPAE_GRANULE(data)) {
 	case SZ_4K:
@@ -833,7 +845,9 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 	      (ARM_LPAE_MAIR_ATTR_WBRWA
 	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_CACHE)) |
 	      (ARM_LPAE_MAIR_ATTR_DEVICE
-	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_DEV));
+	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_DEV)) |
+	      (ARM_LPAE_MAIR_ATTR_SYS_CACHE
+	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_SYS_CACHE));
 
 	cfg->arm_lpae_s1_cfg.mair[0] = reg;
 	cfg->arm_lpae_s1_cfg.mair[1] = 0;
diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
index 2df79093cad9..b5a398380e9f 100644
--- a/drivers/iommu/io-pgtable.h
+++ b/drivers/iommu/io-pgtable.h
@@ -71,12 +71,16 @@ struct io_pgtable_cfg {
 	 *	be accessed by a fully cache-coherent IOMMU or CPU (e.g. for a
 	 *	software-emulated IOMMU), such that pagetable updates need not
 	 *	be treated as explicit DMA data.
+	 *
+	 * IO_PGTABLE_QUIRK_SYS_CACHE: Override the attributes set in TCR for
+	 *	the page table walker when using system cache.
 	 */
 	#define IO_PGTABLE_QUIRK_ARM_NS		BIT(0)
 	#define IO_PGTABLE_QUIRK_NO_PERMS	BIT(1)
 	#define IO_PGTABLE_QUIRK_TLBI_ON_MAP	BIT(2)
 	#define IO_PGTABLE_QUIRK_ARM_MTK_4GB	BIT(3)
 	#define IO_PGTABLE_QUIRK_NO_DMA		BIT(4)
+	#define IO_PGTABLE_QUIRK_SYS_CACHE	BIT(5)
 	unsigned long			quirks;
 	unsigned long			pgsize_bitmap;
 	unsigned int			ias;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 19938ee6eb31..dacb9648e9b3 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -41,6 +41,9 @@
  * if the IOMMU page table format is equivalent.
  */
 #define IOMMU_PRIV	(1 << 5)
+/* Use last level cache available with few architectures */
+#define IOMMU_SYS_CACHE	(1 << 6)
+
 
 struct iommu_ops;
 struct iommu_group;
@@ -124,6 +127,7 @@ enum iommu_attr {
 	DOMAIN_ATTR_FSL_PAMU_ENABLE,
 	DOMAIN_ATTR_FSL_PAMUV1,
 	DOMAIN_ATTR_NESTING,	/* two stages of translation */
+	DOMAIN_ATTR_USE_SYS_CACHE,
 	DOMAIN_ATTR_MAX,
 };
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related

* [linux-sunxi] Re: [PATCH] crypto: sun4i-ss: prevent deadlock on emulated hardware
From: Maxime Ripard @ 2018-06-15 11:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180615091650.GC3047@Red>

On Fri, Jun 15, 2018 at 11:16:50AM +0200, Corentin Labbe wrote:
> On Fri, Jun 15, 2018 at 11:04:12AM +0200, Maxime Ripard wrote:
> > On Fri, Jun 15, 2018 at 10:15:54AM +0200, Corentin Labbe wrote:
> > > On Fri, Jun 15, 2018 at 09:57:54AM +0200, Maxime Ripard wrote:
> > > > On Thu, Jun 14, 2018 at 09:36:59PM +0200, Corentin Labbe wrote:
> > > > > Running a qemu emulated cubieboard with sun4i-ss driver enabled led to a never
> > > > > ending boot.
> > > > > This is due to sun4i-ss deadlocked and taking all cpu in an infinite loop.
> > > > > Since the crypto hardware is not implemented, all registers are read as 0.
> > > > > So sun4i-ss will never progress in any operations. (TX_CNT being always 0)
> > > > > 
> > > > > The first idea is to add a "TX_CNT always zero timeout" but this made cipher/hash loops
> > > > > more complex and prevent a case that never happen on real hardware.
> > > > > 
> > > > > The best way to fix is to check at probe time if we run on a virtual
> > > > > machine with hardware emulated but non-implemented and prevent
> > > > > sun4i-ss to be loaded in that case.
> > > > > Letting sun4i-ss to load is useless anyway since all crypto algorithm will be
> > > > > disabled since they will fail crypto selftests.
> > > > > 
> > > > > Tested-on: qemu-cubieboard
> > > > > Tested-on: cubieboard2
> > > > > 
> > > > > Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> > > > > ---
> > > > >  drivers/crypto/sunxi-ss/sun4i-ss-core.c | 10 ++++++++++
> > > > >  1 file changed, 10 insertions(+)
> > > > > 
> > > > > diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-core.c b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> > > > > index a81d89b3b7d8..a178e80adcf3 100644
> > > > > --- a/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> > > > > +++ b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> > > > > @@ -341,9 +341,18 @@ static int sun4i_ss_probe(struct platform_device *pdev)
> > > > >  	 * I expect to be a sort of Security System Revision number.
> > > > >  	 * Since the A80 seems to have an other version of SS
> > > > >  	 * this info could be useful
> > > > > +	 * Detect virtual machine with non-implemented hardware
> > > > > +	 * (qemu-cubieboard) by checking the register value after a write to it.
> > > > > +	 * On non-implemented hardware, all registers are read as 0.
> > > > > +	 * On real hardware we should have a value > 0.
> > > > >  	 */
> > > > >  	writel(SS_ENABLED, ss->base + SS_CTL);
> > > > >  	v = readl(ss->base + SS_CTL);
> > > > > +	if (!v) {
> > > > > +		dev_err(&pdev->dev, "Qemu with non-implemented SS detected.\n");
> > > > > +		err = -ENODEV;
> > > > > +		goto error_rst;
> > > > > +	}
> > > > 
> > > > This is wrong way to tackle the issue. There's multiple reason why
> > > > this could happen (for example the device not being clocked, or
> > > > maintained in reset). There's nothing specific about qemu here, and
> > > > the fundamental issue isn't that the device isn't functional in qemu,
> > > > it's that qemu lies about which hardware it can emulate in the DT it
> > > > passes to the kernel.
> > > > 
> > > > There's no way this can scale, alone from the fact that qemu should
> > > > patch the DT according to what it can do. Not trying to chase after
> > > > each and every device that is broken in qemu.
> > > > 
> > > > NAK.
> > > > 
> > > 
> > > My fix detect also when the device is badly clocked.
> > 
> > In which case, the proper fix is to enable the clock, not throw the
> > kernel's arm up in the air.
> > 
> 
> By badly I mean "not clocked" or "with the wrong frequencies".
>
> I could change the clock rate range test to exit (it issue only a
> warning for now).  But I think this fix detect all cases and still
> permit someone to play with overclocking/downclocking.

You're still trying to fix the consequence when you should be fixing
the cause.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* [PATCH] arm64/acpi: Add fixup for HPE m400 quirks
From: James Morse @ 2018-06-15 11:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <51d3d738-cdf5-2992-bba5-c3e1f34096c2@infradead.org>

Hi Geoff,

On 13/06/18 19:22, Geoff Levand wrote:
> Adds a new ACPI init routine acpi_fixup_m400_quirks that adds
> a work-around for HPE ProLiant m400 APEI firmware problems.
> 
> The work-around disables APEI when CONFIG_ACPI_APEI is set and
> m400 firmware is detected.  Without this fixup m400 systems
> experience errors like these on startup:
> 
>   [Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 2
>   [Hardware Error]: event severity: fatal
>   [Hardware Error]:  Error 0, type: fatal
>   [Hardware Error]:   section_type: memory error
>   [Hardware Error]:   error_status: 0x0000000000001300

"Access to a memory address which is not mapped to any component"


>   [Hardware Error]:   error_type: 10, invalid address
>   Kernel panic - not syncing: Fatal hardware error!

Why is this a problem?

Surely this is a valid description of an error.
(okay its not particularly useful without the physical address, but the address
is optional in that structure)

When does this happen during boot? This looks like a driver mapping some
non-existent physical address space to see if its device is present...
unsurprisingly this doesn't go well.
(might also be a typo in the DSDT)

Can't we pin down the driver that does this and fix it. Its either wrong for
everyone, or still broken after you disable APEI.


> It seems unlikely there will be any m400 firmware updates to fix
> this problem.

What is the problem? This patch looks like it shoots the messenger for bringing
bad news.


> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 7b09487ff8fb..3c315c2c7476 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -31,6 +31,8 @@
>  #include <asm/cpu_ops.h>
>  #include <asm/smp_plat.h>
>  
> +#include <acpi/apei.h>
> +
>  #ifdef CONFIG_ACPI_APEI
>  # include <linux/efi.h>
>  # include <asm/pgtable.h>
> @@ -177,6 +179,33 @@ static int __init acpi_fadt_sanity_check(void)
>  	return ret;
>  }
>  
> +/*
> + * acpi_fixup_m400_quirks - Work-around for HPE ProLiant m400 APEI firmware
> + * problems.
> + */
> +static void __init acpi_fixup_m400_quirks(void)
> +{
> +	acpi_status status;
> +	struct acpi_table_header *header;
> +#if !defined(CONFIG_ACPI_APEI)
> +	int hest_disable = HEST_DISABLED;
> +#endif

Yuck.


> +
> +	if (!IS_ENABLED(CONFIG_ACPI_APEI) || hest_disable != HEST_ENABLED)
> +		return;
> +
> +	status = acpi_get_table(ACPI_SIG_HEST, 0, &header);
> +
> +	if (ACPI_SUCCESS(status) && !strncmp(header->oem_id, "HPE   ", 6) &&
> +		!strncmp(header->oem_table_id, "ProLiant", 8) &&

You should match the affected range of OEM table revisions too, that way a
firmware upgrade should start working, instead of being permanently disabled
because we think its unlikely.


> +		MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM) {

How is the CPU implementer relevant?

You suggest a firmware-update would make this issue go away...


> +		hest_disable = HEST_DISABLED;
> +		pr_info("Disabled APEI for m400.\n");
> +	}
> +
> +	acpi_put_table(header);
> +}
> +
>  /*
>   * acpi_boot_table_init() called from setup_arch(), always.
>   *	1. find RSDP and get its address, and then find XSDT

Nothing arch-specific here. You're adding this to arch/arm64 because
drivers/acpi/apei doesn't have an existing quirks table?


Thanks,

James

^ permalink raw reply

* [PATCH 5/6] arm64: dts: rockchip: Add missing cooling device properties for CPUs
From: Heiko Stübner @ 2018-06-15 11:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <d7f32cb0c3b77901cb5e37320a454e5e1dfed958.1527225682.git.viresh.kumar@linaro.org>

Am Freitag, 25. Mai 2018, 07:40:05 CEST schrieb Viresh Kumar:
> The cooling device properties, like "#cooling-cells" and
> "dynamic-power-coefficient", should either be present for all the CPUs
> of a cluster or none. If these are present only for a subset of CPUs of
> a cluster then things will start falling apart as soon as the CPUs are
> brought online in a different order. For example, this will happen
> because the operating system looks for such properties in the CPU node
> it is trying to bring up, so that it can register a cooling device.
> 
> Add such missing properties.
> 
> Do minor rearrangement as well to keep ordering consistent.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

applied for 4.19


Thanks
Heiko

^ permalink raw reply

* [PATCH v2] regulator: core: Enable voltage balancing
From: Tony Lindgren @ 2018-06-15 11:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528886026-9457-1-git-send-email-m.purski@samsung.com>

Hi,

* Maciej Purski <m.purski@samsung.com> [180613 10:39]:
> Call regulator_balance_voltage() instead of set_voltage_rdev()
> in set_voltage_unlocked() and in enabling and disabling functions,
> but only if the regulator is coupled.
> 
> Signed-off-by: Maciej Purski <m.purski@samsung.com>
> 
> ---
> Changes in v2:
> - fix compile errors
> - make debug messages more informative

Thanks for updating it. This series still hangs after loading
modules on beagleboard-x15:

[   26.679749] smps12: regulator_set_voltage: 3381
[   26.684529] smps12: regulator_set_voltage_unlocked:  3045
[   26.695616] smps12: _regulator_do_set_voltage: 2912
[   26.701275] smps12: regulator_set_voltage: 3381
[   26.706002] smps12: regulator_set_voltage_unlocked:  3045
[   26.712349] smps12: _regulator_do_set_voltage: 2912
[   26.719329] abb_mpu: regulator_set_voltage: 3381
[   26.724105] abb_mpu: regulator_set_voltage_unlocked:  3045

So it seems to be the abb_mpu where it hangs?

Regards,

Tony

^ permalink raw reply

* v4.18-rc0: ohci-platform on n900 oops-es on reboot
From: Pavel Machek @ 2018-06-15 11:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180614194449.GB17808@amd>

Hi!

> When I enable
> 
> CONFIG_USB_OHCI_HCD=y
> CONFIG_USB_OHCI_HCD_OMAP3=y
> CONFIG_USB_OHCI_HCD_PLATFORM=y
> 
> on n900 (I need it on droid4 and want common config), I get oops when
> attempting to reboot the system. I believe problem is there in v4.17,
> too.
> 
> I'll try to build it as a module and debug, but if you have better
> idea, let me know...

It oopses in the ohci_shutdown, see the "oopses here" below.

Any ideas?
								Pavel

+       printk(KERN_CRIT "ohci_shutdown... have pointers %lx, %lx\n", hcd, ohci);
        ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable);
+       printk(KERN_CRIT "ohci_shutdown... disable done\n");
+       udelay(1000);
+       printk(KERN_CRIT "ohci_shutdown... disable done\n");
 
        /* Software reset, after which the controller goes into SUSPEND */
        ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus);
+       printk(KERN_CRIT "ohci_shutdown... writel done\n");
        ohci_readl(ohci, &ohci->regs->cmdstatus);       /* flush the writes */
+       /* It oopses here */
+       printk(KERN_CRIT "ohci_shutdown... readl done\n");
        udelay(10);
 
+       printk(KERN_CRIT "ohci_shutdown... reset done\n");      
        ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval);
        ohci->rh_state = OHCI_RH_HALTED;
+
+       printk(KERN_CRIT "ohci_shutdown... all ok?\n"); 

	
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180615/1cb8b88e/attachment.sig>

^ permalink raw reply

* [PATCH] arm64: fix infinite stacktrace
From: Mark Rutland @ 2018-06-15 11:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LRH.2.02.1806141457200.4243@file01.intranet.prod.int.rdu2.redhat.com>

Hi,

On Thu, Jun 14, 2018 at 02:58:21PM -0400, Mikulas Patocka wrote:
> I've got this infinite stacktrace when debugging another problem:
> [  908.795225] INFO: rcu_preempt detected stalls on CPUs/tasks:
> [  908.796176]  1-...!: (1 GPs behind) idle=952/1/4611686018427387904 softirq=1462/1462 fqs=355
> [  908.797692]  2-...!: (1 GPs behind) idle=f42/1/4611686018427387904 softirq=1550/1551 fqs=355
> [  908.799189]  (detected by 0, t=2109 jiffies, g=130, c=129, q=235)
> [  908.800284] Task dump for CPU 1:
> [  908.800871] kworker/1:1     R  running task        0    32      2 0x00000022
> [  908.802127] Workqueue: writecache-writeabck writecache_writeback [dm_writecache]
> [  908.820285] Call trace:
> [  908.824785]  __switch_to+0x68/0x90
> [  908.837661]  0xfffffe00603afd90
> [  908.844119]  0xfffffe00603afd90
> [  908.850091]  0xfffffe00603afd90
> [  908.854285]  0xfffffe00603afd90
> [  908.863538]  0xfffffe00603afd90
> [  908.865523]  0xfffffe00603afd90
> 
> The machine just locked up and kept on printing the same line over and
> over again. This patch fixes it.
> 
> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
> Cc: stable at vger.kernel.org

Given this can only occur when there's a corrupted stack (where a frame
record points to itself), I'm not sure this requires a cc stable.

> Index: linux-2.6/arch/arm64/kernel/stacktrace.c
> ===================================================================
> --- linux-2.6.orig/arch/arm64/kernel/stacktrace.c
> +++ linux-2.6/arch/arm64/kernel/stacktrace.c
> @@ -56,6 +56,9 @@ int notrace unwind_frame(struct task_str
>  	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
>  	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
>  
> +	if (frame->fp <= fp)
> +		return -EINVAL;
> +

Dave Martin had a series [1] which addressed this along with a number of
other cases where stack traces might not terminate.

Dave, do you plan to respin that?

Thanks,
Mark.

[1] https://lkml.kernel.org/r/1524503223-17576-1-git-send-email-Dave.Martin at arm.com

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox