+ mpc52xx-psc-spi-master-driver-update.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     mpc52xx-psc-spi-master-driver update
has been added to the -mm tree.  Its filename is
     mpc52xx-psc-spi-master-driver-update.patch

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: mpc52xx-psc-spi-master-driver update
From: Dragos Carp <dragos.carp@xxxxxxxxxxx>

Related to your comments: I used the constants that were already defined
in the mpc52xx.h or mpc52xx_psc.h. I could define them there, but this
will be probably a different patch.
I chose the bus number starting with 0, because I wanted to use the same
rule as the mpc52xx_psc_uart driver, anyway using the OpenFirmware the
bus number will be dynamic allocated based on the order in the
configuration file.
I also changed the name of the driver according to
Documentation/powerpc/mpc52xx-device-tree-bindings.txt.

The newlines were inserted and the inline-s removed.

Cc: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 drivers/spi/mpc52xx_psc_spi.c |  235 ++++++++++++++++++++++++++++----
 1 file changed, 206 insertions(+), 29 deletions(-)

diff -puN drivers/spi/mpc52xx_psc_spi.c~mpc52xx-psc-spi-master-driver-update drivers/spi/mpc52xx_psc_spi.c
--- a/drivers/spi/mpc52xx_psc_spi.c~mpc52xx-psc-spi-master-driver-update
+++ a/drivers/spi/mpc52xx_psc_spi.c
@@ -15,7 +15,13 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+
+#if defined(CONFIG_PPC_MERGE)
+#include <asm/of_platform.h>
+#else
 #include <linux/platform_device.h>
+#endif
+
 #include <linux/workqueue.h>
 #include <linux/completion.h>
 #include <linux/io.h>
@@ -36,6 +42,7 @@ struct mpc52xx_psc_spi {
 
 	/* driver internal data */
 	struct mpc52xx_psc __iomem *psc;
+	unsigned int irq;
 	u8 bits_per_word;
 	u8 busy;
 
@@ -70,7 +77,7 @@ static int mpc52xx_psc_spi_transfer_setu
 	return 0;
 }
 
-static inline void mpc52xx_psc_spi_activate_cs(struct spi_device *spi)
+static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi)
 {
 	struct mpc52xx_psc_spi_cs *cs = spi->controller_state;
 	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
@@ -114,7 +121,7 @@ static inline void mpc52xx_psc_spi_activ
 				(spi->mode & SPI_CS_HIGH) ? 1 : 0);
 }
 
