From owner-svn-src-head@freebsd.org Sat May 6 06:22:15 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 914A1D6181C; Sat, 6 May 2017 06:22:15 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 535111391; Sat, 6 May 2017 06:22:15 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v466ME4O091042; Sat, 6 May 2017 06:22:14 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v466MECl091041; Sat, 6 May 2017 06:22:14 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201705060622.v466MECl091041@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Sat, 6 May 2017 06:22:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r317874 - head/sys/mips/mediatek X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 May 2017 06:22:15 -0000 Author: adrian Date: Sat May 6 06:22:14 2017 New Revision: 317874 URL: https://svnweb.freebsd.org/changeset/base/317874 Log: [mediatek] [gpio] add PPS / interrupt support. Submitted by: Hiroki Mori Reviewed by: mizhka Differential Revision: https://reviews.freebsd.org/D9784 Modified: head/sys/mips/mediatek/mtk_gpio_v1.c Modified: head/sys/mips/mediatek/mtk_gpio_v1.c ============================================================================== --- head/sys/mips/mediatek/mtk_gpio_v1.c Sat May 6 06:20:34 2017 (r317873) +++ head/sys/mips/mediatek/mtk_gpio_v1.c Sat May 6 06:22:14 2017 (r317874) @@ -292,7 +292,8 @@ mtk_gpio_attach(device_t dev) for (i = 0; i < sc->num_pins; i++) { sc->pins[i].pin_caps |= GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | - GPIO_PIN_INVIN | GPIO_PIN_INVOUT; + GPIO_PIN_INVIN | GPIO_PIN_INVOUT | + GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING; sc->pins[i].intr_polarity = INTR_POLARITY_HIGH; sc->pins[i].intr_trigger = INTR_TRIGGER_EDGE; @@ -500,22 +501,78 @@ out: } static int +mtk_gpio_pic_map_fdt(struct mtk_gpio_softc *sc, + struct intr_map_data_fdt *daf, u_int *irqp, uint32_t *modep) +{ + u_int irq; + + if (daf->ncells != 1) { + device_printf(sc->dev, "Invalid #interrupt-cells\n"); + return (EINVAL); + } + + irq = daf->cells[0]; + + if (irq >= sc->num_pins) { + device_printf(sc->dev, "Invalid interrupt number %u\n", irq); + return (EINVAL); + } + + *irqp = irq; + if (modep != NULL) + *modep = GPIO_INTR_EDGE_BOTH; + + return (0); +} + +static int +mtk_gpio_pic_map_gpio(struct mtk_gpio_softc *sc, + struct intr_map_data_gpio *dag, u_int *irqp, uint32_t *modep) +{ + u_int irq; + + irq = dag->gpio_pin_num; + if (irq >= sc->num_pins) { + device_printf(sc->dev, "Invalid interrupt number %u\n", irq); + return (EINVAL); + } + + *irqp = irq; + if (modep != NULL) + *modep = dag->gpio_intr_mode; + + return (0); +} + +static int mtk_gpio_pic_map_intr(device_t dev, struct intr_map_data *data, struct intr_irqsrc **isrcp) { - struct intr_map_data_fdt *daf; + int error; + u_int irq; struct mtk_gpio_softc *sc; - if (data->type != INTR_MAP_DATA_FDT) - return (ENOTSUP); - sc = device_get_softc(dev); - daf = (struct intr_map_data_fdt *)data; + switch (data->type) { + case INTR_MAP_DATA_FDT: + error = (mtk_gpio_pic_map_fdt(sc, + (struct intr_map_data_fdt *)data, &irq, NULL)); + break; + case INTR_MAP_DATA_GPIO: + error = (mtk_gpio_pic_map_gpio(sc, + (struct intr_map_data_gpio *)data, &irq, NULL)); + break; + default: + error = EINVAL; + break; + } - if (daf->ncells != 1 || daf->cells[0] >= sc->num_pins) - return (EINVAL); + if (error != 0) { + device_printf(dev, "Invalid map type\n"); + return (error); + } - *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]); + *isrcp = PIC_INTR_ISRC(sc, irq); return (0); } @@ -600,6 +657,51 @@ mtk_gpio_pic_post_filter(device_t dev, s } static int +mtk_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, + struct resource *res, struct intr_map_data *data) +{ + struct mtk_gpio_softc *sc; + uint32_t val; + int error; + uint32_t mode; + u_int irq; + + if (data == NULL) + return (ENOTSUP); + + sc = device_get_softc(dev); + + switch (data->type) { + case INTR_MAP_DATA_FDT: + error = mtk_gpio_pic_map_fdt(sc, + (struct intr_map_data_fdt *)data, &irq, &mode); + break; + case INTR_MAP_DATA_GPIO: + error = mtk_gpio_pic_map_gpio(sc, + (struct intr_map_data_gpio *)data, &irq, &mode); + break; + default: + error = ENOTSUP; + break; + } + + if (error != 0) + return (error); + + MTK_GPIO_LOCK(sc); + if (mode == GPIO_INTR_EDGE_BOTH || mode == GPIO_INTR_EDGE_RISING) { + val = MTK_READ_4(sc, GPIO_PIORENA) | (1u << irq); + MTK_WRITE_4(sc, GPIO_PIORENA, val); + } + if (mode == GPIO_INTR_EDGE_BOTH || mode == GPIO_INTR_EDGE_FALLING) { + val = MTK_READ_4(sc, GPIO_PIOFENA) | (1u << irq); + MTK_WRITE_4(sc, GPIO_PIOFENA, val); + } + MTK_GPIO_UNLOCK(sc); + return (0); +} + +static int mtk_gpio_intr(void *arg) { struct mtk_gpio_softc *sc; @@ -607,6 +709,7 @@ mtk_gpio_intr(void *arg) sc = arg; interrupts = MTK_READ_4(sc, GPIO_PIOINT); + MTK_WRITE_4(sc, GPIO_PIOINT, interrupts); for (i = 0; interrupts != 0; i++, interrupts >>= 1) { if ((interrupts & 0x1) == 0) @@ -649,6 +752,7 @@ static device_method_t mtk_gpio_methods[ DEVMETHOD(pic_disable_intr, mtk_gpio_pic_disable_intr), DEVMETHOD(pic_enable_intr, mtk_gpio_pic_enable_intr), DEVMETHOD(pic_map_intr, mtk_gpio_pic_map_intr), + DEVMETHOD(pic_setup_intr, mtk_gpio_pic_setup_intr), DEVMETHOD(pic_post_filter, mtk_gpio_pic_post_filter), DEVMETHOD(pic_post_ithread, mtk_gpio_pic_post_ithread), DEVMETHOD(pic_pre_ithread, mtk_gpio_pic_pre_ithread),