diff options
Diffstat (limited to 'drivers/spi/spi-fsl-espi.c')
| -rw-r--r-- | drivers/spi/spi-fsl-espi.c | 115 |
1 files changed, 55 insertions, 60 deletions
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index cf2118dc91f4..f2f1d3298e6c 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Freescale eSPI controller driver. * * Copyright 2010 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/delay.h> #include <linux/err.h> @@ -152,7 +148,7 @@ static inline void fsl_espi_write_reg8(struct fsl_espi *espi, int offset, static int fsl_espi_check_message(struct spi_message *m) { - struct fsl_espi *espi = spi_master_get_devdata(m->spi->master); + struct fsl_espi *espi = spi_controller_get_devdata(m->spi->controller); struct spi_transfer *t, *first; if (m->frame_length > SPCOM_TRANLEN_MAX) { @@ -327,7 +323,7 @@ start: static void fsl_espi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) { - struct fsl_espi *espi = spi_master_get_devdata(spi->master); + struct fsl_espi *espi = spi_controller_get_devdata(spi->controller); int bits_per_word = t ? t->bits_per_word : spi->bits_per_word; u32 pm, hz = t ? t->speed_hz : spi->max_speed_hz; struct fsl_espi_cs *cs = spi_get_ctldata(spi); @@ -349,13 +345,13 @@ static void fsl_espi_setup_transfer(struct spi_device *spi, /* don't write the mode register if the mode doesn't change */ if (cs->hw_mode != hw_mode_old) - fsl_espi_write_reg(espi, ESPI_SPMODEx(spi->chip_select), + fsl_espi_write_reg(espi, ESPI_SPMODEx(spi_get_chipselect(spi, 0)), cs->hw_mode); } static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) { - struct fsl_espi *espi = spi_master_get_devdata(spi->master); + struct fsl_espi *espi = spi_controller_get_devdata(spi->controller); unsigned int rx_len = t->len; u32 mask, spcom; int ret; @@ -363,7 +359,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) reinit_completion(&espi->done); /* Set SPCOM[CS] and SPCOM[TRANLEN] field */ - spcom = SPCOM_CS(spi->chip_select); + spcom = SPCOM_CS(spi_get_chipselect(spi, 0)); spcom |= SPCOM_TRANLEN(t->len - 1); /* configure RXSKIP mode */ @@ -400,7 +396,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans) { - struct fsl_espi *espi = spi_master_get_devdata(m->spi->master); + struct fsl_espi *espi = spi_controller_get_devdata(m->spi->controller); struct spi_device *spi = m->spi; int ret; @@ -431,16 +427,15 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans) ret = fsl_espi_bufs(spi, trans); - if (trans->delay_usecs) - udelay(trans->delay_usecs); + spi_transfer_delay_exec(trans); return ret; } -static int fsl_espi_do_one_msg(struct spi_master *master, +static int fsl_espi_do_one_msg(struct spi_controller *host, struct spi_message *m) { - unsigned int delay_usecs = 0, rx_nbits = 0; + unsigned int rx_nbits = 0, delay_nsecs = 0; struct spi_transfer *t, trans = {}; int ret; @@ -449,8 +444,10 @@ static int fsl_espi_do_one_msg(struct spi_master *master, goto out; list_for_each_entry(t, &m->transfers, transfer_list) { - if (t->delay_usecs > delay_usecs) - delay_usecs = t->delay_usecs; + unsigned int delay = spi_delay_to_ns(&t->delay, t); + + if (delay > delay_nsecs) + delay_nsecs = delay; if (t->rx_nbits > rx_nbits) rx_nbits = t->rx_nbits; } @@ -461,7 +458,8 @@ static int fsl_espi_do_one_msg(struct spi_master *master, trans.len = m->frame_length; trans.speed_hz = t->speed_hz; trans.bits_per_word = t->bits_per_word; - trans.delay_usecs = delay_usecs; + trans.delay.value = delay_nsecs; + trans.delay.unit = SPI_DELAY_UNIT_NSECS; trans.rx_nbits = rx_nbits; if (trans.len) @@ -472,7 +470,7 @@ out: if (m->status == -EINPROGRESS) m->status = ret; - spi_finalize_current_message(master); + spi_finalize_current_message(host); return ret; } @@ -490,11 +488,11 @@ static int fsl_espi_setup(struct spi_device *spi) spi_set_ctldata(spi, cs); } - espi = spi_master_get_devdata(spi->master); + espi = spi_controller_get_devdata(spi->controller); pm_runtime_get_sync(espi->dev); - cs->hw_mode = fsl_espi_read_reg(espi, ESPI_SPMODEx(spi->chip_select)); + cs->hw_mode = fsl_espi_read_reg(espi, ESPI_SPMODEx(spi_get_chipselect(spi, 0))); /* mask out bits we are going to set */ cs->hw_mode &= ~(CSMODE_CP_BEGIN_EDGECLK | CSMODE_CI_INACTIVEHIGH | CSMODE_REV); @@ -515,7 +513,6 @@ static int fsl_espi_setup(struct spi_device *spi) fsl_espi_setup_transfer(spi, NULL); - pm_runtime_mark_last_busy(espi->dev); pm_runtime_put_autosuspend(espi->dev); return 0; @@ -559,13 +556,14 @@ static void fsl_espi_cpu_irq(struct fsl_espi *espi, u32 events) static irqreturn_t fsl_espi_irq(s32 irq, void *context_data) { struct fsl_espi *espi = context_data; - u32 events; + u32 events, mask; spin_lock(&espi->lock); /* Get interrupt events(tx/rx) */ events = fsl_espi_read_reg(espi, ESPI_SPIE); - if (!events) { + mask = fsl_espi_read_reg(espi, ESPI_SPIM); + if (!(events & mask)) { spin_unlock(&espi->lock); return IRQ_NONE; } @@ -585,8 +583,8 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data) #ifdef CONFIG_PM static int fsl_espi_runtime_suspend(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct fsl_espi *espi = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct fsl_espi *espi = spi_controller_get_devdata(host); u32 regval; regval = fsl_espi_read_reg(espi, ESPI_SPMODE); @@ -598,8 +596,8 @@ static int fsl_espi_runtime_suspend(struct device *dev) static int fsl_espi_runtime_resume(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct fsl_espi *espi = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct fsl_espi *espi = spi_controller_get_devdata(host); u32 regval; regval = fsl_espi_read_reg(espi, ESPI_SPMODE); @@ -617,8 +615,8 @@ static size_t fsl_espi_max_message_size(struct spi_device *spi) static void fsl_espi_init_regs(struct device *dev, bool initial) { - struct spi_master *master = dev_get_drvdata(dev); - struct fsl_espi *espi = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct fsl_espi *espi = spi_controller_get_devdata(host); struct device_node *nc; u32 csmode, cs, prop; int ret; @@ -630,10 +628,10 @@ static void fsl_espi_init_regs(struct device *dev, bool initial) fsl_espi_write_reg(espi, ESPI_SPIE, 0xffffffff); /* Init eSPI CS mode register */ - for_each_available_child_of_node(master->dev.of_node, nc) { + for_each_available_child_of_node(host->dev.of_node, nc) { /* get chip select */ ret = of_property_read_u32(nc, "reg", &cs); - if (ret || cs >= master->num_chipselect) + if (ret || cs >= host->num_chipselect) continue; csmode = CSMODE_INIT_VAL; @@ -665,28 +663,28 @@ static void fsl_espi_init_regs(struct device *dev, bool initial) static int fsl_espi_probe(struct device *dev, struct resource *mem, unsigned int irq, unsigned int num_cs) { - struct spi_master *master; + struct spi_controller *host; struct fsl_espi *espi; int ret; - master = spi_alloc_master(dev, sizeof(struct fsl_espi)); - if (!master) + host = spi_alloc_host(dev, sizeof(struct fsl_espi)); + if (!host) return -ENOMEM; - dev_set_drvdata(dev, master); + dev_set_drvdata(dev, host); - master->mode_bits = SPI_RX_DUAL | SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | - SPI_LSB_FIRST | SPI_LOOP; - master->dev.of_node = dev->of_node; - master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); - master->setup = fsl_espi_setup; - master->cleanup = fsl_espi_cleanup; - master->transfer_one_message = fsl_espi_do_one_msg; - master->auto_runtime_pm = true; - master->max_message_size = fsl_espi_max_message_size; - master->num_chipselect = num_cs; + host->mode_bits = SPI_RX_DUAL | SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | + SPI_LSB_FIRST | SPI_LOOP; + host->dev.of_node = dev->of_node; + host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); + host->setup = fsl_espi_setup; + host->cleanup = fsl_espi_cleanup; + host->transfer_one_message = fsl_espi_do_one_msg; + host->auto_runtime_pm = true; + host->max_message_size = fsl_espi_max_message_size; + host->num_chipselect = num_cs; - espi = spi_master_get_devdata(master); + espi = spi_controller_get_devdata(host); spin_lock_init(&espi->lock); espi->dev = dev; @@ -697,8 +695,8 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem, goto err_probe; } /* determined by clock divider fields DIV16/PM in register SPMODEx */ - master->min_speed_hz = DIV_ROUND_UP(espi->spibrg, 4 * 16 * 16); - master->max_speed_hz = DIV_ROUND_UP(espi->spibrg, 4); + host->min_speed_hz = DIV_ROUND_UP(espi->spibrg, 4 * 16 * 16); + host->max_speed_hz = DIV_ROUND_UP(espi->spibrg, 4); init_completion(&espi->done); @@ -721,13 +719,12 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem, pm_runtime_enable(dev); pm_runtime_get_sync(dev); - ret = devm_spi_register_master(dev, master); + ret = devm_spi_register_controller(dev, host); if (ret < 0) goto err_pm; - dev_info(dev, "at 0x%p (irq = %u)\n", espi->reg_base, irq); + dev_info(dev, "irq = %u\n", irq); - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); return 0; @@ -737,7 +734,7 @@ err_pm: pm_runtime_disable(dev); pm_runtime_set_suspended(dev); err_probe: - spi_master_put(master); + spi_controller_put(host); return ret; } @@ -784,20 +781,18 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) return fsl_espi_probe(dev, &mem, irq, num_cs); } -static int of_fsl_espi_remove(struct platform_device *dev) +static void of_fsl_espi_remove(struct platform_device *dev) { pm_runtime_disable(&dev->dev); - - return 0; } #ifdef CONFIG_PM_SLEEP static int of_fsl_espi_suspend(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); + struct spi_controller *host = dev_get_drvdata(dev); int ret; - ret = spi_master_suspend(master); + ret = spi_controller_suspend(host); if (ret) return ret; @@ -806,7 +801,7 @@ static int of_fsl_espi_suspend(struct device *dev) static int of_fsl_espi_resume(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); + struct spi_controller *host = dev_get_drvdata(dev); int ret; fsl_espi_init_regs(dev, false); @@ -815,7 +810,7 @@ static int of_fsl_espi_resume(struct device *dev) if (ret < 0) return ret; - return spi_master_resume(master); + return spi_controller_resume(host); } #endif /* CONFIG_PM_SLEEP */ |
