From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::342; helo=mail-ot1-x342.google.com; envelope-from=tmaimon77@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="b0MJFixe"; dkim-atps=neutral Received: from mail-ot1-x342.google.com (mail-ot1-x342.google.com [IPv6:2607:f8b0:4864:20::342]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 473nNG4lv0zF5R6 for ; Fri, 1 Nov 2019 01:13:02 +1100 (AEDT) Received: by mail-ot1-x342.google.com with SMTP id t8so5495015otl.6 for ; Thu, 31 Oct 2019 07:13:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=kwGz9eM3JXenSRdLtAAHnevUEPAIMbSgiGIQEyNukyM=; b=b0MJFixeSI7C9rY6IEMPpsvzhae0fCZPSQtwR9LlknT0d+2EyZqIxOIHBsrLOweUOu O5kYbn14tj+fhB1sQpHJKW8DMRlH3xERQ5w40nLvqjoYAiB/szv5Ff/L/3ZpNuJzaxty MV1EcGpSJMmhh2eeJ3ZjM+ysH+5KXAXG2Hfp94M4hiGrJxDyfeWyBgnJ5+Z5Izmguhj/ 6Ul5UNq3jU2m3+deYbsJV58lUvwYThhbol8iCi7Y9chKccnyIYzWNxiNHkVL2GYRAyym wD33i6ehybqm3tyeh79OvU+g7/MnpMjQGR6TnRxHQFX6jAhin7OWCC/p+lP6OTfNRVBh EOCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=kwGz9eM3JXenSRdLtAAHnevUEPAIMbSgiGIQEyNukyM=; b=nPoaaGlWLwYViHEvaZaXx03vfe9lbfe/Yx1NVAr+Ar+51u6I54wevS7I+jK0nElMbA ltwnRVcVIDiuz/9Tt4UMavFRtQyXx97qsaoRJoog2t5ICcLyGMF18GYRhfprtYMXCjBH RCcuuyx/ceh0CIyQdzjwC4SWyidTGAozlwQmH7Pt0Ri8G9gV9ZQ8oSzc+0KuCnrriL2D IPs4IaW2F+5qaPvPayXRWWrUHdHB6leTLUPMqtKTvrdl+mpo+JbmoqpSmBq+iYTqlZ5j hqhNJdM321MHu0Z9nVWWJCPx38E5cnk/r81i7LvG4bVsl2R/emtiUGkp8V/NlMsw987Y WEwg== X-Gm-Message-State: APjAAAWUj75G6XF4T1cQaICKBe5vU9ESn8k2z31BzprdvmrcFKHeVELD K/aehVBIw8S2uhPxq29GfNlSYjTtKAc/j2FPynaxCA== X-Google-Smtp-Source: APXvYqxTOD0LddqBpCVjb0+xvXlIwj9bpX8AlzbW9csPp6HciwLxtLUCOB2nM79B5GR2tPqCzMcKzR10krPrZ5PCEuQ= X-Received: by 2002:a9d:6141:: with SMTP id c1mr4819150otk.117.1572530675861; Thu, 31 Oct 2019 07:04:35 -0700 (PDT) MIME-Version: 1.0 References: <20191028155403.134126-1-tmaimon77@gmail.com> <20191028155403.134126-4-tmaimon77@gmail.com> In-Reply-To: From: Tomer Maimon Date: Thu, 31 Oct 2019 16:14:17 +0200 Message-ID: Subject: Re: [PATCH v2 3/3] reset: npcm: add NPCM reset controller driver To: Philipp Zabel Cc: Rob Herring , Mark Rutland , Nancy Yuen , Patrick Venture , Benjamin Fair , Avi Fishman , Joel Stanley , OpenBMC Maillist , Linux Kernel Mailing List , devicetree Content-Type: multipart/alternative; boundary="000000000000554ea905963554b8" X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 31 Oct 2019 14:13:03 -0000 --000000000000554ea905963554b8 Content-Type: text/plain; charset="UTF-8" Hi Philipp, Thanks a lot for your comments. On Tue, 29 Oct 2019 at 17:34, Philipp Zabel wrote: > On Mon, 2019-10-28 at 17:54 +0200, Tomer Maimon wrote: > > Add Nuvoton NPCM BMC reset controller driver. > > > > Signed-off-by: Tomer Maimon > > --- > > drivers/reset/Kconfig | 7 + > > drivers/reset/Makefile | 1 + > > drivers/reset/reset-npcm.c | 275 +++++++++++++++++++++++++++++++++++++ > > 3 files changed, 283 insertions(+) > > create mode 100644 drivers/reset/reset-npcm.c > > > > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig > > index 7b07281aa0ae..5dbfdf6d717a 100644 > > --- a/drivers/reset/Kconfig > > +++ b/drivers/reset/Kconfig > > @@ -89,6 +89,13 @@ config RESET_MESON_AUDIO_ARB > > This enables the reset driver for Audio Memory Arbiter of > > Amlogic's A113 based SoCs > > > > +config RESET_NPCM > > + bool "NPCM BMC Reset Driver" > > + depends on ARCH_NPCM || COMPILE_TEST > > + help > > + This enables the reset controller driver for Nuvoton NPCM > > + BMC SoCs. > > + > > Is there any reason to ever disable this driver when building ARCH_NPCM? > > > config RESET_OXNAS > > bool > > > > diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile > > index cf60ce526064..00767c03f5f2 100644 > > --- a/drivers/reset/Makefile > > +++ b/drivers/reset/Makefile > > @@ -14,6 +14,7 @@ obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o > > obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o > > obj-$(CONFIG_RESET_MESON) += reset-meson.o > > obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o > > +obj-$(CONFIG_RESET_NPCM) += reset-npcm.o > > obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o > > obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o > > obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o > > diff --git a/drivers/reset/reset-npcm.c b/drivers/reset/reset-npcm.c > > new file mode 100644 > > index 000000000000..ebb3071767e1 > > --- /dev/null > > +++ b/drivers/reset/reset-npcm.c > > @@ -0,0 +1,275 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +// Copyright (c) 2019 Nuvoton Technology corporation. > > + > > +#include > > Please remove unused header includes. > > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/* NPCM7xx GCR registers */ > > +#define NPCM_MDLR_OFFSET 0x7C > > +#define NPCM_MDLR_USBD0 BIT(9) > > +#define NPCM_MDLR_USBD1 BIT(8) > > +#define NPCM_MDLR_USBD2_4 BIT(21) > > +#define NPCM_MDLR_USBD5_9 BIT(22) > > + > > +#define NPCM_USB1PHYCTL_OFFSET 0x140 > > +#define NPCM_USB2PHYCTL_OFFSET 0x144 > > +#define NPCM_USBXPHYCTL_RS BIT(28) > > + > > +/* NPCM7xx Reset registers */ > > +#define NPCM_SWRSTR 0x14 > > +#define NPCM_SWRST BIT(2) > > + > > +#define NPCM_IPSRST1 0x20 > > +#define NPCM_IPSRST1_USBD1 BIT(5) > > +#define NPCM_IPSRST1_USBD2 BIT(8) > > +#define NPCM_IPSRST1_USBD3 BIT(25) > > +#define NPCM_IPSRST1_USBD4 BIT(22) > > +#define NPCM_IPSRST1_USBD5 BIT(23) > > +#define NPCM_IPSRST1_USBD6 BIT(24) > > + > > +#define NPCM_IPSRST2 0x24 > > +#define NPCM_IPSRST2_USB_HOST BIT(26) > > + > > +#define NPCM_IPSRST3 0x34 > > +#define NPCM_IPSRST3_USBD0 BIT(4) > > +#define NPCM_IPSRST3_USBD7 BIT(5) > > +#define NPCM_IPSRST3_USBD8 BIT(6) > > +#define NPCM_IPSRST3_USBD9 BIT(7) > > +#define NPCM_IPSRST3_USBPHY1 BIT(24) > > +#define NPCM_IPSRST3_USBPHY2 BIT(25) > > + > > +#define NPCM_RC_RESETS_PER_REG 32 > > + > > +struct npcm_rc_data { > > + struct reset_controller_dev rcdev; > > + struct notifier_block restart_nb; > > + u32 sw_reset_number; > > + void __iomem *base; > > + spinlock_t lock; > > +}; > > + > > +#define to_rc_data(p) container_of(p, struct npcm_rc_data, rcdev) > > + > > +static int npcm_rc_restart(struct notifier_block *nb, unsigned long > mode, > > + void *cmd) > > +{ > > + struct npcm_rc_data *rc = container_of(nb, struct npcm_rc_data, > > + restart_nb); > > + > > + writel(NPCM_SWRST << rc->sw_reset_number, rc->base + NPCM_SWRSTR); > > + mdelay(1000); > > + > > + pr_emerg("%s: unable to restart system\n", __func__); > > + > > + return NOTIFY_DONE; > > +} > > + > > +static int npcm_rc_setclear_reset(struct reset_controller_dev *rcdev, > > + unsigned long id, bool set) > > +{ > > + struct npcm_rc_data *rc = to_rc_data(rcdev); > > + u32 ctrl_offset = NPCM_IPSRST1; > > + unsigned long flags; > > + u32 stat, rst_bit; > > + > > + ctrl_offset += (id / NPCM_RC_RESETS_PER_REG) * sizeof(u32); > > + rst_bit = 1 << (id % NPCM_RC_RESETS_PER_REG); > > + > > + spin_lock_irqsave(&rc->lock, flags); > > + stat = readl(rc->base + ctrl_offset); > > + if (set) > > + writel(stat | rst_bit, rc->base + ctrl_offset); > > + else > > + writel(stat & ~rst_bit, rc->base + ctrl_offset); > > + spin_unlock_irqrestore(&rc->lock, flags); > > + > > + return 0; > > +} > > + > > +static int npcm_rc_assert(struct reset_controller_dev *rcdev, unsigned > long id) > > +{ > > + return npcm_rc_setclear_reset(rcdev, id, true); > > +} > > + > > +static int npcm_rc_deassert(struct reset_controller_dev *rcdev, > > + unsigned long id) > > +{ > > + return npcm_rc_setclear_reset(rcdev, id, false); > > +} > > + > > +static int npcm_rc_status(struct reset_controller_dev *rcdev, > > + unsigned long id) > > +{ > > + struct npcm_rc_data *rc = to_rc_data(rcdev); > > + u32 bit, ctrl_offset = NPCM_IPSRST1; > > + > > + ctrl_offset += (id / NPCM_RC_RESETS_PER_REG) * sizeof(u32); > > + bit = 1 << (id % NPCM_RC_RESETS_PER_REG); > > + > > + return (readl(rc->base + ctrl_offset) & bit); > > +} > > + > > +/* > > + * The following procedure should be observed in USB PHY, USB device > and > > + * USB host initialization at BMC boot > > + */ > > +static int npcm_usb_reset(struct platform_device *pdev, struct > npcm_rc_data *rc) > > +{ > > + struct device_node *np = pdev->dev.of_node; > > + u32 mdlr, iprst1, iprst2, iprst3; > > + struct regmap *gcr_regmap; > > + u32 ipsrst1_bits = 0; > > + u32 ipsrst2_bits = NPCM_IPSRST2_USB_HOST; > > + u32 ipsrst3_bits = 0; > > + > > + if (of_device_is_compatible(np, "nuvoton,npcm750-reset")) { > > + gcr_regmap = > syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr"); > > + if (IS_ERR(gcr_regmap)) { > > + dev_err(&pdev->dev, "Failed to find > nuvoton,npcm750-gcr\n"); > > + return PTR_ERR(gcr_regmap); > > + } > > + } > > + if (!gcr_regmap) > > + return -ENXIO; > > + > > + /* checking which USB device is enabled */ > > + regmap_read(gcr_regmap, NPCM_MDLR_OFFSET, &mdlr); > > + if (!(mdlr & NPCM_MDLR_USBD0)) > > + ipsrst3_bits |= NPCM_IPSRST3_USBD0; > > + if (!(mdlr & NPCM_MDLR_USBD1)) > > + ipsrst1_bits |= NPCM_IPSRST1_USBD1; > > + if (!(mdlr & NPCM_MDLR_USBD2_4)) > > + ipsrst1_bits |= (NPCM_IPSRST1_USBD2 | > > + NPCM_IPSRST1_USBD3 | > > + NPCM_IPSRST1_USBD4); > > + if (!(mdlr & NPCM_MDLR_USBD0)) { > > + ipsrst1_bits |= (NPCM_IPSRST1_USBD5 | > > + NPCM_IPSRST1_USBD6); > > + ipsrst3_bits |= (NPCM_IPSRST3_USBD7 | > > + NPCM_IPSRST3_USBD8 | > > + NPCM_IPSRST3_USBD9); > > + } > > + > > + /* assert reset USB PHY and USB devices */ > > + iprst1 = readl(rc->base + NPCM_IPSRST1); > > + iprst2 = readl(rc->base + NPCM_IPSRST2); > > + iprst3 = readl(rc->base + NPCM_IPSRST3); > > + > > + iprst1 |= ipsrst1_bits; > > + iprst2 |= ipsrst2_bits; > > + iprst3 |= (ipsrst3_bits | NPCM_IPSRST3_USBPHY1 | > > + NPCM_IPSRST3_USBPHY2); > > + > > + writel(iprst1, rc->base + NPCM_IPSRST1); > > + writel(iprst2, rc->base + NPCM_IPSRST2); > > + writel(iprst3, rc->base + NPCM_IPSRST3); > > + > > + /* clear USB PHY RS bit */ > > + regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET, > > + NPCM_USBXPHYCTL_RS, 0); > > + regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET, > > + NPCM_USBXPHYCTL_RS, 0); > > + > > + /* deassert reset USB PHY */ > > + iprst3 &= ~(NPCM_IPSRST3_USBPHY1 | NPCM_IPSRST3_USBPHY2); > > + writel(iprst3, rc->base + NPCM_IPSRST3); > > + > > + udelay(50); > > + > > + /* set USB PHY RS bit */ > > + regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET, > > + NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS); > > + regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET, > > + NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS); > > + > > + /* deassert reset USB devices*/ > > + iprst1 &= ~ipsrst1_bits; > > + iprst2 &= ~ipsrst2_bits; > > + iprst3 &= ~ipsrst3_bits; > > + > > + writel(iprst1, rc->base + NPCM_IPSRST1); > > + writel(iprst2, rc->base + NPCM_IPSRST2); > > + writel(iprst3, rc->base + NPCM_IPSRST3); > > + > > + return 0; > > +} > > Is there no better place for this, such as USB glue code? Sorry, I didn't find a proper place to add it in the USB tree. > > > +static const struct reset_control_ops npcm_rc_ops = { > > + .assert = npcm_rc_assert, > > + .deassert = npcm_rc_deassert, > > + .status = npcm_rc_status, > > +}; > > + > > +static int npcm_rc_probe(struct platform_device *pdev) > > +{ > > + struct npcm_rc_data *rc; > > + struct resource res; > > + int ret; > > + > > + rc = devm_kzalloc(&pdev->dev, sizeof(*rc), GFP_KERNEL); > > + if (!rc) > > + return -ENOMEM; > > + > > + of_address_to_resource(pdev->dev.of_node, 0, &res); > > + rc->base = devm_ioremap_resource(&pdev->dev, &res); > > Can't you just use > > rc->base = devm_platform_ioremap_resource(pdev, 0); > > here? > > > + if (IS_ERR(rc->base)) > > + return PTR_ERR(rc->base); > > + > > + spin_lock_init(&rc->lock); > > + > > + rc->rcdev.owner = THIS_MODULE; > > + rc->rcdev.nr_resets = resource_size(&res) / 4 * BITS_PER_LONG; > > That doesn't seem right. With the ctrl_offset = NPCM_IPSRST1 in > npcm_rc_setclear_reset that would allow access beyond the configured > register range. > > > + rc->rcdev.ops = &npcm_rc_ops; > > + rc->rcdev.of_node = pdev->dev.of_node; > > + > > + platform_set_drvdata(pdev, rc); > > + > > + ret = reset_controller_register(&rc->rcdev); > > ret = devm_reset_controller_register(&pdev->dev, &rc->rcdev); > > > + if (ret) { > > + dev_err(&pdev->dev, "unable to register device\n"); > > + return ret; > > + } > > + > > + if (npcm_usb_reset(pdev, rc)) > > + dev_warn(&pdev->dev, "NPCM USB reset failed, can cause > issues with UDC and USB host\n"); > > + > > + if (!of_property_read_u32(pdev->dev.of_node, > "nuvoton,sw-reset-number", > > + &rc->sw_reset_number)) { > > + if (rc->sw_reset_number && rc->sw_reset_number < 5) { > > + rc->restart_nb.priority = 192, > > + rc->restart_nb.notifier_call = npcm_rc_restart, > > + ret = register_restart_handler(&rc->restart_nb); > > + if (ret) > > + dev_warn(&pdev->dev, "failed to register > restart handler\n"); > > + } > > + } > > + > > + pr_info("NPCM RESET driver probed\n"); > > It think this is a bit verbose. > > > + return ret; > > +} > > + > > +static const struct of_device_id npcm_rc_match[] = { > > + { .compatible = "nuvoton,npcm750-reset" }, > > + { } > > +}; > > + > > +static struct platform_driver npcm_rc_driver = { > > + .probe = npcm_rc_probe, > > + .driver = { > > + .name = "npcm-reset", > > + .of_match_table = npcm_rc_match, > > + .suppress_bind_attrs = true, > > + }, > > +}; > > +builtin_platform_driver(npcm_rc_driver); > > regards > Philipp > > Regards, Tomer --000000000000554ea905963554b8 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Philipp,

Thanks a l= ot for your comments.

On Tue, 29 Oct 2019 at 17:34= , Philipp Zabel <p.zabel@pengu= tronix.de> wrote:
On Mon, 2019-10-28 at 17:54 +0200= , Tomer Maimon wrote:
> Add Nuvoton NPCM BMC reset controller driver.
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> ---
>=C2=A0 drivers/reset/Kconfig=C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A07 +
>=C2=A0 drivers/reset/Makefile=C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A01 +
>=C2=A0 drivers/reset/reset-npcm.c | 275 +++++++++++++++++++++++++++++++= ++++++
>=C2=A0 3 files changed, 283 insertions(+)
>=C2=A0 create mode 100644 drivers/reset/reset-npcm.c
>
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index 7b07281aa0ae..5dbfdf6d717a 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -89,6 +89,13 @@ config RESET_MESON_AUDIO_ARB
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0This enables the reset driver for Aud= io Memory Arbiter of
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Amlogic's A113 based SoCs
>=C2=A0
> +config RESET_NPCM
> +=C2=A0 =C2=A0 =C2=A0bool "NPCM BMC Reset Driver"
> +=C2=A0 =C2=A0 =C2=A0depends on ARCH_NPCM || COMPILE_TEST
> +=C2=A0 =C2=A0 =C2=A0help
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0This enables the reset controller driver f= or Nuvoton NPCM
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0BMC SoCs.
> +

Is there any reason to ever disable this driver when building ARCH_NPCM?
>=C2=A0 config RESET_OXNAS
>=C2=A0 =C2=A0 =C2=A0 =C2=A0bool
>=C2=A0
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index cf60ce526064..00767c03f5f2 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -14,6 +14,7 @@ obj-$(CONFIG_RESET_LANTIQ) +=3D reset-lantiq.o
>=C2=A0 obj-$(CONFIG_RESET_LPC18XX) +=3D reset-lpc18xx.o
>=C2=A0 obj-$(CONFIG_RESET_MESON) +=3D reset-meson.o
>=C2=A0 obj-$(CONFIG_RESET_MESON_AUDIO_ARB) +=3D reset-meson-audio-arb.o=
> +obj-$(CONFIG_RESET_NPCM) +=3D reset-npcm.o
>=C2=A0 obj-$(CONFIG_RESET_OXNAS) +=3D reset-oxnas.o
>=C2=A0 obj-$(CONFIG_RESET_PISTACHIO) +=3D reset-pistachio.o
>=C2=A0 obj-$(CONFIG_RESET_QCOM_AOSS) +=3D reset-qcom-aoss.o
> diff --git a/drivers/reset/reset-npcm.c b/drivers/reset/reset-npcm.c > new file mode 100644
> index 000000000000..ebb3071767e1
> --- /dev/null
> +++ b/drivers/reset/reset-npcm.c
> @@ -0,0 +1,275 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2019 Nuvoton Technology corporation.
> +
> +#include <linux/clk.h>

Please remove unused header includes.

> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/init.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/reboot.h>
> +#include <linux/reset-controller.h>
> +#include <linux/spinlock.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
> +#include <linux/of_address.h>
> +
> +/* NPCM7xx GCR registers */
> +#define NPCM_MDLR_OFFSET=C2=A0 =C2=A0 =C2=A00x7C
> +#define NPCM_MDLR_USBD0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 BIT(9)
> +#define NPCM_MDLR_USBD1=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 BIT(8)
> +#define NPCM_MDLR_USBD2_4=C2=A0 =C2=A0 BIT(21)
> +#define NPCM_MDLR_USBD5_9=C2=A0 =C2=A0 BIT(22)
> +
> +#define NPCM_USB1PHYCTL_OFFSET=C2=A0 =C2=A0 =C2=A0 =C2=A00x140
> +#define NPCM_USB2PHYCTL_OFFSET=C2=A0 =C2=A0 =C2=A0 =C2=A00x144
> +#define NPCM_USBXPHYCTL_RS=C2=A0 =C2=A0BIT(28)
> +
> +/* NPCM7xx Reset registers */
> +#define NPCM_SWRSTR=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0x14
> +#define NPCM_SWRST=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0BIT(2)
> +
> +#define NPCM_IPSRST1=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x20
> +#define NPCM_IPSRST1_USBD1=C2=A0 =C2=A0BIT(5)
> +#define NPCM_IPSRST1_USBD2=C2=A0 =C2=A0BIT(8)
> +#define NPCM_IPSRST1_USBD3=C2=A0 =C2=A0BIT(25)
> +#define NPCM_IPSRST1_USBD4=C2=A0 =C2=A0BIT(22)
> +#define NPCM_IPSRST1_USBD5=C2=A0 =C2=A0BIT(23)
> +#define NPCM_IPSRST1_USBD6=C2=A0 =C2=A0BIT(24)
> +
> +#define NPCM_IPSRST2=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x24
> +#define NPCM_IPSRST2_USB_HOST=C2=A0 =C2=A0 =C2=A0 =C2=A0 BIT(26)
> +
> +#define NPCM_IPSRST3=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x34
> +#define NPCM_IPSRST3_USBD0=C2=A0 =C2=A0BIT(4)
> +#define NPCM_IPSRST3_USBD7=C2=A0 =C2=A0BIT(5)
> +#define NPCM_IPSRST3_USBD8=C2=A0 =C2=A0BIT(6)
> +#define NPCM_IPSRST3_USBD9=C2=A0 =C2=A0BIT(7)
> +#define NPCM_IPSRST3_USBPHY1 BIT(24)
> +#define NPCM_IPSRST3_USBPHY2 BIT(25)
> +
> +#define NPCM_RC_RESETS_PER_REG=C2=A0 =C2=A0 =C2=A0 =C2=A032
> +
> +struct npcm_rc_data {
> +=C2=A0 =C2=A0 =C2=A0struct reset_controller_dev rcdev;
> +=C2=A0 =C2=A0 =C2=A0struct notifier_block restart_nb;
> +=C2=A0 =C2=A0 =C2=A0u32 sw_reset_number;
> +=C2=A0 =C2=A0 =C2=A0void __iomem *base;
> +=C2=A0 =C2=A0 =C2=A0spinlock_t lock;
> +};
> +
> +#define to_rc_data(p) container_of(p, struct npcm_rc_data, rcdev)
> +
> +static int npcm_rc_restart(struct notifier_block *nb, unsigned long m= ode,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 void *cmd)
> +{
> +=C2=A0 =C2=A0 =C2=A0struct npcm_rc_data *rc =3D container_of(nb, stru= ct npcm_rc_data,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 restart_nb);
> +
> +=C2=A0 =C2=A0 =C2=A0writel(NPCM_SWRST << rc->sw_reset_number= , rc->base + NPCM_SWRSTR);
> +=C2=A0 =C2=A0 =C2=A0mdelay(1000);
> +
> +=C2=A0 =C2=A0 =C2=A0pr_emerg("%s: unable to restart system\n&quo= t;, __func__);
> +
> +=C2=A0 =C2=A0 =C2=A0return NOTIFY_DONE;
> +}
> +
> +static int npcm_rc_setclear_reset(struct reset_controller_dev *rcdev,=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned long id, bool set)
> +{
> +=C2=A0 =C2=A0 =C2=A0struct npcm_rc_data *rc =3D to_rc_data(rcdev); > +=C2=A0 =C2=A0 =C2=A0u32 ctrl_offset =3D NPCM_IPSRST1;
> +=C2=A0 =C2=A0 =C2=A0unsigned long flags;
> +=C2=A0 =C2=A0 =C2=A0u32 stat, rst_bit;
> +
> +=C2=A0 =C2=A0 =C2=A0ctrl_offset +=3D (id / NPCM_RC_RESETS_PER_REG) * = sizeof(u32);
> +=C2=A0 =C2=A0 =C2=A0rst_bit =3D 1 << (id % NPCM_RC_RESETS_PER_R= EG);
> +
> +=C2=A0 =C2=A0 =C2=A0spin_lock_irqsave(&rc->lock, flags);
> +=C2=A0 =C2=A0 =C2=A0stat =3D readl(rc->base + ctrl_offset);
> +=C2=A0 =C2=A0 =C2=A0if (set)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0writel(stat | rst_bit= , rc->base + ctrl_offset);
> +=C2=A0 =C2=A0 =C2=A0else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0writel(stat & ~rs= t_bit, rc->base + ctrl_offset);
> +=C2=A0 =C2=A0 =C2=A0spin_unlock_irqrestore(&rc->lock, flags);<= br> > +
> +=C2=A0 =C2=A0 =C2=A0return 0;
> +}
> +
> +static int npcm_rc_assert(struct reset_controller_dev *rcdev, unsigne= d long id)
> +{
> +=C2=A0 =C2=A0 =C2=A0return npcm_rc_setclear_reset(rcdev, id, true); > +}
> +
> +static int npcm_rc_deassert(struct reset_controller_dev *rcdev,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0unsigned long id)
> +{
> +=C2=A0 =C2=A0 =C2=A0return npcm_rc_setclear_reset(rcdev, id, false);<= br> > +}
> +
> +static int npcm_rc_status(struct reset_controller_dev *rcdev,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0unsigned long id)
> +{
> +=C2=A0 =C2=A0 =C2=A0struct npcm_rc_data *rc =3D to_rc_data(rcdev); > +=C2=A0 =C2=A0 =C2=A0u32 bit, ctrl_offset =3D NPCM_IPSRST1;
> +
> +=C2=A0 =C2=A0 =C2=A0ctrl_offset +=3D (id / NPCM_RC_RESETS_PER_REG) * = sizeof(u32);
> +=C2=A0 =C2=A0 =C2=A0bit =3D 1 << (id % NPCM_RC_RESETS_PER_REG);=
> +
> +=C2=A0 =C2=A0 =C2=A0return (readl(rc->base + ctrl_offset) & bi= t);
> +}
> +
> +/*
> + *=C2=A0 The following procedure should be observed in USB PHY, USB d= evice and
> + *=C2=A0 USB host initialization at BMC boot
> + */
> +static int npcm_usb_reset(struct platform_device *pdev, struct npcm_r= c_data *rc)
> +{
> +=C2=A0 =C2=A0 =C2=A0struct device_node *np =3D pdev->dev.of_node;<= br> > +=C2=A0 =C2=A0 =C2=A0u32 mdlr, iprst1, iprst2, iprst3;
> +=C2=A0 =C2=A0 =C2=A0struct regmap *gcr_regmap;
> +=C2=A0 =C2=A0 =C2=A0u32 ipsrst1_bits =3D 0;
> +=C2=A0 =C2=A0 =C2=A0u32 ipsrst2_bits =3D NPCM_IPSRST2_USB_HOST;
> +=C2=A0 =C2=A0 =C2=A0u32 ipsrst3_bits =3D 0;
> +
> +=C2=A0 =C2=A0 =C2=A0if (of_device_is_compatible(np, "nuvoton,npc= m750-reset")) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gcr_regmap =3D syscon= _regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (IS_ERR(gcr_regmap= )) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0dev_err(&pdev->dev, "Failed to find nuvoton,npcm750-gcr\= n");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0return PTR_ERR(gcr_regmap);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0if (!gcr_regmap)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -ENXIO;
> +
> +=C2=A0 =C2=A0 =C2=A0/* checking which USB device is enabled */
> +=C2=A0 =C2=A0 =C2=A0regmap_read(gcr_regmap, NPCM_MDLR_OFFSET, &md= lr);
> +=C2=A0 =C2=A0 =C2=A0if (!(mdlr & NPCM_MDLR_USBD0))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ipsrst3_bits |=3D NPC= M_IPSRST3_USBD0;
> +=C2=A0 =C2=A0 =C2=A0if (!(mdlr & NPCM_MDLR_USBD1))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ipsrst1_bits |=3D NPC= M_IPSRST1_USBD1;
> +=C2=A0 =C2=A0 =C2=A0if (!(mdlr & NPCM_MDLR_USBD2_4))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ipsrst1_bits |=3D (NP= CM_IPSRST1_USBD2 |
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NPCM_IPSRST1_USBD3 |
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NPCM_IPSRST1_USBD4);
> +=C2=A0 =C2=A0 =C2=A0if (!(mdlr & NPCM_MDLR_USBD0)) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ipsrst1_bits |=3D (NP= CM_IPSRST1_USBD5 |
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NPCM_IPSRST1_USBD6);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ipsrst3_bits |=3D (NP= CM_IPSRST3_USBD7 |
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NPCM_IPSRST3_USBD8 |
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NPCM_IPSRST3_USBD9);
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0/* assert reset USB PHY and USB devices */
> +=C2=A0 =C2=A0 =C2=A0iprst1 =3D readl(rc->base + NPCM_IPSRST1);
> +=C2=A0 =C2=A0 =C2=A0iprst2 =3D readl(rc->base + NPCM_IPSRST2);
> +=C2=A0 =C2=A0 =C2=A0iprst3 =3D readl(rc->base + NPCM_IPSRST3);
> +
> +=C2=A0 =C2=A0 =C2=A0iprst1 |=3D ipsrst1_bits;
> +=C2=A0 =C2=A0 =C2=A0iprst2 |=3D ipsrst2_bits;
> +=C2=A0 =C2=A0 =C2=A0iprst3 |=3D (ipsrst3_bits | NPCM_IPSRST3_USBPHY1 = |
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NPCM_IPSRST3_= USBPHY2);
> +
> +=C2=A0 =C2=A0 =C2=A0writel(iprst1, rc->base + NPCM_IPSRST1);
> +=C2=A0 =C2=A0 =C2=A0writel(iprst2, rc->base + NPCM_IPSRST2);
> +=C2=A0 =C2=A0 =C2=A0writel(iprst3, rc->base + NPCM_IPSRST3);
> +
> +=C2=A0 =C2=A0 =C2=A0/* clear USB PHY RS bit */
> +=C2=A0 =C2=A0 =C2=A0regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OF= FSET,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 NPCM_USBXPHYCTL_RS, 0);
> +=C2=A0 =C2=A0 =C2=A0regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OF= FSET,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 NPCM_USBXPHYCTL_RS, 0);
> +
> +=C2=A0 =C2=A0 =C2=A0/* deassert reset USB PHY */
> +=C2=A0 =C2=A0 =C2=A0iprst3 &=3D ~(NPCM_IPSRST3_USBPHY1 | NPCM_IPS= RST3_USBPHY2);
> +=C2=A0 =C2=A0 =C2=A0writel(iprst3, rc->base + NPCM_IPSRST3);
> +
> +=C2=A0 =C2=A0 =C2=A0udelay(50);
> +
> +=C2=A0 =C2=A0 =C2=A0/* set USB PHY RS bit */
> +=C2=A0 =C2=A0 =C2=A0regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OF= FSET,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
> +=C2=A0 =C2=A0 =C2=A0regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OF= FSET,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
> +
> +=C2=A0 =C2=A0 =C2=A0/* deassert reset USB devices*/
> +=C2=A0 =C2=A0 =C2=A0iprst1 &=3D ~ipsrst1_bits;
> +=C2=A0 =C2=A0 =C2=A0iprst2 &=3D ~ipsrst2_bits;
> +=C2=A0 =C2=A0 =C2=A0iprst3 &=3D ~ipsrst3_bits;
> +
> +=C2=A0 =C2=A0 =C2=A0writel(iprst1, rc->base + NPCM_IPSRST1);
> +=C2=A0 =C2=A0 =C2=A0writel(iprst2, rc->base + NPCM_IPSRST2);
> +=C2=A0 =C2=A0 =C2=A0writel(iprst3, rc->base + NPCM_IPSRST3);
> +
> +=C2=A0 =C2=A0 =C2=A0return 0;
> +}