-static inline void mpc52xx_psc_spi_deactivate_cs(struct spi_device *spi)
+static void mpc52xx_psc_spi_deactivate_cs(struct spi_device *spi)
 {
 	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
 
@@ -127,7 +134,7 @@ static inline void mpc52xx_psc_spi_deact
 /* wake up when 80% fifo full */
 #define MPC52xx_PSC_RFALARM (MPC52xx_PSC_BUFSIZE * 20 / 100)
 
-static inline int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
+static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
 						struct spi_transfer *t)
 {
 	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
@@ -309,21 +316,25 @@ static int mpc52xx_psc_spi_transfer(stru
 
 static void mpc52xx_psc_spi_cleanup(struct spi_device *spi)
 {
-	if (spi->controller_state)
-		kfree(spi->controller_state);
+	kfree(spi->controller_state);
 }
 
 static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
 {
 	struct mpc52xx_cdm __iomem *cdm;
 	struct mpc52xx_gpio __iomem *gpio;
-	struct mpc52xx_psc __iomem *psc;
+	struct mpc52xx_psc __iomem *psc = mps->psc;
 	u32 ul;
 	u32 mclken_div;
 	int ret = 0;
 
+#if defined(CONFIG_PPC_MERGE)
+	cdm = mpc52xx_find_and_map("mpc52xx-cdm");
+	gpio = mpc52xx_find_and_map("mpc52xx-gpio");
+#else
 	cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
 	gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
+#endif
 	if (!cdm || !gpio) {
 		printk(KERN_ERR "Error mapping CDM/GPIO\n");
 		ret = -EFAULT;
@@ -379,14 +390,6 @@ static int mpc52xx_psc_spi_port_config(i
 		ret = -EINVAL;
 		goto unmap_regs;
 	}
-	psc = ioremap(MPC52xx_PA(MPC52xx_PSCx_OFFSET(psc_id)),
-			MPC52xx_PSC_SIZE);
-	if (!psc) {
-		printk(KERN_ERR "Error mapping PSC%d\n", psc_id);
-		ret = -EFAULT;
-		goto unmap_regs;
-	}
-	mps->psc = psc;
 
 	/* Reset the PSC into a known state */
 	out_8(&psc->command, MPC52xx_PSC_RST_RX);
@@ -399,7 +402,7 @@ static int mpc52xx_psc_spi_port_config(i
 	out_8(&psc->rfcntl, 0);
 	out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);
 
-	/* Configure 8bit codec mode as an SPI master and use EOF flags */
+	/* Configure 8bit codec mode as a SPI master and use EOF flags */
 	/* SICR_SIM_CODEC8|SICR_GENCLK|SICR_SPI|SICR_MSTR|SICR_USEEOF */
 	out_be32(&psc->sicr, 0x0180C800);
 	out_be16(&psc->ccr, 0x070F); /* by default SPI Clk 1MHz */
@@ -411,8 +414,10 @@ static int mpc52xx_psc_spi_port_config(i
 	mps->bits_per_word = 8;
 
 unmap_regs:
-	if (cdm)  iounmap(cdm);
-	if (gpio) iounmap(gpio);
+	if (cdm)
+		iounmap(cdm);
+	if (gpio)
+		iounmap(gpio);
 
 	return ret;
 }
@@ -431,12 +436,13 @@ static irqreturn_t mpc52xx_psc_spi_isr(i
 	return IRQ_NONE;
 }
 
+#if !defined(CONFIG_PPC_MERGE)
 static int __init mpc52xx_psc_spi_probe(struct platform_device *dev)
 {
 	struct fsl_spi_platform_data *pdata = dev->dev.platform_data;
 	struct mpc52xx_psc_spi *mps;
 	struct spi_master *master;
-	unsigned int irq = platform_get_irq(dev, 0);
+	struct mpc52xx_psc __iomem *psc;
 	int ret;
 
 	if (pdata == NULL)
@@ -459,14 +465,32 @@ static int __init mpc52xx_psc_spi_probe(
 	master->transfer = mpc52xx_psc_spi_transfer;
 	master->cleanup = mpc52xx_psc_spi_cleanup;
 
-	ret = mpc52xx_psc_spi_port_config(dev->id, mps);
-	if (ret < 0)
+	switch(dev->id) {
+	case 1: case 2: case 3: case 6:
+		break;
+	default:
+		ret = -EINVAL;
 		goto free_master;
+	}
+	psc = ioremap(MPC52xx_PA(MPC52xx_PSCx_OFFSET(dev->id)),
+			MPC52xx_PSC_SIZE);
+	if (!psc) {
+		printk(KERN_ERR "Error mapping PSC%d\n", dev->id);
+		ret = -EFAULT;
+		goto free_master;
+	}
+	mps->psc = psc;
 
-	ret = request_irq(irq, mpc52xx_psc_spi_isr, 0, "mpc52xx_psc_spi", mps);
+	mps->irq = platform_get_irq(dev, 0);
+	ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0,
+				"mpc52xx-psc-spi", mps);
 	if (ret)
 		goto free_master;
 
+	ret = mpc52xx_psc_spi_port_config(dev->id, mps);
+	if (ret < 0)
+		goto free_irq;
+
 	spin_lock_init(&mps->lock);
 	init_completion(&mps->done);
 	INIT_WORK(&mps->work, mpc52xx_psc_spi_work);
@@ -476,7 +500,7 @@ static int __init mpc52xx_psc_spi_probe(
 		master->cdev.dev->bus_id);
 	if (mps->workqueue == NULL) {
 		ret = -EBUSY;
-		goto err_workq;
+		goto free_irq;
 	}
 
 	ret = spi_register_master(master);
@@ -487,10 +511,11 @@ static int __init mpc52xx_psc_spi_probe(
 
 unreg_master:
 	destroy_workqueue(mps->workqueue);
-err_workq:
-	free_irq(irq, mps);
+free_irq:
+	free_irq(mps->irq, mps);
 free_master:
-	if (mps->psc)  iounmap(mps->psc);
+	if (mps->psc)
+		iounmap(mps->psc);
 	spi_master_put(master);
 
 	return ret;
@@ -500,13 +525,13 @@ static int __exit mpc52xx_psc_spi_remove
 {
 	struct spi_master *master = platform_get_drvdata(dev);
 	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(master);
-	unsigned int irq = platform_get_irq(dev, 0);
 
 	flush_workqueue(mps->workqueue);
 	destroy_workqueue(mps->workqueue);
 	spi_unregister_master(master);
-	free_irq(irq, mps);
-	if (mps->psc)  iounmap(mps->psc);
+	free_irq(mps->irq, mps);
+	if (mps->psc)
+		iounmap(mps->psc);
 
 	return 0;
 }
@@ -514,26 +539,178 @@ static int __exit mpc52xx_psc_spi_remove
 static struct platform_driver mpc52xx_psc_spi_platform_driver = {
 	.remove = __exit_p(mpc52xx_psc_spi_remove),
 	.driver = {
-		.name = "mpc52xx_psc_spi",
+		.name = "mpc52xx-psc-spi",
 		.owner = THIS_MODULE,
 	},
 };
+#endif	/* !defined(CONFIG_PPC_MERGE) */
 
 
+#if defined(CONFIG_PPC_MERGE)
+static int __init mpc52xx_psc_spi_of_probe(struct of_device *op,
+	const struct of_device_id *match)
+{
+	struct device *dev = &op->dev;
+	struct fsl_spi_platform_data *pdata = dev->platform_data;
+	struct mpc52xx_psc_spi *mps;
+	struct spi_master *master;
+	int ret;
+	const u32 *regaddr_p;
+	u64 regaddr64, size64;
+	struct mpc52xx_psc __iomem *psc;
+
+	if (dev == NULL)
+		return -ENODEV;
+
+	master = spi_alloc_master(dev, sizeof *mps);
+	if (master == NULL)
+		return -ENOMEM;
+	dev_set_drvdata(dev, master);
+	mps = spi_master_get_devdata(master);
+
+	regaddr_p = of_get_address(op->node, 0, &size64, NULL);
+	if (!regaddr_p) {
+		printk(KERN_ERR "Invalid PSC address\n");
+		ret = -EINVAL;
+		goto free_master;
+	}
+	regaddr64 = of_translate_address(op->node, regaddr_p);
+	psc = ioremap((u32)regaddr64, (u32)size64);
+	if (!psc) {
+		printk(KERN_ERR "Error mapping memory at %x (%x bytes)\n",
+			(u32)regaddr64, (u32)size64);
+		ret = -EFAULT;
+		goto free_master;
+	}
+	mps->psc = psc;
+
+	mps->irq = irq_of_parse_and_map(op->node, 0);
+	ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0,
+				"mpc52xx-psc-spi", mps);
+	if (ret)
+		goto free_master;
+
+	if (pdata == NULL) {
+		struct device_node *np;
+		int i = 0;
+
+		dev_warn(dev, "probe called without platform data, no "
+				"(de)activate_cs function will be called\n");
+
+		mps->activate_cs = NULL;
+		mps->deactivate_cs = NULL;
+		mps->sysclk = 0;
+		master->bus_num = -1;
+		for_each_node_by_type(np, "spi") {
+			if (of_find_device_by_node(np) == op) {
+				master->bus_num = i;
+				break;
+			}
+			i++;
+		}
+		master->num_chipselect = 255;
+	} else {
+		mps->activate_cs = pdata->activate_cs;
+		mps->deactivate_cs = pdata->deactivate_cs;
+		mps->sysclk = pdata->sysclk;
+		master->bus_num = pdata->bus_num;
+		master->num_chipselect = pdata->max_chipselect;
+	}
+	master->setup = mpc52xx_psc_spi_setup;
+	master->transfer = mpc52xx_psc_spi_transfer;
+	master->cleanup = mpc52xx_psc_spi_cleanup;
+
+	ret = mpc52xx_psc_spi_port_config(master->bus_num, mps);
+	if (ret < 0)
+		goto free_irq;
+
+	spin_lock_init(&mps->lock);
+	init_completion(&mps->done);
+	INIT_WORK(&mps->work, mpc52xx_psc_spi_work);
+	INIT_LIST_HEAD(&mps->queue);
+
+	mps->workqueue = create_singlethread_workqueue(
+		master->cdev.dev->bus_id);
+	if (mps->workqueue == NULL) {
+		ret = -EBUSY;
+		goto free_irq;
+	}
+
+	ret = spi_register_master(master);
+	if (ret < 0)
+		goto unreg_master;
+
+	return ret;
+
+unreg_master:
+	destroy_workqueue(mps->workqueue);
+free_irq:
+	free_irq(mps->irq, mps);
+free_master:
+	if (mps->psc)
+		iounmap(mps->psc);
+	spi_master_put(master);
+
+	return ret;
+}
+
+static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op)
+{
+	struct spi_master *master = dev_get_drvdata(&op->dev);
+	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(master);
+
+	flush_workqueue(mps->workqueue);
+	destroy_workqueue(mps->workqueue);
+	spi_unregister_master(master);
+	free_irq(mps->irq, mps);
+	if (mps->psc)
+		iounmap(mps->psc);
+
+	return 0;
+}
+
+static struct of_device_id mpc52xx_psc_spi_of_match[] = {
+	{ .type = "spi", .compatible = "mpc52xx-psc-spi", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match);
+
+static struct of_platform_driver mpc52xx_psc_spi_of_driver = {
+	.owner = THIS_MODULE,
+	.name = "mpc52xx-psc-spi",
+	.match_table = mpc52xx_psc_spi_of_match,
+	.probe = mpc52xx_psc_spi_of_probe,
+	.remove = __exit_p(mpc52xx_psc_spi_of_remove),
+	.driver = {
+		.name = "mpc52xx-psc-spi",
+		.owner = THIS_MODULE,
+	},
+};
+#endif	/* defined(CONFIG_PPC_MERGE) */
+
 /* ======================================================================== */
 /* Module                                                                   */
 /* ======================================================================== */
 
 static int __init mpc52xx_psc_spi_init(void)
 {
+#if defined(CONFIG_PPC_MERGE)
+	return of_register_platform_driver(&mpc52xx_psc_spi_of_driver);
+#else
 	return platform_driver_probe(&mpc52xx_psc_spi_platform_driver,
 			mpc52xx_psc_spi_probe);
+#endif
 }
 module_init(mpc52xx_psc_spi_init);
 
 static void __exit mpc52xx_psc_spi_exit(void)
 {
+#if defined(CONFIG_PPC_MERGE)
+	of_unregister_platform_driver(&mpc52xx_psc_spi_of_driver);
+#else
 	platform_driver_unregister(&mpc52xx_psc_spi_platform_driver);
+#endif
 }
 module_exit(mpc52xx_psc_spi_exit);
 
_

Patches currently in -mm which might be from dragos.carp@xxxxxxxxxxx are

mpc52xx-psc-spi-master-driver.patch
mpc52xx-psc-spi-master-driver-update.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux