Index: sys/arm/lpc/lpc_spi.c =================================================================== --- sys/arm/lpc/lpc_spi.c +++ sys/arm/lpc/lpc_spi.c @@ -139,6 +139,24 @@ return (EBUSY); } +static void +lpc_spi_acquire_bus(device_t dev, device_t child) +{ + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + /* Set CS active */ + lpc_gpio_set_state(child, devi->cs, 0); +} + +static void +lpc_spi_release_bus(device_t dev, device_t child) +{ + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + /* Set CS inactive */ + lpc_gpio_set_state(child, devi->cs, 1); +} + static int lpc_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) { @@ -147,9 +165,6 @@ uint8_t *in_buf, *out_buf; int i; - /* Set CS active */ - lpc_gpio_set_state(child, devi->cs, 0); - /* Wait for FIFO to be ready */ while ((lpc_spi_read_4(sc, LPC_SSP_SR) & LPC_SSP_SR_TNF) == 0); @@ -169,9 +184,6 @@ in_buf[i] = lpc_spi_read_4(sc, LPC_SSP_DR); } - /* Set CS inactive */ - lpc_gpio_set_state(child, devi->cs, 1); - return (0); } @@ -183,6 +195,8 @@ /* SPI interface */ DEVMETHOD(spibus_transfer, lpc_spi_transfer), + DEVMETHOD(spibus_acquire_bus, lpc_spi_acquire_bus), + DEVMETHOD(spibus_release_bus, lpc_spi_release_bus), { 0, 0 } }; Index: sys/arm/lpc/ssd1289.c =================================================================== --- sys/arm/lpc/ssd1289.c +++ sys/arm/lpc/ssd1289.c @@ -157,7 +157,8 @@ static __inline void ssd1289_spi_send(struct ssd1289_softc *sc, uint8_t *data, int len) { - struct spi_command cmd; + struct spi_command cmd = SPI_COMMAND_INITIALIZER; + uint8_t buffer[8]; cmd.tx_cmd = data; cmd.tx_cmd_sz = len; @@ -165,7 +166,9 @@ cmd.rx_cmd_sz = len; cmd.tx_data_sz = 0; cmd.rx_data_sz = 0; + SPIBUS_ACQUIRE_BUS(device_get_parent(sc->ss_dev), sc->ss_dev); SPIBUS_TRANSFER(device_get_parent(sc->ss_dev), sc->ss_dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(sc->ss_dev), sc->ss_dev); } static __inline void Index: sys/arm/samsung/exynos/chrome_ec_spi.c =================================================================== --- sys/arm/samsung/exynos/chrome_ec_spi.c +++ sys/arm/samsung/exynos/chrome_ec_spi.c @@ -149,14 +149,19 @@ assert_cs(sc, 1); spi_cmd.rx_cmd_sz = spi_cmd.tx_cmd_sz = dout_len + 4; + + SPIBUS_ACQUIRE_BUS(device_get_parent(sc->dev), sc->dev); ret = SPIBUS_TRANSFER(device_get_parent(sc->dev), sc->dev, &spi_cmd); + SPIBUS_RELEASE_BUS(device_get_parent(sc->dev), sc->dev); /* Wait 0xec */ for (i = 0; i < 1000; i++) { DELAY(10); msg_dout[0] = 0xff; spi_cmd.rx_cmd_sz = spi_cmd.tx_cmd_sz = 1; + SPIBUS_ACQUIRE_BUS(device_get_parent(sc->dev), sc->dev); SPIBUS_TRANSFER(device_get_parent(sc->dev), sc->dev, &spi_cmd); + SPIBUS_RELEASE_BUS(device_get_parent(sc->dev), sc->dev); if (msg_dinp[0] == 0xec) break; } @@ -165,7 +170,9 @@ for (i = 0; i < (dout_len + 4); i++) msg_dout[i] = 0xff; spi_cmd.rx_cmd_sz = spi_cmd.tx_cmd_sz = dout_len + 4 - 1; + SPIBUS_ACQUIRE_BUS(device_get_parent(sc->dev), sc->dev); ret = SPIBUS_TRANSFER(device_get_parent(sc->dev), sc->dev, &spi_cmd); + SPIBUS_RELEASE_BUS(device_get_parent(sc->dev), sc->dev); assert_cs(sc, 0); if (ret != 0) { Index: sys/dev/flash/at45d.c =================================================================== --- sys/dev/flash/at45d.c +++ sys/dev/flash/at45d.c @@ -132,7 +132,9 @@ cmd.tx_cmd = txBuf; cmd.rx_cmd = rxBuf; cmd.rx_cmd_sz = cmd.tx_cmd_sz = 2; + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); *status = rxBuf[1]; return (err); } @@ -152,7 +154,9 @@ cmd.tx_cmd = &txBuf; cmd.rx_cmd = &rxBuf; cmd.tx_cmd_sz = cmd.rx_cmd_sz = 5; + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); if (err) return (err); memcpy(resp, rxBuf + 1, 4); @@ -367,8 +371,12 @@ txBuf[2] = ((addr >> 8) & 0xff); txBuf[3] = 0; cmd.tx_data_sz = cmd.rx_data_sz = 0; + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), + dev); err = SPIBUS_TRANSFER(pdev, dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), + dev); if (err == 0) err = at45d_wait_ready(dev, &status); @@ -385,7 +393,9 @@ txBuf[2] = ((addr >> 8) & 0xff); txBuf[3] = (addr & 0xff); cmd.tx_data_sz = cmd.rx_data_sz = len; + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(pdev, dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); if (err == 0 && bp->bio_cmd != BIO_READ) err = at45d_wait_ready(dev, &status); if (err != 0) { @@ -399,7 +409,9 @@ txBuf[2] = ((addr >> 8) & 0xff); txBuf[3] = 0; cmd.tx_data_sz = cmd.rx_data_sz = 0; + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(pdev, dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); if (err == 0) err = at45d_wait_ready(dev, &status); if (err != 0 || (status & 0x40) != 0) { Index: sys/dev/flash/mx25l.c =================================================================== --- sys/dev/flash/mx25l.c +++ sys/dev/flash/mx25l.c @@ -148,7 +148,9 @@ cmd.rx_cmd = rxBuf; cmd.rx_cmd_sz = 2; cmd.tx_cmd_sz = 2; + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); return (rxBuf[1]); } @@ -182,7 +184,9 @@ */ cmd.tx_cmd_sz = 4; cmd.rx_cmd_sz = 4; + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); if (err) return (NULL); @@ -217,7 +221,9 @@ cmd.rx_cmd = rxBuf; cmd.rx_cmd_sz = 1; cmd.tx_cmd_sz = 1; + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); } static void @@ -254,7 +260,9 @@ txBuf[2] = ((sector >> 8) & 0xff); txBuf[3] = (sector & 0xff); } + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); } static int @@ -339,7 +347,9 @@ mx25l_wait_for_device_ready(dev); mx25l_set_writable(dev, 1); + SPIBUS_ACQUIRE_BUS(pdev, pdev); err = SPIBUS_TRANSFER(pdev, dev, &cmd); + SPIBUS_RELEASE_BUS(pdev, pdev); if (err) break; @@ -400,7 +410,9 @@ cmd.rx_data = data; cmd.rx_data_sz = count; + SPIBUS_ACQUIRE_BUS(pdev, dev); err = SPIBUS_TRANSFER(pdev, dev, &cmd); + SPIBUS_RELEASE_BUS(pdev, dev); return (err); } @@ -426,7 +438,9 @@ txBuf[0] = command; + SPIBUS_ACQUIRE_BUS(pdev, dev); err = SPIBUS_TRANSFER(pdev, dev, &cmd); + SPIBUS_RELEASE_BUS(pdev, dev); mx25l_wait_for_device_ready(dev); Index: sys/dev/spibus/spibus.c =================================================================== --- sys/dev/spibus/spibus.c +++ sys/dev/spibus/spibus.c @@ -30,8 +30,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -46,6 +48,15 @@ #include #include "spibus_if.h" +#define SPIBUS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) +#define SPIBUS_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) +#define SPIBUS_LOCK_INIT(_sc) \ + mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \ + "spibus", MTX_DEF) +#define SPIBUS_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx) +#define SPIBUS_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED) +#define SPIBUS_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED) + static int spibus_probe(device_t dev) { @@ -58,7 +69,8 @@ { struct spibus_softc *sc = SPIBUS_SOFTC(dev); - sc->dev = dev; + sc->sc_dev = dev; + SPIBUS_LOCK_INIT(sc); bus_enumerate_hinted_children(dev); return (bus_generic_attach(dev)); } @@ -70,8 +82,9 @@ static int spibus_detach(device_t dev) { - int err, ndevs, i; + struct spibus_softc *sc = SPIBUS_SOFTC(dev); device_t *devlist; + int err, ndevs, i; if ((err = bus_generic_detach(dev)) != 0) return (err); @@ -81,6 +94,8 @@ device_delete_child(dev, devlist[i]); free(devlist, M_TEMP); + SPIBUS_LOCK_DESTROY(sc); + return (0); } @@ -192,9 +207,57 @@ resource_int_value(dname, dunit, "mode", &devi->mode); } +/* + * TODO: make acquire_bus take a flag set to control whether + * we sleep or not, and for how long to wait. + */ +static void +spibus_acquire_bus_impl(device_t dev, device_t child) +{ + struct spibus_softc *sc = SPIBUS_SOFTC(dev); + + SPIBUS_ASSERT_UNLOCKED(sc); + + /* Wait until bus is free and then set the new bus owner. */ + SPIBUS_LOCK(sc); + while (sc->sc_owner != NULL) { + mtx_sleep(sc, &sc->sc_mtx, 0, "spibus", 0); + } + sc->sc_owner = child; + SPIBUS_UNLOCK(sc); + + /* Select the SPI device. */ + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), child); +} + +static void +spibus_release_bus_impl(device_t dev, device_t child) +{ + struct spibus_softc *sc = SPIBUS_SOFTC(dev); + + SPIBUS_ASSERT_UNLOCKED(sc); + + /* Free the SPI BUS. */ + SPIBUS_LOCK(sc); + if (sc->sc_owner == NULL) + panic("spibus: releasing unowned bus."); + if (sc->sc_owner != child) + panic("spibus: you don't own the bus. game over."); + sc->sc_owner = NULL; + SPIBUS_UNLOCK(sc); + + /* Deselect the SPI device. */ + SPIBUS_RELEASE_BUS(device_get_parent(dev), child); + + wakeup(sc); +} + static int spibus_transfer_impl(device_t dev, device_t child, struct spi_command *cmd) { + KASSERT(SPIBUS_SOFTC(dev)->sc_owner != NULL, + ("SPI transfer on unowned bus")); + return (SPIBUS_TRANSFER(device_get_parent(dev), child, cmd)); } @@ -218,6 +281,8 @@ /* spibus interface */ DEVMETHOD(spibus_transfer, spibus_transfer_impl), + DEVMETHOD(spibus_acquire_bus, spibus_acquire_bus_impl), + DEVMETHOD(spibus_release_bus, spibus_release_bus_impl), DEVMETHOD_END }; Index: sys/dev/spibus/spibus_if.m =================================================================== --- sys/dev/spibus/spibus_if.m +++ sys/dev/spibus/spibus_if.m @@ -32,6 +32,37 @@ INTERFACE spibus; # +# Default implementation +# +CODE { + static void + null_acquire_bus(device_t dev, device_t child) + { + } + + static void + null_release_bus(device_t dev, device_t child) + { + } +}; + +# +# Acquire bus and select the device +# +METHOD void acquire_bus { + device_t dev; + device_t child; +} DEFAULT null_acquire_bus; + +# +# Release bus and deselect the device +# +METHOD void release_bus { + device_t dev; + device_t child; +} DEFAULT null_release_bus; + +# # Do a spi command # METHOD int transfer { Index: sys/dev/spibus/spibusvar.h =================================================================== --- sys/dev/spibus/spibusvar.h +++ sys/dev/spibus/spibusvar.h @@ -31,7 +31,9 @@ struct spibus_softc { - device_t dev; + device_t sc_dev; + device_t sc_owner; + struct mtx sc_mtx; }; #define SPIBUS_MODE_NONE 0 Index: sys/dev/spibus/spigen.c =================================================================== --- sys/dev/spibus/spigen.c +++ sys/dev/spibus/spigen.c @@ -221,8 +221,11 @@ error = copyin(st->st_data.iov_base, transfer.tx_data, transfer.tx_data_sz = transfer.rx_data_sz = st->st_data.iov_len); - if (error == 0) + if (error == 0) { + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); error = SPIBUS_TRANSFER(device_get_parent(dev), dev, &transfer); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); + } if (error == 0) { error = copyout(transfer.rx_cmd, st->st_command.iov_base, transfer.rx_cmd_sz); @@ -266,7 +269,9 @@ transfer.tx_data = transfer.rx_data = (void *)(sc->sc_mmap_kvaddr + stm->stm_command_length); transfer.tx_data_sz = transfer.rx_data_sz = stm->stm_data_length; + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); error = SPIBUS_TRANSFER(device_get_parent(dev), dev, &transfer); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); mtx_lock(&sc->sc_mtx); KASSERT(sc->sc_mmap_busy, ("mmap no longer marked busy")); Index: sys/mips/atheros/ar71xx_spi.c =================================================================== --- sys/mips/atheros/ar71xx_spi.c +++ sys/mips/atheros/ar71xx_spi.c @@ -200,6 +200,26 @@ return (rds & 0xff); } +static void +ar71xx_spi_acquire_bus(device_t dev, device_t child) +{ + struct ar71xx_spi_softc *sc; + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + sc = device_get_softc(dev); + ar71xx_spi_chip_activate(sc, devi->cs); +} + +static void +ar71xx_spi_release_bus(device_t dev, device_t child) +{ + struct ar71xx_spi_softc *sc; + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + sc = device_get_softc(dev); + ar71xx_spi_chip_deactivate(sc, devi->cs); +} + static int ar71xx_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) { @@ -210,8 +230,6 @@ sc = device_get_softc(dev); - ar71xx_spi_chip_activate(sc, devi->cs); - KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, ("TX/RX command sizes should be equal")); KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, @@ -226,15 +244,13 @@ buf_in[i] = ar71xx_spi_txrx(sc, devi->cs, buf_out[i]); /* - * Receive/transmit data (depends on command) + * Receive/transmit data (depends on command) */ buf_out = (uint8_t *)cmd->tx_data; buf_in = (uint8_t *)cmd->rx_data; for (i = 0; i < cmd->tx_data_sz; i++) buf_in[i] = ar71xx_spi_txrx(sc, devi->cs, buf_out[i]); - ar71xx_spi_chip_deactivate(sc, devi->cs); - return (0); } @@ -276,6 +292,8 @@ DEVMETHOD(device_detach, ar71xx_spi_detach), DEVMETHOD(spibus_transfer, ar71xx_spi_transfer), + DEVMETHOD(spibus_acquire_bus, ar71xx_spi_acquire_bus), + DEVMETHOD(spibus_release_bus, ar71xx_spi_release_bus), {0, 0} }; Index: sys/mips/atheros/pcf2123_rtc.c =================================================================== --- sys/mips/atheros/pcf2123_rtc.c +++ sys/mips/atheros/pcf2123_rtc.c @@ -91,7 +91,9 @@ cmd.tx_cmd = txBuf; cmd.rx_cmd_sz = sizeof(rxBuf); cmd.tx_cmd_sz = sizeof(txBuf); + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); DELAY(PCF2123_DELAY); return (0); @@ -120,7 +122,9 @@ cmd.tx_cmd = txTimedate; cmd.rx_cmd_sz = sizeof(rxTimedate); cmd.tx_cmd_sz = sizeof(txTimedate); + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); DELAY(PCF2123_DELAY); ct.nsec = 0; @@ -178,7 +182,9 @@ txTimedate[6] = TOBCD(ct.mon); txTimedate[7] = TOBCD(ct.year - YEAR_BASE); + SPIBUS_ACQUIRE_BUS(device_get_parent(dev), dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + SPIBUS_RELEASE_BUS(device_get_parent(dev), dev); DELAY(PCF2123_DELAY); return (err); Index: sys/mips/conf/AR933X_BASE.hints =================================================================== --- sys/mips/conf/AR933X_BASE.hints +++ sys/mips/conf/AR933X_BASE.hints @@ -48,7 +48,9 @@ hint.spi.0.maddr=0x1f000000 hint.spi.0.msize=0x10 -hint.mx25l.0.at="spibus0" +# This is normally spibus0, but its spibus1 atm because +# a GPIO based bitbanging thing I am testing is claiming spibus0. +hint.mx25l.0.at="spibus1" hint.mx25l.0.cs=0 # Watchdog Index: sys/mips/conf/CARAMBOLA2 =================================================================== --- sys/mips/conf/CARAMBOLA2 +++ sys/mips/conf/CARAMBOLA2 @@ -30,6 +30,8 @@ #device iicbus #device iic +device gpiospi + # Options required for miiproxy and mdiobus options ARGE_MDIO # Export an MDIO bus separate from arge device miiproxy # MDIO bus <-> MII PHY rendezvous @@ -51,5 +53,9 @@ # Used for the static uboot partition map device geom_map +device spigen +device gpiospi + # Boot off of the rootfs, as defined in the geom_map setup. options ROOTDEVNAME=\"ufs:map/rootfs.uzip\" +# options ROOTDEVNAME=\"ufs:da0\" Index: sys/mips/conf/CARAMBOLA2.hints =================================================================== --- sys/mips/conf/CARAMBOLA2.hints +++ sys/mips/conf/CARAMBOLA2.hints @@ -99,3 +99,25 @@ # These are the GPIO LEDs and buttons which can be software controlled. hint.gpio.0.pinmask=0x00fc1803 + +# ok, gpiospi - just a local test, the LCD! +# note: we can't use it in its current form for the LCD, as the +# LCD has a data/command line which we would want to also assert, +# and the current gpiospi code doesn't support a "control" line. +# +# We should eventually extend it to support that so we can +# write a series of spi + lcd command+sequence writes. +# +hint.gpiospi.0.at="gpiobus0" +hint.gpiospi.0.pins=0xc80000 +# cs0=19, rst=20, dc=21, sck=22, mosi=23 +hint.gpiospi.0.sclk=1 +hint.gpiospi.0.mosi=2 +#hint.gpiospi.0.miso= +hint.gpiospi.0.cs0=0 +# rst: 20 +# dc: 21 + +# Try to get spigen to bind +hint.spigen.0.at="spibus0" +hint.spigen.1.at="spibus1" Index: sys/mips/mediatek/mtk_spi_v1.c =================================================================== --- sys/mips/mediatek/mtk_spi_v1.c +++ sys/mips/mediatek/mtk_spi_v1.c @@ -219,6 +219,26 @@ return (0); } +static void +mtk_spi_acquire_bus(device_t dev, device_t child) +{ + struct mtk_spi_softc *sc; + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + sc = device_get_softc(dev); + mtk_spi_chip_activate(sc); +} + +static void +mtk_spi_release_bus(device_t dev, device_t child) +{ + struct mtk_spi_softc *sc; + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + sc = device_get_softc(dev); + mtk_spi_chip_deactivate(sc); +} + static int mtk_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) { @@ -265,8 +285,6 @@ break; } - mtk_spi_chip_activate(sc); - if (cmd->tx_cmd_sz + cmd->rx_cmd_sz) { buf = (uint8_t *)(cmd->rx_cmd); tx_buf = (uint8_t *)(cmd->tx_cmd); @@ -308,7 +326,6 @@ } } mtk_spi_transfer_fail: - mtk_spi_chip_deactivate(sc); return (error); } @@ -328,6 +345,8 @@ DEVMETHOD(device_detach, mtk_spi_detach), DEVMETHOD(spibus_transfer, mtk_spi_transfer), + DEVMETHOD(spibus_acquire_bus, mtk_spi_acquire_bus), + DEVMETHOD(spibus_release_bus, mtk_spi_release_bus), /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_node, mtk_spi_get_node), Index: sys/mips/mediatek/mtk_spi_v2.c =================================================================== --- sys/mips/mediatek/mtk_spi_v2.c +++ sys/mips/mediatek/mtk_spi_v2.c @@ -224,6 +224,26 @@ return (0); } +static void +mtk_spi_acquire_bus(device_t dev, device_t child) +{ + struct mtk_spi_softc *sc; + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + sc = device_get_softc(dev); + mtk_spi_chip_activate(sc); +} + +static void +mtk_spi_release_bus(device_t dev, device_t child) +{ + struct mtk_spi_softc *sc; + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + sc = device_get_softc(dev); + mtk_spi_chip_deactivate(sc); +} + static int mtk_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) { @@ -269,8 +289,6 @@ cmd->rx_cmd_sz = cmd->rx_data_sz = 0; break; } - - mtk_spi_chip_activate(sc); if (cmd->tx_cmd_sz + cmd->rx_cmd_sz) { buf = (uint8_t *)(cmd->rx_cmd); @@ -313,7 +331,6 @@ } } mtk_spi_transfer_fail: - mtk_spi_chip_deactivate(sc); return (0); } @@ -333,6 +350,8 @@ DEVMETHOD(device_detach, mtk_spi_detach), DEVMETHOD(spibus_transfer, mtk_spi_transfer), + DEVMETHOD(spibus_acquire_bus, mtk_spi_acquire_bus), + DEVMETHOD(spibus_release_bus, mtk_spi_release_bus), /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_node, mtk_spi_get_node), Index: sys/mips/rt305x/rt305x_spi.c =================================================================== --- sys/mips/rt305x/rt305x_spi.c +++ sys/mips/rt305x/rt305x_spi.c @@ -214,6 +214,26 @@ return (0); } +static void +rt305x_spi_acquire_bus(device_t dev, device_t child) +{ + struct rt305x_spi_softc *sc; + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + sc = device_get_softc(dev); + rt305x_spi_chip_activate(sc); +} + +static void +rt305x_spi_release_bus(device_t dev, device_t child) +{ + struct rt305x_spi_softc *sc; + struct spibus_ivar *devi = SPIBUS_IVAR(child); + + sc = device_get_softc(dev); + rt305x_spi_chip_deactivate(sc); +} + static int rt305x_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) { @@ -262,8 +282,6 @@ break; } - rt305x_spi_chip_activate(sc); - if (cmd->tx_cmd_sz + cmd->rx_cmd_sz) { buf = (uint8_t *)(cmd->rx_cmd); tx_buf = (uint8_t *)(cmd->tx_cmd); @@ -305,7 +323,6 @@ } } rt305x_spi_transfer_fail: - rt305x_spi_chip_deactivate(sc); return (error); } @@ -327,6 +344,8 @@ DEVMETHOD(device_detach, rt305x_spi_detach), DEVMETHOD(spibus_transfer, rt305x_spi_transfer), + DEVMETHOD(spibus_acquire_bus, rt305x_spi_acquire_bus), + DEVMETHOD(spibus_release_bus, rt305x_spi_release_bus), #ifdef FDT /* ofw_bus interface */