diff mbox

[v3,1/8] hw/arm/virt: Add a GPIO controller

Message ID 1447680189-2128-2-git-send-email-shannon.zhao@linaro.org
State Superseded
Headers show

Commit Message

Shannon Zhao Nov. 16, 2015, 1:23 p.m. UTC
From: Shannon Zhao <shannon.zhao@linaro.org>


ACPI 5.0 supports GPIO-signaled ACPI Events. This can be used for
powerdown, hotplug evnets. Add a GPIO controller in machine virt,
to support powerdown, maybe can be used for cpu hotplug. And
here we use pl061.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>

Reviewed-by: Wei Huang <wei@redhat.com>

Tested-by: Wei Huang <wei@redhat.com>

---
 hw/arm/virt.c         | 30 ++++++++++++++++++++++++++++++
 include/hw/arm/virt.h |  1 +
 2 files changed, 31 insertions(+)

-- 
2.1.0

Comments

Peter Maydell Dec. 1, 2015, 1:49 p.m. UTC | #1
On 1 December 2015 at 13:21, Igor Mammedov <imammedo@redhat.com> wrote:
> On Mon, 16 Nov 2015 21:23:02 +0800

> shannon.zhao@linaro.org wrote:

>

>> From: Shannon Zhao <shannon.zhao@linaro.org>

>>

>> ACPI 5.0 supports GPIO-signaled ACPI Events. This can be used for

>> powerdown, hotplug evnets. Add a GPIO controller in machine virt,

> s/evnets/events/

>

>> to support powerdown, maybe can be used for cpu hotplug. And

>> here we use pl061.

>>



> vvvvv

>> +    nodename = g_strdup_printf("/pl061@%" PRIx64, base);

>> +    qemu_fdt_add_subnode(vbi->fdt, nodename);

>> +    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",

>> +                                 2, base, 2, size);

>> +    qemu_fdt_setprop(vbi->fdt, nodename, "compatible", compat, sizeof(compat));

>> +    qemu_fdt_setprop_cell(vbi->fdt, nodename, "#gpio-cells", 2);

>> +    qemu_fdt_setprop(vbi->fdt, nodename, "gpio-controller", NULL, 0);

>> +    qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",

>> +                           GIC_FDT_IRQ_TYPE_SPI, irq,

>> +                           GIC_FDT_IRQ_FLAGS_LEVEL_HI);

>> +    qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);

>> +    qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");

>> +

>> +    g_free(nodename);

> could you split off DT parts into a separate patch pls.


I think they belong in this patch. We should never add a device
to the 'virt' board without having the DT binding for it too.

thanks
-- PMM
Shannon Zhao Dec. 1, 2015, 3:25 p.m. UTC | #2
On 2015/12/1 22:48, Pavel Fedin wrote:
>   Hello!

>

>>>> ACPI 5.0 supports GPIO-signaled ACPI Events. This can be used for

>>>> powerdown, hotplug evnets. Add a GPIO controller in machine virt,

>>> s/evnets/events/

>>>

>>>> to support powerdown, maybe can be used for cpu hotplug. And

>>>> here we use pl061.

>

>   Sorry for late jumping in, but this was the first message Cc'ed to me.

>   With these devices virt machine IMHO goes farther and farther away from its initial goal: be a minimalistic virtual box, which ensures maximum possible compatibility and portability.

>   virt machine already supports poweroff using PSCI interface. Why we need to add more hardware? Can't ACPI deal with PSCI?

Hi Pavel,

IIUC, the poweroff using PSCI interface is the guest *internal* 
poweroff, that is you type "poweroff" inside guest. But this patch set 
is going to introduce a way to support *external* poweroff, like the 
power button on our desktop. This is something like you push a button to 
shutdown the guest.

>   To tell the truth, i dislike ACPI + EFI thing at all. It looks like cramming PC-oriented firmware into architecture for which it was never meant to be written. Too much overcomplications, we drop already established things and reinvent a (triangular) wheel, but what's the purpose? Is it being done only because vendors want obscure proprietary firmware instead of old good u-boot?

>

> Kind regards,

> Pavel Fedin

> Expert Engineer

> Samsung Electronics Research center Russia

>


-- 
Shannon
diff mbox

Patch

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 9c6792c..7977e3c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -120,6 +120,7 @@  static const MemMapEntry a15memmap[] = {
     [VIRT_UART] =               { 0x09000000, 0x00001000 },
     [VIRT_RTC] =                { 0x09010000, 0x00001000 },
     [VIRT_FW_CFG] =             { 0x09020000, 0x00000018 },
+    [VIRT_GPIO] =               { 0x09030000, 0x00001000 },
     [VIRT_MMIO] =               { 0x0a000000, 0x00000200 },
     /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
     [VIRT_PLATFORM_BUS] =       { 0x0c000000, 0x02000000 },
@@ -135,6 +136,7 @@  static const int a15irqmap[] = {
     [VIRT_UART] = 1,
     [VIRT_RTC] = 2,
     [VIRT_PCIE] = 3, /* ... to 6 */
+    [VIRT_GPIO] = 7,
     [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
     [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
     [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
@@ -538,6 +540,32 @@  static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
     g_free(nodename);
 }
 
+static void create_gpio(const VirtBoardInfo *vbi, qemu_irq *pic)
+{
+    char *nodename;
+    hwaddr base = vbi->memmap[VIRT_GPIO].base;
+    hwaddr size = vbi->memmap[VIRT_GPIO].size;
+    int irq = vbi->irqmap[VIRT_GPIO];
+    const char compat[] = "arm,pl061\0arm,primecell";
+
+    sysbus_create_simple("pl061", base, pic[irq]);
+
+    nodename = g_strdup_printf("/pl061@%" PRIx64, base);
+    qemu_fdt_add_subnode(vbi->fdt, nodename);
+    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
+                                 2, base, 2, size);
+    qemu_fdt_setprop(vbi->fdt, nodename, "compatible", compat, sizeof(compat));
+    qemu_fdt_setprop_cell(vbi->fdt, nodename, "#gpio-cells", 2);
+    qemu_fdt_setprop(vbi->fdt, nodename, "gpio-controller", NULL, 0);
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
+                           GIC_FDT_IRQ_TYPE_SPI, irq,
+                           GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+    qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
+    qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
+
+    g_free(nodename);
+}
+
 static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
 {
     int i;
@@ -1041,6 +1069,8 @@  static void machvirt_init(MachineState *machine)
 
     create_pcie(vbi, pic, vms->highmem);
 
+    create_gpio(vbi, pic);
+
     /* Create mmio transports, so the user can create virtio backends
      * (which will be automatically plugged in to the transports). If
      * no backend is created the transport will just sit harmlessly idle.
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index f464586..925faa7 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -59,6 +59,7 @@  enum {
     VIRT_PCIE_ECAM,
     VIRT_PLATFORM_BUS,
     VIRT_PCIE_MMIO_HIGH,
+    VIRT_GPIO,
 };
 
 typedef struct MemMapEntry {