Merge "spi: spi_qsd: Add multi-ee support."

This commit is contained in:
Linux Build Service Account 2014-06-06 16:35:18 -07:00 committed by Gerrit - the friendly Code Review server
commit bb75883e9f

View file

@ -1726,6 +1726,69 @@ error:
msm_spi_free_cs_gpio(dd);
}
static void reset_core(struct msm_spi *dd)
{
msm_spi_register_init(dd);
/*
* The SPI core generates a bogus input overrun error on some targets,
* when a transition from run to reset state occurs and if the FIFO has
* an odd number of entries. Hence we disable the INPUT_OVER_RUN_ERR_EN
* bit.
*/
msm_spi_enable_error_flags(dd);
writel_relaxed(SPI_IO_C_NO_TRI_STATE, dd->base + SPI_IO_CONTROL);
msm_spi_set_state(dd, SPI_OP_STATE_RESET);
}
static void put_local_resources(struct msm_spi *dd)
{
msm_spi_disable_irqs(dd);
clk_disable_unprepare(dd->clk);
clk_disable_unprepare(dd->pclk);
/* Free the spi clk, miso, mosi, cs gpio */
if (dd->pdata && dd->pdata->gpio_release)
dd->pdata->gpio_release();
msm_spi_free_gpios(dd);
}
static int get_local_resources(struct msm_spi *dd)
{
int ret = -EINVAL;
/* Configure the spi clk, miso, mosi and cs gpio */
if (dd->pdata->gpio_config) {
ret = dd->pdata->gpio_config();
if (ret) {
dev_err(dd->dev,
"%s: error configuring GPIOs\n",
__func__);
return ret;
}
}
ret = msm_spi_request_gpios(dd);
if (ret)
return ret;
ret = clk_prepare_enable(dd->clk);
if (ret)
goto clk0_err;
ret = clk_prepare_enable(dd->pclk);
if (ret)
goto clk1_err;
msm_spi_enable_irqs(dd);
return 0;
clk1_err:
clk_disable_unprepare(dd->clk);
clk0_err:
msm_spi_free_gpios(dd);
return ret;
}
/**
* msm_spi_transfer_one_message: To process one spi message at a time
* @master: spi master controller reference
@ -1759,6 +1822,7 @@ static int msm_spi_transfer_one_message(struct spi_master *master,
status_error = -EINVAL;
msg->status = status_error;
spi_finalize_current_message(master);
put_local_resources(dd);
return 0;
}
}
@ -1769,6 +1833,21 @@ static int msm_spi_transfer_one_message(struct spi_master *master,
dd->transfer_pending = 1;
dd->cur_msg = msg;
spin_unlock_irqrestore(&dd->queue_lock, flags);
/*
* get local resources for each transfer to ensure we're in a good
* state and not interfering with other EE's using this device
*/
if (get_local_resources(dd))
return -EINVAL;
reset_core(dd);
if (dd->use_dma) {
msm_spi_bam_pipe_connect(dd, &dd->bam.prod,
&dd->bam.prod.config);
msm_spi_bam_pipe_connect(dd, &dd->bam.cons,
&dd->bam.cons.config);
}
if (dd->suspended || !msm_spi_is_valid_state(dd)) {
dev_err(dd->dev, "%s: SPI operational state not valid\n",
__func__);
@ -1794,6 +1873,17 @@ static int msm_spi_transfer_one_message(struct spi_master *master,
if (dd->suspended)
wake_up_interruptible(&dd->continue_suspend);
/*
* Put local resources prior to calling finalize to ensure the hw
* is in a known state before notifying the calling thread (which is a
* different context since we're running in the spi kthread here) to
* prevent race conditions between us and any other EE's using this hw.
*/
put_local_resources(dd);
if (dd->use_dma) {
msm_spi_bam_pipe_disconnect(dd, &dd->bam.prod);
msm_spi_bam_pipe_disconnect(dd, &dd->bam.cons);
}
dd->cur_msg->status = status_error;
spi_finalize_current_message(master);
return 0;
@ -2088,15 +2178,9 @@ static int msm_spi_bam_pipe_init(struct msm_spi *dd,
memset(pipe_conf->desc.base, 0x00, pipe_conf->desc.size);
pipe->handle = pipe_handle;
rc = msm_spi_bam_pipe_connect(dd, pipe, pipe_conf);
if (rc)
goto connect_err;
return 0;
connect_err:
dma_free_coherent(dd->dev, pipe_conf->desc.size,
pipe_conf->desc.base, pipe_conf->desc.phys_base);
config_err:
sps_free_endpoint(pipe_handle);
@ -2652,18 +2736,9 @@ static int msm_spi_pm_suspend_runtime(struct device *device)
wait_event_interruptible(dd->continue_suspend,
!dd->transfer_pending);
msm_spi_disable_irqs(dd);
clk_disable_unprepare(dd->clk);
clk_disable_unprepare(dd->pclk);
if (dd->pdata && !dd->pdata->active_only)
msm_spi_clk_path_unvote(dd);
/* Free the spi clk, miso, mosi, cs gpio */
if (dd->pdata && dd->pdata->gpio_release)
dd->pdata->gpio_release();
msm_spi_free_gpios(dd);
suspend_exit:
return 0;
}
@ -2673,7 +2748,6 @@ static int msm_spi_pm_resume_runtime(struct device *device)
struct platform_device *pdev = to_platform_device(device);
struct spi_master *master = platform_get_drvdata(pdev);
struct msm_spi *dd;
int ret = 0;
dev_dbg(device, "pm_runtime: resuming...\n");
if (!master)
@ -2685,27 +2759,9 @@ static int msm_spi_pm_resume_runtime(struct device *device)
if (!dd->suspended)
return 0;
/* Configure the spi clk, miso, mosi and cs gpio */
if (dd->pdata->gpio_config) {
ret = dd->pdata->gpio_config();
if (ret) {
dev_err(dd->dev,
"%s: error configuring GPIOs\n",
__func__);
return ret;
}
}
ret = msm_spi_request_gpios(dd);
if (ret)
return ret;
msm_spi_clk_path_init(dd);
if (!dd->pdata->active_only)
msm_spi_clk_path_vote(dd);
clk_prepare_enable(dd->clk);
clk_prepare_enable(dd->pclk);
msm_spi_enable_irqs(dd);
dd->suspended = 0;
resume_exit: