diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-07 12:16:27 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-07 12:16:27 -0800 | 
| commit | 2d51daaa615e4724f24e43fa01e705c40551080a (patch) | |
| tree | 3596123890aae2645a189a75bdf45789e89ae2d9 | |
| parent | fbce1c234feedb5270468aa4b1770c1cab58a960 (diff) | |
| parent | e583685e998e52ebbf31fadf7d8470ae69951660 (diff) | |
| download | olio-linux-3.10-2d51daaa615e4724f24e43fa01e705c40551080a.tar.xz olio-linux-3.10-2d51daaa615e4724f24e43fa01e705c40551080a.zip  | |
Merge tag 'spi-for-linus' of git://git.secretlab.ca/git/linux-2.6
spi changes queued up for v3.3 merge window
* tag 'spi-for-linus-20120104' of git://git.secretlab.ca/git/linux-2.6:
  spi: Fix device unregistration when unregistering the bus master
  spi-topcliff-pch: Change company name OKI SEMICONDUCTOR to LAPIS Semiconductor
  spi-topcliff-pch: Support new device LAPIS Semiconductor ML7831 IOH
  spi/omap: Correct the error path
  spi/omap: call pm_runtime_disable in error path and remove
  spi/omap: Use a workqueue per omap2_mcspi controller
