From owner-svn-src-projects@FreeBSD.ORG Thu May 7 03:39:25 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3BA31106566B; Thu, 7 May 2009 03:39:25 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2A13B8FC14; Thu, 7 May 2009 03:39:25 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n473dNuP039175; Thu, 7 May 2009 03:39:23 GMT (envelope-from gonzo@svn.freebsd.org) Received: (from gonzo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n473dNDx039173; Thu, 7 May 2009 03:39:23 GMT (envelope-from gonzo@svn.freebsd.org) Message-Id: <200905070339.n473dNDx039173@svn.freebsd.org> From: Oleksandr Tymoshenko Date: Thu, 7 May 2009 03:39:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r191872 - projects/mips/sys/mips/atheros X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 May 2009 03:39:25 -0000 Author: gonzo Date: Thu May 7 03:39:23 2009 New Revision: 191872 URL: http://svn.freebsd.org/changeset/base/191872 Log: - Add interrupt handling for AR71XX PCI bridge Modified: projects/mips/sys/mips/atheros/ar71xx_pci.c projects/mips/sys/mips/atheros/ar71xxreg.h Modified: projects/mips/sys/mips/atheros/ar71xx_pci.c ============================================================================== --- projects/mips/sys/mips/atheros/ar71xx_pci.c Thu May 7 03:23:22 2009 (r191871) +++ projects/mips/sys/mips/atheros/ar71xx_pci.c Thu May 7 03:39:23 2009 (r191872) @@ -68,10 +68,34 @@ struct ar71xx_pci_softc { struct rman sc_mem_rman; struct rman sc_irq_rman; + struct intr_event *sc_eventstab[AR71XX_PCI_NIRQS]; struct resource *sc_irq; void *sc_ih; }; +static int ar71xx_pci_setup_intr(device_t, device_t, struct resource *, int, + driver_filter_t *, driver_intr_t *, void *, void **); +static int ar71xx_pci_teardown_intr(device_t, device_t, struct resource *, + void *); +static int ar71xx_pci_intr(void *); + +static void ar71xx_pci_mask_irq(unsigned int irq) +{ + uint32_t reg; + + reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); + ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg & ~(1 << irq)); + +} + +static void ar71xx_pci_unmask_irq(unsigned int irq) +{ + uint32_t reg; + + reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); + ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg | (1 << irq)); +} + /* * get bitmask for bytes of interest: * 0 - we want this byte, 1 - ignore it. e.g: we read 1 byte @@ -213,13 +237,6 @@ ar71xx_pci_write_config(device_t dev, in } static int -at71xx_pci_intr(void *v) -{ - panic("Implement me: %s\n", __func__); - return FILTER_HANDLED; -} - -static int ar71xx_pci_probe(device_t dev) { @@ -261,7 +278,7 @@ ar71xx_pci_attach(device_t dev) } if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, - at71xx_pci_intr, NULL, sc, &sc->sc_ih))) { + ar71xx_pci_intr, NULL, sc, &sc->sc_ih))) { device_printf(dev, "WARNING: unable to register interrupt handler\n"); return ENXIO; @@ -369,11 +386,85 @@ ar71xx_pci_alloc_resource(device_t bus, } static int -ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *res, +ar71xx_pci_setup_intr(device_t bus, device_t child, struct resource *ires, + int flags, driver_filter_t *filt, driver_intr_t *handler, + void *arg, void **cookiep) +{ + struct ar71xx_pci_softc *sc = device_get_softc(bus); + struct intr_event *event; + int irq, error; + + irq = rman_get_start(ires); + + if (irq > AR71XX_PCI_IRQ_END) + panic("%s: bad irq %d", __func__, irq); + + event = sc->sc_eventstab[irq]; + if (event == NULL) { + error = intr_event_create(&event, (void *)irq, 0, irq, + (mask_fn)ar71xx_pci_mask_irq, + (mask_fn)ar71xx_pci_unmask_irq, + NULL, NULL, + "ar71xx_pci intr%d:", irq); + + sc->sc_eventstab[irq] = event; + } + + intr_event_add_handler(event, device_get_nameunit(child), filt, + handler, arg, intr_priority(flags), flags, cookiep); + + ar71xx_pci_unmask_irq(irq); + + return (0); +} + +static int +ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *ires, void *cookie) { + struct ar71xx_pci_softc *sc = device_get_softc(dev); + int irq, result; + + irq = rman_get_start(ires); + if (irq > AR71XX_PCI_IRQ_END) + panic("%s: bad irq %d", __func__, irq); + + if (sc->sc_eventstab[irq] == NULL) + panic("Trying to teardown unoccupied IRQ"); + + ar71xx_pci_mask_irq(irq); + + result = intr_event_remove_handler(cookie); + if (!result) + sc->sc_eventstab[irq] = NULL; + + return (result); +} + +static int +ar71xx_pci_intr(void *arg) +{ + struct ar71xx_pci_softc *sc = arg; + struct intr_event *event; + uint32_t reg, irq; + + reg = ATH_READ_REG(AR71XX_PCI_INTR_STATUS); + for (irq = AR71XX_PCI_IRQ_START; irq <= AR71XX_PCI_IRQ_END; irq++) { + if (reg & (1 << irq)) { + event = sc->sc_eventstab[irq]; + if (!event || TAILQ_EMPTY(&event->ie_handlers)) { + /* Ignore timer interrupts */ + if (irq != 0) + printf("Stray IRQ %d\n", irq); + continue; + } + + /* TODO: frame instead of NULL? */ + intr_event_handle(event, NULL); + } + } - return (intr_event_remove_handler(cookie)); + return (FILTER_HANDLED); } static int @@ -406,7 +497,7 @@ static device_method_t ar71xx_pci_method DEVMETHOD(bus_release_resource, bus_generic_release_resource), DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_setup_intr, ar71xx_pci_setup_intr), DEVMETHOD(bus_teardown_intr, ar71xx_pci_teardown_intr), /* pcib interface */ Modified: projects/mips/sys/mips/atheros/ar71xxreg.h ============================================================================== --- projects/mips/sys/mips/atheros/ar71xxreg.h Thu May 7 03:23:22 2009 (r191871) +++ projects/mips/sys/mips/atheros/ar71xxreg.h Thu May 7 03:39:23 2009 (r191872) @@ -41,6 +41,7 @@ #define AR71XX_PCI_MEM_SIZE 0x07000000 #define AR71XX_PCI_IRQ_START 0 #define AR71XX_PCI_IRQ_END 2 +#define AR71XX_PCI_NIRQS 3 /* PCI config registers */ #define AR71XX_PCI_LCONF_CMD 0x17010000