Commit 84c86eda authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'spi/topic/mpc512x' into spi-next

parents 4faad26c a81a5094
...@@ -38,7 +38,8 @@ struct mpc512x_psc_spi { ...@@ -38,7 +38,8 @@ struct mpc512x_psc_spi {
struct mpc512x_psc_fifo __iomem *fifo; struct mpc512x_psc_fifo __iomem *fifo;
unsigned int irq; unsigned int irq;
u8 bits_per_word; u8 bits_per_word;
u32 mclk; struct clk *clk_mclk;
u32 mclk_rate;
struct completion txisrdone; struct completion txisrdone;
}; };
...@@ -72,6 +73,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) ...@@ -72,6 +73,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
struct mpc52xx_psc __iomem *psc = mps->psc; struct mpc52xx_psc __iomem *psc = mps->psc;
u32 sicr; u32 sicr;
u32 ccr; u32 ccr;
int speed;
u16 bclkdiv; u16 bclkdiv;
sicr = in_be32(&psc->sicr); sicr = in_be32(&psc->sicr);
...@@ -95,10 +97,10 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) ...@@ -95,10 +97,10 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
ccr = in_be32(&psc->ccr); ccr = in_be32(&psc->ccr);
ccr &= 0xFF000000; ccr &= 0xFF000000;
if (cs->speed_hz) speed = cs->speed_hz;
bclkdiv = (mps->mclk / cs->speed_hz) - 1; if (!speed)
else speed = 1000000; /* default 1MHz */
bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */ bclkdiv = (mps->mclk_rate / speed) - 1;
ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
out_be32(&psc->ccr, ccr); out_be32(&psc->ccr, ccr);
...@@ -386,19 +388,11 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, ...@@ -386,19 +388,11 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
{ {
struct mpc52xx_psc __iomem *psc = mps->psc; struct mpc52xx_psc __iomem *psc = mps->psc;
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo; struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
struct clk *spiclk;
int ret = 0;
char name[32];
u32 sicr; u32 sicr;
u32 ccr; u32 ccr;
int speed;
u16 bclkdiv; u16 bclkdiv;
sprintf(name, "psc%d_mclk", master->bus_num);
spiclk = clk_get(&master->dev, name);
clk_enable(spiclk);
mps->mclk = clk_get_rate(spiclk);
clk_put(spiclk);
/* Reset the PSC into a known state */ /* Reset the PSC into a known state */
out_8(&psc->command, MPC52xx_PSC_RST_RX); out_8(&psc->command, MPC52xx_PSC_RST_RX);
out_8(&psc->command, MPC52xx_PSC_RST_TX); out_8(&psc->command, MPC52xx_PSC_RST_TX);
...@@ -425,7 +419,8 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, ...@@ -425,7 +419,8 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
ccr = in_be32(&psc->ccr); ccr = in_be32(&psc->ccr);
ccr &= 0xFF000000; ccr &= 0xFF000000;
bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */ speed = 1000000; /* default 1MHz */
bclkdiv = (mps->mclk_rate / speed) - 1;
ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
out_be32(&psc->ccr, ccr); out_be32(&psc->ccr, ccr);
...@@ -445,7 +440,7 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, ...@@ -445,7 +440,7 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
mps->bits_per_word = 8; mps->bits_per_word = 8;
return ret; return 0;
} }
static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id)
...@@ -479,6 +474,9 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, ...@@ -479,6 +474,9 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
struct spi_master *master; struct spi_master *master;
int ret; int ret;
void *tempp; void *tempp;
int psc_num;
char clk_name[16];
struct clk *clk;
master = spi_alloc_master(dev, sizeof *mps); master = spi_alloc_master(dev, sizeof *mps);
if (master == NULL) if (master == NULL)
...@@ -521,16 +519,29 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, ...@@ -521,16 +519,29 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
goto free_master; goto free_master;
init_completion(&mps->txisrdone); init_completion(&mps->txisrdone);
psc_num = master->bus_num;
snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
clk = devm_clk_get(dev, clk_name);
if (IS_ERR(clk))
goto free_irq;
ret = clk_prepare_enable(clk);
if (ret)
goto free_irq;
mps->clk_mclk = clk;
mps->mclk_rate = clk_get_rate(clk);
ret = mpc512x_psc_spi_port_config(master, mps); ret = mpc512x_psc_spi_port_config(master, mps);
if (ret < 0) if (ret < 0)
goto free_irq; goto free_clock;
ret = spi_register_master(master); ret = spi_register_master(master);
if (ret < 0) if (ret < 0)
goto free_irq; goto free_clock;
return ret; return ret;
free_clock:
clk_disable_unprepare(mps->clk_mclk);
free_irq: free_irq:
free_irq(mps->irq, mps); free_irq(mps->irq, mps);
free_master: free_master:
...@@ -547,6 +558,7 @@ static int mpc512x_psc_spi_do_remove(struct device *dev) ...@@ -547,6 +558,7 @@ static int mpc512x_psc_spi_do_remove(struct device *dev)
struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
spi_unregister_master(master); spi_unregister_master(master);
clk_disable_unprepare(mps->clk_mclk);
free_irq(mps->irq, mps); free_irq(mps->irq, mps);
if (mps->psc) if (mps->psc)
iounmap(mps->psc); iounmap(mps->psc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment