* Re: [PATCH v2 5/5] mfd: lochnagar: Move binding over to dtschema
From: Charles Keepax @ 2020-05-12 15:06 UTC (permalink / raw)
To: Rob Herring
Cc: lee.jones, broonie, mturquette, sboyd, jdelvare, linux,
linus.walleij, lgirdwood, linux-kernel, devicetree, patches
In-Reply-To: <20200512134949.GA14057@bogus>
On Tue, May 12, 2020 at 08:49:49AM -0500, Rob Herring wrote:
> On Mon, May 04, 2020 at 04:47:57PM +0100, Charles Keepax wrote:
> > Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
> > ---
> >
> > Changes since v1:
> > - Removed contains on the compatible
> > - Moved all sub-nodes into here directly only using $ref for properties
> > - As the regulator binding only contained subnodes that file is now deleted
> > - Removed some pointless descriptions
> >
> > A little nervous about the amount of clock and regulator stuff this
> > pulls into the MFD file, any comments on that welcome? Would it be worth
> > looking into something along the lines of the definitions stuff to keep
> > some of that out in the clock and regulator bindings?
>
> It's fine like this. Other than my comments on patch 3, looks fine.
> Respin and I'll apply.
>
Groovy thanks for the reviews.
Thanks,
Charles
^ permalink raw reply
* [PATCH v10 1/5] usb: xhci: Change the XHCI link order in the Makefile
From: Al Cooper @ 2020-05-12 15:00 UTC (permalink / raw)
To: linux-kernel
Cc: Al Cooper, Alan Stern, Andy Shevchenko, bcm-kernel-feedback-list,
devicetree, Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb,
Mathias Nyman, Rob Herring, Yoshihiro Shimoda, Andy Shevchenko
In-Reply-To: <20200512150019.25903-1-alcooperx@gmail.com>
Some BRCMSTB USB chips have an XHCI, EHCI and OHCI controller
on the same port where XHCI handles 3.0 devices, EHCI handles 2.0
devices and OHCI handles <2.0 devices. Currently the Makefile
has XHCI linking at the bottom which will result in the XHIC driver
initalizing after the EHCI and OHCI drivers and any installed 3.0
device will be seen as a 2.0 device. Moving the XHCI linking
above the EHCI and OHCI linking fixes the issue.
Signed-off-by: Al Cooper <alcooperx@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/usb/host/Makefile | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index b191361257cc..a7f0b8ff7179 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -37,6 +37,16 @@ endif
obj-$(CONFIG_USB_PCI) += pci-quirks.o
+# NOTE: BRCMSTB systems require that xhci driver be linked before the
+# ehci/ohci drivers because they share a port and need the XHCI driver
+# to come up first to properly enumerate 3.0 devices.
+obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o
+obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
+obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
+obj-$(CONFIG_USB_XHCI_HISTB) += xhci-histb.o
+obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o
+obj-$(CONFIG_USB_XHCI_TEGRA) += xhci-tegra.o
+
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o
@@ -69,12 +79,6 @@ obj-$(CONFIG_USB_OHCI_HCD_DAVINCI) += ohci-da8xx.o
obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o
obj-$(CONFIG_USB_FHCI_HCD) += fhci.o
-obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o
-obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
-obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
-obj-$(CONFIG_USB_XHCI_HISTB) += xhci-histb.o
-obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o
-obj-$(CONFIG_USB_XHCI_TEGRA) += xhci-tegra.o
obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o
obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
--
2.17.1
^ permalink raw reply related
* [PATCH v10 3/5] usb: xhci: xhci-plat: Add support for Broadcom STB SoC's
From: Al Cooper @ 2020-05-12 15:00 UTC (permalink / raw)
To: linux-kernel
Cc: Al Cooper, Alan Stern, Andy Shevchenko, bcm-kernel-feedback-list,
devicetree, Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb,
Mathias Nyman, Rob Herring, Yoshihiro Shimoda, Andy Shevchenko
In-Reply-To: <20200512150019.25903-1-alcooperx@gmail.com>
Add support for Broadcom STB SoC's to the xhci platform driver
Signed-off-by: Al Cooper <alcooperx@gmail.com>
Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/usb/host/xhci-plat.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 1d4f6f85f0fe..44406d0eb317 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -112,6 +112,10 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = {
SET_XHCI_PLAT_PRIV_FOR_RCAR(XHCI_RCAR_FIRMWARE_NAME_V3)
};
+static const struct xhci_plat_priv xhci_plat_brcm = {
+ .quirks = XHCI_RESET_ON_RESUME,
+};
+
static const struct of_device_id usb_xhci_of_match[] = {
{
.compatible = "generic-xhci",
@@ -147,6 +151,12 @@ static const struct of_device_id usb_xhci_of_match[] = {
}, {
.compatible = "renesas,rcar-gen3-xhci",
.data = &xhci_plat_renesas_rcar_gen3,
+ }, {
+ .compatible = "brcm,xhci-brcm-v2",
+ .data = &xhci_plat_brcm,
+ }, {
+ .compatible = "brcm,bcm7445-xhci",
+ .data = &xhci_plat_brcm,
},
{},
};
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v2] dt-bindings: thermal: Convert UniPhier thermal monitor to json-schema
From: Rob Herring @ 2020-05-12 15:00 UTC (permalink / raw)
To: Kunihiko Hayashi
Cc: devicetree, Zhang Rui, Amit Kucheria, Rob Herring,
linux-arm-kernel, linux-pm, Daniel Lezcano, linux-kernel,
Masahiro Yamada
In-Reply-To: <1588215934-13252-1-git-send-email-hayashi.kunihiko@socionext.com>
On Thu, 30 Apr 2020 12:05:34 +0900, Kunihiko Hayashi wrote:
> Convert the UniPhier thermal monitor binding to DT schema format.
>
> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
> ---
>
> Changes since v1:
> - Add maxItems to "socionext,tmod-calibration" property
> - Fix indents in examples
>
> .../thermal/socionext,uniphier-thermal.yaml | 59 ++++++++++++++++++++
> .../bindings/thermal/uniphier-thermal.txt | 65 ----------------------
> 2 files changed, 59 insertions(+), 65 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml
> delete mode 100644 Documentation/devicetree/bindings/thermal/uniphier-thermal.txt
>
Applied, thanks!
^ permalink raw reply
* [PATCH v10 4/5] usb: ehci: Add new EHCI driver for Broadcom STB SoC's
From: Al Cooper @ 2020-05-12 15:00 UTC (permalink / raw)
To: linux-kernel
Cc: Al Cooper, Alan Stern, Andy Shevchenko, bcm-kernel-feedback-list,
devicetree, Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb,
Mathias Nyman, Rob Herring, Yoshihiro Shimoda, Andy Shevchenko
In-Reply-To: <20200512150019.25903-1-alcooperx@gmail.com>
Add a new EHCI driver for Broadcom STB SoC's. A new EHCI driver
was created instead of adding support to the existing ehci platform
driver because of the code required to work around bugs in the EHCI
controller. The primary workaround is for a bug where the Core
violates the SOF interval between the first two SOFs transmitted after
resume. This only happens if the resume occurs near the end of a
microframe. The fix is to intercept the ehci-hcd request to complete
RESUME and align it to the start of the next microframe.
Signed-off-by: Al Cooper <alcooperx@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
---
drivers/usb/host/ehci-brcm.c | 280 +++++++++++++++++++++++++++++++++++
1 file changed, 280 insertions(+)
create mode 100644 drivers/usb/host/ehci-brcm.c
diff --git a/drivers/usb/host/ehci-brcm.c b/drivers/usb/host/ehci-brcm.c
new file mode 100644
index 000000000000..3e0ebe8cc649
--- /dev/null
+++ b/drivers/usb/host/ehci-brcm.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2020, Broadcom */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/iopoll.h>
+
+#include "ehci.h"
+
+#define hcd_to_ehci_priv(h) ((struct brcm_priv *)hcd_to_ehci(h)->priv)
+
+struct brcm_priv {
+ struct clk *clk;
+};
+
+/*
+ * ehci_brcm_wait_for_sof
+ * Wait for start of next microframe, then wait extra delay microseconds
+ */
+static inline void ehci_brcm_wait_for_sof(struct ehci_hcd *ehci, u32 delay)
+{
+ u32 frame_idx = ehci_readl(ehci, &ehci->regs->frame_index);
+ u32 val;
+ int res;
+
+ /* Wait for next microframe (every 125 usecs) */
+ res = readl_relaxed_poll_timeout(&ehci->regs->frame_index, val,
+ val != frame_idx, 1, 130);
+ if (res)
+ ehci_err(ehci, "Error waiting for SOF\n");
+ udelay(delay);
+}
+
+/*
+ * ehci_brcm_hub_control
+ * The EHCI controller has a bug where it can violate the SOF
+ * interval between the first two SOF's transmitted after resume
+ * if the resume occurs near the end of the microframe. This causees
+ * the controller to detect babble on the suspended port and
+ * will eventually cause the controller to reset the port.
+ * The fix is to Intercept the echi-hcd request to complete RESUME and
+ * align it to the start of the next microframe.
+ * See SWLINUX-1909 for more details
+ */
+static int ehci_brcm_hub_control(
+ struct usb_hcd *hcd,
+ u16 typeReq,
+ u16 wValue,
+ u16 wIndex,
+ char *buf,
+ u16 wLength)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int ports = HCS_N_PORTS(ehci->hcs_params);
+ u32 __iomem *status_reg;
+ unsigned long flags;
+ int retval, irq_disabled = 0;
+
+ status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
+
+ /*
+ * RESUME is cleared when GetPortStatus() is called 20ms after start
+ * of RESUME
+ */
+ if ((typeReq == GetPortStatus) &&
+ (wIndex && wIndex <= ports) &&
+ ehci->reset_done[wIndex-1] &&
+ time_after_eq(jiffies, ehci->reset_done[wIndex-1]) &&
+ (ehci_readl(ehci, status_reg) & PORT_RESUME)) {
+
+ /*
+ * to make sure we are not interrupted until RESUME bit
+ * is cleared, disable interrupts on current CPU
+ */
+ ehci_dbg(ehci, "SOF alignment workaround\n");
+ irq_disabled = 1;
+ local_irq_save(flags);
+ ehci_brcm_wait_for_sof(ehci, 5);
+ }
+ retval = ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+ if (irq_disabled)
+ local_irq_restore(flags);
+ return retval;
+}
+
+static int ehci_brcm_reset(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int len;
+
+ ehci->big_endian_mmio = 1;
+
+ ehci->caps = (void __iomem *)hcd->regs;
+ len = HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
+ ehci->regs = (void __iomem *)(hcd->regs + len);
+
+ /* This fixes the lockup during reboot due to prior interrupts */
+ ehci_writel(ehci, CMD_RESET, &ehci->regs->command);
+ mdelay(10);
+
+ /*
+ * SWLINUX-1705: Avoid OUT packet underflows during high memory
+ * bus usage
+ * port_status[0x0f] = Broadcom-proprietary USB_EHCI_INSNREG00 @ 0x90
+ */
+ ehci_writel(ehci, 0x00800040, &ehci->regs->port_status[0x10]);
+ ehci_writel(ehci, 0x00000001, &ehci->regs->port_status[0x12]);
+
+ return ehci_setup(hcd);
+}
+
+static struct hc_driver __read_mostly ehci_brcm_hc_driver;
+
+static const struct ehci_driver_overrides brcm_overrides __initconst = {
+ .reset = ehci_brcm_reset,
+ .extra_priv_size = sizeof(struct brcm_priv),
+};
+
+static int ehci_brcm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res_mem;
+ struct brcm_priv *priv;
+ struct usb_hcd *hcd;
+ int irq;
+ int err;
+
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ if (err)
+ return err;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0)
+ return irq ? irq : -EINVAL;
+
+ /* Hook the hub control routine to work around a bug */
+ ehci_brcm_hc_driver.hub_control = ehci_brcm_hub_control;
+
+ /* initialize hcd */
+ hcd = usb_create_hcd(&ehci_brcm_hc_driver, dev, dev_name(dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, hcd);
+ priv = hcd_to_ehci_priv(hcd);
+
+ priv->clk = devm_clk_get_optional(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ err = PTR_ERR(priv->clk);
+ goto err_hcd;
+ }
+
+ err = clk_prepare_enable(priv->clk);
+ if (err)
+ goto err_hcd;
+
+ hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res_mem);
+ if (IS_ERR(hcd->regs)) {
+ err = PTR_ERR(hcd->regs);
+ goto err_clk;
+ }
+ hcd->rsrc_start = res_mem->start;
+ hcd->rsrc_len = resource_size(res_mem);
+ err = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (err)
+ goto err_clk;
+
+ device_wakeup_enable(hcd->self.controller);
+ device_enable_async_suspend(hcd->self.controller);
+
+ return 0;
+
+err_clk:
+ clk_disable_unprepare(priv->clk);
+err_hcd:
+ usb_put_hcd(hcd);
+
+ return err;
+}
+
+static int ehci_brcm_remove(struct platform_device *dev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct brcm_priv *priv = hcd_to_ehci_priv(hcd);
+
+ usb_remove_hcd(hcd);
+ clk_disable_unprepare(priv->clk);
+ usb_put_hcd(hcd);
+ return 0;
+}
+
+static int __maybe_unused ehci_brcm_suspend(struct device *dev)
+{
+ int ret;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct brcm_priv *priv = hcd_to_ehci_priv(hcd);
+ bool do_wakeup = device_may_wakeup(dev);
+
+ ret = ehci_suspend(hcd, do_wakeup);
+ if (ret)
+ return ret;
+ clk_disable_unprepare(priv->clk);
+ return 0;
+}
+
+static int __maybe_unused ehci_brcm_resume(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct brcm_priv *priv = hcd_to_ehci_priv(hcd);
+ int err;
+
+ err = clk_prepare_enable(priv->clk);
+ if (err)
+ return err;
+ /*
+ * SWLINUX-1705: Avoid OUT packet underflows during high memory
+ * bus usage
+ * port_status[0x0f] = Broadcom-proprietary USB_EHCI_INSNREG00
+ * @ 0x90
+ */
+ ehci_writel(ehci, 0x00800040, &ehci->regs->port_status[0x10]);
+ ehci_writel(ehci, 0x00000001, &ehci->regs->port_status[0x12]);
+
+ ehci_resume(hcd, false);
+
+ pm_runtime_disable(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ehci_brcm_pm_ops, ehci_brcm_suspend,
+ ehci_brcm_resume);
+
+static const struct of_device_id brcm_ehci_of_match[] = {
+ { .compatible = "brcm,ehci-brcm-v2", },
+ { .compatible = "brcm,bcm7445-ehci", },
+ {}
+};
+
+static struct platform_driver ehci_brcm_driver = {
+ .probe = ehci_brcm_probe,
+ .remove = ehci_brcm_remove,
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "ehci-brcm",
+ .pm = &ehci_brcm_pm_ops,
+ .of_match_table = brcm_ehci_of_match,
+ }
+};
+
+static int __init ehci_brcm_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ ehci_init_driver(&ehci_brcm_hc_driver, &brcm_overrides);
+ return platform_driver_register(&ehci_brcm_driver);
+}
+module_init(ehci_brcm_init);
+
+static void __exit ehci_brcm_exit(void)
+{
+ platform_driver_unregister(&ehci_brcm_driver);
+}
+module_exit(ehci_brcm_exit);
+
+MODULE_ALIAS("platform:ehci-brcm");
+MODULE_DESCRIPTION("EHCI Broadcom STB driver");
+MODULE_AUTHOR("Al Cooper");
+MODULE_LICENSE("GPL");
--
2.17.1
^ permalink raw reply related
* [PATCH v10 5/5] usb: host: Add ability to build new Broadcom STB USB drivers
From: Al Cooper @ 2020-05-12 15:00 UTC (permalink / raw)
To: linux-kernel
Cc: Al Cooper, Alan Stern, Andy Shevchenko, bcm-kernel-feedback-list,
devicetree, Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb,
Mathias Nyman, Rob Herring, Yoshihiro Shimoda, Andy Shevchenko
In-Reply-To: <20200512150019.25903-1-alcooperx@gmail.com>
Add the build system changes needed to get the Broadcom STB XHCI,
EHCI and OHCI functionality working. The OHCI support does not
require anything unique to Broadcom so the standard ohci-platform
driver is being used. Also update MAINTAINERS.
Signed-off-by: Al Cooper <alcooperx@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
MAINTAINERS | 8 ++++++++
drivers/usb/host/Kconfig | 20 ++++++++++++++++++++
drivers/usb/host/Makefile | 1 +
3 files changed, 29 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 091ec22c1a23..e5e44b595bc4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3481,6 +3481,14 @@ S: Supported
F: Documentation/devicetree/bindings/i2c/brcm,brcmstb-i2c.yaml
F: drivers/i2c/busses/i2c-brcmstb.c
+BROADCOM BRCMSTB USB EHCI DRIVER
+M: Al Cooper <alcooperx@gmail.com>
+L: linux-usb@vger.kernel.org
+L: bcm-kernel-feedback-list@broadcom.com
+S: Maintained
+F: Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml
+F: drivers/usb/host/ehci-brcm.*
+
BROADCOM BRCMSTB USB2 and USB3 PHY DRIVER
M: Al Cooper <alcooperx@gmail.com>
L: linux-kernel@vger.kernel.org
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 55bdfdf11e4c..973386bbb522 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -97,6 +97,26 @@ config USB_XHCI_TEGRA
endif # USB_XHCI_HCD
+config USB_EHCI_BRCMSTB
+ tristate
+
+config USB_BRCMSTB
+ tristate "Broadcom STB USB support"
+ depends on (ARCH_BRCMSTB && PHY_BRCM_USB) || COMPILE_TEST
+ select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
+ select USB_EHCI_BRCMSTB if USB_EHCI_HCD
+ select USB_XHCI_PLATFORM if USB_XHCI_HCD
+ help
+ Enables support for XHCI, EHCI and OHCI host controllers
+ found in Broadcom STB SoC's.
+
+ To compile these drivers as modules, choose M here: the
+ modules will be called ohci-platform.ko, ehci-brcm.ko and
+ xhci-plat-hcd.ko
+
+ Disabling this will keep the controllers and corresponding
+ PHYs powered down.
+
config USB_EHCI_HCD
tristate "EHCI HCD (USB 2.0) support"
depends on HAS_DMA && HAS_IOMEM
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a7f0b8ff7179..265e26cf9209 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_USB_EHCI_HCD_STI) += ehci-st.o
obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
+obj-$(CONFIG_USB_EHCI_BRCMSTB) += ehci-brcm.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
--
2.17.1
^ permalink raw reply related
* [PATCH v10 2/5] dt-bindings: Add Broadcom STB USB support
From: Al Cooper @ 2020-05-12 15:00 UTC (permalink / raw)
To: linux-kernel
Cc: Al Cooper, Alan Stern, Andy Shevchenko, bcm-kernel-feedback-list,
devicetree, Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb,
Mathias Nyman, Rob Herring, Yoshihiro Shimoda, Andy Shevchenko
In-Reply-To: <20200512150019.25903-1-alcooperx@gmail.com>
Add DT bindings for Broadcom STB USB EHCI and XHCI drivers.
NOTE: The OHCI driver is not included because it uses the generic
platform driver.
Signed-off-by: Al Cooper <alcooperx@gmail.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
.../bindings/usb/brcm,bcm7445-ehci.yaml | 59 +++++++++++++++++++
.../devicetree/bindings/usb/usb-xhci.txt | 1 +
2 files changed, 60 insertions(+)
create mode 100644 Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml
diff --git a/Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml b/Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml
new file mode 100644
index 000000000000..2a9acf2b5a64
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/brcm,bcm7445-ehci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom STB USB EHCI Controller Device Tree Bindings
+
+allOf:
+ - $ref: "usb-hcd.yaml"
+
+maintainers:
+ - Al Cooper <alcooperx@gmail.com>
+
+properties:
+ compatible:
+ const: brcm,bcm7445-ehci
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+ description: Clock specifier for the EHCI clock
+
+ clock-names:
+ const: sw_usb
+
+ phys:
+ maxItems: 1
+
+ phy-names:
+ const: usbphy
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - phys
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ usb@f0b00300 {
+ compatible = "brcm,bcm7445-ehci";
+ reg = <0xf0b00300 0xa8>;
+ interrupts = <0x0 0x5a 0x0>;
+ phys = <&usbphy_0 0x0>;
+ phy-names = "usbphy";
+ clocks = <&usb20>;
+ clock-names = "sw_usb";
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt
index dc025f126d71..23e89d798b1b 100644
--- a/Documentation/devicetree/bindings/usb/usb-xhci.txt
+++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt
@@ -24,6 +24,7 @@ Required properties:
device
- "renesas,rcar-gen3-xhci" for a generic R-Car Gen3 or RZ/G2 compatible
device
+ - "brcm,bcm7445-xhci" for Broadcom STB SoCs with XHCI
- "xhci-platform" (deprecated)
When compatible with the generic version, nodes must list the
--
2.17.1
^ permalink raw reply related
* [PATCH v10 0/5] Add XHCI, EHCI and OHCI support for Broadcom STB SoS's
From: Al Cooper @ 2020-05-12 15:00 UTC (permalink / raw)
To: linux-kernel
Cc: Al Cooper, Alan Stern, Andy Shevchenko, bcm-kernel-feedback-list,
devicetree, Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb,
Mathias Nyman, Rob Herring, Yoshihiro Shimoda, Andy Shevchenko
v10 - Fix incorrect error return in ehci-brcmstb.c pointed out by
Alan Stern.
v9 - Fix minor typos in patch description for ehci driver.
- In ehci-brcm.c, use ehci_err() instead of dev_err().
- In ehci-brcm.c, handle zero returned from platform_get_irq()
by returning -EINVAL for 0 or actual return value for < 0.
v8 - The previous v7 had the wrong version of ehci-brcm.c. This time
really, really add the changes Greg requested.
v7 - Cleanup ehci-brcm.c as requested by Greg Kroah-Hartman.
- Split out Makefile re-order change into a separate commit.
v6 - Remove "contains:" from compatible section of
brcm,bcm7445-ehci.yaml as requested by Rob Herring.
v5 - Use devm_platform_get_and_ioremap_resource() in ehci-brcm.c
as requested by Andy Shevchenko.
- Add pm_runtime_set_active() to ehci_resume() in ehci-brcm.c
as requested by Alan Stern.
v4 - A few more fixes to the brcm,bcm7445-ehci.yaml dt-bindings
document requested by Rob Herring.
- Fixed ordering issue in MAINTAINERS as requested by
Andy Shevchenko.
v3 - Addressed all of Andy Shevchenko's review comments for
ehci-brcm.c.
- Fixed the brcm,bcm7445-ehci.yaml dt-bindings document,
dt_binding_check now passes.
- Added the XHCI functionality to xhci-plat.c instead of creating
new brcmstb files, as suggested by Mathias Nyman.
v2 - Addressed Andy Shevchenko's review comments.
- Fixed dt_binding_check error pointed out by Rob Herring.
- Removed pr_info message in ehci_brcm_init as suggested by
Greg Kroah-Hartman.
This adds support for the XHCI, EHCI and OHCI host controllers found
in Broadcom STB SoC's. These drivers depend on getting access to the
new Broadcom STB USB PHY driver through a device-tree phandle and
will fail if the driver is not available.
Al Cooper (5):
usb: xhci: Change the XHCI link order in the Makefile
dt-bindings: Add Broadcom STB USB support
usb: xhci: xhci-plat: Add support for Broadcom STB SoC's
usb: ehci: Add new EHCI driver for Broadcom STB SoC's
usb: host: Add ability to build new Broadcom STB USB drivers
.../bindings/usb/brcm,bcm7445-ehci.yaml | 59 ++++
.../devicetree/bindings/usb/usb-xhci.txt | 1 +
MAINTAINERS | 8 +
drivers/usb/host/Kconfig | 20 ++
drivers/usb/host/Makefile | 17 +-
drivers/usb/host/ehci-brcm.c | 280 ++++++++++++++++++
drivers/usb/host/xhci-plat.c | 10 +
7 files changed, 389 insertions(+), 6 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml
create mode 100644 drivers/usb/host/ehci-brcm.c
--
2.17.1
^ permalink raw reply
* Re: [PATCH V4 1/5] dt-bindings: clock: Convert i.MX6Q clock to json-schema
From: Rob Herring @ 2020-05-12 14:57 UTC (permalink / raw)
To: Anson Huang
Cc: Stephen Boyd, devicetree@vger.kernel.org, festevam@gmail.com,
kernel@pengutronix.de, linux-arm-kernel@lists.infradead.org,
linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org,
mturquette@baylibre.com, s.hauer@pengutronix.de,
shawnguo@kernel.org, dl-linux-imx
In-Reply-To: <DB3PR0402MB39164125CABC889C5DEE5D8AF5A70@DB3PR0402MB3916.eurprd04.prod.outlook.com>
On Tue, May 05, 2020 at 11:32:42AM +0000, Anson Huang wrote:
> Hi, Stephen
>
>
> > Subject: Re: [PATCH V4 1/5] dt-bindings: clock: Convert i.MX6Q clock to
> > json-schema
> >
> > Quoting Anson Huang (2020-04-29 17:51:57)
> > > Convert the i.MX6Q clock binding to DT schema format using json-schema.
> > >
> > > Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> > > ---
> >
> > Please send a cover letter next time. Who is going to apply these patches? I
> > hope Rob? If you need an acked-by feel free to have mine!
>
> OK, will have a cover letter next time for patch series.
>
> Hi, Rob
> Are you going to apply this patch series? If no, can you advise who can apply it, thanks.
Yes, respin fixing interrupts in all the patches.
Rob
^ permalink raw reply
* Re: [PATCH 02/15] dt-bindings: timer: add ti, dmtimer compatible for for system timers
From: Tony Lindgren @ 2020-05-12 14:56 UTC (permalink / raw)
To: Rob Herring
Cc: Keerthy, Stephen Boyd, Thomas Gleixner, Graeme Smecher,
linux-kernel, Tero Kristo, Aaro Koskinen, devicetree,
Andreas Kemnade, H. Nikolaus Schaller, Adam Ford, Lokesh Vutla,
Daniel Lezcano, Brian Hutchinson, linux-clk, linux-omap,
Michael Turquette, linux-arm-kernel
In-Reply-To: <20200512145215.GA23423@bogus>
* Rob Herring <robh@kernel.org> [200512 14:53]:
> On Wed, 29 Apr 2020 14:53:49 -0700, Tony Lindgren wrote:
> > The TI dual-mode timer can be used for both clocksource and clockevent
> > system timers. We need a way to specify which dual-mode timers are
> > reserved for system timers as there are multiple instances available
> > that may require a board specific configuration.
> >
> > Let's add a generic compatible "ti,dmtimer" that TIMER_OF_DECLARE can
> > use as suggested by Daniel Lezcano <daniel.lezcano@linaro.org>.
> >
> > Suggested-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> > Signed-off-by: Tony Lindgren <tony@atomide.com>
> > ---
> > Documentation/devicetree/bindings/timer/ti,timer.txt | 1 +
> > 1 file changed, 1 insertion(+)
> >
>
> Acked-by: Rob Herring <robh@kernel.org>
Looks like this is no longer needed with v3 set in the repost
thread:
"[PATCHv3 00/14] Update omaps to use drivers/clocksource timers"
It now does detection for the preferred system timers based on
the various timer features like you suggested.
Regards,
Tony
^ permalink raw reply
* Re: [PATCH 17/18] dt-bindings: gpio: rcar: Add r8a7742 (RZ/G1H) support
From: Geert Uytterhoeven @ 2020-05-12 14:56 UTC (permalink / raw)
To: Rob Herring
Cc: Lad Prabhakar, Vinod Koul, Lad Prabhakar, Linus Walleij,
Linux-Renesas, Linux Kernel Mailing List, Marc Zyngier,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SERIAL DRIVERS, Thomas Gleixner, Rob Herring,
Bartosz Golaszewski, Greg Kroah-Hartman, Linux ARM, Magnus Damm,
Russell King, Jason Cooper, dmaengine, open list:GPIO SUBSYSTEM
In-Reply-To: <20200512145256.GA25121@bogus>
Hi Rob,
On Tue, May 12, 2020 at 4:53 PM Rob Herring <robh@kernel.org> wrote:
> On Wed, 29 Apr 2020 22:56:54 +0100, Lad Prabhakar wrote:
> > Renesas RZ/G1H (R8A7742) SoC GPIO blocks are identical to the R-Car Gen2
> > family. Add support for its GPIO controllers.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> > Reviewed-by: Marian-Cristian Rotariu <marian-cristian.rotariu.rb@bp.renesas.com>
>
> Acked-by: Rob Herring <robh@kernel.org>
Note that you've just applied 7f7d408e5a00d515 ("dt-bindings: gpio: rcar:
Convert to json-schema"), so this no longer applies.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH V4 2/5] dt-bindings: clock: Convert i.MX6SX clock to json-schema
From: Rob Herring @ 2020-05-12 14:55 UTC (permalink / raw)
To: Anson Huang
Cc: mturquette, sboyd, shawnguo, s.hauer, kernel, festevam, linux-clk,
devicetree, linux-arm-kernel, linux-kernel, Linux-imx
In-Reply-To: <1588207921-20604-2-git-send-email-Anson.Huang@nxp.com>
On Thu, Apr 30, 2020 at 08:51:58AM +0800, Anson Huang wrote:
> Convert the i.MX6SX clock binding to DT schema format using json-schema.
>
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> Changes since V3:
> - update license to be with (GPL-2.0-only OR BSD-2-Clause);
> - remove unnecessary minItem for interrupts;
> - remove label in example.
> ---
> .../devicetree/bindings/clock/imx6sx-clock.txt | 13 -----
> .../devicetree/bindings/clock/imx6sx-clock.yaml | 64 ++++++++++++++++++++++
> 2 files changed, 64 insertions(+), 13 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/clock/imx6sx-clock.txt
> create mode 100644 Documentation/devicetree/bindings/clock/imx6sx-clock.yaml
>
> diff --git a/Documentation/devicetree/bindings/clock/imx6sx-clock.txt b/Documentation/devicetree/bindings/clock/imx6sx-clock.txt
> deleted file mode 100644
> index 22362b9..0000000
> --- a/Documentation/devicetree/bindings/clock/imx6sx-clock.txt
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -* Clock bindings for Freescale i.MX6 SoloX
> -
> -Required properties:
> -- compatible: Should be "fsl,imx6sx-ccm"
> -- reg: Address and length of the register set
> -- #clock-cells: Should be <1>
> -- clocks: list of clock specifiers, must contain an entry for each required
> - entry in clock-names
> -- clock-names: should include entries "ckil", "osc", "ipp_di0" and "ipp_di1"
> -
> -The clock consumer should specify the desired clock by having the clock
> -ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx6sx-clock.h
> -for the full list of i.MX6 SoloX clock IDs.
> diff --git a/Documentation/devicetree/bindings/clock/imx6sx-clock.yaml b/Documentation/devicetree/bindings/clock/imx6sx-clock.yaml
> new file mode 100644
> index 0000000..2c7f625
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/imx6sx-clock.yaml
> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/imx6sx-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Clock bindings for Freescale i.MX6 SoloX
> +
> +maintainers:
> + - Anson Huang <Anson.Huang@nxp.com>
> +
> +properties:
> + compatible:
> + const: fsl,imx6sx-ccm
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 2
Need to define what each one is:
interrupts:
items:
- description: ...
- description: ...
And you should explain why this was added.
> +
> + '#clock-cells':
> + const: 1
> +
> + clocks:
> + items:
> + - description: 32k osc
> + - description: 24m osc
> + - description: ipp_di0 clock input
> + - description: ipp_di1 clock input
> + - description: anaclk1 clock input
> + - description: anaclk2 clock input
> +
> + clock-names:
> + items:
> + - const: ckil
> + - const: osc
> + - const: ipp_di0
> + - const: ipp_di1
> + - const: anaclk1
> + - const: anaclk2
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - '#clock-cells'
> + - clocks
> + - clock-names
> +
> +examples:
> + # Clock Control Module node:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> + clock-controller@20c4000 {
> + compatible = "fsl,imx6sx-ccm";
> + reg = <0x020c4000 0x4000>;
> + interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
> + #clock-cells = <1>;
> + clocks = <&ckil>, <&osc>, <&ipp_di0>, <&ipp_di1>, <&anaclk1>, <&anaclk2>;
> + clock-names = "ckil", "osc", "ipp_di0", "ipp_di1", "anaclk1", "anaclk2";
> + };
> --
> 2.7.4
>
^ permalink raw reply
* Re: [PATCH 17/18] dt-bindings: gpio: rcar: Add r8a7742 (RZ/G1H) support
From: Rob Herring @ 2020-05-12 14:52 UTC (permalink / raw)
To: Lad Prabhakar
Cc: Vinod Koul, Lad Prabhakar, Linus Walleij, linux-renesas-soc,
linux-kernel, Marc Zyngier, devicetree, Geert Uytterhoeven,
linux-serial, Thomas Gleixner, Rob Herring, Bartosz Golaszewski,
Greg Kroah-Hartman, linux-arm-kernel, Magnus Damm, Russell King,
Jason Cooper, dmaengine, linux-gpio
In-Reply-To: <1588197415-13747-18-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com>
On Wed, 29 Apr 2020 22:56:54 +0100, Lad Prabhakar wrote:
> Renesas RZ/G1H (R8A7742) SoC GPIO blocks are identical to the R-Car Gen2
> family. Add support for its GPIO controllers.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Reviewed-by: Marian-Cristian Rotariu <marian-cristian.rotariu.rb@bp.renesas.com>
> ---
> Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt | 1 +
> 1 file changed, 1 insertion(+)
>
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH 02/15] dt-bindings: timer: add ti, dmtimer compatible for for system timers
From: Rob Herring @ 2020-05-12 14:52 UTC (permalink / raw)
To: Tony Lindgren
Cc: Keerthy, Stephen Boyd, Thomas Gleixner, Graeme Smecher,
linux-kernel, Tero Kristo, Aaro Koskinen, devicetree,
Andreas Kemnade, H. Nikolaus Schaller, Adam Ford, Lokesh Vutla,
Daniel Lezcano, Brian Hutchinson, linux-clk, linux-omap,
Michael Turquette, linux-arm-kernel
In-Reply-To: <20200429215402.18125-3-tony@atomide.com>
On Wed, 29 Apr 2020 14:53:49 -0700, Tony Lindgren wrote:
> The TI dual-mode timer can be used for both clocksource and clockevent
> system timers. We need a way to specify which dual-mode timers are
> reserved for system timers as there are multiple instances available
> that may require a board specific configuration.
>
> Let's add a generic compatible "ti,dmtimer" that TIMER_OF_DECLARE can
> use as suggested by Daniel Lezcano <daniel.lezcano@linaro.org>.
>
> Suggested-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> ---
> Documentation/devicetree/bindings/timer/ti,timer.txt | 1 +
> 1 file changed, 1 insertion(+)
>
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH RFC v2 01/11] dt-bindings: net: meson-dwmac: Add the amlogic,rx-delay-ns property
From: Rob Herring @ 2020-05-12 14:51 UTC (permalink / raw)
To: Martin Blumenstingl
Cc: andrew, f.fainelli, linux-amlogic, devicetree, jianxin.pan, davem,
netdev, linux-kernel, linux-arm-kernel
In-Reply-To: <20200429201644.1144546-2-martin.blumenstingl@googlemail.com>
On Wed, Apr 29, 2020 at 10:16:34PM +0200, Martin Blumenstingl wrote:
> The PRG_ETHERNET registers on Meson8b and newer SoCs can add an RX
> delay. Add a property with the known supported values so it can be
> configured according to the board layout.
>
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
> ---
> .../bindings/net/amlogic,meson-dwmac.yaml | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
> index ae91aa9d8616..8d851f59d9f2 100644
> --- a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
> +++ b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
> @@ -67,6 +67,19 @@ allOf:
> PHY and MAC are adding a delay).
> Any configuration is ignored when the phy-mode is set to "rmii".
>
> + amlogic,rx-delay-ns:
> + $ref: /schemas/types.yaml#definitions/uint32
Don't need to define the type when in standard units.
> + enum:
> + - 0
> + - 2
> + description:
> + The internal RGMII RX clock delay (provided by this IP block) in
> + nanoseconds. When phy-mode is set to "rgmii" then the RX delay
> + should be explicitly configured. When not configured a fallback of
> + 0ns is used. When the phy-mode is set to either "rgmii-id" or
'default: 0' expresses this.
> + "rgmii-rxid" the RX clock delay is already provided by the PHY.
> + Any configuration is ignored when the phy-mode is set to "rmii".
> +
> properties:
> compatible:
> additionalItems: true
> --
> 2.26.2
>
^ permalink raw reply
* [PATCH 1/4] misc: sram: add support for remapping reserved regions only
From: Mian Yousaf Kaukab @ 2020-05-12 14:48 UTC (permalink / raw)
To: swarren, robh+dt, robin.murphy
Cc: devicetree, talho, thierry.reding, jonathanh, linux-tegra,
linux-kernel, linux-arm-kernel, afaerber, arnd, gregkh,
Mian Yousaf Kaukab
Some SRAM kernel users may be interested in SRAM’s reserved regions
only, though a bigger SRAM is available on the platform. Add an
optional flag 'reserved-only' which allows to ioremap reserved regions
only. Rest of SRAM is not remapped. ioremap type is selected depending
upon no-memory-wc as usual.
Signed-off-by: Mian Yousaf Kaukab <ykaukab@suse.de>
---
*Tested only on Jetson TX2. Jetson AGX Xavier is untested.*
drivers/misc/sram.c | 73 ++++++++++++++++++++++++++++++++++-----------
drivers/misc/sram.h | 3 ++
2 files changed, 58 insertions(+), 18 deletions(-)
diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index 6c1a23cb3e8c..44e459f39e22 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -97,7 +97,7 @@ static int sram_add_partition(struct sram_dev *sram, struct sram_reserve *block,
struct sram_partition *part = &sram->partition[sram->partitions];
mutex_init(&part->lock);
- part->base = sram->virt_base + block->start;
+ part->base = block->virt_start;
if (block->pool) {
ret = sram_add_pool(sram, block, start, part);
@@ -153,6 +153,25 @@ static int sram_reserve_cmp(void *priv, struct list_head *a,
return ra->start - rb->start;
}
+static int sram_remap_resource(struct sram_dev *sram,
+ struct resource *res, void __iomem **virt)
+{
+ void __iomem *addr;
+
+ if (sram->no_memory_wc)
+ addr = devm_ioremap_resource(sram->dev, res);
+ else
+ addr = devm_ioremap_resource_wc(sram->dev, res);
+
+ if (IS_ERR(addr)) {
+ dev_err(sram->dev, "could not map SRAM region\n");
+ return PTR_ERR(addr);
+ }
+
+ *virt = addr;
+ return 0;
+}
+
static int sram_reserve_regions(struct sram_dev *sram, struct resource *res)
{
struct device_node *np = sram->dev->of_node, *child;
@@ -239,6 +258,16 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res)
block->start, block->start + block->size);
}
+ /* ioremap reserved block as whole sram is not remapped */
+ if (sram->reserved_only) {
+ ret = sram_remap_resource(sram, &child_res,
+ &block->virt_start);
+ if (ret)
+ goto err_chunks;
+ } else {
+ block->virt_start = sram->virt_base + block->start;
+ }
+
block++;
}
child = NULL;
@@ -282,8 +311,11 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res)
}
}
- /* current start is in a reserved block, so continue after it */
- if (block->start == cur_start) {
+ /*
+ * Current start is in a reserved block, so continue after it.
+ * Or if only using reserved blocks
+ */
+ if (block->start == cur_start || sram->reserved_only) {
cur_start = block->start + block->size;
continue;
}
@@ -342,6 +374,7 @@ static int sram_probe(struct platform_device *pdev)
struct sram_dev *sram;
int ret;
int (*init_func)(void);
+ struct resource *res;
sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
if (!sram)
@@ -349,19 +382,22 @@ static int sram_probe(struct platform_device *pdev)
sram->dev = &pdev->dev;
- if (of_property_read_bool(pdev->dev.of_node, "no-memory-wc"))
- sram->virt_base = devm_platform_ioremap_resource(pdev, 0);
- else
- sram->virt_base = devm_platform_ioremap_resource_wc(pdev, 0);
- if (IS_ERR(sram->virt_base)) {
- dev_err(&pdev->dev, "could not map SRAM registers\n");
- return PTR_ERR(sram->virt_base);
- }
+ sram->no_memory_wc =
+ of_property_read_bool(pdev->dev.of_node, "no-memory-wc");
+ sram->reserved_only =
+ of_property_read_bool(pdev->dev.of_node, "reserved-only");
- sram->pool = devm_gen_pool_create(sram->dev, ilog2(SRAM_GRANULARITY),
- NUMA_NO_NODE, NULL);
- if (IS_ERR(sram->pool))
- return PTR_ERR(sram->pool);
+ if (!sram->reserved_only) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ret = sram_remap_resource(sram, res, &sram->virt_base);
+ if (ret)
+ return ret;
+
+ sram->pool = devm_gen_pool_create(sram->dev,
+ ilog2(SRAM_GRANULARITY), NUMA_NO_NODE, NULL);
+ if (IS_ERR(sram->pool))
+ return PTR_ERR(sram->pool);
+ }
sram->clk = devm_clk_get(sram->dev, NULL);
if (IS_ERR(sram->clk))
@@ -383,8 +419,9 @@ static int sram_probe(struct platform_device *pdev)
goto err_free_partitions;
}
- dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
- gen_pool_size(sram->pool) / 1024, sram->virt_base);
+ if (sram->pool)
+ dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
+ gen_pool_size(sram->pool) / 1024, sram->virt_base);
return 0;
@@ -403,7 +440,7 @@ static int sram_remove(struct platform_device *pdev)
sram_free_partitions(sram);
- if (gen_pool_avail(sram->pool) < gen_pool_size(sram->pool))
+ if (sram->pool && gen_pool_avail(sram->pool) < gen_pool_size(sram->pool))
dev_err(sram->dev, "removed while SRAM allocated\n");
if (sram->clk)
diff --git a/drivers/misc/sram.h b/drivers/misc/sram.h
index 9c1d21ff7347..a485fa29458b 100644
--- a/drivers/misc/sram.h
+++ b/drivers/misc/sram.h
@@ -23,6 +23,8 @@ struct sram_dev {
struct sram_partition *partition;
u32 partitions;
+ bool no_memory_wc;
+ bool reserved_only;
};
struct sram_reserve {
@@ -33,6 +35,7 @@ struct sram_reserve {
bool pool;
bool protect_exec;
const char *label;
+ void __iomem *virt_start;
};
#ifdef CONFIG_SRAM_EXEC
--
2.25.0
^ permalink raw reply related
* [PATCH 2/4] dt-bindings: sram: add documentation for reserved-only flag
From: Mian Yousaf Kaukab @ 2020-05-12 14:48 UTC (permalink / raw)
To: swarren, robh+dt, robin.murphy
Cc: devicetree, talho, thierry.reding, jonathanh, linux-tegra,
linux-kernel, linux-arm-kernel, afaerber, arnd, gregkh,
Mian Yousaf Kaukab
In-Reply-To: <20200512144803.24344-1-ykaukab@suse.de>
Add documentation for the new optional flag added for SRAM driver.
Signed-off-by: Mian Yousaf Kaukab <ykaukab@suse.de>
---
Documentation/devicetree/bindings/sram/sram.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/sram/sram.yaml b/Documentation/devicetree/bindings/sram/sram.yaml
index 19d116ff9ddc..4bcc309fa841 100644
--- a/Documentation/devicetree/bindings/sram/sram.yaml
+++ b/Documentation/devicetree/bindings/sram/sram.yaml
@@ -55,6 +55,12 @@ properties:
as write combining. WC is used by default.
type: boolean
+ reserved-only:
+ description:
+ The flag indicating, that only SRAM reserved regions have to be remapped.
+ remapping type is selected depending upon no-memory-wc as usual.
+ type: boolean
+
patternProperties:
"^([a-z]*-)?sram(-section)?@[a-f0-9]+$":
type: object
--
2.25.0
^ permalink raw reply related
* [PATCH 4/4] arm64: tegra194: add reserved-only flag in sysram node
From: Mian Yousaf Kaukab @ 2020-05-12 14:48 UTC (permalink / raw)
To: swarren, robh+dt, robin.murphy
Cc: devicetree, talho, thierry.reding, jonathanh, linux-tegra,
linux-kernel, linux-arm-kernel, afaerber, arnd, gregkh,
Mian Yousaf Kaukab
In-Reply-To: <20200512144803.24344-1-ykaukab@suse.de>
bpmp driver has reserved regions in sysram. Since sysram is only used
by the bpmp driver, add ‘reserved-only’ flag to the sysram node so
that only regions used by the bpmp driver are remapped. Other regions
of the sysram may not be accessible to the kernel and a speculative
access to them can cause SError.
Signed-off-by: Mian Yousaf Kaukab <ykaukab@suse.de>
---
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index e1ae01c2d039..9a5276d9c2a6 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -1743,6 +1743,7 @@ sysram@40000000 {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x0 0x40000000 0x50000>;
+ reserved-only;
cpu_bpmp_tx: shmem@4e000 {
compatible = "nvidia,tegra194-bpmp-shmem";
--
2.25.0
^ permalink raw reply related
* [PATCH 3/4] arm64: tegra186: add reserved-only flag in sysram node
From: Mian Yousaf Kaukab @ 2020-05-12 14:48 UTC (permalink / raw)
To: swarren, robh+dt, robin.murphy
Cc: devicetree, talho, thierry.reding, jonathanh, linux-tegra,
linux-kernel, linux-arm-kernel, afaerber, arnd, gregkh,
Mian Yousaf Kaukab
In-Reply-To: <20200512144803.24344-1-ykaukab@suse.de>
bpmp driver has reserved regions in sysram. Since sysram is only used
by the bpmp driver, add ‘reserved-only’ flag to the sysram node so
that only regions used by the bpmp driver are remapped. Other regions
of the sysram may not be accessible to the kernel and a speculative
access to them can cause SError.
Signed-off-by: Mian Yousaf Kaukab <ykaukab@suse.de>
---
arch/arm64/boot/dts/nvidia/tegra186.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index 58100fb9cd8b..07ce7e7b270c 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -1219,6 +1219,7 @@ sysram@30000000 {
#address-cells = <2>;
#size-cells = <2>;
ranges = <0 0x0 0x0 0x30000000 0x0 0x50000>;
+ reserved-only;
cpu_bpmp_tx: shmem@4e000 {
compatible = "nvidia,tegra186-bpmp-shmem";
--
2.25.0
^ permalink raw reply related
* Re: [PATCH v2 1/4] dt-bindings: iio: add document bindings for wsen-itds accel sensor
From: Rob Herring @ 2020-05-12 14:45 UTC (permalink / raw)
To: Saravanan Sekar
Cc: robh+dt, linux-kernel, devicetree, linux-iio, knaack.h, pmeerw,
jic23, broonie, lars, lgirdwood
In-Reply-To: <20200429133943.18298-2-saravanan@linumiz.com>
On Wed, 29 Apr 2020 15:39:40 +0200, Saravanan Sekar wrote:
> Add device tree binding information for wsen-itds accel sensor driver.
>
> Signed-off-by: Saravanan Sekar <saravanan@linumiz.com>
> ---
> .../bindings/iio/accel/we,wsen-itds.yaml | 55 +++++++++++++++++++
> 1 file changed, 55 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/accel/we,wsen-itds.yaml
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH v3 10/16] gpio: add a reusable generic gpio_chip using regmap
From: Michael Walle @ 2020-05-12 14:41 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Andy Shevchenko, linux-gpio, linux-devicetree, LKML, linux-hwmon,
linux-pwm, LINUXWATCHDOG, arm-soc, Linus Walleij, Rob Herring,
Jean Delvare, Guenter Roeck, Lee Jones, Thierry Reding,
Uwe Kleine-König, Wim Van Sebroeck, Shawn Guo, Li Yang,
Thomas Gleixner, Jason Cooper, Marc Zyngier, Mark Brown,
Greg Kroah-Hartman
In-Reply-To: <CAMpxmJV3XTOxuoKeV-z2d75qWqHkgvV9419tfe3idDeKwoeoLA@mail.gmail.com>
Am 2020-05-12 14:48, schrieb Bartosz Golaszewski:
> czw., 23 kwi 2020 o 19:46 Michael Walle <michael@walle.cc> napisał(a):
>>
>> There are quite a lot simple GPIO controller which are using regmap to
>> access the hardware. This driver tries to be a base to unify existing
>> code into one place. This won't cover everything but it should be a
>> good
>> starting point.
>>
>> It does not implement its own irq_chip because there is already a
>> generic one for regmap based devices. Instead, the irq_chip will be
>> instantiated in the parent driver and its irq domain will be associate
>> to this driver.
>>
>> For now it consists of the usual registers, like set (and an optional
>> clear) data register, an input register and direction registers.
>> Out-of-the-box, it supports consecutive register mappings and mappings
>> where the registers have gaps between them with a linear mapping
>> between
>> GPIO offset and bit position. For weirder mappings the user can
>> register
>> its own .xlate().
>>
>> Signed-off-by: Michael Walle <michael@walle.cc>
>> ---
>
> This looks good to me. Please see some nits below.
>
>> drivers/gpio/Kconfig | 4 +
>> drivers/gpio/Makefile | 1 +
>> drivers/gpio/gpio-regmap.c | 343
>> ++++++++++++++++++++++++++++++++++++
>> include/linux/gpio-regmap.h | 69 ++++++++
>> 4 files changed, 417 insertions(+)
>> create mode 100644 drivers/gpio/gpio-regmap.c
>> create mode 100644 include/linux/gpio-regmap.h
>>
>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
>> index 8ef2179fb999..ae3a49a2e970 100644
>> --- a/drivers/gpio/Kconfig
>> +++ b/drivers/gpio/Kconfig
>> @@ -73,6 +73,10 @@ config GPIO_GENERIC
>> depends on HAS_IOMEM # Only for IOMEM drivers
>> tristate
>>
>> +config GPIO_REGMAP
>> + depends on REGMAP
>> + tristate
>> +
>> # put drivers in the right section, in alphabetical order
>>
>> # This symbol is selected by both I2C and SPI expanders
>> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
>> index b2cfc21a97f3..93e139fdfa57 100644
>> --- a/drivers/gpio/Makefile
>> +++ b/drivers/gpio/Makefile
>> @@ -12,6 +12,7 @@ obj-$(CONFIG_GPIO_SYSFS) += gpiolib-sysfs.o
>> obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o
>>
>> # Device drivers. Generally keep list sorted alphabetically
>> +obj-$(CONFIG_GPIO_REGMAP) += gpio-regmap.o
>> obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
>>
>> # directly supported by gpio-generic
>> diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
>> new file mode 100644
>> index 000000000000..04939c0a22f9
>> --- /dev/null
>> +++ b/drivers/gpio/gpio-regmap.c
>> @@ -0,0 +1,343 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * regmap based generic GPIO driver
>> + *
>> + * Copyright 2019 Michael Walle <michael@walle.cc>
>> + */
>> +
>> +#include <linux/gpio/driver.h>
>> +#include <linux/gpio-regmap.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/regmap.h>
>> +
>> +struct gpio_regmap {
>> + struct device *parent;
>> + struct regmap *regmap;
>> + struct gpio_chip gpio_chip;
>> +
>> + int reg_stride;
>> + int ngpio_per_reg;
>> + unsigned int reg_dat_base;
>> + unsigned int reg_set_base;
>> + unsigned int reg_clr_base;
>> + unsigned int reg_dir_in_base;
>> + unsigned int reg_dir_out_base;
>> +
>> + int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int
>> base,
>> + unsigned int offset, unsigned int *reg,
>> + unsigned int *mask);
>> +
>> + void *driver_data;
>> +};
>> +
>> +static unsigned int gpio_regmap_addr(unsigned int addr)
>> +{
>> + return (addr == GPIO_REGMAP_ADDR_ZERO) ? 0 : addr;
>> +}
>> +
>> +/**
>> + * gpio_regmap_simple_xlate() - translate base/offset to reg/mask
>> + *
>> + * Use a simple linear mapping to translate the offset to the
>> bitmask.
>> + */
>> +static int gpio_regmap_simple_xlate(struct gpio_regmap *gpio,
>> + unsigned int base, unsigned int
>> offset,
>> + unsigned int *reg, unsigned int
>> *mask)
>> +{
>> + unsigned int line = offset % gpio->ngpio_per_reg;
>> + unsigned int stride = offset / gpio->ngpio_per_reg;
>> +
>> + *reg = base + stride * gpio->reg_stride;
>> + *mask = BIT(line);
>> +
>> + return 0;
>> +}
>> +
>> +static int gpio_regmap_get(struct gpio_chip *chip, unsigned int
>> offset)
>> +{
>> + struct gpio_regmap *gpio = gpiochip_get_data(chip);
>> + unsigned int base, val, reg, mask;
>> + int ret;
>> +
>> + /* we might not have an output register if we are input only
>> */
>> + if (gpio->reg_dat_base)
>> + base = gpio_regmap_addr(gpio->reg_dat_base);
>> + else
>> + base = gpio_regmap_addr(gpio->reg_set_base);
>> +
>> + ret = gpio->reg_mask_xlate(gpio, base, offset, ®, &mask);
>> + if (ret)
>> + return ret;
>> +
>> + ret = regmap_read(gpio->regmap, reg, &val);
>> + if (ret)
>> + return ret;
>> +
>> + return (val & mask) ? 1 : 0;
>> +}
>> +
>> +static void gpio_regmap_set(struct gpio_chip *chip, unsigned int
>> offset,
>> + int val)
>> +{
>> + struct gpio_regmap *gpio = gpiochip_get_data(chip);
>> + unsigned int base = gpio_regmap_addr(gpio->reg_set_base);
>> + unsigned int reg, mask;
>> +
>> + gpio->reg_mask_xlate(gpio, base, offset, ®, &mask);
>> + if (val)
>> + regmap_update_bits(gpio->regmap, reg, mask, mask);
>> + else
>> + regmap_update_bits(gpio->regmap, reg, mask, 0);
>> +}
>> +
>> +static void gpio_regmap_set_with_clear(struct gpio_chip *chip,
>> + unsigned int offset, int val)
>> +{
>> + struct gpio_regmap *gpio = gpiochip_get_data(chip);
>> + unsigned int base, reg, mask;
>> +
>> + if (val)
>> + base = gpio_regmap_addr(gpio->reg_set_base);
>> + else
>> + base = gpio_regmap_addr(gpio->reg_clr_base);
>> +
>> + gpio->reg_mask_xlate(gpio, base, offset, ®, &mask);
>> + regmap_write(gpio->regmap, reg, mask);
>> +}
>> +
>> +static int gpio_regmap_get_direction(struct gpio_chip *chip,
>> + unsigned int offset)
>> +{
>> + struct gpio_regmap *gpio = gpiochip_get_data(chip);
>> + unsigned int base, val, reg, mask;
>> + int invert, ret;
>> +
>> + if (gpio->reg_dir_out_base) {
>> + base = gpio_regmap_addr(gpio->reg_dir_out_base);
>> + invert = 0;
>> + } else if (gpio->reg_dir_in_base) {
>> + base = gpio_regmap_addr(gpio->reg_dir_in_base);
>> + invert = 1;
>> + } else {
>> + return GPIO_LINE_DIRECTION_IN;
>> + }
>> +
>> + ret = gpio->reg_mask_xlate(gpio, base, offset, ®, &mask);
>> + if (ret)
>> + return ret;
>> +
>> + ret = regmap_read(gpio->regmap, reg, &val);
>> + if (ret)
>> + return ret;
>> +
>> + if (!!(val & mask) ^ invert)
>> + return GPIO_LINE_DIRECTION_OUT;
>> + else
>> + return GPIO_LINE_DIRECTION_IN;
>> +}
>> +
>> +static int gpio_regmap_set_direction(struct gpio_chip *chip,
>> + unsigned int offset, bool output)
>> +{
>> + struct gpio_regmap *gpio = gpiochip_get_data(chip);
>> + unsigned int base, val, reg, mask;
>> + int invert, ret;
>> +
>> + if (gpio->reg_dir_out_base) {
>> + base = gpio_regmap_addr(gpio->reg_dir_out_base);
>> + invert = 0;
>> + } else if (gpio->reg_dir_in_base) {
>> + base = gpio_regmap_addr(gpio->reg_dir_in_base);
>> + invert = 1;
>> + } else {
>> + return 0;
>> + }
>> +
>> + ret = gpio->reg_mask_xlate(gpio, base, offset, ®, &mask);
>> + if (ret)
>> + return ret;
>> +
>> + if (!invert)
>> + val = (output) ? mask : 0;
>> + else
>> + val = (output) ? 0 : mask;
>> +
>> + return regmap_update_bits(gpio->regmap, reg, mask, val);
>> +}
>> +
>> +static int gpio_regmap_direction_input(struct gpio_chip *chip,
>> + unsigned int offset)
>> +{
>> + return gpio_regmap_set_direction(chip, offset, false);
>> +}
>> +
>> +static int gpio_regmap_direction_output(struct gpio_chip *chip,
>> + unsigned int offset, int
>> value)
>> +{
>> + gpio_regmap_set(chip, offset, value);
>> +
>> + return gpio_regmap_set_direction(chip, offset, true);
>> +}
>> +
>> +void gpio_regmap_set_drvdata(struct gpio_regmap *gpio, void *data)
>> +{
>> + gpio->driver_data = data;
>> +}
>> +EXPORT_SYMBOL_GPL(gpio_regmap_set_drvdata);
>> +
>> +void *gpio_regmap_get_drvdata(struct gpio_regmap *gpio)
>> +{
>> + return gpio->driver_data;
>> +}
>> +EXPORT_SYMBOL_GPL(gpio_regmap_get_drvdata);
>> +
>> +/**
>> + * gpio_regmap_register() - Register a generic regmap GPIO controller
>> + *
>> + * @gpio: gpio_regmap device to register
>> + *
>> + * Returns 0 on success or an errno on failure.
>> + */
>> +struct gpio_regmap *gpio_regmap_register(const struct
>> gpio_regmap_config *config)
>> +{
>> + struct gpio_regmap *gpio;
>> + struct gpio_chip *chip;
>> + int ret;
>> +
>> + if (!config->parent)
>> + return ERR_PTR(-EINVAL);
>> +
>> + if (!config->ngpio)
>> + return ERR_PTR(-EINVAL);
>> +
>> + /* we need at least one */
>> + if (!config->reg_dat_base && !config->reg_set_base)
>> + return ERR_PTR(-EINVAL);
>> +
>> + /* we don't support having both registers simulaniously for
>> now */
>> + if (config->reg_dir_out_base && config->reg_dir_in_base)
>> + return ERR_PTR(-EINVAL);
>> +
>> + gpio = kzalloc(sizeof(*gpio), GFP_KERNEL);
>> + if (!gpio)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + gpio->parent = config->parent;
>> + gpio->regmap = config->regmap;
>> + gpio->ngpio_per_reg = config->ngpio_per_reg;
>> + gpio->reg_stride = config->reg_stride;
>> + gpio->reg_mask_xlate = config->reg_mask_xlate;
>> + gpio->reg_set_base = config->reg_set_base;
>> + gpio->reg_clr_base = config->reg_clr_base;
>> + gpio->reg_dir_in_base = config->reg_dir_in_base;
>> + gpio->reg_dir_out_base = config->reg_dir_out_base;
>> +
>> + /* if not set, assume there is only one register */
>> + if (!gpio->ngpio_per_reg)
>> + gpio->ngpio_per_reg = config->ngpio;
>> +
>> + /* if not set, assume they are consecutive */
>> + if (!gpio->reg_stride)
>> + gpio->reg_stride = 1;
>> +
>> + if (!gpio->reg_mask_xlate)
>> + gpio->reg_mask_xlate = gpio_regmap_simple_xlate;
>> +
>> + chip = &gpio->gpio_chip;
>> + chip->parent = config->parent;
>> + chip->base = -1;
>> + chip->ngpio = config->ngpio;
>> + chip->can_sleep = true;
>> +
>> + if (!chip->label)
>> + chip->label = dev_name(config->parent);
>> + else
>> + chip->label = config->label;
>> +
>> + chip->get = gpio_regmap_get;
>> + if (gpio->reg_set_base && gpio->reg_clr_base)
>> + chip->set = gpio_regmap_set_with_clear;
>> + else if (gpio->reg_set_base)
>> + chip->set = gpio_regmap_set;
>> +
>> + if (gpio->reg_dir_in_base || gpio->reg_dir_out_base) {
>> + chip->get_direction = gpio_regmap_get_direction;
>> + chip->direction_input = gpio_regmap_direction_input;
>> + chip->direction_output = gpio_regmap_direction_output;
>> + }
>> +
>> + ret = gpiochip_add_data(chip, gpio);
>> + if (ret < 0) {
>> + kfree(gpio);
>
> Maybe add a second label at the end of the function?
sure
>> + return ERR_PTR(ret);
>> + }
>> +
>> + if (config->irq_domain) {
>> + ret = gpiochip_irqchip_add_domain(chip,
>> config->irq_domain);
>> + if (ret < 0)
>> + goto err;
>> + }
>> +
>> + return gpio;
>> +
>> +err:
>> + gpiochip_remove(chip);
>> + kfree(gpio);
>> + return ERR_PTR(ret);
>> +}
>> +EXPORT_SYMBOL_GPL(gpio_regmap_register);
>> +
>> +/**
>> + * gpio_regmap_unregister() - Unregister a generic regmap GPIO
>> controller
>> + *
>> + * @gpio: gpio_regmap device to unregister
>> + */
>> +void gpio_regmap_unregister(struct gpio_regmap *gpio)
>> +{
>> + gpiochip_remove(&gpio->gpio_chip);
>> + kfree(gpio);
>> +}
>> +EXPORT_SYMBOL_GPL(gpio_regmap_unregister);
>> +
>> +static void devm_gpio_regmap_unregister(struct device *dev, void
>> *res)
>> +{
>> + gpio_regmap_unregister(*(struct gpio_regmap **)res);
>> +}
>> +
>> +/**
>> + * devm_gpio_regmap_register() - resource managed
>> gpio_regmap_register()
>> + *
>> + * @dev: device that is registering this GPIO device
>> + * @gpio: gpio_regmap device to register
>> + *
>> + * Managed gpio_regmap_register(). For generic regmap GPIO device
>> registered by
>> + * this function, gpio_regmap_unregister() is automatically called on
>> driver
>> + * detach. See gpio_regmap_register() for more information.
>> + */
>> +struct gpio_regmap *devm_gpio_regmap_register(struct device *dev,
>> + const struct
>> gpio_regmap_config *config)
>> +{
>> + struct gpio_regmap **ptr, *gpio;
>> +
>> + ptr = devres_alloc(devm_gpio_regmap_unregister, sizeof(*ptr),
>> + GFP_KERNEL);
>> + if (!ptr)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + gpio = gpio_regmap_register(config);
>> +
>> + if (!IS_ERR(gpio)) {
>> + *ptr = gpio;
>> + devres_add(dev, ptr);
>> + } else {
>> + devres_free(ptr);
>> + }
>> +
>> + return gpio;
>> +}
>> +EXPORT_SYMBOL_GPL(devm_gpio_regmap_register);
>> +
>> +MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
>> +MODULE_DESCRIPTION("GPIO generic regmap driver core");
>> +MODULE_LICENSE("GPL");
>> diff --git a/include/linux/gpio-regmap.h b/include/linux/gpio-regmap.h
>> new file mode 100644
>> index 000000000000..a868cbcde6e9
>> --- /dev/null
>> +++ b/include/linux/gpio-regmap.h
>> @@ -0,0 +1,69 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +
>> +#ifndef _LINUX_GPIO_REGMAP_H
>> +#define _LINUX_GPIO_REGMAP_H
>> +
>> +struct gpio_regmap;
>> +
>> +#define GPIO_REGMAP_ADDR_ZERO ((unsigned long)(-1))
>> +#define GPIO_REGMAP_ADDR(addr) ((addr) ? : GPIO_REGMAP_ADDR_ZERO)
>> +
>
> What if the addr is actually 0?
Then the driver has to set GPIO_REGMAP_ADDR_ZERO or use the convenience
macro GPIO_REGMAP_ADDR.
So you can have
struct gpio_regmap_config config = { 0 };
config.reg_dat_base = 0x10;
config.reg_dir_out_base = 0x20;
or
config.reg_dat_base = GPIO_REGMAP_ADDR_ZERO;
or if you can't be sure if the RHS value might be zero:
config.reg_dat_base = GPIO_REGMAP_ADDR(reg);
> Maybe drop GPIO_REGMAP_ADDR and require users to set unused registers
> to GPIO_REGMAP_ADDR_ZERO?
Thats bad because:
* you'd have to set plenty of unused base registers for a simple driver
* if there will be additional properties in the future, you have to
touch
all other drivers, because they are initialized as 0 (ie. valid reg
0).
>> +/**
>> + * struct gpio_regmap_config - Description of a generic regmap
>> gpio_chip.
>> + *
>> + * @parent: The parent device
>> + * @regmap: The regmap used to access the registers
>> + * given, the name of the device is used
>> + * @label: (Optional) Descriptive name for GPIO
>> controller.
>> + * If not given, the name of the device is used.
>> + * @ngpio: Number of GPIOs
>> + * @reg_dat_base: (Optional) (in) register base address
>> + * @reg_set_base: (Optional) set register base address
>> + * @reg_clr_base: (Optional) clear register base address
>> + * @reg_dir_in_base: (Optional) out setting register base address
>> + * @reg_dir_out_base: (Optional) in setting register base address
>
> The two above are inverted I think?
good catch.
> Also: why the limitation of only supporting one at a time?
they should be exclusive, either you have a register where you set the
output bits to one, or the input bits. Maybe this need a bit more
context
above. in gpio-mmio.c you can set both and both are used in
set_direction(), but only one is read in get_direction().
That being said, I have no strong opinion wether they should be
exclusive
or not, besides the symmetry of set_/get_direction().
-michael
>
>> + * @reg_stride: (Optional) May be set if the registers
>> (of the
>> + * same type, dat, set, etc) are not consecutive.
>> + * @ngpio_per_reg: Number of GPIOs per register
>> + * @irq_domain: (Optional) IRQ domain if the
>> controller is
>> + * interrupt-capable
>> + * @reg_mask_xlate: (Optional) Translates base address and GPIO
>> + * offset to a register/bitmask pair. If not
>> + * given the default gpio_regmap_simple_xlate()
>> + * is used.
>> + *
>> + * The reg_mask_xlate translates a given base address and GPIO offset
>> to
>> + * register and mask pair. The base address is one of the given
>> reg_*_base.
>> + *
>> + * All base addresses may have the special value
>> GPIO_REGMAP_ADDR_ZERO
>> + * which forces the address to the value 0.
>> + */
>> +struct gpio_regmap_config {
>> + struct device *parent;
>> + struct regmap *regmap;
>> +
>> + const char *label;
>> + int ngpio;
>> +
>> + unsigned int reg_dat_base;
>> + unsigned int reg_set_base;
>> + unsigned int reg_clr_base;
>> + unsigned int reg_dir_in_base;
>> + unsigned int reg_dir_out_base;
>> + int reg_stride;
>> + int ngpio_per_reg;
>> + struct irq_domain *irq_domain;
>> +
>> + int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int
>> base,
>> + unsigned int offset, unsigned int *reg,
>> + unsigned int *mask);
>> +};
>> +
>> +struct gpio_regmap *gpio_regmap_register(const struct
>> gpio_regmap_config *config);
>> +void gpio_regmap_unregister(struct gpio_regmap *gpio);
>> +struct gpio_regmap *devm_gpio_regmap_register(struct device *dev,
>> + const struct
>> gpio_regmap_config *config);
>> +void gpio_regmap_set_drvdata(struct gpio_regmap *gpio, void *data);
>> +void *gpio_regmap_get_drvdata(struct gpio_regmap *gpio);
>> +
>> +#endif /* _LINUX_GPIO_REGMAP_H */
>> --
>> 2.20.1
>>
^ permalink raw reply
* Re: [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting
From: Akash Asthana @ 2020-05-12 14:26 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov
In-Reply-To: <20200508190301.GG4525@google.com>
Hi Matthias,
On 5/9/2020 12:33 AM, Matthias Kaehlcke wrote:
> On Fri, May 08, 2020 at 12:03:33PM +0530, Akash Asthana wrote:
>> Add necessary macros and structure variables to support ICC BW
>> voting from individual SE drivers.
>>
>> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
>> ---
>> Changes in V2:
>> - As per Bjorn's comment dropped enums for ICC paths, given the three
>> paths individual members
>>
>> Changes in V3:
>> - Add geni_icc_get, geni_icc_vote_on and geni_icc_vote_off as helper API.
>> - Add geni_icc_path structure in common header
>>
>> Changes in V4:
>> - As per Bjorn's comment print error message in geni_icc_get if return
>> value is not -EPROBE_DEFER.
>> - As per Bjorn's comment remove NULL on path before calling icc_set_bw
>> API.
>> - As per Bjorn's comment drop __func__ print.
>> - As per Matthias's comment, make ICC path a array instead of individual
>> member entry in geni_se struct.
>>
>> Note: I have ignored below check patch suggestion because it was throwing
>> compilation error as 'icc_ddr' is not compile time comstant.
>>
>> WARNING: char * array declaration might be better as static const
>> - FILE: drivers/soc/qcom/qcom-geni-se.c:726:
>> - const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
>>
>> Changes in V5:
>> - As per Matthias's comment defined enums for ICC paths.
>> - Integrate icc_enable/disable with power on/off call for driver.
>> - As per Matthias's comment added icc_path_names array to print icc path name
>> in failure case.
>> - As per Georgi's suggestion assume peak_bw = avg_bw if not mentioned.
>>
>> drivers/soc/qcom/qcom-geni-se.c | 92 +++++++++++++++++++++++++++++++++++++++++
>> include/linux/qcom-geni-se.h | 42 +++++++++++++++++++
>> 2 files changed, 134 insertions(+)
>>
>> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
>> index 7d622ea..63403bf 100644
>> --- a/drivers/soc/qcom/qcom-geni-se.c
>> +++ b/drivers/soc/qcom/qcom-geni-se.c
>> @@ -92,6 +92,9 @@ struct geni_wrapper {
>> struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
>> };
>>
>> +static const char * const icc_path_names[] = {"qup-core", "qup-config",
>> + "qup-memory"};
>> +
>> #define QUP_HW_VER_REG 0x4
>>
>> /* Common SE registers */
>> @@ -720,6 +723,95 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
>> }
>> EXPORT_SYMBOL(geni_se_rx_dma_unprep);
>>
>> +int geni_icc_get(struct geni_se *se, const char *icc_ddr)
>> +{
>> + int i, icc_err;
>> + const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
>> +
>> + for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
>> + if (!icc_names[i])
>> + continue;
>> +
>> + se->icc_paths[i].path = devm_of_icc_get(se->dev, icc_names[i]);
>> + if (IS_ERR(se->icc_paths[i].path))
>> + goto icc_get_failure;
>> + }
>> +
>> + return 0;
>> +
>> +icc_get_failure:
>> + icc_err = PTR_ERR(se->icc_paths[i].path);
>> + if (icc_err != -EPROBE_DEFER)
>> + dev_err_ratelimited(se->dev, "Failed to get ICC path:%s, ret:%d\n",
>> + icc_names[i], icc_err);
>> + return icc_err;
>> +
>> +}
>> +EXPORT_SYMBOL(geni_icc_get);
>> +
>> +void geni_icc_bw_init(struct geni_icc_path *icc_paths, unsigned int avg_bw,
>> + unsigned int peak_bw)
> I noticed that all callers of geni_icc_bw_init() pass 0 as
> 'peak_pw' (aka peak == avg). Unless there are plans to use other
> values for the peak bandwidth in the future it is pointless to
> track the bandwidth(s) in two variables. And if the bandwidth is
> tracked in a single variable this function is not needed.
As of now we are not aware of our peak requirement(avg requirement works
good for us) so I am passing (peak = avg) as per Georgi's suggestion.
But I wanted to make this feature more generic and keeping the
possibilty open that we might have to use other peak(!=0) value in future.
Regards,
Akash
>
>> +{
>> + if (!peak_bw)
>> + peak_bw = avg_bw;
>> + icc_paths->avg_bw = avg_bw;
>> + icc_paths->peak_bw = peak_bw;
>> +}
>> +EXPORT_SYMBOL(geni_icc_bw_init);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v9 4/5] usb: ehci: Add new EHCI driver for Broadcom STB SoC's
From: Alan Cooper @ 2020-05-12 14:24 UTC (permalink / raw)
To: Alan Stern
Cc: : Linux Kernel Mailing List, Andy Shevchenko, BCM Kernel Feedback,
DTML, Greg Kroah-Hartman, Krzysztof Kozlowski, USB list,
Mathias Nyman, Rob Herring, Yoshihiro Shimoda, Andy Shevchenko
In-Reply-To: <Pine.LNX.4.44L0.2005111542310.11417-100000@netrider.rowland.org>
On Mon, May 11, 2020 at 3:51 PM Alan Stern <stern@rowland.harvard.edu> wrote:
>
> On Mon, 11 May 2020, Al Cooper wrote:
>
> > Add a new EHCI driver for Broadcom STB SoC's. A new EHCI driver
> > was created instead of adding support to the existing ehci platform
> > driver because of the code required to work around bugs in the EHCI
> > controller. The primary workaround is for a bug where the Core
> > violates the SOF interval between the first two SOFs transmitted after
> > resume. This only happens if the resume occurs near the end of a
> > microframe. The fix is to intercept the ehci-hcd request to complete
> > RESUME and align it to the start of the next microframe.
> >
> > Signed-off-by: Al Cooper <alcooperx@gmail.com>
> > Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> > Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
> > ---
>
> I hate to point this out...
>
> > +static int ehci_brcm_probe(struct platform_device *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct resource *res_mem;
> > + struct brcm_priv *priv;
> > + struct usb_hcd *hcd;
> > + int irq;
> > + int err;
> > +
> > + err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
> > + if (err)
> > + return err;
> > +
> > + irq = platform_get_irq(pdev, 0);
> > + if (irq <= 0)
> > + return irq ? irq : EINVAL;
>
> That should be -EINVAL.
>
> To tell the truth, I'm not sure it's worthwhile checking for irq == 0.
> That's up to Greg to decide.
Darn, I've been looking at this code for too long :(
Since Greg originally requested <=, I'll fix this and send v10.
Thanks
Al
>
> Anyway, as far as I'm concerned you can either change EINVAL to -EINVAL
> or change the whole thing back to "if (irq < 0) return irq;". Either
> way, you may add:
>
> Acked-by: Alan Stern <stern@rowland.harvard.edu>
>
> Alan Stern
>
^ permalink raw reply
* Re: [PATCH v3 0/2] nvmem: skip nodes with compatibles other than "nvmem-cell"
From: Rob Herring @ 2020-05-12 14:18 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: linux-kernel, kernel, ceggers, devicetree
In-Reply-To: <20200428111829.2215-1-a.fatoum@pengutronix.de>
On Tue, Apr 28, 2020 at 01:18:25PM +0200, Ahmad Fatoum wrote:
> The nvmem cell binding applies to all objects which match "^.*@[0-9a-f]+$",
> without taking a compatible into account. This precludes extension of e.g.
> eeprom nodes by any child nodes other than nvmem. Consider following example:
>
> eeprom@0 {
> reg = <0 64>;
> #address-cells = <1>;
> #size-cells = <1>;
>
> partitions {
> compatible = "fixed-partitions";
> #address-cells = <1>;
> #size-cells = <1>;
> bits = <64 64 64>; /* to verify it's skipped */
>
> part@0 {
> reg = <0x00 16>;
> };
> };
>
> no-cell@10 {
> compatible = "not-nvmem-cell";
> reg = <0x10 4>;
> bits = <64 64 64>; /* to verify it's skipped */
> };
>
> cell-old@14 {
> reg = <0x14 0x2>;
> };
>
> cell-new@16 {
> compatible = "nvmem-cell";
> reg = <0x16 4>;
> };
> };
>
> Without this series, the NVMEM driver interprets all direct children of eeprom@0
> as NVMEM cells and driver probe fails, because the partitions node lacks a reg
> property, e.g.:
>
> nvmem 0-00000: nvmem: invalid reg on /eeprom@0
>
> Running dtbs_check on the snippet will skip partitions (it doesn't match above
> regex), but will flag no-cell@10 and cell-new@16 as invalid.
>
> With this series applied, the driver will skip partitions and no-cell@10,
> because they have a compatible but it's not "nvmem-cell".
Because you have to support no compatible (forever), there's no point
adding this compatible.
> Both cell-old@14 and cell-new@16 will be interpreted as cells.
>
> Likewise, running dtbs_check on the snippet will skip partitions (compatible
> doesn't match and regex doesn't either) and no-cell@10, but accept the other two.
>
> This series resolves an existing clash between this nvmem-cell binding and
> the barebox bootloader binding that extends the fixed-partitions MTD
> binding to EEPROMs[1]. It's also a building block for getting nvmem cells and
> partitions in MTD devices to co-exist in the same device tree node[2].
This violates having multiple nodes at the same address because you are
independently overlaying partitions and nvmem cells on same address
ranges. It also seems seems pretty fragile if you want to update
partitions.
I think instead, nvmem cells should be contained within a partition.
The partition should then have a compatible to indicate it contains
nvmem cells.
Rob
^ permalink raw reply
* [PATCH v8 2/8] tpm: tpm_tis: Add verify_data_integrity handle toy tpm_tis_phy_ops
From: amirmizi6 @ 2020-05-12 14:14 UTC (permalink / raw)
To: Eyal.Cohen, jarkko.sakkinen, oshrialkoby85, alexander.steffen,
robh+dt, "benoit.houyere, peterhuewe, christophe-h.richard,
jgg, arnd, gregkh
Cc: devicetree, linux-kernel, linux-integrity, oshri.alkoby,
tmaimon77, gcwilson, kgoldman, Dan.Morav, oren.tanami,
shmulik.hager, amir.mizinski, Amir Mizinski, Christophe Ricard
In-Reply-To: <20200512141431.83833-1-amirmizi6@gmail.com>
From: Amir Mizinski <amirmizi6@gmail.com>
To validate data integrity we need to compute the CRC over the data
sent at a lower layer (I2C for instance).
To do this, tpm_tis_verify_data_integrity() calls a "verify_data_integrity"
operation (if available).
If the data integrity check fails, a retry to save the sent/received
data is implemented in the tpm_tis_send_main()/tpm_tis_recv() functions.
Co-developed-by: Christophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: Amir Mizinski <amirmizi6@gmail.com>
---
drivers/char/tpm/tpm_tis_core.c | 104 +++++++++++++++++++++++++---------------
drivers/char/tpm/tpm_tis_core.h | 3 ++
2 files changed, 69 insertions(+), 38 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 27c6ca0..5dd5604 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -242,6 +242,17 @@ static u8 tpm_tis_status(struct tpm_chip *chip)
return status;
}
+static bool tpm_tis_verify_data_integrity(struct tpm_chip *chip, const u8 *buf,
+ size_t len)
+{
+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+
+ if (priv->phy_ops->verify_data_integrity)
+ return priv->phy_ops->verify_data_integrity(priv, buf, len);
+
+ return true;
+}
+
static void tpm_tis_ready(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
@@ -308,47 +319,59 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int size = 0;
- int status;
+ int status, i;
u32 expected;
+ bool data_valid = false;
- if (count < TPM_HEADER_SIZE) {
- size = -EIO;
- goto out;
- }
+ for (i = 0; i < TPM_RETRY; i++) {
+ if (count < TPM_HEADER_SIZE) {
+ size = -EIO;
+ goto out;
+ }
- size = recv_data(chip, buf, TPM_HEADER_SIZE);
- /* read first 10 bytes, including tag, paramsize, and result */
- if (size < TPM_HEADER_SIZE) {
- dev_err(&chip->dev, "Unable to read header\n");
- goto out;
- }
+ size = recv_data(chip, buf, TPM_HEADER_SIZE);
+ /* read first 10 bytes, including tag, paramsize, and result */
+ if (size < TPM_HEADER_SIZE) {
+ dev_err(&chip->dev, "Unable to read header\n");
+ goto out;
+ }
- expected = be32_to_cpu(*(__be32 *) (buf + 2));
- if (expected > count || expected < TPM_HEADER_SIZE) {
- size = -EIO;
- goto out;
- }
+ expected = be32_to_cpu(*(__be32 *) (buf + 2));
+ if (expected > count || expected < TPM_HEADER_SIZE) {
+ size = -EIO;
+ goto out;
+ }
- size += recv_data(chip, &buf[TPM_HEADER_SIZE],
- expected - TPM_HEADER_SIZE);
- if (size < expected) {
- dev_err(&chip->dev, "Unable to read remainder of result\n");
- size = -ETIME;
- goto out;
- }
+ size += recv_data(chip, &buf[TPM_HEADER_SIZE],
+ expected - TPM_HEADER_SIZE);
+ if (size < expected) {
+ dev_err(&chip->dev, "Unable to read remainder of result\n");
+ size = -ETIME;
+ goto out;
+ }
- if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
- &priv->int_queue, false) < 0) {
- size = -ETIME;
- goto out;
+ if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+ &priv->int_queue, false) < 0) {
+ size = -ETIME;
+ goto out;
+ }
+
+ status = tpm_tis_status(chip);
+ if (status & TPM_STS_DATA_AVAIL) { /* retry? */
+ dev_err(&chip->dev, "Error left over data\n");
+ size = -EIO;
+ goto out;
+ }
+
+ data_valid = tpm_tis_verify_data_integrity(chip, buf, size);
+ if (!data_valid)
+ tpm_tis_write8(priv, TPM_STS(priv->locality),
+ TPM_STS_RESPONSE_RETRY);
+ else
+ break;
}
- status = tpm_tis_status(chip);
- if (status & TPM_STS_DATA_AVAIL) { /* retry? */
- dev_err(&chip->dev, "Error left over data\n");
+ if (!data_valid)
size = -EIO;
- goto out;
- }
-
out:
tpm_tis_ready(chip);
return size;
@@ -453,14 +476,19 @@ static void disable_interrupts(struct tpm_chip *chip)
static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
- int rc;
+ int rc, i;
u32 ordinal;
unsigned long dur;
+ bool data_valid = false;
- rc = tpm_tis_send_data(chip, buf, len);
- if (rc < 0)
- return rc;
-
+ for (i = 0; i < TPM_RETRY && !data_valid; i++) {
+ rc = tpm_tis_send_data(chip, buf, len);
+ if (rc < 0)
+ return rc;
+ data_valid = tpm_tis_verify_data_integrity(chip, buf, len);
+ }
+ if (!data_valid)
+ return -EIO;
/* go and do it */
rc = tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_GO);
if (rc < 0)
diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
index d06c65b..cd97c01 100644
--- a/drivers/char/tpm/tpm_tis_core.h
+++ b/drivers/char/tpm/tpm_tis_core.h
@@ -34,6 +34,7 @@ enum tis_status {
TPM_STS_GO = 0x20,
TPM_STS_DATA_AVAIL = 0x10,
TPM_STS_DATA_EXPECT = 0x08,
+ TPM_STS_RESPONSE_RETRY = 0x02,
};
enum tis_int_flags {
@@ -106,6 +107,8 @@ struct tpm_tis_phy_ops {
int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result);
int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result);
int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src);
+ bool (*verify_data_integrity)(struct tpm_tis_data *data, const u8 *buf,
+ size_t len);
};
static inline int tpm_tis_read_bytes(struct tpm_tis_data *data, u32 addr,
--
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