From patchwork Thu Apr 23 09:01:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 207032 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72D05C2BA19 for ; Thu, 23 Apr 2020 09:06:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5ACED2075A for ; Thu, 23 Apr 2020 09:06:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726375AbgDWJG0 (ORCPT ); Thu, 23 Apr 2020 05:06:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726335AbgDWJGZ (ORCPT ); Thu, 23 Apr 2020 05:06:25 -0400 Received: from xavier.telenet-ops.be (xavier.telenet-ops.be [IPv6:2a02:1800:120:4::f00:14]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 785C0C08ED7D for ; Thu, 23 Apr 2020 02:06:25 -0700 (PDT) Received: from ramsan ([IPv6:2a02:1810:ac12:ed60:89cc:efc7:85ce:4669]) by xavier.telenet-ops.be with bizsmtp id W91L2200P1RvcFS0191LFD; Thu, 23 Apr 2020 11:01:21 +0200 Received: from rox.of.borg ([192.168.97.57]) by ramsan with esmtp (Exim 4.90_1) (envelope-from ) id 1jRXjU-0006k9-Al; Thu, 23 Apr 2020 11:01:20 +0200 Received: from geert by rox.of.borg with local (Exim 4.90_1) (envelope-from ) id 1jRXjU-0002vW-9V; Thu, 23 Apr 2020 11:01:20 +0200 From: Geert Uytterhoeven To: Peter Maydell , Paolo Bonzini , Alexander Graf , Linus Walleij , Bartosz Golaszewski , Magnus Damm Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, linux-gpio@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH QEMU v2 2/5] ARM: PL061: Extract pl061_create_fdt() Date: Thu, 23 Apr 2020 11:01:15 +0200 Message-Id: <20200423090118.11199-3-geert+renesas@glider.be> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200423090118.11199-1-geert+renesas@glider.be> References: <20200423090118.11199-1-geert+renesas@glider.be> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Move the code to create the DT node for the PL061 GPIO controller from hw/arm/virt.c to the PL061 driver, so it can be reused. While at it, make the created node comply with the PL061 Device Tree bindings: - Use generic node name "gpio" instead of "pl061", - Add missing "#interrupt-cells" and "interrupt-controller" properties. Signed-off-by: Geert Uytterhoeven --- v2: - New. --- hw/arm/virt.c | 20 +++----------------- hw/gpio/pl061.c | 42 +++++++++++++++++++++++++++++++++++++++++ include/hw/gpio/pl061.h | 7 +++++++ 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 7dc96abf72cf2b9a..c88c8850fbe00bdb 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -40,6 +40,7 @@ #include "hw/arm/primecell.h" #include "hw/arm/virt.h" #include "hw/block/flash.h" +#include "hw/gpio/pl061.h" #include "hw/vfio/vfio-calxeda-xgmac.h" #include "hw/vfio/vfio-amd-xgbe.h" #include "hw/display/ramfb.h" @@ -807,30 +808,16 @@ static void virt_powerdown_req(Notifier *n, void *opaque) static void create_gpio(const VirtMachineState *vms) { - char *nodename; DeviceState *pl061_dev; hwaddr base = vms->memmap[VIRT_GPIO].base; hwaddr size = vms->memmap[VIRT_GPIO].size; int irq = vms->irqmap[VIRT_GPIO]; - const char compat[] = "arm,pl061\0arm,primecell"; pl061_dev = sysbus_create_simple("pl061", base, qdev_get_gpio_in(vms->gic, irq)); - uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt); - nodename = g_strdup_printf("/pl061@%" PRIx64, base); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", - 2, base, 2, size); - qemu_fdt_setprop(vms->fdt, nodename, "compatible", compat, sizeof(compat)); - qemu_fdt_setprop_cell(vms->fdt, nodename, "#gpio-cells", 2); - qemu_fdt_setprop(vms->fdt, nodename, "gpio-controller", NULL, 0); - qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", - GIC_FDT_IRQ_TYPE_SPI, irq, - GIC_FDT_IRQ_FLAGS_LEVEL_HI); - qemu_fdt_setprop_cell(vms->fdt, nodename, "clocks", vms->clock_phandle); - qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk"); - qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle); + uint32_t phandle = pl061_create_fdt(vms->fdt, "", 2, base, size, irq, + vms->clock_phandle); gpio_key_dev = sysbus_create_simple("gpio-key", -1, qdev_get_gpio_in(pl061_dev, 3)); @@ -846,7 +833,6 @@ static void create_gpio(const VirtMachineState *vms) KEY_POWER); qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff", "gpios", phandle, 3, 0); - g_free(nodename); } static void create_virtio_devices(const VirtMachineState *vms) diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c index e776c09e474216ef..74ba733a8a5e8ca5 100644 --- a/hw/gpio/pl061.c +++ b/hw/gpio/pl061.c @@ -9,12 +9,14 @@ */ #include "qemu/osdep.h" +#include "hw/arm/fdt.h" #include "hw/gpio/pl061.h" #include "hw/irq.h" #include "hw/sysbus.h" #include "migration/vmstate.h" #include "qemu/log.h" #include "qemu/module.h" +#include "sysemu/device_tree.h" //#define DEBUG_PL061 1 @@ -397,3 +399,43 @@ static void pl061_register_types(void) } type_init(pl061_register_types) + +/* + * pl061_create_fdt: Create a DT node for a PL061 GPIO controller + * @fdt: device tree blob + * @parent: name of the parent node + * @n_cells: value of #address-cells and #size-cells + * @base: base address of the controller's register block + * @size: size of the controller's register block + * @irq: interrupt number + * @clock: phandle of the apb-pclk clock + * + * Return value: a phandle referring to the created DT node. + * + * See the DT Binding Documentation in the Linux kernel source tree: + * Documentation/devicetree/bindings/gpio/pl061-gpio.yaml + */ +uint32_t pl061_create_fdt(void *fdt, const char *parent, unsigned int n_cells, + hwaddr base, hwaddr size, int irq, uint32_t clock) +{ + char *nodename = g_strdup_printf("%s/gpio@%" PRIx64, parent, base); + static const char compat[] = "arm,pl061\0arm,primecell"; + uint32_t phandle = qemu_fdt_alloc_phandle(fdt); + + qemu_fdt_add_subnode(fdt, nodename); + qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", n_cells, base, n_cells, + size); + qemu_fdt_setprop(fdt, nodename, "compatible", compat, sizeof(compat)); + qemu_fdt_setprop_cell(fdt, nodename, "#gpio-cells", 2); + qemu_fdt_setprop(fdt, nodename, "gpio-controller", NULL, 0); + qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2); + qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cells(fdt, nodename, "interrupts", GIC_FDT_IRQ_TYPE_SPI, + irq, GIC_FDT_IRQ_FLAGS_LEVEL_HI); + qemu_fdt_setprop_cell(fdt, nodename, "clocks", clock); + qemu_fdt_setprop_string(fdt, nodename, "clock-names", "apb_pclk"); + qemu_fdt_setprop_cell(fdt, nodename, "phandle", phandle); + g_free(nodename); + + return phandle; +} diff --git a/include/hw/gpio/pl061.h b/include/hw/gpio/pl061.h index 78cc40c52679dc4e..f98c6e24e0e68662 100644 --- a/include/hw/gpio/pl061.h +++ b/include/hw/gpio/pl061.h @@ -11,6 +11,13 @@ #ifndef PL061_GPIO_H #define PL061_GPIO_H +#include + +#include "exec/hwaddr.h" + #define TYPE_PL061 "pl061" +uint32_t pl061_create_fdt(void *fdt, const char *parent, unsigned int n_cells, + hwaddr addr, hwaddr size, int irq, uint32_t clock); + #endif /* PL061_GPIO_H */ From patchwork Thu Apr 23 09:01:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 207030 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5097EC55196 for ; Thu, 23 Apr 2020 09:06:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 360C22075A for ; Thu, 23 Apr 2020 09:06:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726343AbgDWJG0 (ORCPT ); Thu, 23 Apr 2020 05:06:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726145AbgDWJGZ (ORCPT ); Thu, 23 Apr 2020 05:06:25 -0400 Received: from xavier.telenet-ops.be (xavier.telenet-ops.be [IPv6:2a02:1800:120:4::f00:14]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7021FC08E934 for ; Thu, 23 Apr 2020 02:06:25 -0700 (PDT) Received: from ramsan ([IPv6:2a02:1810:ac12:ed60:89cc:efc7:85ce:4669]) by xavier.telenet-ops.be with bizsmtp id W91L2200R1RvcFS0191LFF; Thu, 23 Apr 2020 11:01:21 +0200 Received: from rox.of.borg ([192.168.97.57]) by ramsan with esmtp (Exim 4.90_1) (envelope-from ) id 1jRXjU-0006kH-Bt; Thu, 23 Apr 2020 11:01:20 +0200 Received: from geert by rox.of.borg with local (Exim 4.90_1) (envelope-from ) id 1jRXjU-0002vd-Aq; Thu, 23 Apr 2020 11:01:20 +0200 From: Geert Uytterhoeven To: Peter Maydell , Paolo Bonzini , Alexander Graf , Linus Walleij , Bartosz Golaszewski , Magnus Damm Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, linux-gpio@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH QEMU v2 4/5] ARM: PL061: Add gpiodev support Date: Thu, 23 Apr 2020 11:01:17 +0200 Message-Id: <20200423090118.11199-5-geert+renesas@glider.be> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200423090118.11199-1-geert+renesas@glider.be> References: <20200423090118.11199-1-geert+renesas@glider.be> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Make the PL061 GPIO controller user-creatable, and allow the user to tie a newly created instance to a gpiochip on the host. To create a new GPIO controller, the QEMU command line must be augmented with: -device pl061,host= with the name or label of the gpiochip on the host. Signed-off-by: Geert Uytterhoeven --- v2: - New. --- hw/gpio/pl061.c | 35 +++++++++++++++++++++++++++++++++++ qemu-options.hx | 9 +++++++++ 2 files changed, 44 insertions(+) diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c index 74ba733a8a5e8ca5..98204f9a586ae8c8 100644 --- a/hw/gpio/pl061.c +++ b/hw/gpio/pl061.c @@ -12,11 +12,14 @@ #include "hw/arm/fdt.h" #include "hw/gpio/pl061.h" #include "hw/irq.h" +#include "hw/qdev-properties.h" #include "hw/sysbus.h" #include "migration/vmstate.h" +#include "qapi/error.h" #include "qemu/log.h" #include "qemu/module.h" #include "sysemu/device_tree.h" +#include "sysemu/gpiodev.h" //#define DEBUG_PL061 1 @@ -41,6 +44,9 @@ static const uint8_t pl061_id_luminary[12] = typedef struct PL061State { SysBusDevice parent_obj; +#ifdef CONFIG_GPIODEV + char *host; +#endif MemoryRegion iomem; uint32_t locked; uint32_t data; @@ -370,10 +376,39 @@ static void pl061_init(Object *obj) qdev_init_gpio_out(dev, s->out, 8); } +#ifdef CONFIG_GPIODEV +static Property pl061_properties[] = { + DEFINE_PROP_STRING("host", PL061State, host), + DEFINE_PROP_END_OF_LIST(), +}; + +static void pl061_realize(DeviceState *dev, Error **errp) +{ + PL061State *s = PL061(dev); + + if (!dev->opts) { + /* Not created by user */ + return; + } + + if (!s->host) { + error_setg(errp, "'host' property is required"); + return; + } + + qemu_gpiodev_add(dev, s->host, 8, errp); +} +#endif /* CONFIG_GPIODEV */ + static void pl061_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); +#ifdef CONFIG_GPIODEV + device_class_set_props(dc, pl061_properties); + dc->realize = pl061_realize; + dc->user_creatable = true; +#endif dc->vmsd = &vmstate_pl061; dc->reset = &pl061_reset; } diff --git a/qemu-options.hx b/qemu-options.hx index 292d4e7c0cef6097..182de7fb63923b38 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -875,6 +875,15 @@ SRST ``-device isa-ipmi-bt,bmc=id[,ioport=val][,irq=val]`` Like the KCS interface, but defines a BT interface. The default port is 0xe4 and the default interrupt is 5. + +#ifdef CONFIG_GPIODEV +``-device pl061,host=gpiochip`` + Add a PL061 GPIO controller, and map its virtual GPIO lines to a GPIO + controller on the host. + + ``host=gpiochip`` + The name or label of the GPIO controller on the host. +#endif ERST DEF("name", HAS_ARG, QEMU_OPTION_name,