#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/err.h>
-#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/reset.h>
#include <linux/spi/spi.h>
-#include <linux/clk/tegra.h>
#define SPI_COMMAND 0x000
#define SPI_GO BIT(30)
spinlock_t lock;
struct clk *clk;
+ struct reset_control *rst;
void __iomem *base;
unsigned irq;
- u32 spi_max_frequency;
u32 cur_speed;
struct spi_device *cur_spi;
static int tegra_sflash_runtime_suspend(struct device *dev);
static int tegra_sflash_runtime_resume(struct device *dev);
-static inline unsigned long tegra_sflash_readl(struct tegra_sflash_data *tsd,
+static inline u32 tegra_sflash_readl(struct tegra_sflash_data *tsd,
unsigned long reg)
{
return readl(tsd->base + reg);
}
static inline void tegra_sflash_writel(struct tegra_sflash_data *tsd,
- unsigned long val, unsigned long reg)
+ u32 val, unsigned long reg)
{
writel(val, tsd->base + reg);
}
struct tegra_sflash_data *tsd, struct spi_transfer *t)
{
unsigned nbytes;
- unsigned long status;
+ u32 status;
unsigned max_n_32bit = tsd->curr_xfer_words;
u8 *tx_buf = (u8 *)t->tx_buf + tsd->cur_tx_pos;
status = tegra_sflash_readl(tsd, SPI_STATUS);
while (!(status & SPI_TXF_FULL)) {
int i;
- unsigned int x = 0;
+ u32 x = 0;
for (i = 0; nbytes && (i < tsd->bytes_per_word);
i++, nbytes--)
- x |= ((*tx_buf++) << i*8);
+ x |= (u32)(*tx_buf++) << (i * 8);
tegra_sflash_writel(tsd, x, SPI_TX_FIFO);
if (!nbytes)
break;
static int tegra_sflash_read_rx_fifo_to_client_rxbuf(
struct tegra_sflash_data *tsd, struct spi_transfer *t)
{
- unsigned long status;
+ u32 status;
unsigned int read_words = 0;
u8 *rx_buf = (u8 *)t->rx_buf + tsd->cur_rx_pos;
status = tegra_sflash_readl(tsd, SPI_STATUS);
while (!(status & SPI_RXF_EMPTY)) {
int i;
- unsigned long x;
-
- x = tegra_sflash_readl(tsd, SPI_RX_FIFO);
+ u32 x = tegra_sflash_readl(tsd, SPI_RX_FIFO);
for (i = 0; (i < tsd->bytes_per_word); i++)
*rx_buf++ = (x >> (i*8)) & 0xFF;
read_words++;
static int tegra_sflash_start_cpu_based_transfer(
struct tegra_sflash_data *tsd, struct spi_transfer *t)
{
- unsigned long val = 0;
+ u32 val = 0;
unsigned cur_words;
if (tsd->cur_direction & DATA_DIR_TX)
{
struct tegra_sflash_data *tsd = spi_master_get_devdata(spi->master);
u32 speed;
- unsigned long command;
+ u32 command;
speed = t->speed_hz;
if (speed != tsd->cur_speed) {
tegra_sflash_writel(tsd, command, SPI_COMMAND);
tsd->command_reg = command;
- return tegra_sflash_start_cpu_based_transfer(tsd, t);
-}
-
-static int tegra_sflash_setup(struct spi_device *spi)
-{
- struct tegra_sflash_data *tsd = spi_master_get_devdata(spi->master);
-
- /* Set speed to the spi max fequency if spi device has not set */
- spi->max_speed_hz = spi->max_speed_hz ? : tsd->spi_max_frequency;
- return 0;
+ return tegra_sflash_start_cpu_based_transfer(tsd, t);
}
static int tegra_sflash_transfer_one_message(struct spi_master *master,
dev_err(tsd->dev,
"CpuXfer 0x%08x:0x%08x\n", tsd->command_reg,
tsd->dma_control_reg);
- tegra_periph_reset_assert(tsd->clk);
+ reset_control_assert(tsd->rst);
udelay(2);
- tegra_periph_reset_deassert(tsd->clk);
+ reset_control_deassert(tsd->rst);
complete(&tsd->xfer_completion);
goto exit;
}
return handle_cpu_based_xfer(tsd);
}
-static void tegra_sflash_parse_dt(struct tegra_sflash_data *tsd)
-{
- struct device_node *np = tsd->dev->of_node;
-
- if (of_property_read_u32(np, "spi-max-frequency",
- &tsd->spi_max_frequency))
- tsd->spi_max_frequency = 25000000; /* 25MHz */
-}
-
static struct of_device_id tegra_sflash_of_match[] = {
{ .compatible = "nvidia,tegra20-sflash", },
{}
/* the spi->mode bits understood by this driver: */
master->mode_bits = SPI_CPOL | SPI_CPHA;
- master->setup = tegra_sflash_setup;
master->transfer_one_message = tegra_sflash_transfer_one_message;
master->auto_runtime_pm = true;
master->num_chipselect = MAX_CHIP_SELECT;
- master->bus_num = -1;
platform_set_drvdata(pdev, master);
tsd = spi_master_get_devdata(master);
tsd->dev = &pdev->dev;
spin_lock_init(&tsd->lock);
- tegra_sflash_parse_dt(tsd);
+ if (of_property_read_u32(tsd->dev->of_node, "spi-max-frequency",
+ &master->max_speed_hz))
+ master->max_speed_hz = 25000000; /* 25MHz */
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
tsd->base = devm_ioremap_resource(&pdev->dev, r);
goto exit_free_irq;
}
+ tsd->rst = devm_reset_control_get(&pdev->dev, "spi");
+ if (IS_ERR(tsd->rst)) {
+ dev_err(&pdev->dev, "can not get reset\n");
+ ret = PTR_ERR(tsd->rst);
+ goto exit_free_irq;
+ }
+
init_completion(&tsd->xfer_completion);
pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) {
}
/* Reset controller */
- tegra_periph_reset_assert(tsd->clk);
+ reset_control_assert(tsd->rst);
udelay(2);
- tegra_periph_reset_deassert(tsd->clk);
+ reset_control_deassert(tsd->rst);
tsd->def_command_reg = SPI_M_S | SPI_CS_SW;
tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND);