efm32_spi_filltx(ddata);
-------- init_completion(&ddata->done);
++++++++ reinit_completion(&ddata->done);
efm32_spi_write32(ddata, REG_IF_TXBL | REG_IF_RXDATAV, REG_IEN);
return (reg & REG_ROUTE_LOCATION__MASK) >> __ffs(REG_ROUTE_LOCATION__MASK);
}
--- -----static int efm32_spi_probe_dt(struct platform_device *pdev,
+++ +++++static void efm32_spi_probe_dt(struct platform_device *pdev,
struct spi_master *master, struct efm32_spi_ddata *ddata)
{
struct device_node *np = pdev->dev.of_node;
u32 location;
int ret;
--- ----- if (!np)
--- ----- return 1;
--- -----
--- ----- ret = of_property_read_u32(np, "location", &location);
+++ +++++ ret = of_property_read_u32(np, "efm32,location", &location);
+++ +++++ if (ret)
+++ +++++ /* fall back to old and (wrongly) generic property "location" */
+++ +++++ ret = of_property_read_u32(np, "location", &location);
if (!ret) {
dev_dbg(&pdev->dev, "using location %u\n", location);
} else {
}
ddata->pdata.location = location;
-- -----
-- ----- /* spi core takes care about the bus number using an alias */
-- ----- master->bus_num = -1;
-- -----
--- ----- return 0;
}
static int efm32_spi_probe(struct platform_device *pdev)
int ret;
struct spi_master *master;
struct device_node *np = pdev->dev.of_node;
--- ----- unsigned int num_cs, i;
+++ +++++ int num_cs, i;
+++ +++++
+++ +++++ if (!np)
+++ +++++ return -EINVAL;
num_cs = of_gpio_named_count(np, "cs-gpios");
+++ +++++ if (num_cs < 0)
+++ +++++ return num_cs;
master = spi_alloc_master(&pdev->dev,
sizeof(*ddata) + num_cs * sizeof(unsigned));
ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs;
spin_lock_init(&ddata->lock);
++++++++ init_completion(&ddata->done);
ddata->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(ddata->clk)) {
goto err;
}
--- ----- ret = efm32_spi_probe_dt(pdev, master, ddata);
--- ----- if (ret > 0) {
--- ----- /* not created by device tree */
--- ----- const struct efm32_spi_pdata *pdata =
--- ----- dev_get_platdata(&pdev->dev);
--- -----
--- ----- if (pdata)
--- ----- ddata->pdata = *pdata;
--- ----- else
--- ----- ddata->pdata.location =
--- ----- efm32_spi_get_configured_location(ddata);
--- -----
--- ----- master->bus_num = pdev->id;
--- -----
--- ----- } else if (ret < 0) {
--- ----- goto err_disable_clk;
--- ----- }
+++ +++++ efm32_spi_probe_dt(pdev, master, ddata);
efm32_spi_write32(ddata, 0, REG_IEN);
efm32_spi_write32(ddata, REG_ROUTE_TXPEN | REG_ROUTE_RXPEN |
static const struct of_device_id efm32_spi_dt_ids[] = {
{
+++ +++++ .compatible = "energymicro,efm32-spi",
+++ +++++ }, {
+++ +++++ /* doesn't follow the "vendor,device" scheme, don't use */
.compatible = "efm32,spi",
}, {
/* sentinel */
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
++++++ ++#include <linux/regmap.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/io.h>
struct spi_bitbang bitbang;
struct platform_device *pdev;
------ -- void __iomem *base;
++++++ ++ struct regmap *regmap;
int irq;
------ -- struct clk *clk;
++++++ ++ struct clk *clk;
------ -- struct spi_transfer *cur_transfer;
++++++ ++ struct spi_transfer *cur_transfer;
struct chip_data *cur_chip;
size_t len;
void *tx;
u8 cs;
u16 void_write_data;
------ -- wait_queue_head_t waitq;
------ -- u32 waitflags;
++++++ ++ wait_queue_head_t waitq;
++++++ ++ u32 waitflags;
};
static inline int is_double_byte_mode(struct fsl_dspi *dspi)
{
------ -- return ((readl(dspi->base + SPI_CTAR(dspi->cs)) & SPI_FRAME_BITS_MASK)
------ -- == SPI_FRAME_BITS(8)) ? 0 : 1;
------ --}
++++++ ++ unsigned int val;
------ --static void set_bit_mode(struct fsl_dspi *dspi, unsigned char bits)
------ --{
------ -- u32 temp;
++++++ ++ regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), &val);
------ -- temp = readl(dspi->base + SPI_CTAR(dspi->cs));
------ -- temp &= ~SPI_FRAME_BITS_MASK;
------ -- temp |= SPI_FRAME_BITS(bits);
------ -- writel(temp, dspi->base + SPI_CTAR(dspi->cs));
++++++ ++ return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
}
static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
*/
if (tx_word && (dspi->len == 1)) {
dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
------ -- set_bit_mode(dspi, 8);
++++++ ++ regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs),
++++++ ++ SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
tx_word = 0;
}
dspi_pushr |= SPI_PUSHR_CTCNT; /* clear counter */
}
------ -- writel(dspi_pushr, dspi->base + SPI_PUSHR);
++++++ ++ regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
++++++ ++
tx_count++;
}
while ((dspi->rx < dspi->rx_end)
&& (rx_count < DSPI_FIFO_SIZE)) {
if (rx_word) {
++++++ ++ unsigned int val;
++++++ ++
if ((dspi->rx_end - dspi->rx) == 1)
break;
------ -- d = SPI_POPR_RXDATA(readl(dspi->base + SPI_POPR));
++++++ ++ regmap_read(dspi->regmap, SPI_POPR, &val);
++++++ ++ d = SPI_POPR_RXDATA(val);
if (!(dspi->dataflags & TRAN_STATE_RX_VOID))
*(u16 *)dspi->rx = d;
dspi->rx += 2;
} else {
------ -- d = SPI_POPR_RXDATA(readl(dspi->base + SPI_POPR));
++++++ ++ unsigned int val;
++++++ ++
++++++ ++ regmap_read(dspi->regmap, SPI_POPR, &val);
++++++ ++ d = SPI_POPR_RXDATA(val);
if (!(dspi->dataflags & TRAN_STATE_RX_VOID))
*(u8 *)dspi->rx = d;
dspi->rx++;
if (!dspi->tx)
dspi->dataflags |= TRAN_STATE_TX_VOID;
------ -- writel(dspi->cur_chip->mcr_val, dspi->base + SPI_MCR);
------ -- writel(dspi->cur_chip->ctar_val, dspi->base + SPI_CTAR(dspi->cs));
------ -- writel(SPI_RSER_EOQFE, dspi->base + SPI_RSER);
++++++ ++ regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val);
++++++ ++ regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), dspi->cur_chip->ctar_val);
++++++ ++ regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE);
if (t->speed_hz)
------ -- writel(dspi->cur_chip->ctar_val,
------ -- dspi->base + SPI_CTAR(dspi->cs));
++++++ ++ regmap_write(dspi->regmap, SPI_CTAR(dspi->cs),
++++++ ++ dspi->cur_chip->ctar_val);
dspi_transfer_write(dspi);
static void dspi_chipselect(struct spi_device *spi, int value)
{
struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
------ -- u32 pushr = readl(dspi->base + SPI_PUSHR);
++++++ ++ unsigned int pushr;
++++++ ++
++++++ ++ regmap_read(dspi->regmap, SPI_PUSHR, &pushr);
switch (value) {
case BITBANG_CS_ACTIVE:
break;
}
------ -- writel(pushr, dspi->base + SPI_PUSHR);
++++++ ++ regmap_write(dspi->regmap, SPI_PUSHR, pushr);
}
static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
/* Only alloc on first setup */
chip = spi_get_ctldata(spi);
if (chip == NULL) {
------ -- chip = kcalloc(1, sizeof(struct chip_data), GFP_KERNEL);
++++++ ++ chip = devm_kzalloc(&spi->dev, sizeof(struct chip_data),
++++++ ++ GFP_KERNEL);
if (!chip)
return -ENOMEM;
}
fmsz = spi->bits_per_word - 1;
} else {
pr_err("Invalid wordsize\n");
------ -- kfree(chip);
return -ENODEV;
}
{
struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id;
------ -- writel(SPI_SR_EOQF, dspi->base + SPI_SR);
++++++ ++ regmap_write(dspi->regmap, SPI_SR, SPI_SR_EOQF);
dspi_transfer_read(dspi);
if (!dspi->len) {
if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM)
------ -- set_bit_mode(dspi, 16);
++++++ ++ regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs),
++++++ ++ SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16));
++++++ ++
dspi->waitflags = 1;
wake_up_interruptible(&dspi->waitq);
} else {
static int dspi_resume(struct device *dev)
{
--------
struct spi_master *master = dev_get_drvdata(dev);
struct fsl_dspi *dspi = spi_master_get_devdata(master);
}
#endif /* CONFIG_PM_SLEEP */
------ --static const struct dev_pm_ops dspi_pm = {
------ -- SET_SYSTEM_SLEEP_PM_OPS(dspi_suspend, dspi_resume)
++++++ ++static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume);
++++++ ++
++++++ ++static struct regmap_config dspi_regmap_config = {
++++++ ++ .reg_bits = 32,
++++++ ++ .val_bits = 32,
++++++ ++ .reg_stride = 4,
++++++ ++ .max_register = 0x88,
};
static int dspi_probe(struct platform_device *pdev)
struct spi_master *master;
struct fsl_dspi *dspi;
struct resource *res;
++++++ ++ void __iomem *base;
int ret = 0, cs_num, bus_num;
master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi));
master->bus_num = bus_num;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
------ -- dspi->base = devm_ioremap_resource(&pdev->dev, res);
------ -- if (IS_ERR(dspi->base)) {
------ -- ret = PTR_ERR(dspi->base);
++++++ ++ base = devm_ioremap_resource(&pdev->dev, res);
++++++ ++ if (IS_ERR(base)) {
++++++ ++ ret = PTR_ERR(base);
goto out_master_put;
}
++++++ ++ dspi_regmap_config.lock_arg = dspi;
++++++ ++ dspi_regmap_config.val_format_endian =
++++++ ++ of_property_read_bool(np, "big-endian")
++++++ ++ ? REGMAP_ENDIAN_BIG : REGMAP_ENDIAN_DEFAULT;
++++++ ++ dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dspi", base,
++++++ ++ &dspi_regmap_config);
++++++ ++ if (IS_ERR(dspi->regmap)) {
++++++ ++ dev_err(&pdev->dev, "failed to init regmap: %ld\n",
++++++ ++ PTR_ERR(dspi->regmap));
++++++ ++ return PTR_ERR(dspi->regmap);
++++++ ++ }
++++++ ++
dspi->irq = platform_get_irq(pdev, 0);
if (dspi->irq < 0) {
dev_err(&pdev->dev, "can't get platform irq\n");
clk_prepare_enable(dspi->clk);
init_waitqueue_head(&dspi->waitq);
-------- platform_set_drvdata(pdev, dspi);
++++++++ platform_set_drvdata(pdev, master);
ret = spi_bitbang_start(&dspi->bitbang);
if (ret != 0) {
static int dspi_remove(struct platform_device *pdev)
{
-------- struct fsl_dspi *dspi = platform_get_drvdata(pdev);
++++++++ struct spi_master *master = platform_get_drvdata(pdev);
++++++++ struct fsl_dspi *dspi = spi_master_get_devdata(master);
/* Disconnect from the SPI framework */
spi_bitbang_stop(&dspi->bitbang);