Skip to content

Commit

Permalink
Merge branch 'broonie/spi-next' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/broonie/misc.git

Minor features and bug fixes for PXA, OMAP and GPIO deivce drivers and a
cosmetic change to the bitbang driver.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
  • Loading branch information
Grant Likely committed Feb 5, 2013
2 parents 766ed70 + d560040 commit f305a0a
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 376 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7178,6 +7178,7 @@ F: drivers/clk/spear/

SPI SUBSYSTEM
M: Grant Likely <grant.likely@secretlab.ca>
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
L: spi-devel-general@lists.sourceforge.net
Q: http://patchwork.kernel.org/project/spi-devel-general/list/
T: git git://git.secretlab.ca/git/linux-2.6.git
Expand Down
4 changes: 2 additions & 2 deletions drivers/spi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -299,15 +299,15 @@ config SPI_PPC4xx

config SPI_PXA2XX
tristate "PXA2xx SSP SPI master"
depends on (ARCH_PXA || (X86_32 && PCI)) && EXPERIMENTAL
depends on ARCH_PXA || PCI
select PXA_SSP if ARCH_PXA
help
This enables using a PXA2xx or Sodaville SSP port as a SPI master
controller. The driver can be configured to use any SSP port and
additional documentation can be found a Documentation/spi/pxa2xx.

config SPI_PXA2XX_PCI
def_bool SPI_PXA2XX && X86_32 && PCI
def_tristate SPI_PXA2XX && PCI

config SPI_RSPI
tristate "Renesas RSPI controller"
Expand Down
27 changes: 14 additions & 13 deletions drivers/spi/spi-bitbang.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,40 +427,41 @@ EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
*/
int spi_bitbang_start(struct spi_bitbang *bitbang)
{
int status;
struct spi_master *master = bitbang->master;
int status;

if (!bitbang->master || !bitbang->chipselect)
if (!master || !bitbang->chipselect)
return -EINVAL;

INIT_WORK(&bitbang->work, bitbang_work);
spin_lock_init(&bitbang->lock);
INIT_LIST_HEAD(&bitbang->queue);

if (!bitbang->master->mode_bits)
bitbang->master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
if (!master->mode_bits)
master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;

if (!bitbang->master->transfer)
bitbang->master->transfer = spi_bitbang_transfer;
if (!master->transfer)
master->transfer = spi_bitbang_transfer;
if (!bitbang->txrx_bufs) {
bitbang->use_dma = 0;
bitbang->txrx_bufs = spi_bitbang_bufs;
if (!bitbang->master->setup) {
if (!master->setup) {
if (!bitbang->setup_transfer)
bitbang->setup_transfer =
spi_bitbang_setup_transfer;
bitbang->master->setup = spi_bitbang_setup;
bitbang->master->cleanup = spi_bitbang_cleanup;
master->setup = spi_bitbang_setup;
master->cleanup = spi_bitbang_cleanup;
}
} else if (!bitbang->master->setup)
} else if (!master->setup)
return -EINVAL;
if (bitbang->master->transfer == spi_bitbang_transfer &&
if (master->transfer == spi_bitbang_transfer &&
!bitbang->setup_transfer)
return -EINVAL;

/* this task is the only thing to touch the SPI bits */
bitbang->busy = 0;
bitbang->workqueue = create_singlethread_workqueue(
dev_name(bitbang->master->dev.parent));
dev_name(master->dev.parent));
if (bitbang->workqueue == NULL) {
status = -EBUSY;
goto err1;
Expand All @@ -469,7 +470,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
/* driver may get busy before register() returns, especially
* if someone registered boardinfo for devices
*/
status = spi_register_master(bitbang->master);
status = spi_register_master(master);
if (status < 0)
goto err2;

Expand Down
23 changes: 20 additions & 3 deletions drivers/spi/spi-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,26 @@ static int spi_gpio_probe_dt(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;

pdata->sck = of_get_named_gpio(np, "gpio-sck", 0);
pdata->miso = of_get_named_gpio(np, "gpio-miso", 0);
pdata->mosi = of_get_named_gpio(np, "gpio-mosi", 0);
ret = of_get_named_gpio(np, "gpio-sck", 0);
if (ret < 0) {
dev_err(&pdev->dev, "gpio-sck property not found\n");
goto error_free;
}
pdata->sck = ret;

ret = of_get_named_gpio(np, "gpio-miso", 0);
if (ret < 0) {
dev_info(&pdev->dev, "gpio-miso property not found, switching to no-rx mode\n");
pdata->miso = SPI_GPIO_NO_MISO;
} else
pdata->miso = ret;

ret = of_get_named_gpio(np, "gpio-mosi", 0);
if (ret < 0) {
dev_info(&pdev->dev, "gpio-mosi property not found, switching to no-tx mode\n");
pdata->mosi = SPI_GPIO_NO_MOSI;
} else
pdata->mosi = ret;

ret = of_property_read_u32(np, "num-chipselects", &tmp);
if (ret < 0) {
Expand Down
34 changes: 26 additions & 8 deletions drivers/spi/spi-omap2-mcspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)

struct spi_device *spi;
struct spi_transfer *t = NULL;
struct spi_master *master;
int cs_active = 0;
struct omap2_mcspi_cs *cs;
struct omap2_mcspi_device_config *cd;
Expand All @@ -935,6 +936,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
u32 chconf;

spi = m->spi;
master = spi->master;
cs = spi->controller_state;
cd = spi->controller_data;

Expand All @@ -952,6 +954,14 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
if (!t->speed_hz && !t->bits_per_word)
par_override = 0;
}
if (cd && cd->cs_per_word) {
chconf = mcspi->ctx.modulctrl;
chconf &= ~OMAP2_MCSPI_MODULCTRL_SINGLE;
mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, chconf);
mcspi->ctx.modulctrl =
mcspi_read_cs_reg(spi, OMAP2_MCSPI_MODULCTRL);
}


if (!cs_active) {
omap2_mcspi_force_cs(spi, 1);
Expand Down Expand Up @@ -1013,14 +1023,22 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
if (cs_active)
omap2_mcspi_force_cs(spi, 0);

if (cd && cd->cs_per_word) {
chconf = mcspi->ctx.modulctrl;
chconf |= OMAP2_MCSPI_MODULCTRL_SINGLE;
mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, chconf);
mcspi->ctx.modulctrl =
mcspi_read_cs_reg(spi, OMAP2_MCSPI_MODULCTRL);
}

omap2_mcspi_set_enable(spi, 0);

m->status = status;

}