| -rw-r--r-- | drivers/spi/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 51 | ||||
| -rw-r--r-- | drivers/spi/spi-topcliff-pch.c | 13 | ||||
| -rw-r--r-- | drivers/spi/spi.c | 2 | 
4 files changed, 44 insertions, 28 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8ba4510a951..7587796224c 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -346,14 +346,14 @@ config SPI_TI_SSP  	  serial port.  config SPI_TOPCLIFF_PCH -	tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH SPI controller" +	tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI"  	depends on PCI  	help  	  SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus  	  used in some x86 embedded processors. -	  This driver also supports the ML7213, a companion chip for the -	  Atom E6xx series and compatible with the Intel EG20T PCH. +	  This driver also supports the ML7213/ML7223/ML7831, a companion chip +	  for the Atom E6xx series and compatible with the Intel EG20T PCH.  config SPI_TXX9  	tristate "Toshiba TXx9 SPI controller" diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 322be7aea8b..0b0dfb71c64 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -121,6 +121,7 @@ struct omap2_mcspi {  	/* SPI1 has 4 channels, while SPI2 has 2 */  	struct omap2_mcspi_dma	*dma_channels;  	struct  device		*dev; +	struct workqueue_struct *wq;  };  struct omap2_mcspi_cs { @@ -143,8 +144,6 @@ struct omap2_mcspi_regs {  static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL]; -static struct workqueue_struct *omap2_mcspi_wq; -  #define MOD_REG_BIT(val, mask, set) do { \  	if (set) \  		val |= mask; \ @@ -1043,7 +1042,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)  	spin_lock_irqsave(&mcspi->lock, flags);  	list_add_tail(&m->queue, &mcspi->msg_queue); -	queue_work(omap2_mcspi_wq, &mcspi->work); +	queue_work(mcspi->wq, &mcspi->work);  	spin_unlock_irqrestore(&mcspi->lock, flags);  	return 0; @@ -1088,6 +1087,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)  	struct omap2_mcspi	*mcspi;  	struct resource		*r;  	int			status = 0, i; +	char			wq_name[20];  	master = spi_alloc_master(&pdev->dev, sizeof *mcspi);  	if (master == NULL) { @@ -1111,10 +1111,17 @@ 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; -		goto err1; +		goto free_master;  	}  	r->start += pdata->regs_offset; @@ -1123,14 +1130,14 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)  	if (!request_mem_region(r->start, resource_size(r),  				dev_name(&pdev->dev))) {  		status = -EBUSY; -		goto err1; +		goto free_master;  	}  	mcspi->base = ioremap(r->start, resource_size(r));  	if (!mcspi->base) {  		dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");  		status = -ENOMEM; -		goto err2; +		goto release_region;  	}  	mcspi->dev = &pdev->dev; @@ -1145,7 +1152,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)  			GFP_KERNEL);  	if (mcspi->dma_channels == NULL) -		goto err2; +		goto unmap_io;  	for (i = 0; i < master->num_chipselect; i++) {  		char dma_ch_name[14]; @@ -1175,25 +1182,33 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)  		mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start;  	} +	if (status < 0) +		goto dma_chnl_free; +  	pm_runtime_enable(&pdev->dev);  	if (status || omap2_mcspi_master_setup(mcspi) < 0) -		goto err3; +		goto disable_pm;  	status = spi_register_master(master);  	if (status < 0) -		goto err4; +		goto err_spi_register;  	return status; -err4: +err_spi_register:  	spi_master_put(master); -err3: +disable_pm: +	pm_runtime_disable(&pdev->dev); +dma_chnl_free:  	kfree(mcspi->dma_channels); -err2: -	release_mem_region(r->start, resource_size(r)); +unmap_io:  	iounmap(mcspi->base); -err1: +release_region: +	release_mem_region(r->start, resource_size(r)); +free_master: +	kfree(master); +	platform_set_drvdata(pdev, NULL);  	return status;  } @@ -1210,6 +1225,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)  	dma_channels = mcspi->dma_channels;  	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)); @@ -1217,6 +1233,8 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)  	spi_unregister_master(master);  	iounmap(base);  	kfree(dma_channels); +	destroy_workqueue(mcspi->wq); +	platform_set_drvdata(pdev, NULL);  	return 0;  } @@ -1275,10 +1293,6 @@ static struct platform_driver omap2_mcspi_driver = {  static int __init omap2_mcspi_init(void)  { -	omap2_mcspi_wq = create_singlethread_workqueue( -				omap2_mcspi_driver.driver.name); -	if (omap2_mcspi_wq == NULL) -		return -1;  	return platform_driver_probe(&omap2_mcspi_driver, omap2_mcspi_probe);  }  subsys_initcall(omap2_mcspi_init); @@ -1287,7 +1301,6 @@ static void __exit omap2_mcspi_exit(void)  {  	platform_driver_unregister(&omap2_mcspi_driver); -	destroy_workqueue(omap2_mcspi_wq);  }  module_exit(omap2_mcspi_exit); diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 6a80749391d..7086583b910 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -1,7 +1,7 @@  /*   * SPI bus driver for the Topcliff PCH used by Intel SoCs   * - * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * Copyright (C) 2011 LAPIS Semiconductor Co., 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 @@ -95,16 +95,18 @@  #define PCH_CLOCK_HZ		50000000  #define PCH_MAX_SPBR		1023 -/* Definition for ML7213 by OKI SEMICONDUCTOR */ +/* Definition for ML7213/ML7223/ML7831 by LAPIS Semiconductor */  #define PCI_VENDOR_ID_ROHM		0x10DB  #define PCI_DEVICE_ID_ML7213_SPI	0x802c  #define PCI_DEVICE_ID_ML7223_SPI	0x800F +#define PCI_DEVICE_ID_ML7831_SPI	0x8816  /*   * Set the number of SPI instance max   * Intel EG20T PCH :		1ch - * OKI SEMICONDUCTOR ML7213 IOH :	2ch - * OKI SEMICONDUCTOR ML7223 IOH :	1ch + * LAPIS Semiconductor ML7213 IOH :	2ch + * LAPIS Semiconductor ML7223 IOH :	1ch + * LAPIS Semiconductor ML7831 IOH :	1ch  */  #define PCH_SPI_MAX_DEV			2 @@ -218,6 +220,7 @@ static struct pci_device_id pch_spi_pcidev_id[] = {  	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI),    1, },  	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, },  	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, }, +	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_SPI), 1, },  	{ }  }; @@ -1753,4 +1756,4 @@ MODULE_PARM_DESC(use_dma,  		 "to use DMA for data transfers pass 1 else 0; default 1");  MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR ML7xxx IOH SPI Driver"); +MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor ML7xxx IOH SPI Driver"); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 77eae99af11..b2ccdea30cb 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -319,7 +319,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master)  	}  	spi->master = master; -	spi->dev.parent = dev; +	spi->dev.parent = &master->dev;  	spi->dev.bus = &spi_bus_type;  	spi->dev.release = spidev_release;  	device_initialize(&spi->dev);  |