Commit f305a0a8 authored by Grant Likely's avatar Grant Likely

Merge branch 'broonie/spi-next' of git://git.kernel.org/pub/scm/linux/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: default avatarGrant Likely <grant.likely@secretlab.ca>
parents 766ed704 d560040f
......@@ -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
......
......@@ -299,7 +299,7 @@ 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
......@@ -307,7 +307,7 @@ config SPI_PXA2XX
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"
......
......@@ -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;
......@@ -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;
......
......@@ -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) {
......
......@@ -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;
......@@ -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;
......@@ -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);
......@@ -1013,6 +1023,14 @@ 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;
......@@ -1020,7 +1038,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
}
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;
......@@ -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,
......@@ -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;
}
......@@ -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);
......@@ -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;
......@@ -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;
......@@ -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);
......
......@@ -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) = {
......
This diff is collapsed.
......@@ -957,6 +957,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
if (spi->max_speed_hz >= speed) {
spi->max_speed_hz = speed;
} else {
dev_err(&spi->dev, "Can't set %dHz transfer speed\n",
spi->max_speed_hz);
err = -EINVAL;
goto setup_exit;
}
......
......@@ -22,6 +22,9 @@ struct omap2_mcspi_dev_attr {
struct omap2_mcspi_device_config {
unsigned turbo_mode:1;
/* toggle chip select after every word */
unsigned cs_per_word:1;
};
#endif
......@@ -206,6 +206,15 @@ static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg)
return __raw_readl(dev->mmio_base + reg);
}
#ifdef CONFIG_ARCH_PXA
struct ssp_device *pxa_ssp_request(int port, const char *label);
void pxa_ssp_free(struct ssp_device *);
#else
static inline struct ssp_device *pxa_ssp_request(int port, const char *label)
{
return NULL;
}
static inline void pxa_ssp_free(struct ssp_device *ssp) {}
#endif
#endif
......@@ -28,6 +28,9 @@ struct pxa2xx_spi_master {
u32 clock_enable;
u16 num_chipselect;
u8 enable_dma;
/* For non-PXA arches */
struct ssp_device ssp;
};
/* spi_board_info.controller_data for SPI slave devices,
......@@ -130,23 +133,5 @@ static inline void pxa_free_dma(int dma_ch)
{
}
/*
* The CE4100 does not have the clk framework implemented and SPI clock can
* not be switched on/off or the divider changed.
*/
static inline void clk_disable(struct clk *clk)
{
}
static inline int clk_enable(struct clk *clk)
{
return 0;
}
static inline unsigned long clk_get_rate(struct clk *clk)
{
return 3686400;
}
#endif
#endif
......@@ -62,8 +62,8 @@
*/
struct spi_gpio_platform_data {
unsigned sck;
unsigned mosi;
unsigned miso;
unsigned long mosi;
unsigned long miso;
u16 num_chipselect;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment