summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-mpc512x-psc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-mpc512x-psc.c')
-rw-r--r--drivers/spi/spi-mpc512x-psc.c192
1 files changed, 57 insertions, 135 deletions
diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c
index 03630359ce70..3c1638ba5bee 100644
--- a/drivers/spi/spi-mpc512x-psc.c
+++ b/drivers/spi/spi-mpc512x-psc.c
@@ -14,15 +14,13 @@
#include <linux/kernel.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>
+#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/spi/spi.h>
-#include <linux/fsl_devices.h>
#include <asm/mpc52xx_psc.h>
enum {
@@ -51,16 +49,12 @@ enum {
__ret; })
struct mpc512x_psc_spi {
- void (*cs_control)(struct spi_device *spi, bool on);
-
/* driver internal data */
int type;
void __iomem *psc;
struct mpc512x_psc_fifo __iomem *fifo;
- unsigned int irq;
+ int irq;
u8 bits_per_word;
- struct clk *clk_mclk;
- struct clk *clk_ipg;
u32 mclk_rate;
struct completion txisrdone;
@@ -91,7 +85,7 @@ static int mpc512x_psc_spi_transfer_setup(struct spi_device *spi,
static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
{
struct mpc512x_psc_spi_cs *cs = spi->controller_state;
- struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
+ struct mpc512x_psc_spi *mps = spi_controller_get_devdata(spi->controller);
u32 sicr;
u32 ccr;
int speed;
@@ -127,27 +121,17 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
out_be32(psc_addr(mps, ccr), ccr);
mps->bits_per_word = cs->bits_per_word;
- if (spi->cs_gpiod) {
- if (mps->cs_control)
- /* boardfile override */
- mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0);
- else
- /* gpiolib will deal with the inversion */
- gpiod_set_value(spi->cs_gpiod, 1);
+ if (spi_get_csgpiod(spi, 0)) {
+ /* gpiolib will deal with the inversion */
+ gpiod_set_value(spi_get_csgpiod(spi, 0), 1);
}
}
static void mpc512x_psc_spi_deactivate_cs(struct spi_device *spi)
{
- struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
-
- if (spi->cs_gpiod) {
- if (mps->cs_control)
- /* boardfile override */
- mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1);
- else
- /* gpiolib will deal with the inversion */
- gpiod_set_value(spi->cs_gpiod, 0);
+ if (spi_get_csgpiod(spi, 0)) {
+ /* gpiolib will deal with the inversion */
+ gpiod_set_value(spi_get_csgpiod(spi, 0), 0);
}
}
@@ -159,7 +143,7 @@ static void mpc512x_psc_spi_deactivate_cs(struct spi_device *spi)
static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi,
struct spi_transfer *t)
{
- struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
+ struct mpc512x_psc_spi *mps = spi_controller_get_devdata(spi->controller);
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
size_t tx_len = t->len;
size_t rx_len = t->len;
@@ -296,7 +280,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi,
return 0;
}
-static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
+static int mpc512x_psc_spi_msg_xfer(struct spi_controller *host,
struct spi_message *m)
{
struct spi_device *spi;
@@ -336,15 +320,15 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
mpc512x_psc_spi_transfer_setup(spi, NULL);
- spi_finalize_current_message(master);
+ spi_finalize_current_message(host);
return status;
}
-static int mpc512x_psc_spi_prep_xfer_hw(struct spi_master *master)
+static int mpc512x_psc_spi_prep_xfer_hw(struct spi_controller *host)
{
- struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
+ struct mpc512x_psc_spi *mps = spi_controller_get_devdata(host);
- dev_dbg(&master->dev, "%s()\n", __func__);
+ dev_dbg(&host->dev, "%s()\n", __func__);
/* Zero MR2 */
in_8(psc_addr(mps, mr2));
@@ -356,12 +340,12 @@ static int mpc512x_psc_spi_prep_xfer_hw(struct spi_master *master)
return 0;
}
-static int mpc512x_psc_spi_unprep_xfer_hw(struct spi_master *master)
+static int mpc512x_psc_spi_unprep_xfer_hw(struct spi_controller *host)
{
- struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
+ struct mpc512x_psc_spi *mps = spi_controller_get_devdata(host);
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
- dev_dbg(&master->dev, "%s()\n", __func__);
+ dev_dbg(&host->dev, "%s()\n", __func__);
/* disable transmitter/receiver and fifo interrupt */
out_8(psc_addr(mps, command), MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
@@ -396,7 +380,7 @@ static void mpc512x_psc_spi_cleanup(struct spi_device *spi)
kfree(spi->controller_state);
}
-static int mpc512x_psc_spi_port_config(struct spi_master *master,
+static int mpc512x_psc_spi_port_config(struct spi_controller *host,
struct mpc512x_psc_spi *mps)
{
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
@@ -424,7 +408,7 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
sicr = 0x01000000 | /* SIM = 0001 -- 8 bit */
0x00800000 | /* GenClk = 1 -- internal clk */
0x00008000 | /* SPI = 1 */
- 0x00004000 | /* MSTR = 1 -- SPI master */
+ 0x00004000 | /* MSTR = 1 -- SPI host */
0x00000800; /* UseEOF = 1 -- SS low until EOF */
out_be32(psc_addr(mps, sicr), sicr);
@@ -471,126 +455,65 @@ static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id)
return IRQ_NONE;
}
-static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
- u32 size, unsigned int irq)
+static int mpc512x_psc_spi_of_probe(struct platform_device *pdev)
{
- struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
+ struct device *dev = &pdev->dev;
struct mpc512x_psc_spi *mps;
- struct spi_master *master;
+ struct spi_controller *host;
int ret;
void *tempp;
struct clk *clk;
- master = spi_alloc_master(dev, sizeof(*mps));
- if (master == NULL)
+ host = devm_spi_alloc_host(dev, sizeof(*mps));
+ if (host == NULL)
return -ENOMEM;
- dev_set_drvdata(dev, master);
- mps = spi_master_get_devdata(master);
- mps->type = (int)of_device_get_match_data(dev);
- mps->irq = irq;
+ dev_set_drvdata(dev, host);
+ mps = spi_controller_get_devdata(host);
+ mps->type = (int)device_get_match_data(dev);
- if (pdata) {
- mps->cs_control = pdata->cs_control;
- master->bus_num = pdata->bus_num;
- master->num_chipselect = pdata->max_chipselect;
- }
+ host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
+ host->setup = mpc512x_psc_spi_setup;
+ host->prepare_transfer_hardware = mpc512x_psc_spi_prep_xfer_hw;
+ host->transfer_one_message = mpc512x_psc_spi_msg_xfer;
+ host->unprepare_transfer_hardware = mpc512x_psc_spi_unprep_xfer_hw;
+ host->use_gpio_descriptors = true;
+ host->cleanup = mpc512x_psc_spi_cleanup;
- master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
- master->setup = mpc512x_psc_spi_setup;
- master->prepare_transfer_hardware = mpc512x_psc_spi_prep_xfer_hw;
- master->transfer_one_message = mpc512x_psc_spi_msg_xfer;
- master->unprepare_transfer_hardware = mpc512x_psc_spi_unprep_xfer_hw;
- master->use_gpio_descriptors = true;
- master->cleanup = mpc512x_psc_spi_cleanup;
- master->dev.of_node = dev->of_node;
-
- tempp = devm_ioremap(dev, regaddr, size);
- if (!tempp) {
- dev_err(dev, "could not ioremap I/O port range\n");
- ret = -EFAULT;
- goto free_master;
- }
+ device_set_node(&host->dev, dev_fwnode(dev));
+
+ tempp = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+ if (IS_ERR(tempp))
+ return dev_err_probe(dev, PTR_ERR(tempp), "could not ioremap I/O port range\n");
mps->psc = tempp;
mps->fifo =
(struct mpc512x_psc_fifo *)(tempp + sizeof(struct mpc52xx_psc));
+
+ mps->irq = platform_get_irq(pdev, 0);
+ if (mps->irq < 0)
+ return mps->irq;
+
ret = devm_request_irq(dev, mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED,
"mpc512x-psc-spi", mps);
if (ret)
- goto free_master;
+ return ret;
init_completion(&mps->txisrdone);
- 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_master;
- mps->clk_mclk = clk;
- mps->mclk_rate = clk_get_rate(clk);
+ clk = devm_clk_get_enabled(dev, "mclk");
+ if (IS_ERR(clk))
+ return PTR_ERR(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;
+ mps->mclk_rate = clk_get_rate(clk);
- ret = mpc512x_psc_spi_port_config(master, mps);
- if (ret < 0)
- goto free_ipg_clock;
+ clk = devm_clk_get_enabled(dev, "ipg");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
- ret = devm_spi_register_master(dev, master);
+ ret = mpc512x_psc_spi_port_config(host, mps);
if (ret < 0)
- goto free_ipg_clock;
-
- return ret;
+ return ret;
-free_ipg_clock:
- clk_disable_unprepare(mps->clk_ipg);
-free_mclk_clock:
- clk_disable_unprepare(mps->clk_mclk);
-free_master:
- spi_master_put(master);
-
- return ret;
-}
-
-static int mpc512x_psc_spi_do_remove(struct device *dev)
-{
- struct spi_master *master = dev_get_drvdata(dev);
- struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
-
- clk_disable_unprepare(mps->clk_mclk);
- clk_disable_unprepare(mps->clk_ipg);
-
- return 0;
-}
-
-static int mpc512x_psc_spi_of_probe(struct platform_device *op)
-{
- const u32 *regaddr_p;
- u64 regaddr64, size64;
-
- regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL);
- if (!regaddr_p) {
- dev_err(&op->dev, "Invalid PSC address\n");
- return -EINVAL;
- }
- regaddr64 = of_translate_address(op->dev.of_node, regaddr_p);
-
- return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64,
- irq_of_parse_and_map(op->dev.of_node, 0));
-}
-
-static int mpc512x_psc_spi_of_remove(struct platform_device *op)
-{
- return mpc512x_psc_spi_do_remove(&op->dev);
+ return devm_spi_register_controller(dev, host);
}
static const struct of_device_id mpc512x_psc_spi_of_match[] = {
@@ -603,7 +526,6 @@ MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match);
static struct platform_driver mpc512x_psc_spi_of_driver = {
.probe = mpc512x_psc_spi_of_probe,
- .remove = mpc512x_psc_spi_of_remove,
.driver = {
.name = "mpc512x-psc-spi",
.of_match_table = mpc512x_psc_spi_of_match,