spi/omap-100k: Factor message transfer function out of work queue
In preparation for removing the custom workqueue. Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
69ea672a13
commit
e8153ab3d7
1 changed files with 68 additions and 65 deletions
|
@ -321,10 +321,76 @@ static int omap1_spi100k_setup(struct spi_device *spi)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int omap1_spi100k_transfer_one_message(struct spi_master *master,
|
||||
struct spi_message *m)
|
||||
{
|
||||
struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
|
||||
struct spi_device *spi = m->spi;
|
||||
struct spi_transfer *t = NULL;
|
||||
int cs_active = 0;
|
||||
int par_override = 0;
|
||||
int status = 0;
|
||||
|
||||
list_for_each_entry(t, &m->transfers, transfer_list) {
|
||||
if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
|
||||
status = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (par_override || t->speed_hz || t->bits_per_word) {
|
||||
par_override = 1;
|
||||
status = omap1_spi100k_setup_transfer(spi, t);
|
||||
if (status < 0)
|
||||
break;
|
||||
if (!t->speed_hz && !t->bits_per_word)
|
||||
par_override = 0;
|
||||
}
|
||||
|
||||
if (!cs_active) {
|
||||
omap1_spi100k_force_cs(spi100k, 1);
|
||||
cs_active = 1;
|
||||
}
|
||||
|
||||
if (t->len) {
|
||||
unsigned count;
|
||||
|
||||
count = omap1_spi100k_txrx_pio(spi, t);
|
||||
m->actual_length += count;
|
||||
|
||||
if (count != t->len) {
|
||||
status = -EIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (t->delay_usecs)
|
||||
udelay(t->delay_usecs);
|
||||
|
||||
/* ignore the "leave it on after last xfer" hint */
|
||||
|
||||
if (t->cs_change) {
|
||||
omap1_spi100k_force_cs(spi100k, 0);
|
||||
cs_active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore defaults if they were overriden */
|
||||
if (par_override) {
|
||||
par_override = 0;
|
||||
status = omap1_spi100k_setup_transfer(spi, NULL);
|
||||
}
|
||||
|
||||
if (cs_active)
|
||||
omap1_spi100k_force_cs(spi100k, 0);
|
||||
|
||||
m->status = status;
|
||||
m->complete(m->context);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void omap1_spi100k_work(struct work_struct *work)
|
||||
{
|
||||
struct omap1_spi100k *spi100k;
|
||||
int status = 0;
|
||||
|
||||
spi100k = container_of(work, struct omap1_spi100k, work);
|
||||
spin_lock_irq(&spi100k->lock);
|
||||
|
@ -340,11 +406,6 @@ static void omap1_spi100k_work(struct work_struct *work)
|
|||
*/
|
||||
while (!list_empty(&spi100k->msg_queue)) {
|
||||
struct spi_message *m;
|
||||
struct spi_device *spi;
|
||||
struct spi_transfer *t = NULL;
|
||||
int cs_active = 0;
|
||||
struct omap1_spi100k_cs *cs;
|
||||
int par_override = 0;
|
||||
|
||||
m = container_of(spi100k->msg_queue.next, struct spi_message,
|
||||
queue);
|
||||
|
@ -352,62 +413,7 @@ static void omap1_spi100k_work(struct work_struct *work)
|
|||
list_del_init(&m->queue);
|
||||
spin_unlock_irq(&spi100k->lock);
|
||||
|
||||
spi = m->spi;
|
||||
cs = spi->controller_state;
|
||||
|
||||
list_for_each_entry(t, &m->transfers, transfer_list) {
|
||||
if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
|
||||
status = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (par_override || t->speed_hz || t->bits_per_word) {
|
||||
par_override = 1;
|
||||
status = omap1_spi100k_setup_transfer(spi, t);
|
||||
if (status < 0)
|
||||
break;
|
||||
if (!t->speed_hz && !t->bits_per_word)
|
||||
par_override = 0;
|
||||
}
|
||||
|
||||
if (!cs_active) {
|
||||
omap1_spi100k_force_cs(spi100k, 1);
|
||||
cs_active = 1;
|
||||
}
|
||||
|
||||
if (t->len) {
|
||||
unsigned count;
|
||||
|
||||
count = omap1_spi100k_txrx_pio(spi, t);
|
||||
m->actual_length += count;
|
||||
|
||||
if (count != t->len) {
|
||||
status = -EIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (t->delay_usecs)
|
||||
udelay(t->delay_usecs);
|
||||
|
||||
/* ignore the "leave it on after last xfer" hint */
|
||||
|
||||
if (t->cs_change) {
|
||||
omap1_spi100k_force_cs(spi100k, 0);
|
||||
cs_active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore defaults if they were overriden */
|
||||
if (par_override) {
|
||||
par_override = 0;
|
||||
status = omap1_spi100k_setup_transfer(spi, NULL);
|
||||
}
|
||||
|
||||
if (cs_active)
|
||||
omap1_spi100k_force_cs(spi100k, 0);
|
||||
|
||||
m->status = status;
|
||||
m->complete(m->context);
|
||||
omap1_spi100k_transfer_one_message(m->spi->master, m);
|
||||
|
||||
spin_lock_irq(&spi100k->lock);
|
||||
}
|
||||
|
@ -415,9 +421,6 @@ static void omap1_spi100k_work(struct work_struct *work)
|
|||
clk_disable(spi100k->ick);
|
||||
clk_disable(spi100k->fck);
|
||||
spin_unlock_irq(&spi100k->lock);
|
||||
|
||||
if (status < 0)
|
||||
printk(KERN_WARNING "spi transfer failed with %d\n", status);
|
||||
}
|
||||
|
||||
static int omap1_spi100k_transfer(struct spi_device *spi, struct spi_message *m)
|
||||
|
|
Loading…
Reference in a new issue