static int omap2_mcspi_transfer_one_message(struct spi_master *master,
struct spi_message *m)
struct spi_message *m)
{
struct omap2_mcspi *mcspi;
struct spi_transfer *t;
Expand All @@ -1041,7 +1059,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
|| (len && !(rx_buf || tx_buf))
|| (t->bits_per_word &&
( t->bits_per_word < 4
|| t->bits_per_word > 32))) {
|| t->bits_per_word > 32))) {
dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",
t->speed_hz,
len,
Expand All @@ -1052,8 +1070,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
}
if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) {
dev_dbg(mcspi->dev, "speed_hz %d below minimum %d Hz\n",
t->speed_hz,
OMAP2_MCSPI_MAX_FREQ >> 15);
t->speed_hz,
OMAP2_MCSPI_MAX_FREQ >> 15);
return -EINVAL;
}

Expand Down Expand Up @@ -1099,7 +1117,7 @@ static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
return ret;

mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
OMAP2_MCSPI_WAKEUPENABLE_WKEN);
OMAP2_MCSPI_WAKEUPENABLE_WKEN);
ctx->wakeupenable = OMAP2_MCSPI_WAKEUPENABLE_WKEN;

omap2_mcspi_set_master_mode(master);
Expand Down Expand Up @@ -1228,7 +1246,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)

sprintf(dma_ch_name, "rx%d", i);
dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA,
dma_ch_name);
dma_ch_name);
if (!dma_res) {
dev_dbg(&pdev->dev, "cannot get DMA RX channel\n");
status = -ENODEV;
Expand All @@ -1238,7 +1256,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start;
sprintf(dma_ch_name, "tx%d", i);
dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA,
dma_ch_name);
dma_ch_name);
if (!dma_res) {
dev_dbg(&pdev->dev, "cannot get DMA TX channel\n");
status = -ENODEV;
Expand All @@ -1254,7 +1272,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR(pinctrl))
dev_warn(&pdev->dev,
"pins are not configured from the driver\n");
"pins are not configured from the driver\n");

pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
Expand Down
133 changes: 22 additions & 111 deletions drivers/spi/spi-pxa2xx-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,147 +8,58 @@
#include <linux/module.h>
#include <linux/spi/pxa2xx_spi.h>

struct ce4100_info {
struct ssp_device ssp;
struct platform_device *spi_pdev;
};

static DEFINE_MUTEX(ssp_lock);
static LIST_HEAD(ssp_list);

