From 411a93efef1d409500ebd5cf3c7222c0f1c6ff4d Mon Sep 17 00:00:00 2001 From: kettenis Date: Fri, 5 Aug 2016 19:00:25 +0000 Subject: [PATCH] Switch the sunxi platform over to the new interrupt establish API. This involves turning sxiahci(4) into a real driver that dynamically attaches. ehci(4) now also attaches dynamically. ok jsg@, patrick@ --- sys/arch/armv7/conf/GENERIC | 8 ++--- sys/arch/armv7/conf/RAMDISK | 8 ++--- sys/arch/armv7/sunxi/a1xintc.c | 50 +++++++++++++++++++++++++------- sys/arch/armv7/sunxi/files.sunxi | 9 +++--- sys/arch/armv7/sunxi/sunxi.c | 22 +------------- sys/arch/armv7/sunxi/sxiahci.c | 40 ++++++++++++++++++------- sys/arch/armv7/sunxi/sxie.c | 13 +++------ sys/arch/armv7/sunxi/sxiehci.c | 42 ++++++++++++++++++--------- sys/arch/armv7/sunxi/sxiuart.c | 13 +++------ sys/conf/files | 4 +-- 10 files changed, 121 insertions(+), 88 deletions(-) diff --git a/sys/arch/armv7/conf/GENERIC b/sys/arch/armv7/conf/GENERIC index da2fbeb3a51..28042e808f0 100644 --- a/sys/arch/armv7/conf/GENERIC +++ b/sys/arch/armv7/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.32 2016/08/04 15:52:52 kettenis Exp $ +# $OpenBSD: GENERIC,v 1.33 2016/08/05 19:00:25 kettenis Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -85,7 +85,7 @@ usb* at ehci? sunxi0 at mainbus? # Sunxi on-chip devices -a1xintc* at sunxi? # A1x interrupt controller +a1xintc* at fdt? # A1x interrupt controller sxipio* at sunxi? # GPIO pins for leds & PHYs gpio* at sxipio? sxiccmu* at sunxi? # Clock Control Module/Unit @@ -94,8 +94,8 @@ sxidog* at sunxi? # watchdog timer sxirtc* at sunxi? # Real Time Clock sxiuart* at fdt? # onboard UARTs sxie* at fdt? -ahci* at sunxi? # AHCI/SATA (shim) -ehci* at sunxi? # EHCI (shim) +sxiahci* at fdt? # AHCI/SATA +ehci* at fdt? # EHCI (shim) usb* at ehci? #flags 0x1 #ohci* at sunxi? #usb* at ohci? diff --git a/sys/arch/armv7/conf/RAMDISK b/sys/arch/armv7/conf/RAMDISK index 4b1c87c873b..06b66e1725a 100644 --- a/sys/arch/armv7/conf/RAMDISK +++ b/sys/arch/armv7/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.29 2016/08/04 15:52:52 kettenis Exp $ +# $OpenBSD: RAMDISK,v 1.30 2016/08/05 19:00:25 kettenis Exp $ machine armv7 arm @@ -84,7 +84,7 @@ usb* at ehci? sunxi0 at mainbus? # Sunxi on-chip devices -a1xintc* at sunxi? # A1x interrupt controller +a1xintc* at fdt? # A1x interrupt controller sxipio* at sunxi? # GPIO pins for leds & PHYs gpio* at sxipio? sxiccmu* at sunxi? # Clock Control Module/Unit @@ -93,8 +93,8 @@ sxidog* at sunxi? # watchdog timer sxirtc* at sunxi? # Real Time Clock sxiuart* at fdt? # onboard UARTs sxie* at fdt? -ahci* at sunxi? # AHCI/SATA (shim) -ehci* at sunxi? # EHCI (shim) +sxiahci* at fdt? # AHCI/SATA +ehci* at fdt? # EHCI (shim) usb* at ehci? #flags 0x1 #ohci* at sunxi? #usb* at ohci? diff --git a/sys/arch/armv7/sunxi/a1xintc.c b/sys/arch/armv7/sunxi/a1xintc.c index 67407a9ebdd..3eed1f43924 100644 --- a/sys/arch/armv7/sunxi/a1xintc.c +++ b/sys/arch/armv7/sunxi/a1xintc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a1xintc.c,v 1.7 2016/01/31 00:14:50 jsg Exp $ */ +/* $OpenBSD: a1xintc.c,v 1.8 2016/08/05 19:00:25 kettenis Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn * Copyright (c) 2013 Artturi Alm @@ -24,11 +24,15 @@ #include #include +#include #include #include #include +#include +#include + #ifdef DEBUG_INTC #define DPRINTF(x) do { if (a1xintcdebug) printf x; } while (0) #define DPRINTFN(n,x) do { if (a1xintcdebug>(n)) printf x; } while (0) @@ -134,19 +138,23 @@ volatile int a1xsoftint_pending; struct intrq a1xintc_handler[NIRQ]; u_int32_t a1xintc_smask[NIPL]; u_int32_t a1xintc_imask[NBANKS][NIPL]; +struct interrupt_controller a1xintc_ic; bus_space_tag_t a1xintc_iot; bus_space_handle_t a1xintc_ioh; int a1xintc_nirq; +int a1xintc_match(struct device *, void *, void *); void a1xintc_attach(struct device *, struct device *, void *); int a1xintc_spllower(int); int a1xintc_splraise(int); void a1xintc_setipl(int); void a1xintc_calc_masks(void); +void *a1xintc_intr_establish_fdt(void *, int *, int, int (*)(void *), + void *, char *); struct cfattach a1xintc_ca = { - sizeof (struct device), NULL, a1xintc_attach + sizeof (struct device), a1xintc_match, a1xintc_attach }; struct cfdriver a1xintc_cd = { @@ -155,15 +163,23 @@ struct cfdriver a1xintc_cd = { int a1xintc_attached = 0; +int +a1xintc_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "allwinner,sun4i-a10-ic"); +} + void -a1xintc_attach(struct device *parent, struct device *self, void *args) +a1xintc_attach(struct device *parent, struct device *self, void *aux) { - struct armv7_attach_args *aa = args; + struct fdt_attach_args *faa = aux; int i, j; - a1xintc_iot = aa->aa_iot; - if (bus_space_map(a1xintc_iot, aa->aa_dev->mem[0].addr, - aa->aa_dev->mem[0].size, 0, &a1xintc_ioh)) + a1xintc_iot = faa->fa_iot; + if (bus_space_map(a1xintc_iot, faa->fa_reg[0].addr, + faa->fa_reg[0].size, 0, &a1xintc_ioh)) panic("a1xintc_attach: bus_space_map failed!"); /* disable/mask/clear all interrupts */ @@ -196,6 +212,10 @@ a1xintc_attach(struct device *parent, struct device *self, void *args) a1xintc_setipl(IPL_HIGH); /* XXX ??? */ enable_interrupts(PSR_I); printf("\n"); + + a1xintc_ic.ic_node = faa->fa_node; + a1xintc_ic.ic_establish = a1xintc_intr_establish_fdt; + arm_intr_register_fdt(&a1xintc_ic); } void @@ -353,7 +373,8 @@ a1xintc_irq_handler(void *frame) } void * -a1xintc_intr_establish(int irq, int lvl, int (*f)(void *), void *arg, char *name) +a1xintc_intr_establish(int irq, int level, int (*func)(void *), + void *arg, char *name) { int psw; struct intrhand *ih; @@ -362,7 +383,7 @@ a1xintc_intr_establish(int irq, int lvl, int (*f)(void *), void *arg, char *name if (irq <= 0 || irq >= NIRQ) panic("intr_establish: bogus irq %d %s\n", irq, name); - DPRINTF(("intr_establish: irq %d level %d [%s]\n", irq, lvl, + DPRINTF(("intr_establish: irq %d level %d [%s]\n", irq, level, name != NULL ? name : "NULL")); psw = disable_interrupts(PSR_I); @@ -372,9 +393,9 @@ a1xintc_intr_establish(int irq, int lvl, int (*f)(void *), void *arg, char *name cold ? M_NOWAIT : M_WAITOK); if (ih == NULL) panic("intr_establish: can't malloc handler info\n"); - ih->ih_func = f; + ih->ih_func = func; ih->ih_arg = arg; - ih->ih_ipl = lvl; + ih->ih_ipl = level; ih->ih_irq = irq; ih->ih_name = name; @@ -395,6 +416,13 @@ a1xintc_intr_establish(int irq, int lvl, int (*f)(void *), void *arg, char *name return (ih); } +void * +a1xintc_intr_establish_fdt(void *cookie, int *cell, int level, + int (*func)(void *), void *arg, char *name) +{ + return a1xintc_intr_establish(cell[0], level, func, arg, name); +} + void a1xintc_intr_disestablish(void *cookie) { diff --git a/sys/arch/armv7/sunxi/files.sunxi b/sys/arch/armv7/sunxi/files.sunxi index b1e72ad558f..59d75620db2 100644 --- a/sys/arch/armv7/sunxi/files.sunxi +++ b/sys/arch/armv7/sunxi/files.sunxi @@ -1,4 +1,4 @@ -# $OpenBSD: files.sunxi,v 1.6 2016/06/11 07:07:59 jsg Exp $ +# $OpenBSD: files.sunxi,v 1.7 2016/08/05 19:00:25 kettenis Exp $ define sunxi {} device sunxi: sunxi @@ -17,7 +17,7 @@ attach sxipio at sunxi file arch/armv7/sunxi/sxipio.c sxipio device a1xintc -attach a1xintc at sunxi +attach a1xintc at fdt file arch/armv7/sunxi/a1xintc.c a1xintc device sxitimer @@ -32,13 +32,14 @@ device sxirtc attach sxirtc at sunxi file arch/armv7/sunxi/sxirtc.c sxirtc -attach ahci at sunxi with sxiahci +device sxiahci: scsi, atascsi +attach sxiahci at fdt file arch/armv7/sunxi/sxiahci.c sxiahci #attach ohci at sunxi with sxiohci #file arch/armv7/sunxi/sxiohci.c sxiohci -attach ehci at sunxi with sxiehci +attach ehci at fdt with sxiehci file arch/armv7/sunxi/sxiehci.c sxiehci device sxiuart diff --git a/sys/arch/armv7/sunxi/sunxi.c b/sys/arch/armv7/sunxi/sunxi.c index 9287ed126e1..dc4bec7eacf 100644 --- a/sys/arch/armv7/sunxi/sunxi.c +++ b/sys/arch/armv7/sunxi/sunxi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sunxi.c,v 1.14 2016/07/27 22:03:52 mglocker Exp $ */ +/* $OpenBSD: sunxi.c,v 1.15 2016/08/05 19:00:25 kettenis Exp $ */ /* * Copyright (c) 2005,2008 Dale Rahn * @@ -42,34 +42,21 @@ struct cfdriver sunxi_cd = { struct board_dev sun4i_devs[] = { { "sxipio", 0 }, { "sxiccmu", 0 }, - { "a1xintc", 0 }, { "sxitimer", 0 }, { "sxitimer", 1 }, { "sxitimer", 2 }, { "sxidog", 0 }, { "sxirtc", 0 }, - { "ahci", 0 }, - { "ehci", 0 }, - { "ehci", 1 }, -#if 0 - { "ohci", 0 }, - { "ohci", 1 }, -#endif { NULL, 0 } }; struct board_dev sun5i_devs[] = { { "sxipio", 0 }, { "sxiccmu", 0 }, - { "a1xintc", 0 }, { "sxitimer", 0 }, { "sxitimer", 1 }, { "sxitimer", 2 }, { "sxidog", 0 }, - { "ehci", 0 }, -#if 0 - { "ohci", 0 }, -#endif { NULL, 0 } }; @@ -78,13 +65,6 @@ struct board_dev sun7i_devs[] = { { "sxiccmu", 0 }, { "sxidog", 0 }, { "sxirtc", 0 }, - { "ahci", 0 }, - { "ehci", 0 }, - { "ehci", 1 }, -#if 0 - { "ohci", 0 }, - { "ohci", 1 }, -#endif { NULL, 0 } }; diff --git a/sys/arch/armv7/sunxi/sxiahci.c b/sys/arch/armv7/sunxi/sxiahci.c index 7e1b794e9ea..5595c41a40d 100644 --- a/sys/arch/armv7/sunxi/sxiahci.c +++ b/sys/arch/armv7/sunxi/sxiahci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sxiahci.c,v 1.8 2015/01/22 14:33:01 krw Exp $ */ +/* $OpenBSD: sxiahci.c,v 1.9 2016/08/05 19:00:25 kettenis Exp $ */ /* * Copyright (c) 2013 Patrick Wildt * Copyright (c) 2013,2014 Artturi Alm @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -34,6 +35,9 @@ #include #include +#include +#include + #define SXIAHCI_CAP 0x0000 #define SXIAHCI_GHC 0x0004 #define SXIAHCI_PI 0x000c @@ -49,6 +53,7 @@ #define SXIAHCI_PREG_DMA_MASK (0xff<<8) #define SXIAHCI_PREG_DMA_INIT (0x44<<8) +int sxiahci_match(struct device *, void *, void *); void sxiahci_attach(struct device *, struct device *, void *); int sxiahci_detach(struct device *, int); int sxiahci_activate(struct device *, int); @@ -68,30 +73,41 @@ struct sxiahci_softc { struct cfattach sxiahci_ca = { sizeof(struct sxiahci_softc), - NULL, + sxiahci_match, sxiahci_attach, sxiahci_detach, sxiahci_activate }; struct cfdriver sxiahci_cd = { - NULL, "ahci", DV_DULL + NULL, "sxiahci", DV_DULL }; +int +sxiahci_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "allwinner,sun4i-a10-ahci"); +} + void -sxiahci_attach(struct device *parent, struct device *self, void *args) +sxiahci_attach(struct device *parent, struct device *self, void *aux) { - struct armv7_attach_args *aa = args; struct sxiahci_softc *sxisc = (struct sxiahci_softc *)self; struct ahci_softc *sc = &sxisc->sc; + struct fdt_attach_args *faa = aux; uint32_t timo; - sc->sc_iot = aa->aa_iot; - sc->sc_ios = aa->aa_dev->mem[0].size; - sc->sc_dmat = aa->aa_dmat; + if (faa->fa_nreg < 1) + return; - if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, - sc->sc_ios, 0, &sc->sc_ioh)) + sc->sc_iot = faa->fa_iot; + sc->sc_ios = faa->fa_reg[0].size; + sc->sc_dmat = faa->fa_dmat; + + if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, + faa->fa_reg[0].size, 0, &sc->sc_ioh)) panic("sxiahci_attach: bus_space_map failed!"); /* enable clock */ @@ -152,13 +168,15 @@ sxiahci_attach(struct device *parent, struct device *self, void *args) sxipio_setcfg(SXIAHCI_PWRPIN, SXIPIO_OUTPUT); sxipio_setpin(SXIAHCI_PWRPIN); - sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_BIO, + sc->sc_ih = arm_intr_establish_fdt(faa->fa_node, IPL_BIO, ahci_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); goto clrpwr; } + printf(":"); + SXIWRITE4(sc, SXIAHCI_PI, 1); SXICLR4(sc, SXIAHCI_CAP, AHCI_REG_CAP_SPM); sc->sc_flags |= AHCI_F_NO_PMP; diff --git a/sys/arch/armv7/sunxi/sxie.c b/sys/arch/armv7/sunxi/sxie.c index c0d4fd8666b..cdcc2819633 100644 --- a/sys/arch/armv7/sunxi/sxie.c +++ b/sys/arch/armv7/sunxi/sxie.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sxie.c,v 1.17 2016/07/27 11:45:02 patrick Exp $ */ +/* $OpenBSD: sxie.c,v 1.18 2016/08/05 19:00:25 kettenis Exp $ */ /* * Copyright (c) 2012-2013 Patrick Wildt * Copyright (c) 2013 Artturi Alm @@ -211,16 +211,11 @@ sxie_attach(struct device *parent, struct device *self, void *aux) struct fdt_attach_args *faa = aux; struct mii_data *mii; struct ifnet *ifp; - int s, irq; + int s; - if (faa->fa_nreg != 1 || (faa->fa_nintr != 1 && faa->fa_nintr != 3)) + if (faa->fa_nreg < 1) return; - if (faa->fa_nintr == 1) - irq = faa->fa_intr[0]; - else - irq = faa->fa_intr[1]; - sc->sc_iot = faa->fa_iot; if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, @@ -233,7 +228,7 @@ sxie_attach(struct device *parent, struct device *self, void *aux) sxie_socware_init(sc); sc->txf_inuse = 0; - sc->sc_ih = arm_intr_establish(irq, IPL_NET, + sc->sc_ih = arm_intr_establish_fdt(faa->fa_node, IPL_NET, sxie_intr, sc, sc->sc_dev.dv_xname); s = splnet(); diff --git a/sys/arch/armv7/sunxi/sxiehci.c b/sys/arch/armv7/sunxi/sxiehci.c index 05c912092cd..e02da5dc0d5 100644 --- a/sys/arch/armv7/sunxi/sxiehci.c +++ b/sys/arch/armv7/sunxi/sxiehci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sxiehci.c,v 1.4 2014/05/19 13:11:31 mpi Exp $ */ +/* $OpenBSD: sxiehci.c,v 1.5 2016/08/05 19:00:25 kettenis Exp $ */ /* * Copyright (c) 2005 David Gwynne @@ -52,6 +52,7 @@ #include #include +#include #include #include @@ -62,6 +63,9 @@ #include #include +#include +#include + #include #include @@ -78,6 +82,7 @@ #define AHB_INCR4 (1 << 9) #define AHB_INCR8 (1 << 10) +int sxiehci_match(struct device *, void *, void *); void sxiehci_attach(struct device *, struct device *, void *); int sxiehci_detach(struct device *, int); int sxiehci_activate(struct device *, int); @@ -90,28 +95,39 @@ struct sxiehci_softc { int sxiehci_init(struct sxiehci_softc *, int); struct cfattach sxiehci_ca = { - sizeof (struct sxiehci_softc), NULL, sxiehci_attach, + sizeof(struct sxiehci_softc), sxiehci_match, sxiehci_attach, sxiehci_detach, sxiehci_activate }; -/* XXX - * given the nature of SoCs, i think this should just panic on failure, - * instead of disestablishing interrupt and unmapping space etc.. - */ +int +sxiehci_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + if (OF_is_compatible(faa->fa_node, "allwinner,sun4i-a10-ehci")) + return 1; + if (OF_is_compatible(faa->fa_node, "allwinner,sun5i-a13-ehci")) + return 1; + if (OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-ehci")) + return 1; + + return 0; +} + void sxiehci_attach(struct device *parent, struct device *self, void *aux) { struct sxiehci_softc *sc = (struct sxiehci_softc *)self; - struct armv7_attach_args *aa = aux; + struct fdt_attach_args *faa = aux; usbd_status r; char *devname = sc->sc.sc_bus.bdev.dv_xname; - sc->sc.iot = aa->aa_iot; - sc->sc.sc_bus.dmatag = aa->aa_dmat; - sc->sc.sc_size = aa->aa_dev->mem[0].size; + sc->sc.iot = faa->fa_iot; + sc->sc.sc_bus.dmatag = faa->fa_dmat; + sc->sc.sc_size = faa->fa_reg[0].size; - if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[0].addr, - aa->aa_dev->mem[0].size, 0, &sc->sc.ioh)) { + if (bus_space_map(sc->sc.iot, faa->fa_reg[0].addr, + faa->fa_reg[0].size, 0, &sc->sc.ioh)) { printf(": cannot map mem space\n"); goto out; } @@ -125,7 +141,7 @@ sxiehci_attach(struct device *parent, struct device *self, void *aux) sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); EOWRITE2(&sc->sc, EHCI_USBINTR, 0); - sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_USB, + sc->sc_ih = arm_intr_establish_fdt(faa->fa_node, IPL_USB, ehci_intr, &sc->sc, devname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); diff --git a/sys/arch/armv7/sunxi/sxiuart.c b/sys/arch/armv7/sunxi/sxiuart.c index c08de46b677..5d1b592c145 100644 --- a/sys/arch/armv7/sunxi/sxiuart.c +++ b/sys/arch/armv7/sunxi/sxiuart.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sxiuart.c,v 1.9 2016/07/27 11:45:02 patrick Exp $ */ +/* $OpenBSD: sxiuart.c,v 1.10 2016/08/05 19:00:25 kettenis Exp $ */ /* * Copyright (c) 2005 Dale Rahn * Copyright (c) 2013 Artturi Alm @@ -173,16 +173,11 @@ sxiuart_attach(struct device *parent, struct device *self, void *aux) struct fdt_attach_args *faa = aux; bus_space_tag_t iot; bus_space_handle_t ioh; - int s, irq; + int s; - if (faa->fa_nreg != 1 || (faa->fa_nintr != 1 && faa->fa_nintr != 3)) + if (faa->fa_nreg < 1) return; - if (faa->fa_nintr == 1) - irq = faa->fa_intr[0]; - else - irq = faa->fa_intr[1]; - sc->sc_iot = iot = faa->fa_iot; if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, faa->fa_reg[0].size, 0, &sc->sc_ioh)) @@ -225,7 +220,7 @@ sxiuart_attach(struct device *parent, struct device *self, void *aux) bus_space_write_1(sc->sc_iot, sc->sc_ioh, SXIUART_MCR, sc->sc_mcr); splx(s); - arm_intr_establish(irq, IPL_TTY, + arm_intr_establish_fdt(faa->fa_node, IPL_TTY, sxiuart_intr, sc, sc->sc_dev.dv_xname); printf("\n"); diff --git a/sys/conf/files b/sys/conf/files index c46413abcec..2cc5dc17fcd 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.621 2016/08/05 11:40:22 kettenis Exp $ +# $OpenBSD: files,v 1.622 2016/08/05 19:00:25 kettenis Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -194,7 +194,7 @@ file dev/ic/qla.c qla # Advanced Host Controller Interface for Serial ATA device ahci: scsi, atascsi file dev/ic/ahci.c ahci | (ahci_pci | ahci_jmb | - imxahci) needs-flag + imxahci | sxiahci) needs-flag # NVM Express Controller device nvme: scsi -- 2.20.1