Is there no better place for this, such as USB glue code?
= Sorry, I didn't find a proper place to add it in the USB tree.
=C2=A0
=C2=A0
<= /blockquote>
> +static const struct reset_control_ops npcm_rc_ops =3D {
> +=C2=A0 =C2=A0 =C2=A0.assert=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D npcm= _rc_assert,
> +=C2=A0 =C2=A0 =C2=A0.deassert=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D npcm_rc_d= eassert,
> +=C2=A0 =C2=A0 =C2=A0.status=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D npcm= _rc_status,
> +};
> +
> +static int npcm_rc_probe(struct platform_device *pdev)
> +{
> +=C2=A0 =C2=A0 =C2=A0struct npcm_rc_data *rc;
> +=C2=A0 =C2=A0 =C2=A0struct resource res;
> +=C2=A0 =C2=A0 =C2=A0int ret;
> +
> +=C2=A0 =C2=A0 =C2=A0rc =3D devm_kzalloc(&pdev->dev, sizeof(*rc= ), GFP_KERNEL);
> +=C2=A0 =C2=A0 =C2=A0if (!rc)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -ENOMEM;
> +
> +=C2=A0 =C2=A0 =C2=A0of_address_to_resource(pdev->dev.of_node, 0, &= amp;res);
> +=C2=A0 =C2=A0 =C2=A0rc->base =3D devm_ioremap_resource(&pdev-&= gt;dev, &res);

Can't you just use

=C2=A0 =C2=A0 =C2=A0 =C2=A0 rc->base =3D devm_platform_ioremap_resource(= pdev, 0);

here?

> +=C2=A0 =C2=A0 =C2=A0if (IS_ERR(rc->base))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return PTR_ERR(rc->= ;base);
> +
> +=C2=A0 =C2=A0 =C2=A0spin_lock_init(&rc->lock);
> +
> +=C2=A0 =C2=A0 =C2=A0rc->rcdev.owner =3D THIS_MODULE;
> +=C2=A0 =C2=A0 =C2=A0rc->rcdev.nr_resets =3D resource_size(&res= ) / 4 * BITS_PER_LONG;

That doesn't seem right. With the ctrl_offset =3D NPCM_IPSRST1 in
npcm_rc_setclear_reset that would allow access beyond the configured
register range.

> +=C2=A0 =C2=A0 =C2=A0rc->rcdev.ops =3D &npcm_rc_ops;
> +=C2=A0 =C2=A0 =C2=A0rc->rcdev.of_node =3D pdev->dev.of_node; > +
> +=C2=A0 =C2=A0 =C2=A0platform_set_drvdata(pdev, rc);
> +
> +=C2=A0 =C2=A0 =C2=A0ret =3D reset_controller_register(&rc->rcd= ev);

=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D devm_reset_controller_register(&pde= v->dev, &rc->rcdev);

> +=C2=A0 =C2=A0 =C2=A0if (ret) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev_err(&pdev->= ;dev, "unable to register device\n");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return ret;
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0if (npcm_usb_reset(pdev, rc))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev_warn(&pdev-&g= t;dev, "NPCM USB reset failed, can cause issues with UDC and USB host\= n");
> +
> +=C2=A0 =C2=A0 =C2=A0if (!of_property_read_u32(pdev->dev.of_node, &= quot;nuvoton,sw-reset-number",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&rc->sw_reset_number)) { > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (rc->sw_reset_n= umber && rc->sw_reset_number < 5) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0rc->restart_nb.priority =3D 192,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0rc->restart_nb.notifier_call =3D npcm_rc_restart,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0ret =3D register_restart_handler(&rc->restart_nb);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0if (ret)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev_warn(&pdev->dev, "failed= to register restart handler\n");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0pr_info("NPCM RESET driver probed\n");<= br>
It think this is a bit verbose.

> +=C2=A0 =C2=A0 =C2=A0return ret;
> +}
> +
> +static const struct of_device_id npcm_rc_match[] =3D {
> +=C2=A0 =C2=A0 =C2=A0{ .compatible =3D "nuvoton,npcm750-reset&quo= t; },
> +=C2=A0 =C2=A0 =C2=A0{ }
> +};
> +
> +static struct platform_driver npcm_rc_driver =3D {
> +=C2=A0 =C2=A0 =C2=A0.probe=C2=A0 =3D npcm_rc_probe,
> +=C2=A0 =C2=A0 =C2=A0.driver =3D {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.name=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D "npcm-reset= ",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.of_match_table=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D npcm_rc_match,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.suppress_bind_attrs= =C2=A0 =C2=A0 =3D true,
> +=C2=A0 =C2=A0 =C2=A0},
> +};
> +builtin_platform_driver(npcm_rc_driver);

regards
Philipp


Regards,

Tome= r=C2=A0
--000000000000554ea905963554b8--