Commit dcf695b5 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/topic/fsl-dspi', 'spi/topic/fsl-espi',...

Merge remote-tracking branches 'spi/topic/fsl-dspi', 'spi/topic/fsl-espi', 'spi/topic/gpio', 'spi/topic/img-spfi' and 'spi/topic/meson' into spi-next
...@@ -8,8 +8,10 @@ Required properties: ...@@ -8,8 +8,10 @@ Required properties:
- gpio-sck: GPIO spec for the SCK line to use - gpio-sck: GPIO spec for the SCK line to use
- gpio-miso: GPIO spec for the MISO line to use - gpio-miso: GPIO spec for the MISO line to use
- gpio-mosi: GPIO spec for the MOSI line to use - gpio-mosi: GPIO spec for the MOSI line to use
- cs-gpios: GPIOs to use for chipselect lines - cs-gpios: GPIOs to use for chipselect lines.
- num-chipselects: number of chipselect lines Not needed if num-chipselects = <0>.
- num-chipselects: Number of chipselect lines. Should be <0> if a single device
with no chip select is connected.
Example: Example:
......
IMG Synchronous Peripheral Flash Interface (SPFI) controller
Required properties:
- compatible: Must be "img,spfi".
- reg: Must contain the base address and length of the SPFI registers.
- interrupts: Must contain the SPFI interrupt.
- clocks: Must contain an entry for each entry in clock-names.
See ../clock/clock-bindings.txt for details.
- clock-names: Must include the following entries:
- spfi: SPI operating clock
- sys: SPI system interface clock
- dmas: Must contain an entry for each entry in dma-names.
See ../dma/dma.txt for details.
- dma-names: Must include the following entries:
- rx
- tx
- #address-cells: Must be 1.
- #size-cells: Must be 0.
Optional properties:
- img,supports-quad-mode: Should be set if the interface supports quad mode
SPI transfers.
Example:
spi@18100f00 {
compatible = "img,spfi";
reg = <0x18100f00 0x100>;
interrupts = <GIC_SHARED 22 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&spi_clk>, <&system_clk>;
clock-names = "spfi", "sys";
dmas = <&mdc 9 0xffffffff 0>, <&mdc 10 0xffffffff 0>;
dma-names = "rx", "tx";
#address-cells = <1>;
#size-cells = <0>;
};
Amlogic Meson SPI controllers
* SPIFC (SPI Flash Controller)
The Meson SPIFC is a controller optimized for communication with SPI
NOR memories, without DMA support and a 64-byte unified transmit /
receive buffer.
Required properties:
- compatible: should be "amlogic,meson6-spifc"
- reg: physical base address and length of the controller registers
- clocks: phandle of the input clock for the baud rate generator
- #address-cells: should be 1
- #size-cells: should be 0
spi@c1108c80 {
compatible = "amlogic,meson6-spifc";
reg = <0xc1108c80 0x80>;
clocks = <&clk81>;
#address-cells = <1>;
#size-cells = <0>;
};
...@@ -225,6 +225,13 @@ config SPI_GPIO ...@@ -225,6 +225,13 @@ config SPI_GPIO
GPIO operations, you should be able to leverage that for better GPIO operations, you should be able to leverage that for better
speed with a custom version of this driver; see the source code. speed with a custom version of this driver; see the source code.
config SPI_IMG_SPFI
tristate "IMG SPFI controller"
depends on MIPS || COMPILE_TEST
help
This enables support for the SPFI master controller found on
IMG SoCs.
config SPI_IMX config SPI_IMX
tristate "Freescale i.MX SPI controllers" tristate "Freescale i.MX SPI controllers"
depends on ARCH_MXC || COMPILE_TEST depends on ARCH_MXC || COMPILE_TEST
...@@ -301,6 +308,14 @@ config SPI_FSL_ESPI ...@@ -301,6 +308,14 @@ config SPI_FSL_ESPI
From MPC8536, 85xx platform uses the controller, and all P10xx, From MPC8536, 85xx platform uses the controller, and all P10xx,
P20xx, P30xx,P40xx, P50xx uses this controller. P20xx, P30xx,P40xx, P50xx uses this controller.
config SPI_MESON_SPIFC
tristate "Amlogic Meson SPIFC controller"
depends on ARCH_MESON || COMPILE_TEST
select REGMAP_MMIO
help
This enables master mode support for the SPIFC (SPI flash
controller) available in Amlogic Meson SoCs.
config SPI_OC_TINY config SPI_OC_TINY
tristate "OpenCores tiny SPI" tristate "OpenCores tiny SPI"
depends on GPIOLIB depends on GPIOLIB
......
...@@ -40,8 +40,10 @@ obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o ...@@ -40,8 +40,10 @@ obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o
obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o
obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
obj-$(CONFIG_SPI_GPIO) += spi-gpio.o obj-$(CONFIG_SPI_GPIO) += spi-gpio.o
obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o
obj-$(CONFIG_SPI_IMX) += spi-imx.o obj-$(CONFIG_SPI_IMX) += spi-imx.o
obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o
obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
......
...@@ -438,7 +438,7 @@ static int dspi_resume(struct device *dev) ...@@ -438,7 +438,7 @@ static int dspi_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume);
static struct regmap_config dspi_regmap_config = { static const struct regmap_config dspi_regmap_config = {
.reg_bits = 32, .reg_bits = 32,
.val_bits = 32, .val_bits = 32,
.reg_stride = 4, .reg_stride = 4,
...@@ -492,7 +492,6 @@ static int dspi_probe(struct platform_device *pdev) ...@@ -492,7 +492,6 @@ static int dspi_probe(struct platform_device *pdev)
goto out_master_put; goto out_master_put;
} }
dspi_regmap_config.lock_arg = dspi;
dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dspi", base, dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dspi", base,
&dspi_regmap_config); &dspi_regmap_config);
if (IS_ERR(dspi->regmap)) { if (IS_ERR(dspi->regmap)) {
......
...@@ -411,7 +411,8 @@ static void fsl_espi_rw_trans(struct spi_message *m, ...@@ -411,7 +411,8 @@ static void fsl_espi_rw_trans(struct spi_message *m,
kfree(local_buf); kfree(local_buf);
} }
static void fsl_espi_do_one_msg(struct spi_message *m) static int fsl_espi_do_one_msg(struct spi_master *master,
struct spi_message *m)
{ {
struct spi_transfer *t; struct spi_transfer *t;
u8 *rx_buf = NULL; u8 *rx_buf = NULL;
...@@ -441,8 +442,8 @@ static void fsl_espi_do_one_msg(struct spi_message *m) ...@@ -441,8 +442,8 @@ static void fsl_espi_do_one_msg(struct spi_message *m)
m->actual_length = espi_trans.actual_length; m->actual_length = espi_trans.actual_length;
m->status = espi_trans.status; m->status = espi_trans.status;
if (m->complete) spi_finalize_current_message(master);
m->complete(m->context); return 0;
} }
static int fsl_espi_setup(struct spi_device *spi) static int fsl_espi_setup(struct spi_device *spi)
...@@ -587,6 +588,38 @@ static void fsl_espi_remove(struct mpc8xxx_spi *mspi) ...@@ -587,6 +588,38 @@ static void fsl_espi_remove(struct mpc8xxx_spi *mspi)
iounmap(mspi->reg_base); iounmap(mspi->reg_base);
} }
static int fsl_espi_suspend(struct spi_master *master)
{
struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_espi_reg *reg_base;
u32 regval;
mpc8xxx_spi = spi_master_get_devdata(master);
reg_base = mpc8xxx_spi->reg_base;
regval = mpc8xxx_spi_read_reg(&reg_base->mode);
regval &= ~SPMODE_ENABLE;
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
return 0;
}
static int fsl_espi_resume(struct spi_master *master)
{
struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_espi_reg *reg_base;
u32 regval;
mpc8xxx_spi = spi_master_get_devdata(master);
reg_base = mpc8xxx_spi->reg_base;
regval = mpc8xxx_spi_read_reg(&reg_base->mode);
regval |= SPMODE_ENABLE;
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
return 0;
}
static struct spi_master * fsl_espi_probe(struct device *dev, static struct spi_master * fsl_espi_probe(struct device *dev,
struct resource *mem, unsigned int irq) struct resource *mem, unsigned int irq)
{ {
...@@ -607,16 +640,16 @@ static struct spi_master * fsl_espi_probe(struct device *dev, ...@@ -607,16 +640,16 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
dev_set_drvdata(dev, master); dev_set_drvdata(dev, master);
ret = mpc8xxx_spi_probe(dev, mem, irq); mpc8xxx_spi_probe(dev, mem, irq);
if (ret)
goto err_probe;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
master->setup = fsl_espi_setup; master->setup = fsl_espi_setup;
master->cleanup = fsl_espi_cleanup; master->cleanup = fsl_espi_cleanup;
master->transfer_one_message = fsl_espi_do_one_msg;
master->prepare_transfer_hardware = fsl_espi_resume;
master->unprepare_transfer_hardware = fsl_espi_suspend;
mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi = spi_master_get_devdata(master);
mpc8xxx_spi->spi_do_one_msg = fsl_espi_do_one_msg;
mpc8xxx_spi->spi_remove = fsl_espi_remove; mpc8xxx_spi->spi_remove = fsl_espi_remove;
mpc8xxx_spi->reg_base = ioremap(mem->start, resource_size(mem)); mpc8xxx_spi->reg_base = ioremap(mem->start, resource_size(mem));
...@@ -762,25 +795,15 @@ static int of_fsl_espi_remove(struct platform_device *dev) ...@@ -762,25 +795,15 @@ static int of_fsl_espi_remove(struct platform_device *dev)
static int of_fsl_espi_suspend(struct device *dev) static int of_fsl_espi_suspend(struct device *dev)
{ {
struct spi_master *master = dev_get_drvdata(dev); struct spi_master *master = dev_get_drvdata(dev);
struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_espi_reg *reg_base;
u32 regval;
int ret; int ret;
mpc8xxx_spi = spi_master_get_devdata(master);
reg_base = mpc8xxx_spi->reg_base;
ret = spi_master_suspend(master); ret = spi_master_suspend(master);
if (ret) { if (ret) {
dev_warn(dev, "cannot suspend master\n"); dev_warn(dev, "cannot suspend master\n");
return ret; return ret;
} }
regval = mpc8xxx_spi_read_reg(&reg_base->mode); return fsl_espi_suspend(master);
regval &= ~SPMODE_ENABLE;
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
return 0;
} }
static int of_fsl_espi_resume(struct device *dev) static int of_fsl_espi_resume(struct device *dev)
......
...@@ -61,44 +61,6 @@ struct mpc8xxx_spi_probe_info *to_of_pinfo(struct fsl_spi_platform_data *pdata) ...@@ -61,44 +61,6 @@ struct mpc8xxx_spi_probe_info *to_of_pinfo(struct fsl_spi_platform_data *pdata)
return container_of(pdata, struct mpc8xxx_spi_probe_info, pdata); return container_of(pdata, struct mpc8xxx_spi_probe_info, pdata);
} }
static void mpc8xxx_spi_work(struct work_struct *work)
{
struct mpc8xxx_spi *mpc8xxx_spi = container_of(work, struct mpc8xxx_spi,
work);
spin_lock_irq(&mpc8xxx_spi->lock);
while (!list_empty(&mpc8xxx_spi->queue)) {
struct spi_message *m = container_of(mpc8xxx_spi->queue.next,
struct spi_message, queue);
list_del_init(&m->queue);
spin_unlock_irq(&mpc8xxx_spi->lock);
if (mpc8xxx_spi->spi_do_one_msg)
mpc8xxx_spi->spi_do_one_msg(m);
spin_lock_irq(&mpc8xxx_spi->lock);
}
spin_unlock_irq(&mpc8xxx_spi->lock);
}
int mpc8xxx_spi_transfer(struct spi_device *spi,
struct spi_message *m)
{
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
unsigned long flags;
m->actual_length = 0;
m->status = -EINPROGRESS;
spin_lock_irqsave(&mpc8xxx_spi->lock, flags);
list_add_tail(&m->queue, &mpc8xxx_spi->queue);
queue_work(mpc8xxx_spi->workqueue, &mpc8xxx_spi->work);
spin_unlock_irqrestore(&mpc8xxx_spi->lock, flags);
return 0;
}
const char *mpc8xxx_spi_strmode(unsigned int flags) const char *mpc8xxx_spi_strmode(unsigned int flags)
{ {
if (flags & SPI_QE_CPU_MODE) { if (flags & SPI_QE_CPU_MODE) {
...@@ -114,13 +76,12 @@ const char *mpc8xxx_spi_strmode(unsigned int flags) ...@@ -114,13 +76,12 @@ const char *mpc8xxx_spi_strmode(unsigned int flags)
return "CPU"; return "CPU";
} }
int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, void mpc8xxx_spi_probe(struct device *dev, struct resource *mem,
unsigned int irq) unsigned int irq)
{ {
struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct spi_master *master; struct spi_master *master;
struct mpc8xxx_spi *mpc8xxx_spi; struct mpc8xxx_spi *mpc8xxx_spi;
int ret = 0;
master = dev_get_drvdata(dev); master = dev_get_drvdata(dev);
...@@ -128,7 +89,6 @@ int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, ...@@ -128,7 +89,6 @@ int mpc8xxx_spi_probe(struct device *dev, struct resource *mem,
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH
| SPI_LSB_FIRST | SPI_LOOP; | SPI_LSB_FIRST | SPI_LOOP;
master->transfer = mpc8xxx_spi_transfer;
master->dev.of_node = dev->of_node; master->dev.of_node = dev->of_node;
mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi = spi_master_get_devdata(master);
...@@ -147,22 +107,7 @@ int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, ...@@ -147,22 +107,7 @@ int mpc8xxx_spi_probe(struct device *dev, struct resource *mem,
master->bus_num = pdata->bus_num; master->bus_num = pdata->bus_num;
master->num_chipselect = pdata->max_chipselect; master->num_chipselect = pdata->max_chipselect;
spin_lock_init(&mpc8xxx_spi->lock);
init_completion(&mpc8xxx_spi->done); init_completion(&mpc8xxx_spi->done);
INIT_WORK(&mpc8xxx_spi->work, mpc8xxx_spi_work);
INIT_LIST_HEAD(&mpc8xxx_spi->queue);
mpc8xxx_spi->workqueue = create_singlethread_workqueue(
dev_name(master->dev.parent));
if (mpc8xxx_spi->workqueue == NULL) {
ret = -EBUSY;
goto err;
}
return 0;
err:
return ret;
} }
int mpc8xxx_spi_remove(struct device *dev) int mpc8xxx_spi_remove(struct device *dev)
...@@ -173,8 +118,6 @@ int mpc8xxx_spi_remove(struct device *dev) ...@@ -173,8 +118,6 @@ int mpc8xxx_spi_remove(struct device *dev)
master = dev_get_drvdata(dev); master = dev_get_drvdata(dev);
mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi = spi_master_get_devdata(master);
flush_workqueue(mpc8xxx_spi->workqueue);
destroy_workqueue(mpc8xxx_spi->workqueue);
spi_unregister_master(master); spi_unregister_master(master);
free_irq(mpc8xxx_spi->irq, mpc8xxx_spi); free_irq(mpc8xxx_spi->irq, mpc8xxx_spi);
......
...@@ -55,7 +55,6 @@ struct mpc8xxx_spi { ...@@ -55,7 +55,6 @@ struct mpc8xxx_spi {
u32(*get_tx) (struct mpc8xxx_spi *); u32(*get_tx) (struct mpc8xxx_spi *);
/* hooks for different controller driver */ /* hooks for different controller driver */
void (*spi_do_one_msg) (struct spi_message *m);
void (*spi_remove) (struct mpc8xxx_spi *mspi); void (*spi_remove) (struct mpc8xxx_spi *mspi);
unsigned int count; unsigned int count;
...@@ -78,12 +77,6 @@ struct mpc8xxx_spi { ...@@ -78,12 +77,6 @@ struct mpc8xxx_spi {
int bits_per_word, int msb_first); int bits_per_word, int msb_first);
#endif #endif
struct workqueue_struct *workqueue;
struct work_struct work;
struct list_head queue;
spinlock_t lock;
struct completion done; struct completion done;
}; };
...@@ -123,9 +116,8 @@ extern struct mpc8xxx_spi_probe_info *to_of_pinfo( ...@@ -123,9 +116,8 @@ extern struct mpc8xxx_spi_probe_info *to_of_pinfo(
struct fsl_spi_platform_data *pdata); struct fsl_spi_platform_data *pdata);
extern int mpc8xxx_spi_bufs(struct mpc8xxx_spi *mspi, extern int mpc8xxx_spi_bufs(struct mpc8xxx_spi *mspi,
struct spi_transfer *t, unsigned int len); struct spi_transfer *t, unsigned int len);
extern int mpc8xxx_spi_transfer(struct spi_device *spi, struct spi_message *m);
extern const char *mpc8xxx_spi_strmode(unsigned int flags); extern const char *mpc8xxx_spi_strmode(unsigned int flags);
extern int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, extern void mpc8xxx_spi_probe(struct device *dev, struct resource *mem,
unsigned int irq); unsigned int irq);
extern int mpc8xxx_spi_remove(struct device *dev); extern int mpc8xxx_spi_remove(struct device *dev);
extern int of_mpc8xxx_spi_probe(struct platform_device *ofdev); extern int of_mpc8xxx_spi_probe(struct platform_device *ofdev);
......
...@@ -353,7 +353,8 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t, ...@@ -353,7 +353,8 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t,
return mpc8xxx_spi->count; return mpc8xxx_spi->count;
} }
static void fsl_spi_do_one_msg(struct spi_message *m) static int fsl_spi_do_one_msg(struct spi_master *master,
struct spi_message *m)
{ {
struct spi_device *spi = m->spi; struct spi_device *spi = m->spi;
struct spi_transfer *t, *first; struct spi_transfer *t, *first;
...@@ -367,10 +368,9 @@ static void fsl_spi_do_one_msg(struct spi_message *m) ...@@ -367,10 +368,9 @@ static void fsl_spi_do_one_msg(struct spi_message *m)
list_for_each_entry(t, &m->transfers, transfer_list) { list_for_each_entry(t, &m->transfers, transfer_list) {
if ((first->bits_per_word != t->bits_per_word) || if ((first->bits_per_word != t->bits_per_word) ||
(first->speed_hz != t->speed_hz)) { (first->speed_hz != t->speed_hz)) {
status = -EINVAL;
dev_err(&spi->dev, dev_err(&spi->dev,
"bits_per_word/speed_hz should be same for the same SPI transfer\n"); "bits_per_word/speed_hz should be same for the same SPI transfer\n");
return; return -EINVAL;
} }
} }
...@@ -408,8 +408,7 @@ static void fsl_spi_do_one_msg(struct spi_message *m) ...@@ -408,8 +408,7 @@ static void fsl_spi_do_one_msg(struct spi_message *m)
} }
m->status = status; m->status = status;
if (m->complete) spi_finalize_current_message(master);
m->complete(m->context);
if (status || !cs_change) { if (status || !cs_change) {
ndelay(nsecs); ndelay(nsecs);
...@@ -417,6 +416,7 @@ static void fsl_spi_do_one_msg(struct spi_message *m) ...@@ -417,6 +416,7 @@ static void fsl_spi_do_one_msg(struct spi_message *m)
} }
fsl_spi_setup_transfer(spi, NULL); fsl_spi_setup_transfer(spi, NULL);
return 0;
} }
static int fsl_spi_setup(struct spi_device *spi) static int fsl_spi_setup(struct spi_device *spi)
...@@ -624,15 +624,13 @@ static struct spi_master * fsl_spi_probe(struct device *dev, ...@@ -624,15 +624,13 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
dev_set_drvdata(dev, master); dev_set_drvdata(dev, master);
ret = mpc8xxx_spi_probe(dev, mem, irq); mpc8xxx_spi_probe(dev, mem, irq);
if (ret)
goto err_probe;
master->setup = fsl_spi_setup; master->setup = fsl_spi_setup;
master->cleanup = fsl_spi_cleanup; master->cleanup = fsl_spi_cleanup;
master->transfer_one_message = fsl_spi_do_one_msg;
mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi = spi_master_get_devdata(master);
mpc8xxx_spi->spi_do_one_msg = fsl_spi_do_one_msg;
mpc8xxx_spi->spi_remove = fsl_spi_remove; mpc8xxx_spi->spi_remove = fsl_spi_remove;
mpc8xxx_spi->max_bits_per_word = 32; mpc8xxx_spi->max_bits_per_word = 32;
mpc8xxx_spi->type = fsl_spi_get_type(dev); mpc8xxx_spi->type = fsl_spi_get_type(dev);
...@@ -704,7 +702,6 @@ static struct spi_master * fsl_spi_probe(struct device *dev, ...@@ -704,7 +702,6 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
err_ioremap: err_ioremap:
fsl_spi_cpm_free(mpc8xxx_spi); fsl_spi_cpm_free(mpc8xxx_spi);
err_cpm_init: err_cpm_init:
err_probe:
spi_master_put(master); spi_master_put(master);
err: err:
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -48,7 +48,7 @@ struct spi_gpio { ...@@ -48,7 +48,7 @@ struct spi_gpio {
struct spi_bitbang bitbang; struct spi_bitbang bitbang;
struct spi_gpio_platform_data pdata; struct spi_gpio_platform_data pdata;
struct platform_device *pdev; struct platform_device *pdev;
int cs_gpios[0]; unsigned long cs_gpios[0];
}; };
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
...@@ -220,7 +220,7 @@ static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, ...@@ -220,7 +220,7 @@ static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi,
static void spi_gpio_chipselect(struct spi_device *spi, int is_active) static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
{ {
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
/* set initial clock polarity */ /* set initial clock polarity */
if (is_active) if (is_active)
...@@ -234,7 +234,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active) ...@@ -234,7 +234,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
static int spi_gpio_setup(struct spi_device *spi) static int spi_gpio_setup(struct spi_device *spi)
{ {
unsigned int cs; unsigned long cs;
int status = 0; int status = 0;
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
struct device_node *np = spi->master->dev.of_node; struct device_node *np = spi->master->dev.of_node;
...@@ -249,7 +249,7 @@ static int spi_gpio_setup(struct spi_device *spi) ...@@ -249,7 +249,7 @@ static int spi_gpio_setup(struct spi_device *spi)
/* /*
* ... otherwise, take it from spi->controller_data * ... otherwise, take it from spi->controller_data
*/ */
cs = (unsigned int)(uintptr_t) spi->controller_data; cs = (uintptr_t) spi->controller_data;
} }
if (!spi->controller_state) { if (!spi->controller_state) {
...@@ -277,7 +277,7 @@ static int spi_gpio_setup(struct spi_device *spi) ...@@ -277,7 +277,7 @@ static int spi_gpio_setup(struct spi_device *spi)
static void spi_gpio_cleanup(struct spi_device *spi) static void spi_gpio_cleanup(struct spi_device *spi)
{ {
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
if (cs != SPI_GPIO_NO_CHIPSELECT) if (cs != SPI_GPIO_NO_CHIPSELECT)
gpio_free(cs); gpio_free(cs);
...@@ -413,6 +413,7 @@ static int spi_gpio_probe(struct platform_device *pdev) ...@@ -413,6 +413,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
struct spi_gpio_platform_data *pdata; struct spi_gpio_platform_data *pdata;
u16 master_flags = 0; u16 master_flags = 0;
bool use_of = 0; bool use_of = 0;
int num_devices;
status = spi_gpio_probe_dt(pdev); status = spi_gpio_probe_dt(pdev);
if (status < 0) if (status < 0)
...@@ -422,16 +423,21 @@ static int spi_gpio_probe(struct platform_device *pdev) ...@@ -422,16 +423,21 @@ static int spi_gpio_probe(struct platform_device *pdev)
pdata = dev_get_platdata(&pdev->dev); pdata = dev_get_platdata(&pdev->dev);
#ifdef GENERIC_BITBANG #ifdef GENERIC_BITBANG
if (!pdata || !pdata->num_chipselect) if (!pdata || (!use_of && !pdata->num_chipselect))
return -ENODEV; return -ENODEV;
#endif #endif
if (use_of && !SPI_N_CHIPSEL)
num_devices = 1;
else
num_devices = SPI_N_CHIPSEL;
status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags); status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags);
if (status < 0) if (status < 0)
return status; return status;
master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) + master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) +
(sizeof(int) * SPI_N_CHIPSEL)); (sizeof(unsigned long) * num_devices));
if (!master) { if (!master) {
status = -ENOMEM; status = -ENOMEM;
goto gpio_free; goto gpio_free;
...@@ -446,7 +452,7 @@ static int spi_gpio_probe(struct platform_device *pdev) ...@@ -446,7 +452,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->flags = master_flags; master->flags = master_flags;
master->bus_num = pdev->id; master->bus_num = pdev->id;
master->num_chipselect = SPI_N_CHIPSEL; master->num_chipselect = num_devices;
master->setup = spi_gpio_setup; master->setup = spi_gpio_setup;
master->cleanup = spi_gpio_cleanup; master->cleanup = spi_gpio_cleanup;
#ifdef CONFIG_OF #ifdef CONFIG_OF
...@@ -461,9 +467,18 @@ static int spi_gpio_probe(struct platform_device *pdev) ...@@ -461,9 +467,18 @@ static int spi_gpio_probe(struct platform_device *pdev)
* property of the node. * property of the node.
*/ */
for (i = 0; i < SPI_N_CHIPSEL; i++) if (!SPI_N_CHIPSEL)
spi_gpio->cs_gpios[i] = spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT;
of_get_named_gpio(np, "cs-gpios", i); else
for (i = 0; i < SPI_N_CHIPSEL; i++) {
status = of_get_named_gpio(np, "cs-gpios", i);
if (status < 0) {
dev_err(&pdev->dev,
"invalid cs-gpios property\n");
goto gpio_free;
}
spi_gpio->cs_gpios[i] = status;
}
} }
#endif #endif
......
This diff is collapsed.
This diff is collapsed.
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