diff options
Diffstat (limited to 'drivers/spi/spi-mpc512x-psc.c')
| -rw-r--r-- | drivers/spi/spi-mpc512x-psc.c | 77 |
1 files changed, 34 insertions, 43 deletions
diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index dbc5e999a1f..577d23a1276 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -16,10 +16,10 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/completion.h> #include <linux/io.h> @@ -39,6 +39,7 @@ struct mpc512x_psc_spi { unsigned int irq; u8 bits_per_word; struct clk *clk_mclk; + struct clk *clk_ipg; u32 mclk_rate; struct completion txisrdone; @@ -166,7 +167,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, } /* have the ISR trigger when the TX FIFO is empty */ - INIT_COMPLETION(mps->txisrdone); + reinit_completion(&mps->txisrdone); out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY); out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY); wait_for_completion(&mps->txisrdone); @@ -299,7 +300,8 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master, } m->status = status; - m->complete(m->context); + if (m->complete) + m->complete(m->context); if (status || !cs_change) mpc512x_psc_spi_deactivate_cs(spi); @@ -464,18 +466,14 @@ static void mpc512x_spi_cs_control(struct spi_device *spi, bool onoff) gpio_set_value(spi->cs_gpio, onoff); } -/* bus_num is used only for the case dev->platform_data == NULL */ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, - u32 size, unsigned int irq, - s16 bus_num) + u32 size, unsigned int irq) { struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct mpc512x_psc_spi *mps; struct spi_master *master; int ret; void *tempp; - int psc_num; - char clk_name[16]; struct clk *clk; master = spi_alloc_master(dev, sizeof *mps); @@ -488,7 +486,6 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, if (pdata == NULL) { mps->cs_control = mpc512x_spi_cs_control; - master->bus_num = bus_num; } else { mps->cs_control = pdata->cs_control; master->bus_num = pdata->bus_num; @@ -503,7 +500,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, master->cleanup = mpc512x_psc_spi_cleanup; master->dev.of_node = dev->of_node; - tempp = ioremap(regaddr, size); + tempp = devm_ioremap(dev, regaddr, size); if (!tempp) { dev_err(dev, "could not ioremap I/O port range\n"); ret = -EFAULT; @@ -512,41 +509,48 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, mps->psc = tempp; mps->fifo = (struct mpc512x_psc_fifo *)(tempp + sizeof(struct mpc52xx_psc)); - - ret = request_irq(mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED, - "mpc512x-psc-spi", mps); + ret = devm_request_irq(dev, mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED, + "mpc512x-psc-spi", mps); if (ret) goto free_master; 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; + clk = devm_clk_get(dev, "mclk"); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto free_master; + } ret = clk_prepare_enable(clk); if (ret) - goto free_irq; + goto free_master; mps->clk_mclk = clk; mps->mclk_rate = clk_get_rate(clk); + clk = devm_clk_get(dev, "ipg"); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto free_mclk_clock; + } + ret = clk_prepare_enable(clk); + if (ret) + goto free_mclk_clock; + mps->clk_ipg = clk; + ret = mpc512x_psc_spi_port_config(master, mps); if (ret < 0) - goto free_clock; + goto free_ipg_clock; - ret = spi_register_master(master); + ret = devm_spi_register_master(dev, master); if (ret < 0) - goto free_clock; + goto free_ipg_clock; return ret; -free_clock: +free_ipg_clock: + clk_disable_unprepare(mps->clk_ipg); +free_mclk_clock: clk_disable_unprepare(mps->clk_mclk); -free_irq: - free_irq(mps->irq, mps); free_master: - if (mps->psc) - iounmap(mps->psc); spi_master_put(master); return ret; @@ -554,15 +558,11 @@ free_master: static int mpc512x_psc_spi_do_remove(struct device *dev) { - struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct spi_master *master = dev_get_drvdata(dev); struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); - spi_unregister_master(master); clk_disable_unprepare(mps->clk_mclk); - free_irq(mps->irq, mps); - if (mps->psc) - iounmap(mps->psc); - spi_master_put(master); + clk_disable_unprepare(mps->clk_ipg); return 0; } @@ -571,7 +571,6 @@ static int mpc512x_psc_spi_of_probe(struct platform_device *op) { const u32 *regaddr_p; u64 regaddr64, size64; - s16 id = -1; regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { @@ -580,16 +579,8 @@ static int mpc512x_psc_spi_of_probe(struct platform_device *op) } regaddr64 = of_translate_address(op->dev.of_node, regaddr_p); - /* get PSC id (0..11, used by port_config) */ - id = of_alias_get_id(op->dev.of_node, "spi"); - if (id < 0) { - dev_err(&op->dev, "no alias id for %s\n", - op->dev.of_node->full_name); - return id; - } - return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, - irq_of_parse_and_map(op->dev.of_node, 0), id); + irq_of_parse_and_map(op->dev.of_node, 0)); } static int mpc512x_psc_spi_of_remove(struct platform_device *op) |
