Commit c508709b authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/topic/res', 'spi/topic/rockchip',...

Merge remote-tracking branches 'spi/topic/res', 'spi/topic/rockchip', 'spi/topic/sh', 'spi/topic/ti-qspi' and 'spi/topic/xilinx' into spi-next
...@@ -9,6 +9,7 @@ Required Properties: ...@@ -9,6 +9,7 @@ Required Properties:
"rockchip,rk3066-spi" for rk3066. "rockchip,rk3066-spi" for rk3066.
"rockchip,rk3188-spi", "rockchip,rk3066-spi" for rk3188. "rockchip,rk3188-spi", "rockchip,rk3066-spi" for rk3188.
"rockchip,rk3288-spi", "rockchip,rk3066-spi" for rk3288. "rockchip,rk3288-spi", "rockchip,rk3066-spi" for rk3288.
"rockchip,rk3399-spi", "rockchip,rk3066-spi" for rk3399.
- reg: physical base address of the controller and length of memory mapped - reg: physical base address of the controller and length of memory mapped
region. region.
- interrupts: The interrupt number to the cpu. The interrupt specifier format - interrupts: The interrupt number to the cpu. The interrupt specifier format
......
Xilinx SPI controller Device Tree Bindings
-------------------------------------------------
Required properties:
- compatible : Should be "xlnx,xps-spi-2.00.a" or "xlnx,xps-spi-2.00.b"
- reg : Physical base address and size of SPI registers map.
- interrupts : Property with a value describing the interrupt
number.
- interrupt-parent : Must be core interrupt controller
Optional properties:
- xlnx,num-ss-bits : Number of chip selects used.
Example:
axi_quad_spi@41e00000 {
compatible = "xlnx,xps-spi-2.00.a";
interrupt-parent = <&intc>;
interrupts = <0 31 1>;
reg = <0x41e00000 0x10000>;
xlnx,num-ss-bits = <0x1>;
};
...@@ -487,7 +487,7 @@ config SPI_RB4XX ...@@ -487,7 +487,7 @@ config SPI_RB4XX
config SPI_RSPI config SPI_RSPI
tristate "Renesas RSPI/QSPI controller" tristate "Renesas RSPI/QSPI controller"
depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
help help
SPI driver for Renesas RSPI and QSPI blocks. SPI driver for Renesas RSPI and QSPI blocks.
...@@ -537,7 +537,7 @@ config SPI_SC18IS602 ...@@ -537,7 +537,7 @@ config SPI_SC18IS602
config SPI_SH_MSIOF config SPI_SH_MSIOF
tristate "SuperH MSIOF SPI controller" tristate "SuperH MSIOF SPI controller"
depends on HAVE_CLK && HAS_DMA depends on HAVE_CLK && HAS_DMA
depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
help help
SPI driver for SuperH and SH Mobile MSIOF blocks. SPI driver for SuperH and SH Mobile MSIOF blocks.
...@@ -556,7 +556,7 @@ config SPI_SH_SCI ...@@ -556,7 +556,7 @@ config SPI_SH_SCI
config SPI_SH_HSPI config SPI_SH_HSPI
tristate "SuperH HSPI controller" tristate "SuperH HSPI controller"
depends on ARCH_SHMOBILE || COMPILE_TEST depends on ARCH_RENESAS || COMPILE_TEST
help help
SPI driver for SuperH HSPI blocks. SPI driver for SuperH HSPI blocks.
......
...@@ -13,20 +13,14 @@ ...@@ -13,20 +13,14 @@
* *
*/ */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/dmaengine.h>
#include <linux/delay.h> #include <linux/module.h>
#include <linux/interrupt.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/scatterlist.h>
#include <linux/of.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/io.h> #include <linux/scatterlist.h>
#include <linux/dmaengine.h>
#define DRIVER_NAME "rockchip-spi" #define DRIVER_NAME "rockchip-spi"
...@@ -179,7 +173,7 @@ struct rockchip_spi { ...@@ -179,7 +173,7 @@ struct rockchip_spi {
u8 tmode; u8 tmode;
u8 bpw; u8 bpw;
u8 n_bytes; u8 n_bytes;
u8 rsd_nsecs; u32 rsd_nsecs;
unsigned len; unsigned len;
u32 speed; u32 speed;
...@@ -192,8 +186,6 @@ struct rockchip_spi { ...@@ -192,8 +186,6 @@ struct rockchip_spi {
/* protect state */ /* protect state */
spinlock_t lock; spinlock_t lock;
struct completion xfer_completion;
u32 use_dma; u32 use_dma;
struct sg_table tx_sg; struct sg_table tx_sg;
struct sg_table rx_sg; struct sg_table rx_sg;
...@@ -265,7 +257,10 @@ static inline u32 rx_max(struct rockchip_spi *rs) ...@@ -265,7 +257,10 @@ static inline u32 rx_max(struct rockchip_spi *rs)
static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
{ {
u32 ser; u32 ser;
struct rockchip_spi *rs = spi_master_get_devdata(spi->master); struct spi_master *master = spi->master;
struct rockchip_spi *rs = spi_master_get_devdata(master);
pm_runtime_get_sync(rs->dev);
ser = readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & SER_MASK; ser = readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & SER_MASK;
...@@ -290,6 +285,8 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) ...@@ -290,6 +285,8 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
ser &= ~(1 << spi->chip_select); ser &= ~(1 << spi->chip_select);
writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER); writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER);
pm_runtime_put_sync(rs->dev);
} }
static int rockchip_spi_prepare_message(struct spi_master *master, static int rockchip_spi_prepare_message(struct spi_master *master,
...@@ -319,12 +316,12 @@ static void rockchip_spi_handle_err(struct spi_master *master, ...@@ -319,12 +316,12 @@ static void rockchip_spi_handle_err(struct spi_master *master,
*/ */
if (rs->use_dma) { if (rs->use_dma) {
if (rs->state & RXBUSY) { if (rs->state & RXBUSY) {
dmaengine_terminate_all(rs->dma_rx.ch); dmaengine_terminate_async(rs->dma_rx.ch);
flush_fifo(rs); flush_fifo(rs);
} }
if (rs->state & TXBUSY) if (rs->state & TXBUSY)
dmaengine_terminate_all(rs->dma_tx.ch); dmaengine_terminate_async(rs->dma_tx.ch);
} }
spin_unlock_irqrestore(&rs->lock, flags); spin_unlock_irqrestore(&rs->lock, flags);
...@@ -433,7 +430,7 @@ static void rockchip_spi_dma_txcb(void *data) ...@@ -433,7 +430,7 @@ static void rockchip_spi_dma_txcb(void *data)
spin_unlock_irqrestore(&rs->lock, flags); spin_unlock_irqrestore(&rs->lock, flags);
} }
static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) static int rockchip_spi_prepare_dma(struct rockchip_spi *rs)
{ {
unsigned long flags; unsigned long flags;
struct dma_slave_config rxconf, txconf; struct dma_slave_config rxconf, txconf;
...@@ -456,6 +453,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) ...@@ -456,6 +453,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs)
rs->dma_rx.ch, rs->dma_rx.ch,
rs->rx_sg.sgl, rs->rx_sg.nents, rs->rx_sg.sgl, rs->rx_sg.nents,
rs->dma_rx.direction, DMA_PREP_INTERRUPT); rs->dma_rx.direction, DMA_PREP_INTERRUPT);
if (!rxdesc)
return -EINVAL;
rxdesc->callback = rockchip_spi_dma_rxcb; rxdesc->callback = rockchip_spi_dma_rxcb;
rxdesc->callback_param = rs; rxdesc->callback_param = rs;
...@@ -473,6 +472,11 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) ...@@ -473,6 +472,11 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs)
rs->dma_tx.ch, rs->dma_tx.ch,
rs->tx_sg.sgl, rs->tx_sg.nents, rs->tx_sg.sgl, rs->tx_sg.nents,
rs->dma_tx.direction, DMA_PREP_INTERRUPT); rs->dma_tx.direction, DMA_PREP_INTERRUPT);
if (!txdesc) {
if (rxdesc)
dmaengine_terminate_sync(rs->dma_rx.ch);
return -EINVAL;
}
txdesc->callback = rockchip_spi_dma_txcb; txdesc->callback = rockchip_spi_dma_txcb;
txdesc->callback_param = rs; txdesc->callback_param = rs;
...@@ -494,6 +498,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) ...@@ -494,6 +498,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs)
dmaengine_submit(txdesc); dmaengine_submit(txdesc);
dma_async_issue_pending(rs->dma_tx.ch); dma_async_issue_pending(rs->dma_tx.ch);
} }
return 0;
} }
static void rockchip_spi_config(struct rockchip_spi *rs) static void rockchip_spi_config(struct rockchip_spi *rs)
...@@ -503,7 +509,8 @@ static void rockchip_spi_config(struct rockchip_spi *rs) ...@@ -503,7 +509,8 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
int rsd = 0; int rsd = 0;
u32 cr0 = (CR0_BHT_8BIT << CR0_BHT_OFFSET) u32 cr0 = (CR0_BHT_8BIT << CR0_BHT_OFFSET)
| (CR0_SSD_ONE << CR0_SSD_OFFSET); | (CR0_SSD_ONE << CR0_SSD_OFFSET)
| (CR0_EM_BIG << CR0_EM_OFFSET);
cr0 |= (rs->n_bytes << CR0_DFS_OFFSET); cr0 |= (rs->n_bytes << CR0_DFS_OFFSET);
cr0 |= ((rs->mode & 0x3) << CR0_SCPH_OFFSET); cr0 |= ((rs->mode & 0x3) << CR0_SCPH_OFFSET);
...@@ -606,12 +613,12 @@ static int rockchip_spi_transfer_one( ...@@ -606,12 +613,12 @@ static int rockchip_spi_transfer_one(
if (rs->use_dma) { if (rs->use_dma) {
if (rs->tmode == CR0_XFM_RO) { if (rs->tmode == CR0_XFM_RO) {
/* rx: dma must be prepared first */ /* rx: dma must be prepared first */
rockchip_spi_prepare_dma(rs); ret = rockchip_spi_prepare_dma(rs);
spi_enable_chip(rs, 1); spi_enable_chip(rs, 1);
} else { } else {
/* tx or tr: spi must be enabled first */ /* tx or tr: spi must be enabled first */
spi_enable_chip(rs, 1); spi_enable_chip(rs, 1);
rockchip_spi_prepare_dma(rs); ret = rockchip_spi_prepare_dma(rs);
} }
} else { } else {
spi_enable_chip(rs, 1); spi_enable_chip(rs, 1);
...@@ -717,8 +724,14 @@ static int rockchip_spi_probe(struct platform_device *pdev) ...@@ -717,8 +724,14 @@ static int rockchip_spi_probe(struct platform_device *pdev)
master->handle_err = rockchip_spi_handle_err; master->handle_err = rockchip_spi_handle_err;
rs->dma_tx.ch = dma_request_slave_channel(rs->dev, "tx"); rs->dma_tx.ch = dma_request_slave_channel(rs->dev, "tx");
if (!rs->dma_tx.ch) if (IS_ERR_OR_NULL(rs->dma_tx.ch)) {
/* Check tx to see if we need defer probing driver */
if (PTR_ERR(rs->dma_tx.ch) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
goto err_get_fifo_len;
}
dev_warn(rs->dev, "Failed to request TX DMA channel\n"); dev_warn(rs->dev, "Failed to request TX DMA channel\n");
}
rs->dma_rx.ch = dma_request_slave_channel(rs->dev, "rx"); rs->dma_rx.ch = dma_request_slave_channel(rs->dev, "rx");
if (!rs->dma_rx.ch) { if (!rs->dma_rx.ch) {
...@@ -871,6 +884,7 @@ static const struct of_device_id rockchip_spi_dt_match[] = { ...@@ -871,6 +884,7 @@ static const struct of_device_id rockchip_spi_dt_match[] = {
{ .compatible = "rockchip,rk3066-spi", }, { .compatible = "rockchip,rk3066-spi", },
{ .compatible = "rockchip,rk3188-spi", }, { .compatible = "rockchip,rk3188-spi", },
{ .compatible = "rockchip,rk3288-spi", }, { .compatible = "rockchip,rk3288-spi", },
{ .compatible = "rockchip,rk3399-spi", },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match); MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match);
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
...@@ -44,8 +46,9 @@ struct ti_qspi { ...@@ -44,8 +46,9 @@ struct ti_qspi {
struct spi_master *master; struct spi_master *master;
void __iomem *base; void __iomem *base;
void __iomem *ctrl_base;
void __iomem *mmap_base; void __iomem *mmap_base;
struct regmap *ctrl_base;
unsigned int ctrl_reg;
struct clk *fclk; struct clk *fclk;
struct device *dev; struct device *dev;
...@@ -55,7 +58,7 @@ struct ti_qspi { ...@@ -55,7 +58,7 @@ struct ti_qspi {
u32 cmd; u32 cmd;
u32 dc; u32 dc;
bool ctrl_mod; bool mmap_enabled;
}; };
#define QSPI_PID (0x0) #define QSPI_PID (0x0)
...@@ -65,11 +68,8 @@ struct ti_qspi { ...@@ -65,11 +68,8 @@ struct ti_qspi {
#define QSPI_SPI_CMD_REG (0x48) #define QSPI_SPI_CMD_REG (0x48)
#define QSPI_SPI_STATUS_REG (0x4c) #define QSPI_SPI_STATUS_REG (0x4c)
#define QSPI_SPI_DATA_REG (0x50) #define QSPI_SPI_DATA_REG (0x50)
#define QSPI_SPI_SETUP0_REG (0x54) #define QSPI_SPI_SETUP_REG(n) ((0x54 + 4 * n))
#define QSPI_SPI_SWITCH_REG (0x64) #define QSPI_SPI_SWITCH_REG (0x64)
#define QSPI_SPI_SETUP1_REG (0x58)
#define QSPI_SPI_SETUP2_REG (0x5c)
#define QSPI_SPI_SETUP3_REG (0x60)
#define QSPI_SPI_DATA_REG_1 (0x68) #define QSPI_SPI_DATA_REG_1 (0x68)
#define QSPI_SPI_DATA_REG_2 (0x6c) #define QSPI_SPI_DATA_REG_2 (0x6c)
#define QSPI_SPI_DATA_REG_3 (0x70) #define QSPI_SPI_DATA_REG_3 (0x70)
...@@ -109,6 +109,17 @@ struct ti_qspi { ...@@ -109,6 +109,17 @@ struct ti_qspi {
#define QSPI_AUTOSUSPEND_TIMEOUT 2000 #define QSPI_AUTOSUSPEND_TIMEOUT 2000
#define MEM_CS_EN(n) ((n + 1) << 8)
#define MEM_CS_MASK (7 << 8)
#define MM_SWITCH 0x1
#define QSPI_SETUP_RD_NORMAL (0x0 << 12)
#define QSPI_SETUP_RD_DUAL (0x1 << 12)
#define QSPI_SETUP_RD_QUAD (0x3 << 12)
#define QSPI_SETUP_ADDR_SHIFT 8
#define QSPI_SETUP_DUMMY_SHIFT 10
static inline unsigned long ti_qspi_read(struct ti_qspi *qspi, static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
unsigned long reg) unsigned long reg)
{ {
...@@ -366,6 +377,72 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t) ...@@ -366,6 +377,72 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t)
return 0; return 0;
} }
static void ti_qspi_enable_memory_map(struct spi_device *spi)
{
struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
if (qspi->ctrl_base) {
regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg,
MEM_CS_EN(spi->chip_select),
MEM_CS_MASK);
}
qspi->mmap_enabled = true;
}
static void ti_qspi_disable_memory_map(struct spi_device *spi)
{
struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
if (qspi->ctrl_base)
regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg,
0, MEM_CS_MASK);
qspi->mmap_enabled = false;
}
static void ti_qspi_setup_mmap_read(struct spi_device *spi,
struct spi_flash_read_message *msg)
{
struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
u32 memval = msg->read_opcode;
switch (msg->data_nbits) {
case SPI_NBITS_QUAD:
memval |= QSPI_SETUP_RD_QUAD;
break;
case SPI_NBITS_DUAL:
memval |= QSPI_SETUP_RD_DUAL;
break;
default:
memval |= QSPI_SETUP_RD_NORMAL;
break;
}
memval |= ((msg->addr_width - 1) << QSPI_SETUP_ADDR_SHIFT |
msg->dummy_bytes << QSPI_SETUP_DUMMY_SHIFT);
ti_qspi_write(qspi, memval,
QSPI_SPI_SETUP_REG(spi->chip_select));
}
static int ti_qspi_spi_flash_read(struct spi_device *spi,
struct spi_flash_read_message *msg)
{
struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
int ret = 0;
mutex_lock(&qspi->list_lock);
if (!qspi->mmap_enabled)
ti_qspi_enable_memory_map(spi);
ti_qspi_setup_mmap_read(spi, msg);
memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len);
msg->retlen = msg->len;
mutex_unlock(&qspi->list_lock);
return ret;
}
static int ti_qspi_start_transfer_one(struct spi_master *master, static int ti_qspi_start_transfer_one(struct spi_master *master,
struct spi_message *m) struct spi_message *m)
{ {
...@@ -398,6 +475,9 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, ...@@ -398,6 +475,9 @@ static int ti_qspi_start_transfer_one(struct spi_master *master,
mutex_lock(&qspi->list_lock); mutex_lock(&qspi->list_lock);
if (qspi->mmap_enabled)
ti_qspi_disable_memory_map(spi);
list_for_each_entry(t, &m->transfers, transfer_list) { list_for_each_entry(t, &m->transfers, transfer_list) {
qspi->cmd |= QSPI_WLEN(t->bits_per_word); qspi->cmd |= QSPI_WLEN(t->bits_per_word);
...@@ -441,7 +521,7 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -441,7 +521,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
{ {
struct ti_qspi *qspi; struct ti_qspi *qspi;
struct spi_master *master; struct spi_master *master;
struct resource *r, *res_ctrl, *res_mmap; struct resource *r, *res_mmap;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
u32 max_freq; u32 max_freq;
int ret = 0, num_cs, irq; int ret = 0, num_cs, irq;
...@@ -487,16 +567,6 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -487,16 +567,6 @@ static int ti_qspi_probe(struct platform_device *pdev)
} }
} }
res_ctrl = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "qspi_ctrlmod");
if (res_ctrl == NULL) {
res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 2);
if (res_ctrl == NULL) {
dev_dbg(&pdev->dev,
"control module resources not required\n");
}
}
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n"); dev_err(&pdev->dev, "no irq resource?\n");
...@@ -511,20 +581,31 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -511,20 +581,31 @@ static int ti_qspi_probe(struct platform_device *pdev)
goto free_master; goto free_master;
} }
if (res_ctrl) { if (res_mmap) {
qspi->ctrl_mod = true; qspi->mmap_base = devm_ioremap_resource(&pdev->dev,
qspi->ctrl_base = devm_ioremap_resource(&pdev->dev, res_ctrl); res_mmap);
if (IS_ERR(qspi->ctrl_base)) { master->spi_flash_read = ti_qspi_spi_flash_read;
ret = PTR_ERR(qspi->ctrl_base); if (IS_ERR(qspi->mmap_base)) {
goto free_master; dev_err(&pdev->dev,
"falling back to PIO mode\n");
master->spi_flash_read = NULL;
} }
} }
qspi->mmap_enabled = false;
if (res_mmap) { if (of_property_read_bool(np, "syscon-chipselects")) {
qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap); qspi->ctrl_base =
if (IS_ERR(qspi->mmap_base)) { syscon_regmap_lookup_by_phandle(np,
ret = PTR_ERR(qspi->mmap_base); "syscon-chipselects");
goto free_master; if (IS_ERR(qspi->ctrl_base))
return PTR_ERR(qspi->ctrl_base);
ret = of_property_read_u32_index(np,
"syscon-chipselects",
1, &qspi->ctrl_reg);
if (ret) {
dev_err(&pdev->dev,
"couldn't get ctrl_mod reg index\n");
return ret;
} }
} }
......
...@@ -604,6 +604,10 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); ...@@ -604,6 +604,10 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
* SPI resource management while processing a SPI message * SPI resource management while processing a SPI message
*/ */
typedef void (*spi_res_release_t)(struct spi_master *master,
struct spi_message *msg,
void *res);
/** /**
* struct spi_res - spi resource management structure * struct spi_res - spi resource management structure
* @entry: list entry * @entry: list entry
...@@ -613,9 +617,6 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); ...@@ -613,9 +617,6 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
* this is based on ideas from devres, but focused on life-cycle * this is based on ideas from devres, but focused on life-cycle
* management during spi_message processing * management during spi_message processing
*/ */
typedef void (*spi_res_release_t)(struct spi_master *master,
struct spi_message *msg,
void *res);
struct spi_res { struct spi_res {
struct list_head entry; struct list_head entry;
spi_res_release_t release; spi_res_release_t release;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment