Merge branch 'spi-5.5' into spi-next

This commit is contained in:
Mark Brown
2019-11-22 19:56:35 +00:00
73 changed files with 1416 additions and 713 deletions

View File

@ -92,7 +92,7 @@ static ssize_t driver_override_store(struct device *dev,
if (len) {
spi->driver_override = driver_override;
} else {
/* Emptry string, disable driver override */
/* Empty string, disable driver override */
spi->driver_override = NULL;
kfree(driver_override);
}
@ -469,7 +469,7 @@ static LIST_HEAD(board_list);
static LIST_HEAD(spi_controller_list);
/*
* Used to protect add/del opertion for board_info list and
* Used to protect add/del operation for board_info list and
* spi_controller list, and their matching process
* also used to protect object of type struct idr
*/
@ -775,6 +775,15 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
static void spi_set_cs(struct spi_device *spi, bool enable)
{
bool enable1 = enable;
if (!spi->controller->set_cs_timing) {
if (enable1)
spi_delay_exec(&spi->controller->cs_setup, NULL);
else
spi_delay_exec(&spi->controller->cs_hold, NULL);
}
if (spi->mode & SPI_CS_HIGH)
enable = !enable;
@ -800,6 +809,11 @@ static void spi_set_cs(struct spi_device *spi, bool enable)
} else if (spi->controller->set_cs) {
spi->controller->set_cs(spi, !enable);
}
if (!spi->controller->set_cs_timing) {
if (!enable1)
spi_delay_exec(&spi->controller->cs_inactive, NULL);
}
}
#ifdef CONFIG_HAS_DMA
@ -1106,42 +1120,79 @@ static void _spi_transfer_delay_ns(u32 ns)
}
}
static void _spi_transfer_cs_change_delay(struct spi_message *msg,
struct spi_transfer *xfer)
int spi_delay_to_ns(struct spi_delay *_delay, struct spi_transfer *xfer)
{
u32 delay = xfer->cs_change_delay;
u32 unit = xfer->cs_change_delay_unit;
u32 delay = _delay->value;
u32 unit = _delay->unit;
u32 hz;
/* return early on "fast" mode - for everything but USECS */
if (!delay && unit != SPI_DELAY_UNIT_USECS)
return;
if (!delay)
return 0;
switch (unit) {
case SPI_DELAY_UNIT_USECS:
/* for compatibility use default of 10us */
if (!delay)
delay = 10000;
else
delay *= 1000;
delay *= 1000;
break;
case SPI_DELAY_UNIT_NSECS: /* nothing to do here */
break;
case SPI_DELAY_UNIT_SCK:
/* clock cycles need to be obtained from spi_transfer */
if (!xfer)
return -EINVAL;
/* if there is no effective speed know, then approximate
* by underestimating with half the requested hz
*/
hz = xfer->effective_speed_hz ?: xfer->speed_hz / 2;
if (!hz)
return -EINVAL;
delay *= DIV_ROUND_UP(1000000000, hz);
break;
default:
return -EINVAL;
}
return delay;
}
EXPORT_SYMBOL_GPL(spi_delay_to_ns);
int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer)
{
int delay;
if (!_delay)
return -EINVAL;
delay = spi_delay_to_ns(_delay, xfer);
if (delay < 0)
return delay;
_spi_transfer_delay_ns(delay);
return 0;
}
EXPORT_SYMBOL_GPL(spi_delay_exec);
static void _spi_transfer_cs_change_delay(struct spi_message *msg,
struct spi_transfer *xfer)
{
u32 delay = xfer->cs_change_delay.value;
u32 unit = xfer->cs_change_delay.unit;
int ret;
/* return early on "fast" mode - for everything but USECS */
if (!delay) {
if (unit == SPI_DELAY_UNIT_USECS)
_spi_transfer_delay_ns(10000);
return;
}
ret = spi_delay_exec(&xfer->cs_change_delay, xfer);
if (ret) {
dev_err_once(&msg->spi->dev,
"Use of unsupported delay unit %i, using default of 10us\n",
xfer->cs_change_delay_unit);
delay = 10000;
unit);
_spi_transfer_delay_ns(10000);
}
/* now sleep for the requested amount of time */
_spi_transfer_delay_ns(delay);
}
/*
@ -1171,6 +1222,11 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
spi_statistics_add_transfer_stats(statm, xfer, ctlr);
spi_statistics_add_transfer_stats(stats, xfer, ctlr);
if (!ctlr->ptp_sts_supported) {
xfer->ptp_sts_word_pre = 0;
ptp_read_system_prets(xfer->ptp_sts);
}
if (xfer->tx_buf || xfer->rx_buf) {
reinit_completion(&ctlr->xfer_completion);
@ -1197,13 +1253,17 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
xfer->len);
}
if (!ctlr->ptp_sts_supported) {
ptp_read_system_postts(xfer->ptp_sts);
xfer->ptp_sts_word_post = xfer->len;
}
trace_spi_transfer_stop(msg, xfer);
if (msg->status != -EINPROGRESS)
goto out;
if (xfer->delay_usecs)
_spi_transfer_delay_ns(xfer->delay_usecs * 1000);
spi_transfer_delay_exec(xfer);
if (xfer->cs_change) {
if (list_is_last(&xfer->transfer_list,
@ -1265,6 +1325,7 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
*/
static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
{
struct spi_transfer *xfer;
struct spi_message *msg;
bool was_busy = false;
unsigned long flags;
@ -1391,6 +1452,13 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
goto out;
}
if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) {
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
xfer->ptp_sts_word_pre = 0;
ptp_read_system_prets(xfer->ptp_sts);
}
}
ret = ctlr->transfer_one_message(ctlr, msg);
if (ret) {
dev_err(&ctlr->dev,
@ -1418,6 +1486,99 @@ static void spi_pump_messages(struct kthread_work *work)
__spi_pump_messages(ctlr, true);
}
/**
* spi_take_timestamp_pre - helper for drivers to collect the beginning of the
* TX timestamp for the requested byte from the SPI
* transfer. The frequency with which this function
* must be called (once per word, once for the whole
* transfer, once per batch of words etc) is arbitrary
* as long as the @tx buffer offset is greater than or
* equal to the requested byte at the time of the
* call. The timestamp is only taken once, at the
* first such call. It is assumed that the driver
* advances its @tx buffer pointer monotonically.
* @ctlr: Pointer to the spi_controller structure of the driver
* @xfer: Pointer to the transfer being timestamped
* @tx: Pointer to the current word within the xfer->tx_buf that the driver is
* preparing to transmit right now.
* @irqs_off: If true, will disable IRQs and preemption for the duration of the
* transfer, for less jitter in time measurement. Only compatible
* with PIO drivers. If true, must follow up with
* spi_take_timestamp_post or otherwise system will crash.
* WARNING: for fully predictable results, the CPU frequency must
* also be under control (governor).
*/
void spi_take_timestamp_pre(struct spi_controller *ctlr,
struct spi_transfer *xfer,
const void *tx, bool irqs_off)
{
u8 bytes_per_word = DIV_ROUND_UP(xfer->bits_per_word, 8);
if (!xfer->ptp_sts)
return;
if (xfer->timestamped_pre)
return;
if (tx < (xfer->tx_buf + xfer->ptp_sts_word_pre * bytes_per_word))
return;
/* Capture the resolution of the timestamp */
xfer->ptp_sts_word_pre = (tx - xfer->tx_buf) / bytes_per_word;
xfer->timestamped_pre = true;
if (irqs_off) {
local_irq_save(ctlr->irq_flags);
preempt_disable();
}
ptp_read_system_prets(xfer->ptp_sts);
}
EXPORT_SYMBOL_GPL(spi_take_timestamp_pre);
/**
* spi_take_timestamp_post - helper for drivers to collect the end of the
* TX timestamp for the requested byte from the SPI
* transfer. Can be called with an arbitrary
* frequency: only the first call where @tx exceeds
* or is equal to the requested word will be
* timestamped.
* @ctlr: Pointer to the spi_controller structure of the driver
* @xfer: Pointer to the transfer being timestamped
* @tx: Pointer to the current word within the xfer->tx_buf that the driver has
* just transmitted.
* @irqs_off: If true, will re-enable IRQs and preemption for the local CPU.
*/
void spi_take_timestamp_post(struct spi_controller *ctlr,
struct spi_transfer *xfer,
const void *tx, bool irqs_off)
{
u8 bytes_per_word = DIV_ROUND_UP(xfer->bits_per_word, 8);
if (!xfer->ptp_sts)
return;
if (xfer->timestamped_post)
return;
if (tx < (xfer->tx_buf + xfer->ptp_sts_word_post * bytes_per_word))
return;
ptp_read_system_postts(xfer->ptp_sts);
if (irqs_off) {
local_irq_restore(ctlr->irq_flags);
preempt_enable();
}
/* Capture the resolution of the timestamp */
xfer->ptp_sts_word_post = (tx - xfer->tx_buf) / bytes_per_word;
xfer->timestamped_post = true;
}
EXPORT_SYMBOL_GPL(spi_take_timestamp_post);
/**
* spi_set_thread_rt - set the controller to pump at realtime priority
* @ctlr: controller to boost priority of
@ -1503,6 +1664,7 @@ EXPORT_SYMBOL_GPL(spi_get_next_queued_message);
*/
void spi_finalize_current_message(struct spi_controller *ctlr)
{
struct spi_transfer *xfer;
struct spi_message *mesg;
unsigned long flags;
int ret;
@ -1511,6 +1673,13 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
mesg = ctlr->cur_msg;
spin_unlock_irqrestore(&ctlr->queue_lock, flags);
if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) {
list_for_each_entry(xfer, &mesg->transfers, transfer_list) {
ptp_read_system_postts(xfer->ptp_sts);
xfer->ptp_sts_word_post = xfer->len;
}
}
spi_unmap_msg(ctlr, mesg);
if (ctlr->cur_msg_prepared && ctlr->unprepare_message) {
@ -2872,10 +3041,11 @@ struct spi_replaced_transfers *spi_replace_transfers(
/* add to list */
list_add(&xfer->transfer_list, rxfer->replaced_after);
/* clear cs_change and delay_usecs for all but the last */
/* clear cs_change and delay for all but the last */
if (i) {
xfer->cs_change = false;
xfer->delay_usecs = 0;
xfer->delay.value = 0;
}
}
@ -3092,7 +3262,29 @@ int spi_setup(struct spi_device *spi)
if (spi->controller->setup)
status = spi->controller->setup(spi);
spi_set_cs(spi, false);
if (spi->controller->auto_runtime_pm && spi->controller->set_cs) {
status = pm_runtime_get_sync(spi->controller->dev.parent);
if (status < 0) {
pm_runtime_put_noidle(spi->controller->dev.parent);
dev_err(&spi->controller->dev, "Failed to power device: %d\n",
status);
return status;
}
/*
* We do not want to return positive value from pm_runtime_get,
* there are many instances of devices calling spi_setup() and
* checking for a non-zero return value instead of a negative
* return value.
*/
status = 0;
spi_set_cs(spi, false);
pm_runtime_mark_last_busy(spi->controller->dev.parent);
pm_runtime_put_autosuspend(spi->controller->dev.parent);
} else {
spi_set_cs(spi, false);
}
if (spi->rt && !spi->controller->rt) {
spi->controller->rt = true;
@ -3115,18 +3307,71 @@ EXPORT_SYMBOL_GPL(spi_setup);
/**
* spi_set_cs_timing - configure CS setup, hold, and inactive delays
* @spi: the device that requires specific CS timing configuration
* @setup: CS setup time in terms of clock count
* @hold: CS hold time in terms of clock count
* @inactive_dly: CS inactive delay between transfers in terms of clock count
* @setup: CS setup time specified via @spi_delay
* @hold: CS hold time specified via @spi_delay
* @inactive: CS inactive delay between transfers specified via @spi_delay
*
* Return: zero on success, else a negative error code.
*/
void spi_set_cs_timing(struct spi_device *spi, u8 setup, u8 hold,
u8 inactive_dly)
int spi_set_cs_timing(struct spi_device *spi, struct spi_delay *setup,
struct spi_delay *hold, struct spi_delay *inactive)
{
size_t len;
if (spi->controller->set_cs_timing)
spi->controller->set_cs_timing(spi, setup, hold, inactive_dly);
return spi->controller->set_cs_timing(spi, setup, hold,
inactive);
if ((setup && setup->unit == SPI_DELAY_UNIT_SCK) ||
(hold && hold->unit == SPI_DELAY_UNIT_SCK) ||
(inactive && inactive->unit == SPI_DELAY_UNIT_SCK)) {
dev_err(&spi->dev,
"Clock-cycle delays for CS not supported in SW mode\n");
return -ENOTSUPP;
}
len = sizeof(struct spi_delay);
/* copy delays to controller */
if (setup)
memcpy(&spi->controller->cs_setup, setup, len);
else
memset(&spi->controller->cs_setup, 0, len);
if (hold)
memcpy(&spi->controller->cs_hold, hold, len);
else
memset(&spi->controller->cs_hold, 0, len);
if (inactive)
memcpy(&spi->controller->cs_inactive, inactive, len);
else
memset(&spi->controller->cs_inactive, 0, len);
return 0;
}
EXPORT_SYMBOL_GPL(spi_set_cs_timing);
static int _spi_xfer_word_delay_update(struct spi_transfer *xfer,
struct spi_device *spi)
{
int delay1, delay2;
delay1 = spi_delay_to_ns(&xfer->word_delay, xfer);
if (delay1 < 0)
return delay1;
delay2 = spi_delay_to_ns(&spi->word_delay, xfer);
if (delay2 < 0)
return delay2;
if (delay1 < delay2)
memcpy(&xfer->word_delay, &spi->word_delay,
sizeof(xfer->word_delay));
return 0;
}
static int __spi_validate(struct spi_device *spi, struct spi_message *message)
{
struct spi_controller *ctlr = spi->controller;
@ -3262,8 +3507,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
return -EINVAL;
}
if (xfer->word_delay_usecs < spi->word_delay_usecs)
xfer->word_delay_usecs = spi->word_delay_usecs;
if (_spi_xfer_word_delay_update(xfer, spi))
return -EINVAL;
}
message->status = -EINPROGRESS;
@ -3274,6 +3519,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
static int __spi_async(struct spi_device *spi, struct spi_message *message)
{
struct spi_controller *ctlr = spi->controller;
struct spi_transfer *xfer;
/*
* Some controllers do not support doing regular SPI transfers. Return
@ -3289,6 +3535,13 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
trace_spi_message_submit(message);
if (!ctlr->ptp_sts_supported) {
list_for_each_entry(xfer, &message->transfers, transfer_list) {
xfer->ptp_sts_word_pre = 0;
ptp_read_system_prets(xfer->ptp_sts);
}
}
return ctlr->transfer(spi, message);
}