spi changes queued up for v3.3 merge window
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJPBSnZAAoJEEFnBt12D9kBaDgP/3V73Uhy1yfkuOOgx9Fh5MeM 0X7b7qGI/cIH9eAjm1CNXr6nDiPgpXnUkoxc7tTTKNuQLNPsaUg03VAkBoTc4K+R f88RQq41Ni82hgSI/+ls9PXvc5FIZfgESKw01yCa3aOD/uf1RWGW/95G5xHV/C2V VGoN7f058j7lyhH8WmeaJg0i+x/9PYie3/BdNyaz3hFIFiYPZribIiGQ1ezuM5SN srf+Uu0MqgXfX41kqdRTiU5UGtGOOabE8bk/3TwjwXFWKhJANkqVVZgcYDTK+brL ZIIO1uHAapmy4asG2DyfbK19gOkN7abO4pcbGmmQIN3RKH4QNQQBhYSpex4xMOQ5 TeysEadQ2W/JXL7yKiHt2qJPBovg3WEK+Q0StwnCLjqnWNw4Q+W+zs6TAi7DPfZc plWv27FGhhWYCp8ZGKnlMGGvvHtThuBCqYVIjYbi1CRfJ9mUVdV4zcc4Fj1VJNuU taEIP3Ga9AOtTRbQ904Kza7CQEwBjD5y70TLymoVSk2/XBW2q/Mint9By3ZtA7aq GxASd4sh50x9uoGZU5T5RqA+jImSvlhudKsczNXtl+Y5FMvPNludjncNsie2NrF/ GwYavWFI+zHrFljxOcVQftSQfiMMEAZk9g167AyAGvPxECMoTDrp0A1Q7v5ppSrr AMbbkfxFvo7HIeabEtHI =uyNO -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
2d51daaa61
|
@ -346,14 +346,14 @@ config SPI_TI_SSP
|
||||||
serial port.
|
serial port.
|
||||||
|
|
||||||
config SPI_TOPCLIFF_PCH
|
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
|
depends on PCI
|
||||||
help
|
help
|
||||||
SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus
|
SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus
|
||||||
used in some x86 embedded processors.
|
used in some x86 embedded processors.
|
||||||
|
|
||||||
This driver also supports the ML7213, a companion chip for the
|
This driver also supports the ML7213/ML7223/ML7831, a companion chip
|
||||||
Atom E6xx series and compatible with the Intel EG20T PCH.
|
for the Atom E6xx series and compatible with the Intel EG20T PCH.
|
||||||
|
|
||||||
config SPI_TXX9
|
config SPI_TXX9
|
||||||
tristate "Toshiba TXx9 SPI controller"
|
tristate "Toshiba TXx9 SPI controller"
|
||||||
|
|
|
@ -121,6 +121,7 @@ struct omap2_mcspi {
|
||||||
/* SPI1 has 4 channels, while SPI2 has 2 */
|
/* SPI1 has 4 channels, while SPI2 has 2 */
|
||||||
struct omap2_mcspi_dma *dma_channels;
|
struct omap2_mcspi_dma *dma_channels;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
struct workqueue_struct *wq;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct omap2_mcspi_cs {
|
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 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 { \
|
#define MOD_REG_BIT(val, mask, set) do { \
|
||||||
if (set) \
|
if (set) \
|
||||||
val |= mask; \
|
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);
|
spin_lock_irqsave(&mcspi->lock, flags);
|
||||||
list_add_tail(&m->queue, &mcspi->msg_queue);
|
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);
|
spin_unlock_irqrestore(&mcspi->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1088,6 +1087,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
|
||||||
struct omap2_mcspi *mcspi;
|
struct omap2_mcspi *mcspi;
|
||||||
struct resource *r;
|
struct resource *r;
|
||||||
int status = 0, i;
|
int status = 0, i;
|
||||||
|
char wq_name[20];
|
||||||
|
|
||||||
master = spi_alloc_master(&pdev->dev, sizeof *mcspi);
|
master = spi_alloc_master(&pdev->dev, sizeof *mcspi);
|
||||||
if (master == NULL) {
|
if (master == NULL) {
|
||||||
|
@ -1111,10 +1111,17 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
|
||||||
mcspi = spi_master_get_devdata(master);
|
mcspi = spi_master_get_devdata(master);
|
||||||
mcspi->master = 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);
|
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
if (r == NULL) {
|
if (r == NULL) {
|
||||||
status = -ENODEV;
|
status = -ENODEV;
|
||||||
goto err1;
|
goto free_master;
|
||||||
}
|
}
|
||||||
|
|
||||||
r->start += pdata->regs_offset;
|
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),
|
if (!request_mem_region(r->start, resource_size(r),
|
||||||
dev_name(&pdev->dev))) {
|
dev_name(&pdev->dev))) {
|
||||||
status = -EBUSY;
|
status = -EBUSY;
|
||||||
goto err1;
|
goto free_master;
|
||||||
}
|
}
|
||||||
|
|
||||||
mcspi->base = ioremap(r->start, resource_size(r));
|
mcspi->base = ioremap(r->start, resource_size(r));
|
||||||
if (!mcspi->base) {
|
if (!mcspi->base) {
|
||||||
dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
|
dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
|
||||||
status = -ENOMEM;
|
status = -ENOMEM;
|
||||||
goto err2;
|
goto release_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
mcspi->dev = &pdev->dev;
|
mcspi->dev = &pdev->dev;
|
||||||
|
@ -1145,7 +1152,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|
||||||
if (mcspi->dma_channels == NULL)
|
if (mcspi->dma_channels == NULL)
|
||||||
goto err2;
|
goto unmap_io;
|
||||||
|
|
||||||
for (i = 0; i < master->num_chipselect; i++) {
|
for (i = 0; i < master->num_chipselect; i++) {
|
||||||
char dma_ch_name[14];
|
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;
|
mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
goto dma_chnl_free;
|
||||||
|
|
||||||
pm_runtime_enable(&pdev->dev);
|
pm_runtime_enable(&pdev->dev);
|
||||||
|
|
||||||
if (status || omap2_mcspi_master_setup(mcspi) < 0)
|
if (status || omap2_mcspi_master_setup(mcspi) < 0)
|
||||||
goto err3;
|
goto disable_pm;
|
||||||
|
|
||||||
status = spi_register_master(master);
|
status = spi_register_master(master);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
goto err4;
|
goto err_spi_register;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
err4:
|
err_spi_register:
|
||||||
spi_master_put(master);
|
spi_master_put(master);
|
||||||
err3:
|
disable_pm:
|
||||||
|
pm_runtime_disable(&pdev->dev);
|
||||||
|
dma_chnl_free:
|
||||||
kfree(mcspi->dma_channels);
|
kfree(mcspi->dma_channels);
|
||||||
err2:
|
unmap_io:
|
||||||
release_mem_region(r->start, resource_size(r));
|
|
||||||
iounmap(mcspi->base);
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1210,6 +1225,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
|
||||||
dma_channels = mcspi->dma_channels;
|
dma_channels = mcspi->dma_channels;
|
||||||
|
|
||||||
omap2_mcspi_disable_clocks(mcspi);
|
omap2_mcspi_disable_clocks(mcspi);
|
||||||
|
pm_runtime_disable(&pdev->dev);
|
||||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
release_mem_region(r->start, resource_size(r));
|
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);
|
spi_unregister_master(master);
|
||||||
iounmap(base);
|
iounmap(base);
|
||||||
kfree(dma_channels);
|
kfree(dma_channels);
|
||||||
|
destroy_workqueue(mcspi->wq);
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1275,10 +1293,6 @@ static struct platform_driver omap2_mcspi_driver = {
|
||||||
|
|
||||||
static int __init omap2_mcspi_init(void)
|
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);
|
return platform_driver_probe(&omap2_mcspi_driver, omap2_mcspi_probe);
|
||||||
}
|
}
|
||||||
subsys_initcall(omap2_mcspi_init);
|
subsys_initcall(omap2_mcspi_init);
|
||||||
|
@ -1287,7 +1301,6 @@ static void __exit omap2_mcspi_exit(void)
|
||||||
{
|
{
|
||||||
platform_driver_unregister(&omap2_mcspi_driver);
|
platform_driver_unregister(&omap2_mcspi_driver);
|
||||||
|
|
||||||
destroy_workqueue(omap2_mcspi_wq);
|
|
||||||
}
|
}
|
||||||
module_exit(omap2_mcspi_exit);
|
module_exit(omap2_mcspi_exit);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* SPI bus driver for the Topcliff PCH used by Intel SoCs
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -95,16 +95,18 @@
|
||||||
#define PCH_CLOCK_HZ 50000000
|
#define PCH_CLOCK_HZ 50000000
|
||||||
#define PCH_MAX_SPBR 1023
|
#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_VENDOR_ID_ROHM 0x10DB
|
||||||
#define PCI_DEVICE_ID_ML7213_SPI 0x802c
|
#define PCI_DEVICE_ID_ML7213_SPI 0x802c
|
||||||
#define PCI_DEVICE_ID_ML7223_SPI 0x800F
|
#define PCI_DEVICE_ID_ML7223_SPI 0x800F
|
||||||
|
#define PCI_DEVICE_ID_ML7831_SPI 0x8816
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the number of SPI instance max
|
* Set the number of SPI instance max
|
||||||
* Intel EG20T PCH : 1ch
|
* Intel EG20T PCH : 1ch
|
||||||
* OKI SEMICONDUCTOR ML7213 IOH : 2ch
|
* LAPIS Semiconductor ML7213 IOH : 2ch
|
||||||
* OKI SEMICONDUCTOR ML7223 IOH : 1ch
|
* LAPIS Semiconductor ML7223 IOH : 1ch
|
||||||
|
* LAPIS Semiconductor ML7831 IOH : 1ch
|
||||||
*/
|
*/
|
||||||
#define PCH_SPI_MAX_DEV 2
|
#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(INTEL, PCI_DEVICE_ID_GE_SPI), 1, },
|
||||||
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, },
|
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, },
|
||||||
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, },
|
{ 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");
|
"to use DMA for data transfers pass 1 else 0; default 1");
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
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");
|
||||||
|
|
|
@ -319,7 +319,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master)
|
||||||
}
|
}
|
||||||
|
|
||||||
spi->master = master;
|
spi->master = master;
|
||||||
spi->dev.parent = dev;
|
spi->dev.parent = &master->dev;
|
||||||
spi->dev.bus = &spi_bus_type;
|
spi->dev.bus = &spi_bus_type;
|
||||||
spi->dev.release = spidev_release;
|
spi->dev.release = spidev_release;
|
||||||
device_initialize(&spi->dev);
|
device_initialize(&spi->dev);
|
||||||
|
|
Loading…
Reference in New Issue