Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e2c225d authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'spi/fix/core' into spi-linus

parents 7e22e911 13a42798
Loading
Loading
Loading
Loading
+20 −8
Original line number Original line Diff line number Diff line
@@ -370,6 +370,17 @@ static void spi_dev_set_name(struct spi_device *spi)
		     spi->chip_select);
		     spi->chip_select);
}
}


static int spi_dev_check(struct device *dev, void *data)
{
	struct spi_device *spi = to_spi_device(dev);
	struct spi_device *new_spi = data;

	if (spi->master == new_spi->master &&
	    spi->chip_select == new_spi->chip_select)
		return -EBUSY;
	return 0;
}

/**
/**
 * spi_add_device - Add spi_device allocated with spi_alloc_device
 * spi_add_device - Add spi_device allocated with spi_alloc_device
 * @spi: spi_device to register
 * @spi: spi_device to register
@@ -384,7 +395,6 @@ int spi_add_device(struct spi_device *spi)
	static DEFINE_MUTEX(spi_add_lock);
	static DEFINE_MUTEX(spi_add_lock);
	struct spi_master *master = spi->master;
	struct spi_master *master = spi->master;
	struct device *dev = master->dev.parent;
	struct device *dev = master->dev.parent;
	struct device *d;
	int status;
	int status;


	/* Chipselects are numbered 0..max; validate. */
	/* Chipselects are numbered 0..max; validate. */
@@ -404,12 +414,10 @@ int spi_add_device(struct spi_device *spi)
	 */
	 */
	mutex_lock(&spi_add_lock);
	mutex_lock(&spi_add_lock);


	d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
	status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
	if (d != NULL) {
	if (status) {
		dev_err(dev, "chipselect %d already in use\n",
		dev_err(dev, "chipselect %d already in use\n",
				spi->chip_select);
				spi->chip_select);
		put_device(d);
		status = -EBUSY;
		goto done;
		goto done;
	}
	}


@@ -591,8 +599,10 @@ static int spi_transfer_one_message(struct spi_master *master,
			goto out;
			goto out;
		}
		}


		if (ret > 0)
		if (ret > 0) {
			ret = 0;
			wait_for_completion(&master->xfer_completion);
			wait_for_completion(&master->xfer_completion);
		}


		trace_spi_transfer_stop(msg, xfer);
		trace_spi_transfer_stop(msg, xfer);


@@ -632,7 +642,7 @@ static int spi_transfer_one_message(struct spi_master *master,
 *
 *
 * Called by SPI drivers using the core transfer_one_message()
 * Called by SPI drivers using the core transfer_one_message()
 * implementation to notify it that the current interrupt driven
 * implementation to notify it that the current interrupt driven
 * transfer has finised and the next one may be scheduled.
 * transfer has finished and the next one may be scheduled.
 */
 */
void spi_finalize_current_transfer(struct spi_master *master)
void spi_finalize_current_transfer(struct spi_master *master)
{
{
@@ -735,7 +745,9 @@ static void spi_pump_messages(struct kthread_work *work)
	ret = master->transfer_one_message(master, master->cur_msg);
	ret = master->transfer_one_message(master, master->cur_msg);
	if (ret) {
	if (ret) {
		dev_err(&master->dev,
		dev_err(&master->dev,
			"failed to transfer one message from queue\n");
			"failed to transfer one message from queue: %d\n", ret);
		master->cur_msg->status = ret;
		spi_finalize_current_message(master);
		return;
		return;
	}
	}
}
}
+7 −5
Original line number Original line Diff line number Diff line
@@ -277,15 +277,17 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
 * @unprepare_transfer_hardware: there are currently no more messages on the
 * @unprepare_transfer_hardware: there are currently no more messages on the
 *	queue so the subsystem notifies the driver that it may relax the
 *	queue so the subsystem notifies the driver that it may relax the
 *	hardware by issuing this call
 *	hardware by issuing this call
 * @set_cs: assert or deassert chip select, true to assert.  May be called
 * @set_cs: set the logic level of the chip select line.  May be called
 *          from interrupt context.
 *          from interrupt context.
 * @prepare_message: set up the controller to transfer a single message,
 * @prepare_message: set up the controller to transfer a single message,
 *                   for example doing DMA mapping.  Called from threaded
 *                   for example doing DMA mapping.  Called from threaded
 *                   context.
 *                   context.
 * @transfer_one: transfer a single spi_transfer. When the
 * @transfer_one: transfer a single spi_transfer.
 *	          driver is finished with this transfer it must call
 *                  - return 0 if the transfer is finished,
 *	          spi_finalize_current_transfer() so the subsystem can issue
 *                  - return 1 if the transfer is still in progress. When
 *                the next transfer
 *                    the driver is finished with this transfer it must
 *                    call spi_finalize_current_transfer() so the subsystem
 *                    can issue the next transfer
 * @unprepare_message: undo any work done by prepare_message().
 * @unprepare_message: undo any work done by prepare_message().
 * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
 * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
 *	number. Any individual value may be -ENOENT for CS lines that
 *	number. Any individual value may be -ENOENT for CS lines that