struct ssp_device *pxa_ssp_request(int port, const char *label)
{
struct ssp_device *ssp = NULL;

mutex_lock(&ssp_lock);

list_for_each_entry(ssp, &ssp_list, node) {
if (ssp->port_id == port && ssp->use_count == 0) {
ssp->use_count++;
ssp->label = label;
break;
}
}

mutex_unlock(&ssp_lock);

if (&ssp->node == &ssp_list)
return NULL;

return ssp;
}
EXPORT_SYMBOL_GPL(pxa_ssp_request);

void pxa_ssp_free(struct ssp_device *ssp)
{
mutex_lock(&ssp_lock);
if (ssp->use_count) {
ssp->use_count--;
ssp->label = NULL;
} else
dev_err(&ssp->pdev->dev, "device already free\n");
mutex_unlock(&ssp_lock);
}
EXPORT_SYMBOL_GPL(pxa_ssp_free);

static int ce4100_spi_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
struct platform_device_info pi;
int ret;
resource_size_t phys_beg;
resource_size_t phys_len;
struct ce4100_info *spi_info;
struct platform_device *pdev;
struct pxa2xx_spi_master spi_pdata;
struct ssp_device *ssp;

ret = pci_enable_device(dev);
ret = pcim_enable_device(dev);
if (ret)
return ret;

phys_beg = pci_resource_start(dev, 0);
phys_len = pci_resource_len(dev, 0);

if (!request_mem_region(phys_beg, phys_len,
"CE4100 SPI")) {
dev_err(&dev->dev, "Can't request register space.\n");
ret = -EBUSY;
ret = pcim_iomap_regions(dev, 1 << 0, "PXA2xx SPI");
if (!ret)
return ret;
}

pdev = platform_device_alloc("pxa2xx-spi", dev->devfn);
spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL);
if (!pdev || !spi_info ) {
ret = -ENOMEM;
goto err_nomem;
}
memset(&spi_pdata, 0, sizeof(spi_pdata));
spi_pdata.num_chipselect = dev->devfn;

ret = platform_device_add_data(pdev, &spi_pdata, sizeof(spi_pdata));
if (ret)
goto err_nomem;

pdev->dev.parent = &dev->dev;
pdev->dev.of_node = dev->dev.of_node;
ssp = &spi_info->ssp;
ssp = &spi_pdata.ssp;
ssp->phys_base = pci_resource_start(dev, 0);
ssp->mmio_base = ioremap(phys_beg, phys_len);
ssp->mmio_base = pcim_iomap_table(dev)[0];
if (!ssp->mmio_base) {
dev_err(&pdev->dev, "failed to ioremap() registers\n");
ret = -EIO;
goto err_nomem;
dev_err(&dev->dev, "failed to ioremap() registers\n");
return -EIO;
}
ssp->irq = dev->irq;
ssp->port_id = pdev->id;
ssp->port_id = dev->devfn;
ssp->type = PXA25x_SSP;

mutex_lock(&ssp_lock);
list_add(&ssp->node, &ssp_list);
mutex_unlock(&ssp_lock);
memset(&pi, 0, sizeof(pi));
pi.parent = &dev->dev;
pi.name = "pxa2xx-spi";
pi.id = ssp->port_id;
pi.data = &spi_pdata;
pi.size_data = sizeof(spi_pdata);

pci_set_drvdata(dev, spi_info);
pdev = platform_device_register_full(&pi);
if (!pdev)
return -ENOMEM;

ret = platform_device_add(pdev);
if (ret)
goto err_dev_add;
pci_set_drvdata(dev, pdev);

return ret;

err_dev_add:
pci_set_drvdata(dev, NULL);
mutex_lock(&ssp_lock);
list_del(&ssp->node);
mutex_unlock(&ssp_lock);
iounmap(ssp->mmio_base);

err_nomem:
release_mem_region(phys_beg, phys_len);
platform_device_put(pdev);
kfree(spi_info);
return ret;
return 0;
}

static void ce4100_spi_remove(struct pci_dev *dev)
{
struct ce4100_info *spi_info;
struct ssp_device *ssp;

spi_info = pci_get_drvdata(dev);
ssp = &spi_info->ssp;
platform_device_unregister(spi_info->spi_pdev);

iounmap(ssp->mmio_base);
release_mem_region(pci_resource_start(dev, 0),
pci_resource_len(dev, 0));

mutex_lock(&ssp_lock);
list_del(&ssp->node);
mutex_unlock(&ssp_lock);
struct platform_device *pdev = pci_get_drvdata(dev);

pci_set_drvdata(dev, NULL);
pci_disable_device(dev);
kfree(spi_info);
platform_device_unregister(pdev);
}

static DEFINE_PCI_DEVICE_TABLE(ce4100_spi_devices) = {
Expand Down
Loading

0 comments on commit f305a0a

Please sign in to comment.