diff options
Diffstat (limited to 'drivers/spi')
| -rw-r--r-- | drivers/spi/spi-ath79.c | 3 | ||||
| -rw-r--r-- | drivers/spi/spi-coldfire-qspi.c | 255 | ||||
| -rw-r--r-- | drivers/spi/spi-dw-pci.c | 13 | ||||
| -rw-r--r-- | drivers/spi/spi-ep93xx.c | 37 | ||||
| -rw-r--r-- | drivers/spi/spi-fsl-espi.c | 1 | ||||
| -rw-r--r-- | drivers/spi/spi-fsl-lib.c | 2 | ||||
| -rw-r--r-- | drivers/spi/spi-fsl-spi.c | 2 | ||||
| -rw-r--r-- | drivers/spi/spi-lm70llp.c | 3 | ||||
| -rw-r--r-- | drivers/spi/spi-mpc52xx.c | 3 | ||||
| -rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 373 | ||||
| -rw-r--r-- | drivers/spi/spi-ppc4xx.c | 4 | ||||
| -rw-r--r-- | drivers/spi/spi-pxa2xx-pci.c | 12 | ||||
| -rw-r--r-- | drivers/spi/spi-rspi.c | 320 | ||||
| -rw-r--r-- | drivers/spi/spi-sirf.c | 20 | ||||
| -rw-r--r-- | drivers/spi/spi-topcliff-pch.c | 3 | ||||
| -rw-r--r-- | drivers/spi/spi.c | 98 | 
16 files changed, 705 insertions, 444 deletions
| diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index acc88b4d2869..249077e5cc48 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -216,9 +216,6 @@ static __devinit int ath79_spi_probe(struct platform_device *pdev)  	if (pdata) {  		master->bus_num = pdata->bus_num;  		master->num_chipselect = pdata->num_chipselect; -	} else { -		master->bus_num = -1; -		master->num_chipselect = 1;  	}  	sp->bitbang.master = spi_master_get(master); diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index 6eee64a5d240..b2d4b9e4e010 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -25,12 +25,12 @@  #include <linux/errno.h>  #include <linux/platform_device.h>  #include <linux/sched.h> -#include <linux/workqueue.h>  #include <linux/delay.h>  #include <linux/io.h>  #include <linux/clk.h>  #include <linux/err.h>  #include <linux/spi/spi.h> +#include <linux/pm_runtime.h>  #include <asm/coldfire.h>  #include <asm/mcfsim.h> @@ -78,10 +78,7 @@ struct mcfqspi {  	wait_queue_head_t waitq; -	struct work_struct work; -	struct workqueue_struct *workq; -	spinlock_t lock; -	struct list_head msgq; +	struct device *dev;  };  static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val) @@ -303,120 +300,80 @@ static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,  	}  } -static void mcfqspi_work(struct work_struct *work) +static int mcfqspi_transfer_one_message(struct spi_master *master, +					 struct spi_message *msg)  { -	struct mcfqspi *mcfqspi = container_of(work, struct mcfqspi, work); -	unsigned long flags; - -	spin_lock_irqsave(&mcfqspi->lock, flags); -	while (!list_empty(&mcfqspi->msgq)) { -		struct spi_message *msg; -		struct spi_device *spi; -		struct spi_transfer *xfer; -		int status = 0; - -		msg = container_of(mcfqspi->msgq.next, struct spi_message, -				   queue); - -		list_del_init(&msg->queue); -		spin_unlock_irqrestore(&mcfqspi->lock, flags); - -		spi = msg->spi; - -		list_for_each_entry(xfer, &msg->transfers, transfer_list) { -			bool cs_high = spi->mode & SPI_CS_HIGH; -			u16 qmr = MCFQSPI_QMR_MSTR; - -			if (xfer->bits_per_word) -				qmr |= xfer->bits_per_word << 10; -			else -				qmr |= spi->bits_per_word << 10; -			if (spi->mode & SPI_CPHA) -				qmr |= MCFQSPI_QMR_CPHA; -			if (spi->mode & SPI_CPOL) -				qmr |= MCFQSPI_QMR_CPOL; -			if (xfer->speed_hz) -				qmr |= mcfqspi_qmr_baud(xfer->speed_hz); -			else -				qmr |= mcfqspi_qmr_baud(spi->max_speed_hz); -			mcfqspi_wr_qmr(mcfqspi, qmr); - -			mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high); - -			mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); -			if ((xfer->bits_per_word ? xfer->bits_per_word : -						spi->bits_per_word) == 8) -				mcfqspi_transfer_msg8(mcfqspi, xfer->len, -						      xfer->tx_buf, -						      xfer->rx_buf); -			else -				mcfqspi_transfer_msg16(mcfqspi, xfer->len / 2, -						       xfer->tx_buf, -						       xfer->rx_buf); -			mcfqspi_wr_qir(mcfqspi, 0); - -			if (xfer->delay_usecs) -				udelay(xfer->delay_usecs); -			if (xfer->cs_change) { -				if (!list_is_last(&xfer->transfer_list, -						  &msg->transfers)) -					mcfqspi_cs_deselect(mcfqspi, -							    spi->chip_select, -							    cs_high); -			} else { -				if (list_is_last(&xfer->transfer_list, -						 &msg->transfers)) -					mcfqspi_cs_deselect(mcfqspi, -							    spi->chip_select, -							    cs_high); -			} -			msg->actual_length += xfer->len; +	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); +	struct spi_device *spi = msg->spi; +	struct spi_transfer *t; +	int status = 0; + +	list_for_each_entry(t, &msg->transfers, transfer_list) { +		bool cs_high = spi->mode & SPI_CS_HIGH; +		u16 qmr = MCFQSPI_QMR_MSTR; + +		if (t->bits_per_word) +			qmr |= t->bits_per_word << 10; +		else +			qmr |= spi->bits_per_word << 10; +		if (spi->mode & SPI_CPHA) +			qmr |= MCFQSPI_QMR_CPHA; +		if (spi->mode & SPI_CPOL) +			qmr |= MCFQSPI_QMR_CPOL; +		if (t->speed_hz) +			qmr |= mcfqspi_qmr_baud(t->speed_hz); +		else +			qmr |= mcfqspi_qmr_baud(spi->max_speed_hz); +		mcfqspi_wr_qmr(mcfqspi, qmr); + +		mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high); + +		mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); +		if ((t->bits_per_word ? t->bits_per_word : +					spi->bits_per_word) == 8) +			mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, +					t->rx_buf); +		else +			mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf, +					t->rx_buf); +		mcfqspi_wr_qir(mcfqspi, 0); + +		if (t->delay_usecs) +			udelay(t->delay_usecs); +		if (t->cs_change) { +			if (!list_is_last(&t->transfer_list, &msg->transfers)) +				mcfqspi_cs_deselect(mcfqspi, spi->chip_select, +						cs_high); +		} else { +			if (list_is_last(&t->transfer_list, &msg->transfers)) +				mcfqspi_cs_deselect(mcfqspi, spi->chip_select, +						cs_high);  		} -		msg->status = status; -		msg->complete(msg->context); - -		spin_lock_irqsave(&mcfqspi->lock, flags); +		msg->actual_length += t->len;  	} -	spin_unlock_irqrestore(&mcfqspi->lock, flags); +	msg->status = status; +	spi_finalize_current_message(master); + +	return status; +  } -static int mcfqspi_transfer(struct spi_device *spi, struct spi_message *msg) +static int mcfqspi_prepare_transfer_hw(struct spi_master *master)  { -	struct mcfqspi *mcfqspi; -	struct spi_transfer *xfer; -	unsigned long flags; - -	mcfqspi = spi_master_get_devdata(spi->master); - -	list_for_each_entry(xfer, &msg->transfers, transfer_list) { -		if (xfer->bits_per_word && ((xfer->bits_per_word < 8) -					|| (xfer->bits_per_word > 16))) { -			dev_dbg(&spi->dev, -				"%d bits per word is not supported\n", -				xfer->bits_per_word); -			goto fail; -		} -		if (xfer->speed_hz) { -			u32 real_speed = MCFQSPI_BUSCLK / -				mcfqspi_qmr_baud(xfer->speed_hz); -			if (real_speed != xfer->speed_hz) -				dev_dbg(&spi->dev, -					"using speed %d instead of %d\n", -					real_speed, xfer->speed_hz); -		} -	} -	msg->status = -EINPROGRESS; -	msg->actual_length = 0; +	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); -	spin_lock_irqsave(&mcfqspi->lock, flags); -	list_add_tail(&msg->queue, &mcfqspi->msgq); -	queue_work(mcfqspi->workq, &mcfqspi->work); -	spin_unlock_irqrestore(&mcfqspi->lock, flags); +	pm_runtime_get_sync(mcfqspi->dev); + +	return 0; +} + +static int mcfqspi_unprepare_transfer_hw(struct spi_master *master) +{ +	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); + +	pm_runtime_put_sync(mcfqspi->dev);  	return 0; -fail: -	msg->status = -EINVAL; -	return -EINVAL;  }  static int mcfqspi_setup(struct spi_device *spi) @@ -502,21 +459,10 @@ static int __devinit mcfqspi_probe(struct platform_device *pdev)  	}  	clk_enable(mcfqspi->clk); -	mcfqspi->workq = create_singlethread_workqueue(dev_name(master->dev.parent)); -	if (!mcfqspi->workq) { -		dev_dbg(&pdev->dev, "create_workqueue failed\n"); -		status = -ENOMEM; -		goto fail4; -	} -	INIT_WORK(&mcfqspi->work, mcfqspi_work); -	spin_lock_init(&mcfqspi->lock); -	INIT_LIST_HEAD(&mcfqspi->msgq); -	init_waitqueue_head(&mcfqspi->waitq); -  	pdata = pdev->dev.platform_data;  	if (!pdata) {  		dev_dbg(&pdev->dev, "platform data is missing\n"); -		goto fail5; +		goto fail4;  	}  	master->bus_num = pdata->bus_num;  	master->num_chipselect = pdata->num_chipselect; @@ -525,28 +471,33 @@ static int __devinit mcfqspi_probe(struct platform_device *pdev)  	status = mcfqspi_cs_setup(mcfqspi);  	if (status) {  		dev_dbg(&pdev->dev, "error initializing cs_control\n"); -		goto fail5; +		goto fail4;  	} +	init_waitqueue_head(&mcfqspi->waitq); +	mcfqspi->dev = &pdev->dev; +  	master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;  	master->setup = mcfqspi_setup; -	master->transfer = mcfqspi_transfer; +	master->transfer_one_message = mcfqspi_transfer_one_message; +	master->prepare_transfer_hardware = mcfqspi_prepare_transfer_hw; +	master->unprepare_transfer_hardware = mcfqspi_unprepare_transfer_hw;  	platform_set_drvdata(pdev, master);  	status = spi_register_master(master);  	if (status) {  		dev_dbg(&pdev->dev, "spi_register_master failed\n"); -		goto fail6; +		goto fail5;  	} +	pm_runtime_enable(mcfqspi->dev); +  	dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");  	return 0; -fail6: -	mcfqspi_cs_teardown(mcfqspi);  fail5: -	destroy_workqueue(mcfqspi->workq); +	mcfqspi_cs_teardown(mcfqspi);  fail4:  	clk_disable(mcfqspi->clk);  	clk_put(mcfqspi->clk); @@ -570,12 +521,12 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev)  	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);  	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	pm_runtime_disable(mcfqspi->dev);  	/* disable the hardware (set the baud rate to 0) */  	mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);  	platform_set_drvdata(pdev, NULL);  	mcfqspi_cs_teardown(mcfqspi); -	destroy_workqueue(mcfqspi->workq);  	clk_disable(mcfqspi->clk);  	clk_put(mcfqspi->clk);  	free_irq(mcfqspi->irq, mcfqspi); @@ -587,11 +538,13 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev)  	return 0;  } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP  static int mcfqspi_suspend(struct device *dev)  { -	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev)); +	struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); +	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); + +	spi_master_suspend(master);  	clk_disable(mcfqspi->clk); @@ -600,27 +553,47 @@ static int mcfqspi_suspend(struct device *dev)  static int mcfqspi_resume(struct device *dev)  { -	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev)); +	struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); +	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); + +	spi_master_resume(master);  	clk_enable(mcfqspi->clk);  	return 0;  } +#endif -static struct dev_pm_ops mcfqspi_dev_pm_ops = { -	.suspend	= mcfqspi_suspend, -	.resume		= mcfqspi_resume, -}; +#ifdef CONFIG_PM_RUNTIME +static int mcfqspi_runtime_suspend(struct device *dev) +{ +	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev)); -#define	MCFQSPI_DEV_PM_OPS	(&mcfqspi_dev_pm_ops) -#else -#define	MCFQSPI_DEV_PM_OPS	NULL +	clk_disable(mcfqspi->clk); + +	return 0; +} + +static int mcfqspi_runtime_resume(struct device *dev) +{ +	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev)); + +	clk_enable(mcfqspi->clk); + +	return 0; +}  #endif +static const struct dev_pm_ops mcfqspi_pm = { +	SET_SYSTEM_SLEEP_PM_OPS(mcfqspi_suspend, mcfqspi_resume) +	SET_RUNTIME_PM_OPS(mcfqspi_runtime_suspend, mcfqspi_runtime_resume, +			NULL) +}; +  static struct platform_driver mcfqspi_driver = {  	.driver.name	= DRIVER_NAME,  	.driver.owner	= THIS_MODULE, -	.driver.pm	= MCFQSPI_DEV_PM_OPS, +	.driver.pm	= &mcfqspi_pm,  	.probe		= mcfqspi_probe,  	.remove		= __devexit_p(mcfqspi_remove),  }; diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 14f7cc9523f0..ff81abbb3066 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -164,18 +164,7 @@ static struct pci_driver dw_spi_driver = {  	.resume	=	spi_resume,  }; -static int __init mrst_spi_init(void) -{ -	return pci_register_driver(&dw_spi_driver); -} - -static void __exit mrst_spi_exit(void) -{ -	pci_unregister_driver(&dw_spi_driver); -} - -module_init(mrst_spi_init); -module_exit(mrst_spi_exit); +module_pci_driver(dw_spi_driver);  MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>");  MODULE_DESCRIPTION("PCI interface driver for DW SPI Core"); diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index e8055073e84d..f97f1d248800 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -76,7 +76,6 @@   * @clk: clock for the controller   * @regs_base: pointer to ioremap()'d registers   * @sspdr_phys: physical address of the SSPDR register - * @irq: IRQ number used by the driver   * @min_rate: minimum clock rate (in Hz) supported by the controller   * @max_rate: maximum clock rate (in Hz) supported by the controller   * @running: is the queue running @@ -114,7 +113,6 @@ struct ep93xx_spi {  	struct clk			*clk;  	void __iomem			*regs_base;  	unsigned long			sspdr_phys; -	int				irq;  	unsigned long			min_rate;  	unsigned long			max_rate;  	bool				running; @@ -1031,6 +1029,7 @@ static int __devinit ep93xx_spi_probe(struct platform_device *pdev)  	struct ep93xx_spi_info *info;  	struct ep93xx_spi *espi;  	struct resource *res; +	int irq;  	int error;  	info = pdev->dev.platform_data; @@ -1070,8 +1069,8 @@ static int __devinit ep93xx_spi_probe(struct platform_device *pdev)  	espi->min_rate = clk_get_rate(espi->clk) / (254 * 256);  	espi->pdev = pdev; -	espi->irq = platform_get_irq(pdev, 0); -	if (espi->irq < 0) { +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) {  		error = -EBUSY;  		dev_err(&pdev->dev, "failed to get irq resources\n");  		goto fail_put_clock; @@ -1084,26 +1083,20 @@ static int __devinit ep93xx_spi_probe(struct platform_device *pdev)  		goto fail_put_clock;  	} -	res = request_mem_region(res->start, resource_size(res), pdev->name); -	if (!res) { -		dev_err(&pdev->dev, "unable to request iomem resources\n"); -		error = -EBUSY; -		goto fail_put_clock; -	} -  	espi->sspdr_phys = res->start + SSPDR; -	espi->regs_base = ioremap(res->start, resource_size(res)); + +	espi->regs_base = devm_request_and_ioremap(&pdev->dev, res);  	if (!espi->regs_base) {  		dev_err(&pdev->dev, "failed to map resources\n");  		error = -ENODEV; -		goto fail_free_mem; +		goto fail_put_clock;  	} -	error = request_irq(espi->irq, ep93xx_spi_interrupt, 0, -			    "ep93xx-spi", espi); +	error = devm_request_irq(&pdev->dev, irq, ep93xx_spi_interrupt, +				0, "ep93xx-spi", espi);  	if (error) {  		dev_err(&pdev->dev, "failed to request irq\n"); -		goto fail_unmap_regs; +		goto fail_put_clock;  	}  	if (info->use_dma && ep93xx_spi_setup_dma(espi)) @@ -1128,7 +1121,7 @@ static int __devinit ep93xx_spi_probe(struct platform_device *pdev)  	}  	dev_info(&pdev->dev, "EP93xx SPI Controller at 0x%08lx irq %d\n", -		 (unsigned long)res->start, espi->irq); +		 (unsigned long)res->start, irq);  	return 0; @@ -1136,11 +1129,6 @@ fail_free_queue:  	destroy_workqueue(espi->wq);  fail_free_dma:  	ep93xx_spi_release_dma(espi); -	free_irq(espi->irq, espi); -fail_unmap_regs: -	iounmap(espi->regs_base); -fail_free_mem: -	release_mem_region(res->start, resource_size(res));  fail_put_clock:  	clk_put(espi->clk);  fail_release_master: @@ -1154,7 +1142,6 @@ static int __devexit ep93xx_spi_remove(struct platform_device *pdev)  {  	struct spi_master *master = platform_get_drvdata(pdev);  	struct ep93xx_spi *espi = spi_master_get_devdata(master); -	struct resource *res;  	spin_lock_irq(&espi->lock);  	espi->running = false; @@ -1180,10 +1167,6 @@ static int __devexit ep93xx_spi_remove(struct platform_device *pdev)  	spin_unlock_irq(&espi->lock);  	ep93xx_spi_release_dma(espi); -	free_irq(espi->irq, espi); -	iounmap(espi->regs_base); -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	release_mem_region(res->start, resource_size(res));  	clk_put(espi->clk);  	platform_set_drvdata(pdev, NULL); diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 7523a2429d09..27bdc47b5250 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -17,7 +17,6 @@  #include <linux/mm.h>  #include <linux/of.h>  #include <linux/of_platform.h> -#include <linux/of_spi.h>  #include <linux/interrupt.h>  #include <linux/err.h>  #include <sysdev/fsl_soc.h> diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c index 2674fad7f68a..1503574b215a 100644 --- a/drivers/spi/spi-fsl-lib.c +++ b/drivers/spi/spi-fsl-lib.c @@ -22,7 +22,7 @@  #include <linux/dma-mapping.h>  #include <linux/mm.h>  #include <linux/of_platform.h> -#include <linux/of_spi.h> +#include <linux/spi/spi.h>  #include <sysdev/fsl_soc.h>  #include "spi-fsl-lib.h" diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 5f748c0d96bd..6a62934ca74c 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -933,7 +933,7 @@ err:  static void fsl_spi_cs_control(struct spi_device *spi, bool on)  { -	struct device *dev = spi->dev.parent; +	struct device *dev = spi->dev.parent->parent;  	struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);  	u16 cs = spi->chip_select;  	int gpio = pinfo->gpios[cs]; diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index 933eb9d9ddd4..0759b5db9883 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -219,9 +219,6 @@ static void spi_lm70llp_attach(struct parport *p)  	}  	pp = spi_master_get_devdata(master); -	master->bus_num = -1;	/* dynamic alloc of a bus number */ -	master->num_chipselect = 1; -  	/*  	 * SPI and bitbang hookup.  	 */ diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 57633d963456..cb3a3830b0a5 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -433,7 +433,6 @@ static int __devinit mpc52xx_spi_probe(struct platform_device *op)  		goto err_alloc;  	} -	master->bus_num = -1;  	master->setup = mpc52xx_spi_setup;  	master->transfer = mpc52xx_spi_transfer;  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; @@ -479,8 +478,6 @@ static int __devinit mpc52xx_spi_probe(struct platform_device *op)  			gpio_direction_output(gpio_cs, 1);  			ms->gpio_cs[i] = gpio_cs;  		} -	} else { -		master->num_chipselect = 1;  	}  	spin_lock_init(&ms->lock); diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index bb9274c2526d..46ef5fe51db5 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -44,9 +44,7 @@  #include <plat/mcspi.h>  #define OMAP2_MCSPI_MAX_FREQ		48000000 - -/* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */ -#define OMAP2_MCSPI_MAX_CTRL 		4 +#define SPI_AUTOSUSPEND_TIMEOUT		2000  #define OMAP2_MCSPI_REVISION		0x00  #define OMAP2_MCSPI_SYSSTATUS		0x14 @@ -111,19 +109,25 @@ struct omap2_mcspi_dma {  #define DMA_MIN_BYTES			160 +/* + * Used for context save and restore, structure members to be updated whenever + * corresponding registers are modified. + */ +struct omap2_mcspi_regs { +	u32 modulctrl; +	u32 wakeupenable; +	struct list_head cs; +}; +  struct omap2_mcspi { -	struct work_struct	work; -	/* lock protects queue and registers */ -	spinlock_t		lock; -	struct list_head	msg_queue;  	struct spi_master	*master;  	/* Virtual base address of the controller */  	void __iomem		*base;  	unsigned long		phys;  	/* SPI1 has 4 channels, while SPI2 has 2 */  	struct omap2_mcspi_dma	*dma_channels; -	struct  device		*dev; -	struct workqueue_struct *wq; +	struct device		*dev; +	struct omap2_mcspi_regs ctx;  };  struct omap2_mcspi_cs { @@ -135,17 +139,6 @@ struct omap2_mcspi_cs {  	u32			chconf0;  }; -/* used for context save and restore, structure members to be updated whenever - * corresponding registers are modified. - */ -struct omap2_mcspi_regs { -	u32 modulctrl; -	u32 wakeupenable; -	struct list_head cs; -}; - -static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL]; -  #define MOD_REG_BIT(val, mask, set) do { \  	if (set) \  		val |= mask; \ @@ -236,9 +229,12 @@ static void omap2_mcspi_force_cs(struct spi_device *spi, int cs_active)  static void omap2_mcspi_set_master_mode(struct spi_master *master)  { +	struct omap2_mcspi	*mcspi = spi_master_get_devdata(master); +	struct omap2_mcspi_regs	*ctx = &mcspi->ctx;  	u32 l; -	/* setup when switching from (reset default) slave mode +	/* +	 * Setup when switching from (reset default) slave mode  	 * to single-channel master mode  	 */  	l = mcspi_read_reg(master, OMAP2_MCSPI_MODULCTRL); @@ -247,29 +243,26 @@ static void omap2_mcspi_set_master_mode(struct spi_master *master)  	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1);  	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l); -	omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l; +	ctx->modulctrl = l;  }  static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)  { -	struct spi_master *spi_cntrl; -	struct omap2_mcspi_cs *cs; -	spi_cntrl = mcspi->master; +	struct spi_master	*spi_cntrl = mcspi->master; +	struct omap2_mcspi_regs	*ctx = &mcspi->ctx; +	struct omap2_mcspi_cs	*cs;  	/* McSPI: context restore */ -	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, -			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl); - -	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, -			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable); +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, ctx->modulctrl); +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, ctx->wakeupenable); -	list_for_each_entry(cs, &omap2_mcspi_ctx[spi_cntrl->bus_num - 1].cs, -			node) +	list_for_each_entry(cs, &ctx->cs, node)  		__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);  }  static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)  { -	pm_runtime_put_sync(mcspi->dev); +	pm_runtime_mark_last_busy(mcspi->dev); +	pm_runtime_put_autosuspend(mcspi->dev);  }  static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) @@ -277,6 +270,23 @@ static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)  	return pm_runtime_get_sync(mcspi->dev);  } +static int omap2_prepare_transfer(struct spi_master *master) +{ +	struct omap2_mcspi *mcspi = spi_master_get_devdata(master); + +	pm_runtime_get_sync(mcspi->dev); +	return 0; +} + +static int omap2_unprepare_transfer(struct spi_master *master) +{ +	struct omap2_mcspi *mcspi = spi_master_get_devdata(master); + +	pm_runtime_mark_last_busy(mcspi->dev); +	pm_runtime_put_autosuspend(mcspi->dev); +	return 0; +} +  static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)  {  	unsigned long timeout; @@ -777,7 +787,8 @@ static int omap2_mcspi_request_dma(struct spi_device *spi)  static int omap2_mcspi_setup(struct spi_device *spi)  {  	int			ret; -	struct omap2_mcspi	*mcspi; +	struct omap2_mcspi	*mcspi = spi_master_get_devdata(spi->master); +	struct omap2_mcspi_regs	*ctx = &mcspi->ctx;  	struct omap2_mcspi_dma	*mcspi_dma;  	struct omap2_mcspi_cs	*cs = spi->controller_state; @@ -787,11 +798,10 @@ static int omap2_mcspi_setup(struct spi_device *spi)  		return -EINVAL;  	} -	mcspi = spi_master_get_devdata(spi->master);  	mcspi_dma = &mcspi->dma_channels[spi->chip_select];  	if (!cs) { -		cs = kzalloc(sizeof *cs, GFP_KERNEL); +		cs = devm_kzalloc(&spi->dev , sizeof *cs, GFP_KERNEL);  		if (!cs)  			return -ENOMEM;  		cs->base = mcspi->base + spi->chip_select * 0x14; @@ -799,8 +809,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)  		cs->chconf0 = 0;  		spi->controller_state = cs;  		/* Link this to context save list */ -		list_add_tail(&cs->node, -			&omap2_mcspi_ctx[mcspi->master->bus_num - 1].cs); +		list_add_tail(&cs->node, &ctx->cs);  	}  	if (mcspi_dma->dma_rx_channel == -1 @@ -833,7 +842,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)  		cs = spi->controller_state;  		list_del(&cs->node); -		kfree(spi->controller_state);  	}  	if (spi->chip_select < spi->master->num_chipselect) { @@ -850,144 +858,122 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)  	}  } -static void omap2_mcspi_work(struct work_struct *work) +static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)  { -	struct omap2_mcspi	*mcspi; - -	mcspi = container_of(work, struct omap2_mcspi, work); - -	if (omap2_mcspi_enable_clocks(mcspi) < 0) -		return; - -	spin_lock_irq(&mcspi->lock);  	/* We only enable one channel at a time -- the one whose message is -	 * at the head of the queue -- although this controller would gladly +	 * -- although this controller would gladly  	 * arbitrate among multiple channels.  This corresponds to "single  	 * channel" master mode.  As a side effect, we need to manage the  	 * chipselect with the FORCE bit ... CS != channel enable.  	 */ -	while (!list_empty(&mcspi->msg_queue)) { -		struct spi_message		*m; -		struct spi_device		*spi; -		struct spi_transfer		*t = NULL; -		int				cs_active = 0; -		struct omap2_mcspi_cs		*cs; -		struct omap2_mcspi_device_config *cd; -		int				par_override = 0; -		int				status = 0; -		u32				chconf; - -		m = container_of(mcspi->msg_queue.next, struct spi_message, -				 queue); - -		list_del_init(&m->queue); -		spin_unlock_irq(&mcspi->lock); - -		spi = m->spi; -		cs = spi->controller_state; -		cd = spi->controller_data; -		omap2_mcspi_set_enable(spi, 1); -		list_for_each_entry(t, &m->transfers, transfer_list) { -			if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { -				status = -EINVAL; -				break; -			} -			if (par_override || t->speed_hz || t->bits_per_word) { -				par_override = 1; -				status = omap2_mcspi_setup_transfer(spi, t); -				if (status < 0) -					break; -				if (!t->speed_hz && !t->bits_per_word) -					par_override = 0; -			} +	struct spi_device		*spi; +	struct spi_transfer		*t = NULL; +	int				cs_active = 0; +	struct omap2_mcspi_cs		*cs; +	struct omap2_mcspi_device_config *cd; +	int				par_override = 0; +	int				status = 0; +	u32				chconf; -			if (!cs_active) { -				omap2_mcspi_force_cs(spi, 1); -				cs_active = 1; -			} +	spi = m->spi; +	cs = spi->controller_state; +	cd = spi->controller_data; -			chconf = mcspi_cached_chconf0(spi); -			chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; -			chconf &= ~OMAP2_MCSPI_CHCONF_TURBO; +	omap2_mcspi_set_enable(spi, 1); +	list_for_each_entry(t, &m->transfers, transfer_list) { +		if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { +			status = -EINVAL; +			break; +		} +		if (par_override || t->speed_hz || t->bits_per_word) { +			par_override = 1; +			status = omap2_mcspi_setup_transfer(spi, t); +			if (status < 0) +				break; +			if (!t->speed_hz && !t->bits_per_word) +				par_override = 0; +		} -			if (t->tx_buf == NULL) -				chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; -			else if (t->rx_buf == NULL) -				chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; - -			if (cd && cd->turbo_mode && t->tx_buf == NULL) { -				/* Turbo mode is for more than one word */ -				if (t->len > ((cs->word_len + 7) >> 3)) -					chconf |= OMAP2_MCSPI_CHCONF_TURBO; -			} +		if (!cs_active) { +			omap2_mcspi_force_cs(spi, 1); +			cs_active = 1; +		} -			mcspi_write_chconf0(spi, chconf); +		chconf = mcspi_cached_chconf0(spi); +		chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; +		chconf &= ~OMAP2_MCSPI_CHCONF_TURBO; -			if (t->len) { -				unsigned	count; +		if (t->tx_buf == NULL) +			chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; +		else if (t->rx_buf == NULL) +			chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; -				/* RX_ONLY mode needs dummy data in TX reg */ -				if (t->tx_buf == NULL) -					__raw_writel(0, cs->base -							+ OMAP2_MCSPI_TX0); +		if (cd && cd->turbo_mode && t->tx_buf == NULL) { +			/* Turbo mode is for more than one word */ +			if (t->len > ((cs->word_len + 7) >> 3)) +				chconf |= OMAP2_MCSPI_CHCONF_TURBO; +		} -				if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES) -					count = omap2_mcspi_txrx_dma(spi, t); -				else -					count = omap2_mcspi_txrx_pio(spi, t); -				m->actual_length += count; +		mcspi_write_chconf0(spi, chconf); -				if (count != t->len) { -					status = -EIO; -					break; -				} -			} +		if (t->len) { +			unsigned	count; -			if (t->delay_usecs) -				udelay(t->delay_usecs); +			/* RX_ONLY mode needs dummy data in TX reg */ +			if (t->tx_buf == NULL) +				__raw_writel(0, cs->base +						+ OMAP2_MCSPI_TX0); + +			if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES) +				count = omap2_mcspi_txrx_dma(spi, t); +			else +				count = omap2_mcspi_txrx_pio(spi, t); +			m->actual_length += count; -			/* ignore the "leave it on after last xfer" hint */ -			if (t->cs_change) { -				omap2_mcspi_force_cs(spi, 0); -				cs_active = 0; +			if (count != t->len) { +				status = -EIO; +				break;  			}  		} -		/* Restore defaults if they were overriden */ -		if (par_override) { -			par_override = 0; -			status = omap2_mcspi_setup_transfer(spi, NULL); -		} +		if (t->delay_usecs) +			udelay(t->delay_usecs); -		if (cs_active) +		/* ignore the "leave it on after last xfer" hint */ +		if (t->cs_change) {  			omap2_mcspi_force_cs(spi, 0); +			cs_active = 0; +		} +	} +	/* Restore defaults if they were overriden */ +	if (par_override) { +		par_override = 0; +		status = omap2_mcspi_setup_transfer(spi, NULL); +	} -		omap2_mcspi_set_enable(spi, 0); - -		m->status = status; -		m->complete(m->context); +	if (cs_active) +		omap2_mcspi_force_cs(spi, 0); -		spin_lock_irq(&mcspi->lock); -	} +	omap2_mcspi_set_enable(spi, 0); -	spin_unlock_irq(&mcspi->lock); +	m->status = status; -	omap2_mcspi_disable_clocks(mcspi);  } -static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) +static int omap2_mcspi_transfer_one_message(struct spi_master *master, +						struct spi_message *m)  {  	struct omap2_mcspi	*mcspi; -	unsigned long		flags;  	struct spi_transfer	*t; +	mcspi = spi_master_get_devdata(master);  	m->actual_length = 0;  	m->status = 0;  	/* reject invalid messages and transfers */ -	if (list_empty(&m->transfers) || !m->complete) +	if (list_empty(&m->transfers))  		return -EINVAL;  	list_for_each_entry(t, &m->transfers, transfer_list) {  		const void	*tx_buf = t->tx_buf; @@ -999,7 +985,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)  				|| (t->bits_per_word &&  					(  t->bits_per_word < 4  					|| t->bits_per_word > 32))) { -			dev_dbg(&spi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n", +			dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",  					t->speed_hz,  					len,  					tx_buf ? "tx" : "", @@ -1008,7 +994,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)  			return -EINVAL;  		}  		if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) { -			dev_dbg(&spi->dev, "speed_hz %d below minimum %d Hz\n", +			dev_dbg(mcspi->dev, "speed_hz %d below minimum %d Hz\n",  				t->speed_hz,  				OMAP2_MCSPI_MAX_FREQ >> 15);  			return -EINVAL; @@ -1018,51 +1004,46 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)  			continue;  		if (tx_buf != NULL) { -			t->tx_dma = dma_map_single(&spi->dev, (void *) tx_buf, +			t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf,  					len, DMA_TO_DEVICE); -			if (dma_mapping_error(&spi->dev, t->tx_dma)) { -				dev_dbg(&spi->dev, "dma %cX %d bytes error\n", +			if (dma_mapping_error(mcspi->dev, t->tx_dma)) { +				dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",  						'T', len);  				return -EINVAL;  			}  		}  		if (rx_buf != NULL) { -			t->rx_dma = dma_map_single(&spi->dev, rx_buf, t->len, +			t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len,  					DMA_FROM_DEVICE); -			if (dma_mapping_error(&spi->dev, t->rx_dma)) { -				dev_dbg(&spi->dev, "dma %cX %d bytes error\n", +			if (dma_mapping_error(mcspi->dev, t->rx_dma)) { +				dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",  						'R', len);  				if (tx_buf != NULL) -					dma_unmap_single(&spi->dev, t->tx_dma, +					dma_unmap_single(mcspi->dev, t->tx_dma,  							len, DMA_TO_DEVICE);  				return -EINVAL;  			}  		}  	} -	mcspi = spi_master_get_devdata(spi->master); - -	spin_lock_irqsave(&mcspi->lock, flags); -	list_add_tail(&m->queue, &mcspi->msg_queue); -	queue_work(mcspi->wq, &mcspi->work); -	spin_unlock_irqrestore(&mcspi->lock, flags); - +	omap2_mcspi_work(mcspi, m); +	spi_finalize_current_message(master);  	return 0;  }  static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)  {  	struct spi_master	*master = mcspi->master; -	u32			tmp; -	int ret = 0; +	struct omap2_mcspi_regs	*ctx = &mcspi->ctx; +	int			ret = 0;  	ret = omap2_mcspi_enable_clocks(mcspi);  	if (ret < 0)  		return ret; -	tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN; -	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp); -	omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp; +	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, +				OMAP2_MCSPI_WAKEUPENABLE_WKEN); +	ctx->wakeupenable = OMAP2_MCSPI_WAKEUPENABLE_WKEN;  	omap2_mcspi_set_master_mode(master);  	omap2_mcspi_disable_clocks(mcspi); @@ -1102,14 +1083,13 @@ static const struct of_device_id omap_mcspi_of_match[] = {  };  MODULE_DEVICE_TABLE(of, omap_mcspi_of_match); -static int __init omap2_mcspi_probe(struct platform_device *pdev) +static int __devinit omap2_mcspi_probe(struct platform_device *pdev)  {  	struct spi_master	*master;  	struct omap2_mcspi_platform_config *pdata;  	struct omap2_mcspi	*mcspi;  	struct resource		*r;  	int			status = 0, i; -	char			wq_name[20];  	u32			regs_offset = 0;  	static int		bus_num = 1;  	struct device_node	*node = pdev->dev.of_node; @@ -1125,7 +1105,9 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;  	master->setup = omap2_mcspi_setup; -	master->transfer = omap2_mcspi_transfer; +	master->prepare_transfer_hardware = omap2_prepare_transfer; +	master->unprepare_transfer_hardware = omap2_unprepare_transfer; +	master->transfer_one_message = omap2_mcspi_transfer_one_message;  	master->cleanup = omap2_mcspi_cleanup;  	master->dev.of_node = node; @@ -1150,13 +1132,6 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)  	mcspi = spi_master_get_devdata(master);  	mcspi->master = master; -	sprintf(wq_name, "omap2_mcspi/%d", master->bus_num); -	mcspi->wq = alloc_workqueue(wq_name, WQ_MEM_RECLAIM, 1); -	if (mcspi->wq == NULL) { -		status = -ENOMEM; -		goto free_master; -	} -  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (r == NULL) {  		status = -ENODEV; @@ -1166,32 +1141,24 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)  	r->start += regs_offset;  	r->end += regs_offset;  	mcspi->phys = r->start; -	if (!request_mem_region(r->start, resource_size(r), -				dev_name(&pdev->dev))) { -		status = -EBUSY; -		goto free_master; -	} -	mcspi->base = ioremap(r->start, resource_size(r)); +	mcspi->base = devm_request_and_ioremap(&pdev->dev, r);  	if (!mcspi->base) {  		dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");  		status = -ENOMEM; -		goto release_region; +		goto free_master;  	}  	mcspi->dev = &pdev->dev; -	INIT_WORK(&mcspi->work, omap2_mcspi_work); -	spin_lock_init(&mcspi->lock); -	INIT_LIST_HEAD(&mcspi->msg_queue); -	INIT_LIST_HEAD(&omap2_mcspi_ctx[master->bus_num - 1].cs); +	INIT_LIST_HEAD(&mcspi->ctx.cs);  	mcspi->dma_channels = kcalloc(master->num_chipselect,  			sizeof(struct omap2_mcspi_dma),  			GFP_KERNEL);  	if (mcspi->dma_channels == NULL) -		goto unmap_io; +		goto free_master;  	for (i = 0; i < master->num_chipselect; i++) {  		char dma_ch_name[14]; @@ -1224,6 +1191,8 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)  	if (status < 0)  		goto dma_chnl_free; +	pm_runtime_use_autosuspend(&pdev->dev); +	pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);  	pm_runtime_enable(&pdev->dev);  	if (status || omap2_mcspi_master_setup(mcspi) < 0) @@ -1241,23 +1210,17 @@ disable_pm:  	pm_runtime_disable(&pdev->dev);  dma_chnl_free:  	kfree(mcspi->dma_channels); -unmap_io: -	iounmap(mcspi->base); -release_region: -	release_mem_region(r->start, resource_size(r));  free_master:  	kfree(master);  	platform_set_drvdata(pdev, NULL);  	return status;  } -static int __exit omap2_mcspi_remove(struct platform_device *pdev) +static int __devexit omap2_mcspi_remove(struct platform_device *pdev)  {  	struct spi_master	*master;  	struct omap2_mcspi	*mcspi;  	struct omap2_mcspi_dma	*dma_channels; -	struct resource		*r; -	void __iomem *base;  	master = dev_get_drvdata(&pdev->dev);  	mcspi = spi_master_get_devdata(master); @@ -1265,14 +1228,9 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)  	omap2_mcspi_disable_clocks(mcspi);  	pm_runtime_disable(&pdev->dev); -	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	release_mem_region(r->start, resource_size(r)); -	base = mcspi->base;  	spi_unregister_master(master); -	iounmap(base);  	kfree(dma_channels); -	destroy_workqueue(mcspi->wq);  	platform_set_drvdata(pdev, NULL);  	return 0; @@ -1291,13 +1249,12 @@ static int omap2_mcspi_resume(struct device *dev)  {  	struct spi_master	*master = dev_get_drvdata(dev);  	struct omap2_mcspi	*mcspi = spi_master_get_devdata(master); -	struct omap2_mcspi_cs *cs; +	struct omap2_mcspi_regs	*ctx = &mcspi->ctx; +	struct omap2_mcspi_cs	*cs;  	omap2_mcspi_enable_clocks(mcspi); -	list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs, -			    node) { +	list_for_each_entry(cs, &ctx->cs, node) {  		if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { -  			/*  			 * We need to toggle CS state for OMAP take this  			 * change in account. @@ -1327,21 +1284,9 @@ static struct platform_driver omap2_mcspi_driver = {  		.pm =		&omap2_mcspi_pm_ops,  		.of_match_table = omap_mcspi_of_match,  	}, -	.remove =	__exit_p(omap2_mcspi_remove), +	.probe =	omap2_mcspi_probe, +	.remove =	__devexit_p(omap2_mcspi_remove),  }; - -static int __init omap2_mcspi_init(void) -{ -	return platform_driver_probe(&omap2_mcspi_driver, omap2_mcspi_probe); -} -subsys_initcall(omap2_mcspi_init); - -static void __exit omap2_mcspi_exit(void) -{ -	platform_driver_unregister(&omap2_mcspi_driver); - -} -module_exit(omap2_mcspi_exit); - +module_platform_driver(omap2_mcspi_driver);  MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 98ec53285fc7..75ac9d48ef46 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -30,7 +30,6 @@  #include <linux/errno.h>  #include <linux/wait.h>  #include <linux/of_platform.h> -#include <linux/of_spi.h>  #include <linux/of_gpio.h>  #include <linux/interrupt.h>  #include <linux/delay.h> @@ -467,9 +466,6 @@ static int __init spi_ppc4xx_of_probe(struct platform_device *op)  	bbp->master->setup = spi_ppc4xx_setup;  	bbp->master->cleanup = spi_ppc4xx_cleanup; -	/* Allocate bus num dynamically. */ -	bbp->master->bus_num = -1; -  	/* the spi->mode bits understood by this driver: */  	bbp->master->mode_bits =  		SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST; diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 3fb44afe27b4..9f6ba34b172c 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -164,17 +164,7 @@ static struct pci_driver ce4100_spi_driver = {  	.remove         = __devexit_p(ce4100_spi_remove),  }; -static int __init ce4100_spi_init(void) -{ -	return pci_register_driver(&ce4100_spi_driver); -} -module_init(ce4100_spi_init); - -static void __exit ce4100_spi_exit(void) -{ -	pci_unregister_driver(&ce4100_spi_driver); -} -module_exit(ce4100_spi_exit); +module_pci_driver(ce4100_spi_driver);  MODULE_DESCRIPTION("CE4100 PCI-SPI glue code for PXA's driver");  MODULE_LICENSE("GPL v2"); diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 354f170eab95..4894bde4bbff 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -31,7 +31,11 @@  #include <linux/platform_device.h>  #include <linux/io.h>  #include <linux/clk.h> +#include <linux/dmaengine.h> +#include <linux/dma-mapping.h> +#include <linux/sh_dma.h>  #include <linux/spi/spi.h> +#include <linux/spi/rspi.h>  #define RSPI_SPCR		0x00  #define RSPI_SSLP		0x01 @@ -141,6 +145,16 @@ struct rspi_data {  	spinlock_t lock;  	struct clk *clk;  	unsigned char spsr; + +	/* for dmaengine */ +	struct sh_dmae_slave dma_tx; +	struct sh_dmae_slave dma_rx; +	struct dma_chan *chan_tx; +	struct dma_chan *chan_rx; +	int irq; + +	unsigned dma_width_16bit:1; +	unsigned dma_callbacked:1;  };  static void rspi_write8(struct rspi_data *rspi, u8 data, u16 offset) @@ -265,11 +279,125 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,  	return 0;  } -static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, -			    struct spi_transfer *t) +static void rspi_dma_complete(void *arg) +{ +	struct rspi_data *rspi = arg; + +	rspi->dma_callbacked = 1; +	wake_up_interruptible(&rspi->wait); +} + +static int rspi_dma_map_sg(struct scatterlist *sg, void *buf, unsigned len, +			   struct dma_chan *chan, +			   enum dma_transfer_direction dir) +{ +	sg_init_table(sg, 1); +	sg_set_buf(sg, buf, len); +	sg_dma_len(sg) = len; +	return dma_map_sg(chan->device->dev, sg, 1, dir); +} + +static void rspi_dma_unmap_sg(struct scatterlist *sg, struct dma_chan *chan, +			      enum dma_transfer_direction dir) +{ +	dma_unmap_sg(chan->device->dev, sg, 1, dir); +} + +static void rspi_memory_to_8bit(void *buf, const void *data, unsigned len) +{ +	u16 *dst = buf; +	const u8 *src = data; + +	while (len) { +		*dst++ = (u16)(*src++); +		len--; +	} +} + +static void rspi_memory_from_8bit(void *buf, const void *data, unsigned len) +{ +	u8 *dst = buf; +	const u16 *src = data; + +	while (len) { +		*dst++ = (u8)*src++; +		len--; +	} +} + +static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t) +{ +	struct scatterlist sg; +	void *buf = NULL; +	struct dma_async_tx_descriptor *desc; +	unsigned len; +	int ret = 0; + +	if (rspi->dma_width_16bit) { +		/* +		 * If DMAC bus width is 16-bit, the driver allocates a dummy +		 * buffer. And, the driver converts original data into the +		 * DMAC data as the following format: +		 *  original data: 1st byte, 2nd byte ... +		 *  DMAC data:     1st byte, dummy, 2nd byte, dummy ... +		 */ +		len = t->len * 2; +		buf = kmalloc(len, GFP_KERNEL); +		if (!buf) +			return -ENOMEM; +		rspi_memory_to_8bit(buf, t->tx_buf, t->len); +	} else { +		len = t->len; +		buf = (void *)t->tx_buf; +	} + +	if (!rspi_dma_map_sg(&sg, buf, len, rspi->chan_tx, DMA_TO_DEVICE)) { +		ret = -EFAULT; +		goto end_nomap; +	} +	desc = dmaengine_prep_slave_sg(rspi->chan_tx, &sg, 1, DMA_TO_DEVICE, +				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +	if (!desc) { +		ret = -EIO; +		goto end; +	} + +	/* +	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be +	 * called. So, this driver disables the IRQ while DMA transfer. +	 */ +	disable_irq(rspi->irq); + +	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR); +	rspi_enable_irq(rspi, SPCR_SPTIE); +	rspi->dma_callbacked = 0; + +	desc->callback = rspi_dma_complete; +	desc->callback_param = rspi; +	dmaengine_submit(desc); +	dma_async_issue_pending(rspi->chan_tx); + +	ret = wait_event_interruptible_timeout(rspi->wait, +					       rspi->dma_callbacked, HZ); +	if (ret > 0 && rspi->dma_callbacked) +		ret = 0; +	else if (!ret) +		ret = -ETIMEDOUT; +	rspi_disable_irq(rspi, SPCR_SPTIE); + +	enable_irq(rspi->irq); + +end: +	rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE); +end_nomap: +	if (rspi->dma_width_16bit) +		kfree(buf); + +	return ret; +} + +static void rspi_receive_init(struct rspi_data *rspi)  { -	int remain = t->len; -	u8 *data;  	unsigned char spsr;  	spsr = rspi_read8(rspi, RSPI_SPSR); @@ -278,6 +406,15 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,  	if (spsr & SPSR_OVRF)  		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,  			    RSPI_SPCR); +} + +static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, +			    struct spi_transfer *t) +{ +	int remain = t->len; +	u8 *data; + +	rspi_receive_init(rspi);  	data = (u8 *)t->rx_buf;  	while (remain > 0) { @@ -307,6 +444,120 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,  	return 0;  } +static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) +{ +	struct scatterlist sg, sg_dummy; +	void *dummy = NULL, *rx_buf = NULL; +	struct dma_async_tx_descriptor *desc, *desc_dummy; +	unsigned len; +	int ret = 0; + +	if (rspi->dma_width_16bit) { +		/* +		 * If DMAC bus width is 16-bit, the driver allocates a dummy +		 * buffer. And, finally the driver converts the DMAC data into +		 * actual data as the following format: +		 *  DMAC data:   1st byte, dummy, 2nd byte, dummy ... +		 *  actual data: 1st byte, 2nd byte ... +		 */ +		len = t->len * 2; +		rx_buf = kmalloc(len, GFP_KERNEL); +		if (!rx_buf) +			return -ENOMEM; +	 } else { +		len = t->len; +		rx_buf = t->rx_buf; +	} + +	/* prepare dummy transfer to generate SPI clocks */ +	dummy = kzalloc(len, GFP_KERNEL); +	if (!dummy) { +		ret = -ENOMEM; +		goto end_nomap; +	} +	if (!rspi_dma_map_sg(&sg_dummy, dummy, len, rspi->chan_tx, +			     DMA_TO_DEVICE)) { +		ret = -EFAULT; +		goto end_nomap; +	} +	desc_dummy = dmaengine_prep_slave_sg(rspi->chan_tx, &sg_dummy, 1, +			DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +	if (!desc_dummy) { +		ret = -EIO; +		goto end_dummy_mapped; +	} + +	/* prepare receive transfer */ +	if (!rspi_dma_map_sg(&sg, rx_buf, len, rspi->chan_rx, +			     DMA_FROM_DEVICE)) { +		ret = -EFAULT; +		goto end_dummy_mapped; + +	} +	desc = dmaengine_prep_slave_sg(rspi->chan_rx, &sg, 1, DMA_FROM_DEVICE, +				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +	if (!desc) { +		ret = -EIO; +		goto end; +	} + +	rspi_receive_init(rspi); + +	/* +	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be +	 * called. So, this driver disables the IRQ while DMA transfer. +	 */ +	disable_irq(rspi->irq); + +	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR); +	rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); +	rspi->dma_callbacked = 0; + +	desc->callback = rspi_dma_complete; +	desc->callback_param = rspi; +	dmaengine_submit(desc); +	dma_async_issue_pending(rspi->chan_rx); + +	desc_dummy->callback = NULL;	/* No callback */ +	dmaengine_submit(desc_dummy); +	dma_async_issue_pending(rspi->chan_tx); + +	ret = wait_event_interruptible_timeout(rspi->wait, +					       rspi->dma_callbacked, HZ); +	if (ret > 0 && rspi->dma_callbacked) +		ret = 0; +	else if (!ret) +		ret = -ETIMEDOUT; +	rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); + +	enable_irq(rspi->irq); + +end: +	rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE); +end_dummy_mapped: +	rspi_dma_unmap_sg(&sg_dummy, rspi->chan_tx, DMA_TO_DEVICE); +end_nomap: +	if (rspi->dma_width_16bit) { +		if (!ret) +			rspi_memory_from_8bit(t->rx_buf, rx_buf, t->len); +		kfree(rx_buf); +	} +	kfree(dummy); + +	return ret; +} + +static int rspi_is_dma(struct rspi_data *rspi, struct spi_transfer *t) +{ +	if (t->tx_buf && rspi->chan_tx) +		return 1; +	/* If the module receives data by DMAC, it also needs TX DMAC */ +	if (t->rx_buf && rspi->chan_tx && rspi->chan_rx) +		return 1; + +	return 0; +} +  static void rspi_work(struct work_struct *work)  {  	struct rspi_data *rspi = container_of(work, struct rspi_data, ws); @@ -325,12 +576,18 @@ static void rspi_work(struct work_struct *work)  		list_for_each_entry(t, &mesg->transfers, transfer_list) {  			if (t->tx_buf) { -				ret = rspi_send_pio(rspi, mesg, t); +				if (rspi_is_dma(rspi, t)) +					ret = rspi_send_dma(rspi, t); +				else +					ret = rspi_send_pio(rspi, mesg, t);  				if (ret < 0)  					goto error;  			}  			if (t->rx_buf) { -				ret = rspi_receive_pio(rspi, mesg, t); +				if (rspi_is_dma(rspi, t)) +					ret = rspi_receive_dma(rspi, t); +				else +					ret = rspi_receive_pio(rspi, mesg, t);  				if (ret < 0)  					goto error;  			} @@ -406,11 +663,58 @@ static irqreturn_t rspi_irq(int irq, void *_sr)  	return ret;  } +static bool rspi_filter(struct dma_chan *chan, void *filter_param) +{ +	chan->private = filter_param; +	return true; +} + +static void __devinit rspi_request_dma(struct rspi_data *rspi, +				       struct platform_device *pdev) +{ +	struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; +	dma_cap_mask_t mask; + +	if (!rspi_pd) +		return; + +	rspi->dma_width_16bit = rspi_pd->dma_width_16bit; + +	/* If the module receives data by DMAC, it also needs TX DMAC */ +	if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) { +		dma_cap_zero(mask); +		dma_cap_set(DMA_SLAVE, mask); +		rspi->dma_rx.slave_id = rspi_pd->dma_rx_id; +		rspi->chan_rx = dma_request_channel(mask, rspi_filter, +						    &rspi->dma_rx); +		if (rspi->chan_rx) +			dev_info(&pdev->dev, "Use DMA when rx.\n"); +	} +	if (rspi_pd->dma_tx_id) { +		dma_cap_zero(mask); +		dma_cap_set(DMA_SLAVE, mask); +		rspi->dma_tx.slave_id = rspi_pd->dma_tx_id; +		rspi->chan_tx = dma_request_channel(mask, rspi_filter, +						    &rspi->dma_tx); +		if (rspi->chan_tx) +			dev_info(&pdev->dev, "Use DMA when tx\n"); +	} +} + +static void __devexit rspi_release_dma(struct rspi_data *rspi) +{ +	if (rspi->chan_tx) +		dma_release_channel(rspi->chan_tx); +	if (rspi->chan_rx) +		dma_release_channel(rspi->chan_rx); +} +  static int __devexit rspi_remove(struct platform_device *pdev)  {  	struct rspi_data *rspi = dev_get_drvdata(&pdev->dev);  	spi_unregister_master(rspi->master); +	rspi_release_dma(rspi);  	free_irq(platform_get_irq(pdev, 0), rspi);  	clk_put(rspi->clk);  	iounmap(rspi->addr); @@ -483,6 +787,9 @@ static int __devinit rspi_probe(struct platform_device *pdev)  		goto error3;  	} +	rspi->irq = irq; +	rspi_request_dma(rspi, pdev); +  	ret = spi_register_master(master);  	if (ret < 0) {  		dev_err(&pdev->dev, "spi_register_master error.\n"); @@ -494,6 +801,7 @@ static int __devinit rspi_probe(struct platform_device *pdev)  	return 0;  error4: +	rspi_release_dma(rspi);  	free_irq(irq, rspi);  error3:  	clk_put(rspi->clk); diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 52fe495bb32a..ecc3d9763d10 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -19,7 +19,7 @@  #include <linux/of_gpio.h>  #include <linux/spi/spi.h>  #include <linux/spi/spi_bitbang.h> -#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/consumer.h>  #define DRIVER_NAME "sirfsoc_spi" @@ -127,7 +127,7 @@ struct sirfsoc_spi {  	void __iomem *base;  	u32 ctrl_freq;  /* SPI controller clock speed */  	struct clk *clk; -	struct pinmux *pmx; +	struct pinctrl *p;  	/* rx & tx bufs from the spi_transfer */  	const void *tx; @@ -560,17 +560,15 @@ static int __devinit spi_sirfsoc_probe(struct platform_device *pdev)  	master->bus_num = pdev->id;  	sspi->bitbang.master->dev.of_node = pdev->dev.of_node; -	sspi->pmx = pinmux_get(&pdev->dev, NULL); -	ret = IS_ERR(sspi->pmx); +	sspi->p = pinctrl_get_select_default(&pdev->dev); +	ret = IS_ERR(sspi->p);  	if (ret)  		goto free_master; -	pinmux_enable(sspi->pmx); -  	sspi->clk = clk_get(&pdev->dev, NULL);  	if (IS_ERR(sspi->clk)) {  		ret = -EINVAL; -		goto free_pmx; +		goto free_pin;  	}  	clk_enable(sspi->clk);  	sspi->ctrl_freq = clk_get_rate(sspi->clk); @@ -598,9 +596,8 @@ static int __devinit spi_sirfsoc_probe(struct platform_device *pdev)  free_clk:  	clk_disable(sspi->clk);  	clk_put(sspi->clk); -free_pmx: -	pinmux_disable(sspi->pmx); -	pinmux_put(sspi->pmx); +free_pin: +	pinctrl_put(sspi->p);  free_master:  	spi_master_put(master);  err_cs: @@ -623,8 +620,7 @@ static int  __devexit spi_sirfsoc_remove(struct platform_device *pdev)  	}  	clk_disable(sspi->clk);  	clk_put(sspi->clk); -	pinmux_disable(sspi->pmx); -	pinmux_put(sspi->pmx); +	pinctrl_put(sspi->p);  	spi_master_put(master);  	return 0;  } diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index ec47d3bdfd13..cd56dcf46320 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -1438,7 +1438,6 @@ static int __devinit pch_spi_pd_probe(struct platform_device *plat_dev)  		plat_dev->id, data->io_remap_addr);  	/* initialize members of SPI master */ -	master->bus_num = -1;  	master->num_chipselect = PCH_MAX_CS;  	master->setup = pch_spi_setup;  	master->transfer = pch_spi_transfer; @@ -1779,7 +1778,7 @@ static struct pci_driver pch_spi_pcidev_driver = {  	.name = "pch_spi",  	.id_table = pch_spi_pcidev_id,  	.probe = pch_spi_probe, -	.remove = pch_spi_remove, +	.remove = __devexit_p(pch_spi_remove),  	.suspend = pch_spi_suspend,  	.resume = pch_spi_resume,  }; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 3d8f662e4fe9..1041cb83d67a 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2,6 +2,7 @@   * SPI init/core code   *   * Copyright (C) 2005 David Brownell + * Copyright (C) 2008 Secret Lab Technologies Ltd.   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -19,15 +20,16 @@   */  #include <linux/kernel.h> +#include <linux/kmod.h>  #include <linux/device.h>  #include <linux/init.h>  #include <linux/cache.h>  #include <linux/mutex.h>  #include <linux/of_device.h> +#include <linux/of_irq.h>  #include <linux/slab.h>  #include <linux/mod_devicetable.h>  #include <linux/spi/spi.h> -#include <linux/of_spi.h>  #include <linux/pm_runtime.h>  #include <linux/export.h>  #include <linux/sched.h> @@ -530,7 +532,7 @@ static void spi_pump_messages(struct kthread_work *work)  	/* Lock queue and check for queue work */  	spin_lock_irqsave(&master->queue_lock, flags);  	if (list_empty(&master->queue) || !master->running) { -		if (master->busy) { +		if (master->busy && master->unprepare_transfer_hardware) {  			ret = master->unprepare_transfer_hardware(master);  			if (ret) {  				spin_unlock_irqrestore(&master->queue_lock, flags); @@ -560,7 +562,7 @@ static void spi_pump_messages(struct kthread_work *work)  		master->busy = true;  	spin_unlock_irqrestore(&master->queue_lock, flags); -	if (!was_busy) { +	if (!was_busy && master->prepare_transfer_hardware) {  		ret = master->prepare_transfer_hardware(master);  		if (ret) {  			dev_err(&master->dev, @@ -798,6 +800,94 @@ err_init_queue:  /*-------------------------------------------------------------------------*/ +#if defined(CONFIG_OF) && !defined(CONFIG_SPARC) +/** + * of_register_spi_devices() - Register child devices onto the SPI bus + * @master:	Pointer to spi_master device + * + * Registers an spi_device for each child node of master node which has a 'reg' + * property. + */ +static void of_register_spi_devices(struct spi_master *master) +{ +	struct spi_device *spi; +	struct device_node *nc; +	const __be32 *prop; +	int rc; +	int len; + +	if (!master->dev.of_node) +		return; + +	for_each_child_of_node(master->dev.of_node, nc) { +		/* Alloc an spi_device */ +		spi = spi_alloc_device(master); +		if (!spi) { +			dev_err(&master->dev, "spi_device alloc error for %s\n", +				nc->full_name); +			spi_dev_put(spi); +			continue; +		} + +		/* Select device driver */ +		if (of_modalias_node(nc, spi->modalias, +				     sizeof(spi->modalias)) < 0) { +			dev_err(&master->dev, "cannot find modalias for %s\n", +				nc->full_name); +			spi_dev_put(spi); +			continue; +		} + +		/* Device address */ +		prop = of_get_property(nc, "reg", &len); +		if (!prop || len < sizeof(*prop)) { +			dev_err(&master->dev, "%s has no 'reg' property\n", +				nc->full_name); +			spi_dev_put(spi); +			continue; +		} +		spi->chip_select = be32_to_cpup(prop); + +		/* Mode (clock phase/polarity/etc.) */ +		if (of_find_property(nc, "spi-cpha", NULL)) +			spi->mode |= SPI_CPHA; +		if (of_find_property(nc, "spi-cpol", NULL)) +			spi->mode |= SPI_CPOL; +		if (of_find_property(nc, "spi-cs-high", NULL)) +			spi->mode |= SPI_CS_HIGH; + +		/* Device speed */ +		prop = of_get_property(nc, "spi-max-frequency", &len); +		if (!prop || len < sizeof(*prop)) { +			dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n", +				nc->full_name); +			spi_dev_put(spi); +			continue; +		} +		spi->max_speed_hz = be32_to_cpup(prop); + +		/* IRQ */ +		spi->irq = irq_of_parse_and_map(nc, 0); + +		/* Store a pointer to the node in the device structure */ +		of_node_get(nc); +		spi->dev.of_node = nc; + +		/* Register the new device */ +		request_module(spi->modalias); +		rc = spi_add_device(spi); +		if (rc) { +			dev_err(&master->dev, "spi_device register error %s\n", +				nc->full_name); +			spi_dev_put(spi); +		} + +	} +} +#else +static void of_register_spi_devices(struct spi_master *master) { } +#endif +  static void spi_master_release(struct device *dev)  {  	struct spi_master *master; @@ -846,6 +936,8 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)  		return NULL;  	device_initialize(&master->dev); +	master->bus_num = -1; +	master->num_chipselect = 1;  	master->dev.class = &spi_master_class;  	master->dev.parent = get_device(dev);  	spi_master_set_devdata(master, &master[1]); | 
