Skip to content

Commit

Permalink
spi/pxa2xx: convert to the common clk framework
Browse files Browse the repository at this point in the history
Convert clk_enable() to clk_prepare_enable() and clk_disable() to
clk_disable_unprepare() respectively in order to support the common clk
framework. Otherwise we get warnings on the console as the clock is not
prepared before it is enabled.

In addition we must cache the maximum clock rate to drv_data->max_clk_rate
at probe time because clk_get_rate() cannot be called in tasklet context.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Mika Westerberg authored and Mark Brown committed Jan 26, 2013
1 parent 7f86bde commit 3343b7a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 31 deletions.
33 changes: 20 additions & 13 deletions drivers/spi/spi-pxa2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/clk.h>

#include <asm/io.h>
#include <asm/irq.h>
Expand Down Expand Up @@ -114,6 +115,9 @@ struct driver_data {
u32 clear_sr;
u32 mask_sr;

/* Maximun clock rate */
unsigned long max_clk_rate;

/* Message Transfer pump */
struct tasklet_struct pump_transfers;

Expand Down Expand Up @@ -891,9 +895,12 @@ static int set_dma_burst_and_threshold(struct chip_data *chip,
return retval;
}

static unsigned int ssp_get_clk_div(struct ssp_device *ssp, int rate)
static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
{
unsigned long ssp_clk = clk_get_rate(ssp->clk);
unsigned long ssp_clk = drv_data->max_clk_rate;
const struct ssp_device *ssp = drv_data->ssp;

rate = min_t(int, ssp_clk, rate);

if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP)
return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8;
Expand All @@ -908,7 +915,6 @@ static void pump_transfers(unsigned long data)
struct spi_transfer *transfer = NULL;
struct spi_transfer *previous = NULL;
struct chip_data *chip = NULL;
struct ssp_device *ssp = drv_data->ssp;
void __iomem *reg = drv_data->ioaddr;
u32 clk_div = 0;
u8 bits = 0;
Expand Down Expand Up @@ -1005,7 +1011,7 @@ static void pump_transfers(unsigned long data)
if (transfer->bits_per_word)
bits = transfer->bits_per_word;

clk_div = ssp_get_clk_div(ssp, speed);
clk_div = ssp_get_clk_div(drv_data, speed);

if (bits <= 8) {
drv_data->n_bytes = 1;
Expand Down Expand Up @@ -1214,7 +1220,6 @@ static int setup(struct spi_device *spi)
struct pxa2xx_spi_chip *chip_info = NULL;
struct chip_data *chip;
struct driver_data *drv_data = spi_master_get_devdata(spi->master);
struct ssp_device *ssp = drv_data->ssp;
unsigned int clk_div;
uint tx_thres = TX_THRESH_DFLT;
uint rx_thres = RX_THRESH_DFLT;
Expand Down Expand Up @@ -1296,7 +1301,7 @@ static int setup(struct spi_device *spi)
}
}

clk_div = ssp_get_clk_div(ssp, spi->max_speed_hz);
clk_div = ssp_get_clk_div(drv_data, spi->max_speed_hz);
chip->speed_hz = spi->max_speed_hz;

chip->cr0 = clk_div
Expand All @@ -1312,12 +1317,12 @@ static int setup(struct spi_device *spi)
/* NOTE: PXA25x_SSP _could_ use external clocking ... */
if (!pxa25x_ssp_comp(drv_data))
dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
clk_get_rate(ssp->clk)
drv_data->max_clk_rate
/ (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)),
chip->enable_dma ? "DMA" : "PIO");
else
dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
clk_get_rate(ssp->clk) / 2
drv_data->max_clk_rate / 2
/ (1 + ((chip->cr0 & SSCR0_SCR(0x0ff)) >> 8)),
chip->enable_dma ? "DMA" : "PIO");

Expand Down Expand Up @@ -1470,7 +1475,9 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
}

/* Enable SOC clock */
clk_enable(ssp->clk);
clk_prepare_enable(ssp->clk);

drv_data->max_clk_rate = clk_get_rate(ssp->clk);

/* Load default SSP configuration */
write_SSCR0(0, drv_data->ioaddr);
Expand Down Expand Up @@ -1499,7 +1506,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
return status;

out_error_clock_enabled:
clk_disable(ssp->clk);
clk_disable_unprepare(ssp->clk);

out_error_dma_alloc:
if (drv_data->tx_channel != -1)
Expand Down Expand Up @@ -1527,7 +1534,7 @@ static int pxa2xx_spi_remove(struct platform_device *pdev)

/* Disable the SSP at the peripheral and SOC level */
write_SSCR0(0, drv_data->ioaddr);
clk_disable(ssp->clk);
clk_disable_unprepare(ssp->clk);

/* Release DMA */
if (drv_data->master_info->enable_dma) {
Expand Down Expand Up @@ -1571,7 +1578,7 @@ static int pxa2xx_spi_suspend(struct device *dev)
if (status != 0)
return status;
write_SSCR0(0, drv_data->ioaddr);
clk_disable(ssp->clk);
clk_disable_unprepare(ssp->clk);

return 0;
}
Expand All @@ -1590,7 +1597,7 @@ static int pxa2xx_spi_resume(struct device *dev)
DRCMR_MAPVLD | drv_data->tx_channel;

/* Enable the SSP clock */
clk_enable(ssp->clk);
clk_prepare_enable(ssp->clk);

/* Start the queue running */
status = spi_master_resume(drv_data->master);
Expand Down
18 changes: 0 additions & 18 deletions include/linux/spi/pxa2xx_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,5 @@ static inline void pxa_free_dma(int dma_ch)
{
}

/*
* The CE4100 does not have the clk framework implemented and SPI clock can
* not be switched on/off or the divider changed.
*/
static inline void clk_disable(struct clk *clk)
{
}

static inline int clk_enable(struct clk *clk)
{
return 0;
}

static inline unsigned long clk_get_rate(struct clk *clk)
{
return 3686400;
}

#endif
#endif

0 comments on commit 3343b7a

Please sign in to comment.