From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: nick.hawkins@hpe.com
Cc: verdun@hpe.com, "David Airlie" <airlied@linux.ie>,
"Daniel Vetter" <daniel@ffwll.ch>,
"Rob Herring" <robh+dt@kernel.org>,
"Linus Walleij" <linus.walleij@linaro.org>,
"Bartosz Golaszewski" <brgl@bgdev.pl>,
"Corey Minyard" <minyard@acm.org>,
"Krzysztof Kozlowski" <krzysztof.kozlowski@canonical.com>,
"Miquel Raynal" <miquel.raynal@bootlin.com>,
"Richard Weinberger" <richard@nod.at>,
"Vignesh Raghavendra" <vigneshr@ti.com>,
"David S. Miller" <davem@davemloft.net>,
"Jakub Kicinski" <kuba@kernel.org>,
"Thierry Reding" <thierry.reding@gmail.com>,
"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
"Lee Jones" <lee.jones@linaro.org>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Mark Brown" <broonie@kernel.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Daniel Lezcano" <daniel.lezcano@linaro.org>,
"Amit Kucheria" <amitk@kernel.org>,
"Zhang Rui" <rui.zhang@intel.com>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Wim Van Sebroeck" <wim@linux-watchdog.org>,
"Guenter Roeck" <linux@roeck-us.net>,
"Arnd Bergmann" <arnd@arndb.de>,
"Olof Johansson" <olof@lixom.net>,
soc@kernel.org, "Shawn Guo" <shawnguo@kernel.org>,
"Stanislav Jakubek" <stano.jakubek@gmail.com>,
"Sam Ravnborg" <sam@ravnborg.org>,
"Hao Fang" <fanghao11@huawei.com>,
"Mark Rutland" <mark.rutland@arm.com>,
"Marc Zyngier" <maz@kernel.org>,
"Ard Biesheuvel" <ardb@kernel.org>,
"Anshuman Khandual" <anshuman.khandual@arm.com>,
"Wang Kefeng" <wangkefeng.wang@huawei.com>,
"Lukas Bulwahn" <lukas.bulwahn@gmail.com>,
"Masahiro Yamada" <masahiroy@kernel.org>,
dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
linux-i2c@vger.kernel.org,
openipmi-developer@lists.sourceforge.net,
linux-mtd@lists.infradead.org, netdev@vger.kernel.org,
linux-pwm@vger.kernel.org, linux-serial@vger.kernel.org,
linux-spi@vger.kernel.org, linux-pm@vger.kernel.org,
linux-usb@vger.kernel.org, linux-watchdog@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] HPE BMC GXP SUPPORT
Date: Fri, 4 Feb 2022 12:05:47 +0000 [thread overview]
Message-ID: <Yf0Wm1kOV1Pss9HJ@shell.armlinux.org.uk> (raw)
In-Reply-To: <20220202165315.18282-1-nick.hawkins@hpe.com>
Hi,
On Wed, Feb 02, 2022 at 10:52:50AM -0600, nick.hawkins@hpe.com wrote:
> diff --git a/arch/arm/mach-hpe/Makefile b/arch/arm/mach-hpe/Makefile
> new file mode 100644
> index 000000000000..8b0a91234df4
> --- /dev/null
> +++ b/arch/arm/mach-hpe/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_ARCH_HPE_GXP) += gxp.o
> diff --git a/arch/arm/mach-hpe/gxp.c b/arch/arm/mach-hpe/gxp.c
> new file mode 100644
> index 000000000000..a37838247948
> --- /dev/null
> +++ b/arch/arm/mach-hpe/gxp.c
> @@ -0,0 +1,62 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +
> +#include <linux/init.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/map.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clocksource.h>
It's normal to list all linux/ includes before asm/ includes. Please
rearrange.
> +
> +#define IOP_REGS_PHYS_BASE 0xc0000000
> +#define IOP_REGS_VIRT_BASE 0xf0000000
> +#define IOP_REGS_SIZE (240*SZ_1M)
> +
> +#define IOP_EHCI_USBCMD 0x0efe0010
> +
> +static struct map_desc gxp_io_desc[] __initdata = {
> + {
> + .virtual = (unsigned long)IOP_REGS_VIRT_BASE,
> + .pfn = __phys_to_pfn(IOP_REGS_PHYS_BASE),
> + .length = IOP_REGS_SIZE,
> + .type = MT_DEVICE,
If you keep this, please indent the above four lines by one more tab.
> + },
> +};
> +
> +void __init gxp_map_io(void)
> +{
> + iotable_init(gxp_io_desc, ARRAY_SIZE(gxp_io_desc));
> +}
> +
> +static void __init gxp_dt_init(void)
> +{
> + /*reset EHCI host controller for clear start*/
> + __raw_writel(0x00080002,
> + (void __iomem *)(IOP_REGS_VIRT_BASE + IOP_EHCI_USBCMD));
Please consider making IOP_REGS_VIRT_BASE a 'void __iomem' pointer, it
being a _virtual_ iomem address. This should save you needing repeated
casts except for the initialiser above.
> + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +}
> +
> +static void gxp_restart(enum reboot_mode mode, const char *cmd)
> +{
> + __raw_writel(1, (void __iomem *) IOP_REGS_VIRT_BASE);
> +}
> +
> +static const char * const gxp_board_dt_compat[] = {
> + "HPE,GXP",
> + NULL,
> +};
> +
> +DT_MACHINE_START(GXP_DT, "HPE GXP")
> + .init_machine = gxp_dt_init,
> + .map_io = gxp_map_io,
> + .restart = gxp_restart,
> + .dt_compat = gxp_board_dt_compat,
> +MACHINE_END
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index cfb8ea0df3b1..5916dade7608 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -617,6 +617,14 @@ config CLKSRC_ST_LPC
> Enable this option to use the Low Power controller timer
> as clocksource.
>
> +config GXP_TIMER
> + bool "GXP timer driver"
> + depends on ARCH_HPE
> + default y
> + help
> + Provides a driver for the timer control found on HPE
> + GXP SOCs. This is required for all GXP SOCs.
> +
> config ATCPIT100_TIMER
> bool "ATCPIT100 timer driver"
> depends on NDS32 || COMPILE_TEST
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index fa5f624eadb6..ffca09ec34de 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -89,3 +89,4 @@ obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
> obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o
> obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o
> obj-$(CONFIG_MSC313E_TIMER) += timer-msc313e.o
> +obj-$(CONFIG_GXP_TIMER) += gxp_timer.o
> diff --git a/drivers/clocksource/gxp_timer.c b/drivers/clocksource/gxp_timer.c
> new file mode 100644
> index 000000000000..e3c617036e0d
> --- /dev/null
> +++ b/drivers/clocksource/gxp_timer.c
> @@ -0,0 +1,158 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clockchips.h>
> +#include <linux/clocksource.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqreturn.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/sched_clock.h>
> +
> +#include <asm/irq.h>
Why do you need asm/irq.h ?
> +
> +#define TIMER0_FREQ 1000000
> +#define TIMER1_FREQ 1000000
> +
> +#define MASK_TCS_ENABLE 0x01
> +#define MASK_TCS_PERIOD 0x02
> +#define MASK_TCS_RELOAD 0x04
> +#define MASK_TCS_TC 0x80
> +
> +struct gxp_timer {
> + void __iomem *counter;
> + void __iomem *control;
> + struct clock_event_device evt;
> +};
> +
> +static void __iomem *system_clock __read_mostly;
> +
> +static u64 notrace gxp_sched_read(void)
> +{
> + return readl_relaxed(system_clock);
> +}
> +
> +static int gxp_time_set_next_event(unsigned long event,
> + struct clock_event_device *evt_dev)
> +{
> + struct gxp_timer *timer = container_of(evt_dev, struct gxp_timer, evt);
> + /*clear TC by write 1 and disable timer int and counting*/
> + writeb_relaxed(MASK_TCS_TC, timer->control);
> + /*update counter value*/
> + writel_relaxed(event, timer->counter);
> + /*enable timer counting and int*/
> + writeb_relaxed(MASK_TCS_TC|MASK_TCS_ENABLE, timer->control);
Spaces around the | please. checkpatch probably should've noticed that.
> +
> + return 0;
> +}
> +
> +static irqreturn_t gxp_time_interrupt(int irq, void *dev_id)
> +{
> + struct gxp_timer *timer = dev_id;
> + void (*event_handler)(struct clock_event_device *timer);
> +
> +
One too many blank lines.
> + if (readb_relaxed(timer->control) & MASK_TCS_TC) {
> + writeb_relaxed(MASK_TCS_TC, timer->control);
> +
> + event_handler = READ_ONCE(timer->evt.event_handler);
> + if (event_handler)
> + event_handler(&timer->evt);
> + return IRQ_HANDLED;
> + } else {
> + return IRQ_NONE;
> + }
> +}
> +
> +static int __init gxp_timer_init(struct device_node *node)
> +{
> + void __iomem *base_counter;
> + void __iomem *base_control;
> + u32 freq;
> + int ret, irq;
> + struct gxp_timer *gxp_timer;
> +
> + base_counter = of_iomap(node, 0);
> + if (!base_counter) {
> + pr_err("Can't remap counter registers");
> + return -ENXIO;
> + }
> +
> + base_control = of_iomap(node, 1);
> + if (!base_control) {
> + pr_err("Can't remap control registers");
iounmap base_counter?
> + return -ENXIO;
> + }
> +
> + system_clock = of_iomap(node, 2);
> + if (!system_clock) {
> + pr_err("Can't remap control registers");
iounmap base_counter and base_control?
> + return -ENXIO;
> + }
> +
> + if (of_property_read_u32(node, "clock-frequency", &freq)) {
> + pr_err("Can't read clock-frequency\n");
> + goto err_iounmap;
> + }
> +
> + sched_clock_register(gxp_sched_read, 32, freq);
> + clocksource_mmio_init(system_clock, node->name, freq,
> + 300, 32, clocksource_mmio_readl_up);
We normally align continutation lines in function arguments to the
opening ( thusly:
clocksource_mmio_init(system_clock, node->name, freq,
300, 32, clocksource_mmio_readl_up);
> +
> + irq = irq_of_parse_and_map(node, 0);
> + if (irq <= 0) {
> + ret = -EINVAL;
> + pr_err("GXP Timer Can't parse IRQ %d", irq);
> + goto err_iounmap;
> + }
> +
> + gxp_timer = kzalloc(sizeof(*gxp_timer), GFP_KERNEL);
> + if (!gxp_timer) {
> + ret = -ENOMEM;
> + goto err_iounmap;
> + }
> +
> + gxp_timer->counter = base_counter;
> + gxp_timer->control = base_control;
> + gxp_timer->evt.name = node->name;
> + gxp_timer->evt.rating = 300;
> + gxp_timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
> + gxp_timer->evt.set_next_event = gxp_time_set_next_event;
> + gxp_timer->evt.cpumask = cpumask_of(0);
> +
> + if (request_irq(irq, gxp_time_interrupt, IRQF_TIMER | IRQF_SHARED,
> + node->name, gxp_timer)) {
Again:
if (request_irq(irq, gxp_time_interrupt, IRQF_TIMER | IRQF_SHARED,
node->name, gxp_timer)) {
> + pr_err("%s: request_irq() failed\n", "GXP Timer Tick");
Consider storing the error code from request_irq() and printing it here.
So:
err = request_irq(...);
if (err) {
pr_err("%s: request_irq() failed: %pe\n", "GXP Timer Tick",
ERR_PTR(err));
> + goto err_timer_free;
> + }
> +
> + clockevents_config_and_register(&gxp_timer->evt, TIMER0_FREQ,
> + 0xf, 0xffffffff);
> +
> + pr_info("gxp: system timer (irq = %d)\n", irq);
> + return 0;
> +
> +
> +err_timer_free:
> + kfree(gxp_timer);
> +
> +err_iounmap:
> + iounmap(system_clock);
> + iounmap(base_control);
> + iounmap(base_counter);
> + return ret;
> +}
> +
> +TIMER_OF_DECLARE(gxp, "hpe,gxp-timer", gxp_timer_init);
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
WARNING: multiple messages have this Message-ID (diff)
From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: nick.hawkins@hpe.com
Cc: verdun@hpe.com, "David Airlie" <airlied@linux.ie>,
"Daniel Vetter" <daniel@ffwll.ch>,
"Rob Herring" <robh+dt@kernel.org>,
"Linus Walleij" <linus.walleij@linaro.org>,
"Bartosz Golaszewski" <brgl@bgdev.pl>,
"Corey Minyard" <minyard@acm.org>,
"Krzysztof Kozlowski" <krzysztof.kozlowski@canonical.com>,
"Miquel Raynal" <miquel.raynal@bootlin.com>,
"Richard Weinberger" <richard@nod.at>,
"Vignesh Raghavendra" <vigneshr@ti.com>,
"David S. Miller" <davem@davemloft.net>,
"Jakub Kicinski" <kuba@kernel.org>,
"Thierry Reding" <thierry.reding@gmail.com>,
"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
"Lee Jones" <lee.jones@linaro.org>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Mark Brown" <broonie@kernel.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Daniel Lezcano" <daniel.lezcano@linaro.org>,
"Amit Kucheria" <amitk@kernel.org>,
"Zhang Rui" <rui.zhang@intel.com>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Wim Van Sebroeck" <wim@linux-watchdog.org>,
"Guenter Roeck" <linux@roeck-us.net>,
"Arnd Bergmann" <arnd@arndb.de>,
"Olof Johansson" <olof@lixom.net>,
soc@kernel.org, "Shawn Guo" <shawnguo@kernel.org>,
"Stanislav Jakubek" <stano.jakubek@gmail.com>,
"Sam Ravnborg" <sam@ravnborg.org>,
"Hao Fang" <fanghao11@huawei.com>,
"Mark Rutland" <mark.rutland@arm.com>,
"Marc Zyngier" <maz@kernel.org>,
"Ard Biesheuvel" <ardb@kernel.org>,
"Anshuman Khandual" <anshuman.khandual@arm.com>,
"Wang Kefeng" <wangkefeng.wang@huawei.com>,
"Lukas Bulwahn" <lukas.bulwahn@gmail.com>,
"Masahiro Yamada" <masahiroy@kernel.org>,
dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
linux-i2c@vger.kernel.org,
openipmi-developer@lists.sourceforge.net,
linux-mtd@lists.infradead.org, netdev@vger.kernel.org,
linux-pwm@vger.kernel.org, linux-serial@vger.kernel.org,
linux-spi@vger.kernel.org, linux-pm@vger.kernel.org,
linux-usb@vger.kernel.org, linux-watchdog@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] HPE BMC GXP SUPPORT
Date: Fri, 4 Feb 2022 12:05:47 +0000 [thread overview]
Message-ID: <Yf0Wm1kOV1Pss9HJ@shell.armlinux.org.uk> (raw)
In-Reply-To: <20220202165315.18282-1-nick.hawkins@hpe.com>
Hi,
On Wed, Feb 02, 2022 at 10:52:50AM -0600, nick.hawkins@hpe.com wrote:
> diff --git a/arch/arm/mach-hpe/Makefile b/arch/arm/mach-hpe/Makefile
> new file mode 100644
> index 000000000000..8b0a91234df4
> --- /dev/null
> +++ b/arch/arm/mach-hpe/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_ARCH_HPE_GXP) += gxp.o
> diff --git a/arch/arm/mach-hpe/gxp.c b/arch/arm/mach-hpe/gxp.c
> new file mode 100644
> index 000000000000..a37838247948
> --- /dev/null
> +++ b/arch/arm/mach-hpe/gxp.c
> @@ -0,0 +1,62 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +
> +#include <linux/init.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/map.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clocksource.h>
It's normal to list all linux/ includes before asm/ includes. Please
rearrange.
> +
> +#define IOP_REGS_PHYS_BASE 0xc0000000
> +#define IOP_REGS_VIRT_BASE 0xf0000000
> +#define IOP_REGS_SIZE (240*SZ_1M)
> +
> +#define IOP_EHCI_USBCMD 0x0efe0010
> +
> +static struct map_desc gxp_io_desc[] __initdata = {
> + {
> + .virtual = (unsigned long)IOP_REGS_VIRT_BASE,
> + .pfn = __phys_to_pfn(IOP_REGS_PHYS_BASE),
> + .length = IOP_REGS_SIZE,
> + .type = MT_DEVICE,
If you keep this, please indent the above four lines by one more tab.
> + },
> +};
> +
> +void __init gxp_map_io(void)
> +{
> + iotable_init(gxp_io_desc, ARRAY_SIZE(gxp_io_desc));
> +}
> +
> +static void __init gxp_dt_init(void)
> +{
> + /*reset EHCI host controller for clear start*/
> + __raw_writel(0x00080002,
> + (void __iomem *)(IOP_REGS_VIRT_BASE + IOP_EHCI_USBCMD));
Please consider making IOP_REGS_VIRT_BASE a 'void __iomem' pointer, it
being a _virtual_ iomem address. This should save you needing repeated
casts except for the initialiser above.
> + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +}
> +
> +static void gxp_restart(enum reboot_mode mode, const char *cmd)
> +{
> + __raw_writel(1, (void __iomem *) IOP_REGS_VIRT_BASE);
> +}
> +
> +static const char * const gxp_board_dt_compat[] = {
> + "HPE,GXP",
> + NULL,
> +};
> +
> +DT_MACHINE_START(GXP_DT, "HPE GXP")
> + .init_machine = gxp_dt_init,
> + .map_io = gxp_map_io,
> + .restart = gxp_restart,
> + .dt_compat = gxp_board_dt_compat,
> +MACHINE_END
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index cfb8ea0df3b1..5916dade7608 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -617,6 +617,14 @@ config CLKSRC_ST_LPC
> Enable this option to use the Low Power controller timer
> as clocksource.
>
> +config GXP_TIMER
> + bool "GXP timer driver"
> + depends on ARCH_HPE
> + default y
> + help
> + Provides a driver for the timer control found on HPE
> + GXP SOCs. This is required for all GXP SOCs.
> +
> config ATCPIT100_TIMER
> bool "ATCPIT100 timer driver"
> depends on NDS32 || COMPILE_TEST
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index fa5f624eadb6..ffca09ec34de 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -89,3 +89,4 @@ obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
> obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o
> obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o
> obj-$(CONFIG_MSC313E_TIMER) += timer-msc313e.o
> +obj-$(CONFIG_GXP_TIMER) += gxp_timer.o
> diff --git a/drivers/clocksource/gxp_timer.c b/drivers/clocksource/gxp_timer.c
> new file mode 100644
> index 000000000000..e3c617036e0d
> --- /dev/null
> +++ b/drivers/clocksource/gxp_timer.c
> @@ -0,0 +1,158 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clockchips.h>
> +#include <linux/clocksource.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqreturn.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/sched_clock.h>
> +
> +#include <asm/irq.h>
Why do you need asm/irq.h ?
> +
> +#define TIMER0_FREQ 1000000
> +#define TIMER1_FREQ 1000000
> +
> +#define MASK_TCS_ENABLE 0x01
> +#define MASK_TCS_PERIOD 0x02
> +#define MASK_TCS_RELOAD 0x04
> +#define MASK_TCS_TC 0x80
> +
> +struct gxp_timer {
> + void __iomem *counter;
> + void __iomem *control;
> + struct clock_event_device evt;
> +};
> +
> +static void __iomem *system_clock __read_mostly;
> +
> +static u64 notrace gxp_sched_read(void)
> +{
> + return readl_relaxed(system_clock);
> +}
> +
> +static int gxp_time_set_next_event(unsigned long event,
> + struct clock_event_device *evt_dev)
> +{
> + struct gxp_timer *timer = container_of(evt_dev, struct gxp_timer, evt);
> + /*clear TC by write 1 and disable timer int and counting*/
> + writeb_relaxed(MASK_TCS_TC, timer->control);
> + /*update counter value*/
> + writel_relaxed(event, timer->counter);
> + /*enable timer counting and int*/
> + writeb_relaxed(MASK_TCS_TC|MASK_TCS_ENABLE, timer->control);
Spaces around the | please. checkpatch probably should've noticed that.
> +
> + return 0;
> +}
> +
> +static irqreturn_t gxp_time_interrupt(int irq, void *dev_id)
> +{
> + struct gxp_timer *timer = dev_id;
> + void (*event_handler)(struct clock_event_device *timer);
> +
> +
One too many blank lines.
> + if (readb_relaxed(timer->control) & MASK_TCS_TC) {
> + writeb_relaxed(MASK_TCS_TC, timer->control);
> +
> + event_handler = READ_ONCE(timer->evt.event_handler);
> + if (event_handler)
> + event_handler(&timer->evt);
> + return IRQ_HANDLED;
> + } else {
> + return IRQ_NONE;
> + }
> +}
> +
> +static int __init gxp_timer_init(struct device_node *node)
> +{
> + void __iomem *base_counter;
> + void __iomem *base_control;
> + u32 freq;
> + int ret, irq;
> + struct gxp_timer *gxp_timer;
> +
> + base_counter = of_iomap(node, 0);
> + if (!base_counter) {
> + pr_err("Can't remap counter registers");
> + return -ENXIO;
> + }
> +
> + base_control = of_iomap(node, 1);
> + if (!base_control) {
> + pr_err("Can't remap control registers");
iounmap base_counter?
> + return -ENXIO;
> + }
> +
> + system_clock = of_iomap(node, 2);
> + if (!system_clock) {
> + pr_err("Can't remap control registers");
iounmap base_counter and base_control?
> + return -ENXIO;
> + }
> +
> + if (of_property_read_u32(node, "clock-frequency", &freq)) {
> + pr_err("Can't read clock-frequency\n");
> + goto err_iounmap;
> + }
> +
> + sched_clock_register(gxp_sched_read, 32, freq);
> + clocksource_mmio_init(system_clock, node->name, freq,
> + 300, 32, clocksource_mmio_readl_up);
We normally align continutation lines in function arguments to the
opening ( thusly:
clocksource_mmio_init(system_clock, node->name, freq,
300, 32, clocksource_mmio_readl_up);
> +
> + irq = irq_of_parse_and_map(node, 0);
> + if (irq <= 0) {
> + ret = -EINVAL;
> + pr_err("GXP Timer Can't parse IRQ %d", irq);
> + goto err_iounmap;
> + }
> +
> + gxp_timer = kzalloc(sizeof(*gxp_timer), GFP_KERNEL);
> + if (!gxp_timer) {
> + ret = -ENOMEM;
> + goto err_iounmap;
> + }
> +
> + gxp_timer->counter = base_counter;
> + gxp_timer->control = base_control;
> + gxp_timer->evt.name = node->name;
> + gxp_timer->evt.rating = 300;
> + gxp_timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
> + gxp_timer->evt.set_next_event = gxp_time_set_next_event;
> + gxp_timer->evt.cpumask = cpumask_of(0);
> +
> + if (request_irq(irq, gxp_time_interrupt, IRQF_TIMER | IRQF_SHARED,
> + node->name, gxp_timer)) {
Again:
if (request_irq(irq, gxp_time_interrupt, IRQF_TIMER | IRQF_SHARED,
node->name, gxp_timer)) {
> + pr_err("%s: request_irq() failed\n", "GXP Timer Tick");
Consider storing the error code from request_irq() and printing it here.
So:
err = request_irq(...);
if (err) {
pr_err("%s: request_irq() failed: %pe\n", "GXP Timer Tick",
ERR_PTR(err));
> + goto err_timer_free;
> + }
> +
> + clockevents_config_and_register(&gxp_timer->evt, TIMER0_FREQ,
> + 0xf, 0xffffffff);
> +
> + pr_info("gxp: system timer (irq = %d)\n", irq);
> + return 0;
> +
> +
> +err_timer_free:
> + kfree(gxp_timer);
> +
> +err_iounmap:
> + iounmap(system_clock);
> + iounmap(base_control);
> + iounmap(base_counter);
> + return ret;
> +}
> +
> +TIMER_OF_DECLARE(gxp, "hpe,gxp-timer", gxp_timer_init);
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
WARNING: multiple messages have this Message-ID (diff)
From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: nick.hawkins@hpe.com
Cc: "Mark Rutland" <mark.rutland@arm.com>,
"Wang Kefeng" <wangkefeng.wang@huawei.com>,
"Vignesh Raghavendra" <vigneshr@ti.com>,
"Sam Ravnborg" <sam@ravnborg.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"David Airlie" <airlied@linux.ie>,
verdun@hpe.com, "Amit Kucheria" <amitk@kernel.org>,
dri-devel@lists.freedesktop.org,
"Thierry Reding" <thierry.reding@gmail.com>,
linux-mtd@lists.infradead.org, linux-i2c@vger.kernel.org,
"Miquel Raynal" <miquel.raynal@bootlin.com>,
netdev@vger.kernel.org, "Lee Jones" <lee.jones@linaro.org>,
"Ard Biesheuvel" <ardb@kernel.org>,
"Stanislav Jakubek" <stano.jakubek@gmail.com>,
"Hao Fang" <fanghao11@huawei.com>,
"Arnd Bergmann" <arnd@arndb.de>,
"Krzysztof Kozlowski" <krzysztof.kozlowski@canonical.com>,
"Richard Weinberger" <richard@nod.at>,
"Bartosz Golaszewski" <brgl@bgdev.pl>,
"Daniel Lezcano" <daniel.lezcano@linaro.org>,
linux-pwm@vger.kernel.org, linux-serial@vger.kernel.org,
"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
openipmi-developer@lists.sourceforge.net,
"Jakub Kicinski" <kuba@kernel.org>,
"Zhang Rui" <rui.zhang@intel.com>,
"Masahiro Yamada" <masahiroy@kernel.org>,
"Guenter Roeck" <linux@roeck-us.net>,
devicetree@vger.kernel.org, linux-watchdog@vger.kernel.org,
"Corey Minyard" <minyard@acm.org>,
"Anshuman Khandual" <anshuman.khandual@arm.com>,
linux-gpio@vger.kernel.org, soc@kernel.org,
"Rob Herring" <robh+dt@kernel.org>,
"Lukas Bulwahn" <lukas.bulwahn@gmail.com>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Wim Van Sebroeck" <wim@linux-watchdog.org>,
linux-arm-kernel@lists.infradead.org,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
linux-pm@vger.kernel.org, linux-usb@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org,
"Mark Brown" <broonie@kernel.org>,
"Marc Zyngier" <maz@kernel.org>,
"Shawn Guo" <shawnguo@kernel.org>,
"David S. Miller" <davem@davemloft.net>
Subject: Re: [PATCH] HPE BMC GXP SUPPORT
Date: Fri, 4 Feb 2022 12:05:47 +0000 [thread overview]
Message-ID: <Yf0Wm1kOV1Pss9HJ@shell.armlinux.org.uk> (raw)
In-Reply-To: <20220202165315.18282-1-nick.hawkins@hpe.com>
Hi,
On Wed, Feb 02, 2022 at 10:52:50AM -0600, nick.hawkins@hpe.com wrote:
> diff --git a/arch/arm/mach-hpe/Makefile b/arch/arm/mach-hpe/Makefile
> new file mode 100644
> index 000000000000..8b0a91234df4
> --- /dev/null
> +++ b/arch/arm/mach-hpe/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_ARCH_HPE_GXP) += gxp.o
> diff --git a/arch/arm/mach-hpe/gxp.c b/arch/arm/mach-hpe/gxp.c
> new file mode 100644
> index 000000000000..a37838247948
> --- /dev/null
> +++ b/arch/arm/mach-hpe/gxp.c
> @@ -0,0 +1,62 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +
> +#include <linux/init.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/map.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clocksource.h>
It's normal to list all linux/ includes before asm/ includes. Please
rearrange.
> +
> +#define IOP_REGS_PHYS_BASE 0xc0000000
> +#define IOP_REGS_VIRT_BASE 0xf0000000
> +#define IOP_REGS_SIZE (240*SZ_1M)
> +
> +#define IOP_EHCI_USBCMD 0x0efe0010
> +
> +static struct map_desc gxp_io_desc[] __initdata = {
> + {
> + .virtual = (unsigned long)IOP_REGS_VIRT_BASE,
> + .pfn = __phys_to_pfn(IOP_REGS_PHYS_BASE),
> + .length = IOP_REGS_SIZE,
> + .type = MT_DEVICE,
If you keep this, please indent the above four lines by one more tab.
> + },
> +};
> +
> +void __init gxp_map_io(void)
> +{
> + iotable_init(gxp_io_desc, ARRAY_SIZE(gxp_io_desc));
> +}
> +
> +static void __init gxp_dt_init(void)
> +{
> + /*reset EHCI host controller for clear start*/
> + __raw_writel(0x00080002,
> + (void __iomem *)(IOP_REGS_VIRT_BASE + IOP_EHCI_USBCMD));
Please consider making IOP_REGS_VIRT_BASE a 'void __iomem' pointer, it
being a _virtual_ iomem address. This should save you needing repeated
casts except for the initialiser above.
> + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +}
> +
> +static void gxp_restart(enum reboot_mode mode, const char *cmd)
> +{
> + __raw_writel(1, (void __iomem *) IOP_REGS_VIRT_BASE);
> +}
> +
> +static const char * const gxp_board_dt_compat[] = {
> + "HPE,GXP",
> + NULL,
> +};
> +
> +DT_MACHINE_START(GXP_DT, "HPE GXP")
> + .init_machine = gxp_dt_init,
> + .map_io = gxp_map_io,
> + .restart = gxp_restart,
> + .dt_compat = gxp_board_dt_compat,
> +MACHINE_END
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index cfb8ea0df3b1..5916dade7608 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -617,6 +617,14 @@ config CLKSRC_ST_LPC
> Enable this option to use the Low Power controller timer
> as clocksource.
>
> +config GXP_TIMER
> + bool "GXP timer driver"
> + depends on ARCH_HPE
> + default y
> + help
> + Provides a driver for the timer control found on HPE
> + GXP SOCs. This is required for all GXP SOCs.
> +
> config ATCPIT100_TIMER
> bool "ATCPIT100 timer driver"
> depends on NDS32 || COMPILE_TEST
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index fa5f624eadb6..ffca09ec34de 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -89,3 +89,4 @@ obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
> obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o
> obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o
> obj-$(CONFIG_MSC313E_TIMER) += timer-msc313e.o
> +obj-$(CONFIG_GXP_TIMER) += gxp_timer.o
> diff --git a/drivers/clocksource/gxp_timer.c b/drivers/clocksource/gxp_timer.c
> new file mode 100644
> index 000000000000..e3c617036e0d
> --- /dev/null
> +++ b/drivers/clocksource/gxp_timer.c
> @@ -0,0 +1,158 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clockchips.h>
> +#include <linux/clocksource.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqreturn.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/sched_clock.h>
> +
> +#include <asm/irq.h>
Why do you need asm/irq.h ?
> +
> +#define TIMER0_FREQ 1000000
> +#define TIMER1_FREQ 1000000
> +
> +#define MASK_TCS_ENABLE 0x01
> +#define MASK_TCS_PERIOD 0x02
> +#define MASK_TCS_RELOAD 0x04
> +#define MASK_TCS_TC 0x80
> +
> +struct gxp_timer {
> + void __iomem *counter;
> + void __iomem *control;
> + struct clock_event_device evt;
> +};
> +
> +static void __iomem *system_clock __read_mostly;
> +
> +static u64 notrace gxp_sched_read(void)
> +{
> + return readl_relaxed(system_clock);
> +}
> +
> +static int gxp_time_set_next_event(unsigned long event,
> + struct clock_event_device *evt_dev)
> +{
> + struct gxp_timer *timer = container_of(evt_dev, struct gxp_timer, evt);
> + /*clear TC by write 1 and disable timer int and counting*/
> + writeb_relaxed(MASK_TCS_TC, timer->control);
> + /*update counter value*/
> + writel_relaxed(event, timer->counter);
> + /*enable timer counting and int*/
> + writeb_relaxed(MASK_TCS_TC|MASK_TCS_ENABLE, timer->control);
Spaces around the | please. checkpatch probably should've noticed that.
> +
> + return 0;
> +}
> +
> +static irqreturn_t gxp_time_interrupt(int irq, void *dev_id)
> +{
> + struct gxp_timer *timer = dev_id;
> + void (*event_handler)(struct clock_event_device *timer);
> +
> +
One too many blank lines.
> + if (readb_relaxed(timer->control) & MASK_TCS_TC) {
> + writeb_relaxed(MASK_TCS_TC, timer->control);
> +
> + event_handler = READ_ONCE(timer->evt.event_handler);
> + if (event_handler)
> + event_handler(&timer->evt);
> + return IRQ_HANDLED;
> + } else {
> + return IRQ_NONE;
> + }
> +}
> +
> +static int __init gxp_timer_init(struct device_node *node)
> +{
> + void __iomem *base_counter;
> + void __iomem *base_control;
> + u32 freq;
> + int ret, irq;
> + struct gxp_timer *gxp_timer;
> +
> + base_counter = of_iomap(node, 0);
> + if (!base_counter) {
> + pr_err("Can't remap counter registers");
> + return -ENXIO;
> + }
> +
> + base_control = of_iomap(node, 1);
> + if (!base_control) {
> + pr_err("Can't remap control registers");
iounmap base_counter?
> + return -ENXIO;
> + }
> +
> + system_clock = of_iomap(node, 2);
> + if (!system_clock) {
> + pr_err("Can't remap control registers");
iounmap base_counter and base_control?
> + return -ENXIO;
> + }
> +
> + if (of_property_read_u32(node, "clock-frequency", &freq)) {
> + pr_err("Can't read clock-frequency\n");
> + goto err_iounmap;
> + }
> +
> + sched_clock_register(gxp_sched_read, 32, freq);
> + clocksource_mmio_init(system_clock, node->name, freq,
> + 300, 32, clocksource_mmio_readl_up);
We normally align continutation lines in function arguments to the
opening ( thusly:
clocksource_mmio_init(system_clock, node->name, freq,
300, 32, clocksource_mmio_readl_up);
> +
> + irq = irq_of_parse_and_map(node, 0);
> + if (irq <= 0) {
> + ret = -EINVAL;
> + pr_err("GXP Timer Can't parse IRQ %d", irq);
> + goto err_iounmap;
> + }
> +
> + gxp_timer = kzalloc(sizeof(*gxp_timer), GFP_KERNEL);
> + if (!gxp_timer) {
> + ret = -ENOMEM;
> + goto err_iounmap;
> + }
> +
> + gxp_timer->counter = base_counter;
> + gxp_timer->control = base_control;
> + gxp_timer->evt.name = node->name;
> + gxp_timer->evt.rating = 300;
> + gxp_timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
> + gxp_timer->evt.set_next_event = gxp_time_set_next_event;
> + gxp_timer->evt.cpumask = cpumask_of(0);
> +
> + if (request_irq(irq, gxp_time_interrupt, IRQF_TIMER | IRQF_SHARED,
> + node->name, gxp_timer)) {
Again:
if (request_irq(irq, gxp_time_interrupt, IRQF_TIMER | IRQF_SHARED,
node->name, gxp_timer)) {
> + pr_err("%s: request_irq() failed\n", "GXP Timer Tick");
Consider storing the error code from request_irq() and printing it here.
So:
err = request_irq(...);
if (err) {
pr_err("%s: request_irq() failed: %pe\n", "GXP Timer Tick",
ERR_PTR(err));
> + goto err_timer_free;
> + }
> +
> + clockevents_config_and_register(&gxp_timer->evt, TIMER0_FREQ,
> + 0xf, 0xffffffff);
> +
> + pr_info("gxp: system timer (irq = %d)\n", irq);
> + return 0;
> +
> +
> +err_timer_free:
> + kfree(gxp_timer);
> +
> +err_iounmap:
> + iounmap(system_clock);
> + iounmap(base_control);
> + iounmap(base_counter);
> + return ret;
> +}
> +
> +TIMER_OF_DECLARE(gxp, "hpe,gxp-timer", gxp_timer_init);
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
next prev parent reply other threads:[~2022-02-04 12:07 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-02 16:52 [PATCH] HPE BMC GXP SUPPORT nick.hawkins
2022-02-02 16:52 ` nick.hawkins
2022-02-02 16:52 ` nick.hawkins
2022-02-02 17:56 ` Corey Minyard
2022-02-02 17:56 ` Corey Minyard
2022-02-02 17:56 ` Corey Minyard
2022-02-02 18:14 ` Verdun, Jean-Marie
2022-02-02 18:14 ` Verdun, Jean-Marie
2022-02-02 18:14 ` Verdun, Jean-Marie
2022-02-02 21:21 ` Arnd Bergmann
2022-02-02 21:21 ` Arnd Bergmann
2022-02-02 21:21 ` Arnd Bergmann
2022-02-02 22:10 ` [Openipmi-developer] " Corey Minyard
2022-02-02 22:10 ` Corey Minyard
2022-02-02 22:10 ` Corey Minyard
2022-02-02 18:14 ` Sam Ravnborg
2022-02-02 18:14 ` Sam Ravnborg
2022-02-02 18:14 ` Sam Ravnborg
2022-02-03 1:10 ` Andrew Lunn
2022-02-03 1:10 ` Andrew Lunn
2022-02-03 1:10 ` Andrew Lunn
2022-02-03 7:41 ` Krzysztof Kozlowski
2022-02-03 7:41 ` Krzysztof Kozlowski
2022-02-03 7:41 ` Krzysztof Kozlowski
2022-02-03 14:29 ` Rob Herring
2022-02-03 14:29 ` Rob Herring
2022-02-03 14:29 ` Rob Herring
2022-02-03 14:55 ` Krzysztof Kozlowski
2022-02-03 14:55 ` Krzysztof Kozlowski
2022-02-03 14:55 ` Krzysztof Kozlowski
2022-02-03 17:07 ` Verdun, Jean-Marie
2022-02-03 17:07 ` Verdun, Jean-Marie
2022-02-03 17:07 ` Verdun, Jean-Marie
2022-02-04 8:52 ` Krzysztof Kozlowski
2022-02-04 8:52 ` Krzysztof Kozlowski
2022-02-04 8:52 ` Krzysztof Kozlowski
2022-02-04 12:05 ` Russell King (Oracle) [this message]
2022-02-04 12:05 ` Russell King (Oracle)
2022-02-04 12:05 ` Russell King (Oracle)
2022-02-04 12:18 ` Joe Perches
2022-02-04 12:18 ` Joe Perches
2022-02-04 12:18 ` Joe Perches
2022-02-04 12:31 ` Russell King (Oracle)
2022-02-04 12:31 ` Russell King (Oracle)
2022-02-04 12:31 ` Russell King (Oracle)
2022-02-04 14:01 ` Joe Perches
2022-02-04 14:01 ` Joe Perches
2022-02-04 14:01 ` Joe Perches
2022-02-04 13:32 ` Andrew Lunn
2022-02-04 13:32 ` Andrew Lunn
2022-02-04 13:32 ` Andrew Lunn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Yf0Wm1kOV1Pss9HJ@shell.armlinux.org.uk \
--to=linux@armlinux.org.uk \
--cc=airlied@linux.ie \
--cc=amitk@kernel.org \
--cc=anshuman.khandual@arm.com \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=brgl@bgdev.pl \
--cc=broonie@kernel.org \
--cc=daniel.lezcano@linaro.org \
--cc=daniel@ffwll.ch \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=fanghao11@huawei.com \
--cc=gregkh@linuxfoundation.org \
--cc=krzysztof.kozlowski@canonical.com \
--cc=kuba@kernel.org \
--cc=lee.jones@linaro.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=linux-spi@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=linux-watchdog@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=lukas.bulwahn@gmail.com \
--cc=mark.rutland@arm.com \
--cc=masahiroy@kernel.org \
--cc=maz@kernel.org \
--cc=minyard@acm.org \
--cc=miquel.raynal@bootlin.com \
--cc=netdev@vger.kernel.org \
--cc=nick.hawkins@hpe.com \
--cc=olof@lixom.net \
--cc=openipmi-developer@lists.sourceforge.net \
--cc=rafael@kernel.org \
--cc=richard@nod.at \
--cc=robh+dt@kernel.org \
--cc=rui.zhang@intel.com \
--cc=sam@ravnborg.org \
--cc=shawnguo@kernel.org \
--cc=soc@kernel.org \
--cc=stano.jakubek@gmail.com \
--cc=tglx@linutronix.de \
--cc=thierry.reding@gmail.com \
--cc=u.kleine-koenig@pengutronix.de \
--cc=verdun@hpe.com \
--cc=vigneshr@ti.com \
--cc=wangkefeng.wang@huawei.com \
--cc=wim@linux-watchdog.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.