From 2bdf5151a3a9224d622f1f2bdd20f56bad5d2505 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Thu, 10 Sep 2015 16:11:39 +0200 Subject: spi/bcm63xx: remove unused rx_tail variable Fixes the following warning: drivers/spi/spi-bcm63xx.c:125:5: warning: unused variable 'rx_tail' [-Wunused-variable] u8 rx_tail; ^ Signed-off-by: Jonas Gorski Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index e73e2b052c9c..2b908db0abb1 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -122,7 +122,6 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first, struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); u16 msg_ctl; u16 cmd; - u8 rx_tail; unsigned int i, timeout = 0, prepend_len = 0, len = 0; struct spi_transfer *t = first; bool do_rx = false; -- cgit v1.2.3-59-g8ed1b From 65059997306901f4da1f5168db65de8225d5d04c Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Thu, 10 Sep 2015 16:11:40 +0200 Subject: spi/bcm63xx: always use a fixed number of CS We always pass 8 for the number of chip selects, so we can as well hardcode it to this number. Signed-off-by: Jonas Gorski Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 2b908db0abb1..a997c641b692 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -31,6 +31,8 @@ #define BCM63XX_SPI_MAX_PREPEND 15 +#define BCM63XX_SPI_MAX_CS 8 + struct bcm63xx_spi { struct completion done; @@ -368,7 +370,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) } master->bus_num = pdata->bus_num; - master->num_chipselect = pdata->num_chipselect; + master->num_chipselect = BCM63XX_SPI_MAX_CS; master->transfer_one_message = bcm63xx_spi_transfer_one; master->mode_bits = MODEBITS; master->bits_per_word_mask = SPI_BPW_MASK(8); -- cgit v1.2.3-59-g8ed1b From a45fcea5b20f1dcc2abb08aa29ecb2feacae60f2 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Thu, 10 Sep 2015 16:11:41 +0200 Subject: spi/bcm63xx: hardcode busnum to 0 We always pass 0 as the spi bus number, so we might as well hard code it. Signed-off-by: Jonas Gorski Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index a997c641b692..c1364a8fa268 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -32,6 +32,7 @@ #define BCM63XX_SPI_MAX_PREPEND 15 #define BCM63XX_SPI_MAX_CS 8 +#define BCM63XX_SPI_BUS_NUM 0 struct bcm63xx_spi { struct completion done; @@ -369,7 +370,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) goto out_err; } - master->bus_num = pdata->bus_num; + master->bus_num = BCM63XX_SPI_BUS_NUM; master->num_chipselect = BCM63XX_SPI_MAX_CS; master->transfer_one_message = bcm63xx_spi_transfer_one; master->mode_bits = MODEBITS; -- cgit v1.2.3-59-g8ed1b From 158fcc4e050a75b609bbef1007cf7bf2a01ca043 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Thu, 10 Sep 2015 16:11:42 +0200 Subject: spi/bcm63xx: replace custom io accessors with standard ones Replace all bcm_read* with (io)read. Due to this block following system endianness, make sure we match that. Signed-off-by: Jonas Gorski Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index c1364a8fa268..ef05387c1341 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -56,25 +56,33 @@ struct bcm63xx_spi { static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs, unsigned int offset) { - return bcm_readb(bs->regs + bcm63xx_spireg(offset)); + return readb(bs->regs + bcm63xx_spireg(offset)); } static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs, unsigned int offset) { - return bcm_readw(bs->regs + bcm63xx_spireg(offset)); +#ifdef CONFIG_BIG_ENDIAN + return ioread16(bs->regs + bcm63xx_spireg(offset)); +#else + return readw(bs->regs + bcm63xx_spireg(offset)); +#endif } static inline void bcm_spi_writeb(struct bcm63xx_spi *bs, u8 value, unsigned int offset) { - bcm_writeb(value, bs->regs + bcm63xx_spireg(offset)); + writeb(value, bs->regs + bcm63xx_spireg(offset)); } static inline void bcm_spi_writew(struct bcm63xx_spi *bs, u16 value, unsigned int offset) { - bcm_writew(value, bs->regs + bcm63xx_spireg(offset)); +#ifdef CONFIG_BIG_ENDIAN + iowrite16(value, bs->regs + bcm63xx_spireg(offset)); +#else + writew(value, bs->regs + bcm63xx_spireg(offset)); +#endif } static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { -- cgit v1.2.3-59-g8ed1b From 6774eea6d7a61616384743b218cf77f322e060d9 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Thu, 20 Aug 2015 23:28:38 +0530 Subject: spi: bcm53xx: Adjust devm usage Remove use of spi_unregister_master in remove function as devm_spi_register_master in probe function automatically handles it. To be compatible with the change, use direct return instead of goto and remove unnedded label out. Also, remove bcm53xxspi_bcma_remove as it is now redundant. Signed-off-by: Vaishali Thakkar Signed-off-by: Mark Brown --- drivers/spi/spi-bcm53xx.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bcm53xx.c b/drivers/spi/spi-bcm53xx.c index 1520554978a3..cc3f938f0a6b 100644 --- a/drivers/spi/spi-bcm53xx.c +++ b/drivers/spi/spi-bcm53xx.c @@ -247,28 +247,19 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) if (err) { spi_master_put(master); bcma_set_drvdata(core, NULL); - goto out; + return err; } /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */ spi_new_device(master, &bcm53xx_info); -out: - return err; -} - -static void bcm53xxspi_bcma_remove(struct bcma_device *core) -{ - struct bcm53xxspi *b53spi = bcma_get_drvdata(core); - - spi_unregister_master(b53spi->master); + return 0; } static struct bcma_driver bcm53xxspi_bcma_driver = { .name = KBUILD_MODNAME, .id_table = bcm53xxspi_bcma_tbl, .probe = bcm53xxspi_bcma_probe, - .remove = bcm53xxspi_bcma_remove, }; /************************************************** -- cgit v1.2.3-59-g8ed1b From 57b48ab49b7a9ac5ff94402ade2ccb5d63579816 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 15 Sep 2015 16:26:16 +0300 Subject: spi: bfin-sport: Calculate transfer speed unconditionally SPI core validates the transfer speed and defaults to spi->max_speed_hz in case the transfer speed is not set so code here won't use the chip->baud value (which is derived from spi->max_speed_hz). Please note driver uses chip->baud at the beginning of message transmission by calling the bfin_sport_spi_restore_state() but then programs per transfer speed in bfin_sport_spi_pump_transfers(). I'm not familiar with the HW so I don't know would it be possible to remove chip->baud completely by either using constant value in bfin_sport_spi_restore_state() or by removing the tclkdiv register write there. Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- drivers/spi/spi-bfin-sport.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c index a78693189f45..6c967555a56a 100644 --- a/drivers/spi/spi-bfin-sport.c +++ b/drivers/spi/spi-bfin-sport.c @@ -352,10 +352,7 @@ bfin_sport_spi_pump_transfers(unsigned long data) transfer = drv_data->cur_transfer; chip = drv_data->cur_chip; - if (transfer->speed_hz) - transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz); - else - transfer_speed = chip->baud; + transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz); bfin_write(&drv_data->regs->tclkdiv, transfer_speed); SSYNC(); -- cgit v1.2.3-59-g8ed1b From 95a8fde23ef426aeee579bc99f35dc854e711225 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 15 Sep 2015 16:26:17 +0300 Subject: spi: spi-bfin5xx: Calculate transfer speed unconditionally SPI core validates the transfer speed and defaults to spi->max_speed_hz in case the transfer speed is not set so code here won't use the chip->baud value (which is derived from spi->max_speed_hz). Please note driver uses chip->baud at the beginning of message transmission by calling the bfin_spi_restore_state() but then programs per transfer speed in bfin_spi_pump_transfers(). I'm not familiar with the HW so I don't know would it be possible to remove chip->baud completely by either using constant value in bfin_spi_restore_state() or by removing the baud register write there. Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- drivers/spi/spi-bfin5xx.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index a3d65b4f4944..1e91325bf39c 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c @@ -661,11 +661,7 @@ static void bfin_spi_pump_transfers(unsigned long data) message->state = RUNNING_STATE; dma_config = 0; - /* Speed setup (surely valid because already checked) */ - if (transfer->speed_hz) - bfin_write(&drv_data->regs->baud, hz_to_spi_baud(transfer->speed_hz)); - else - bfin_write(&drv_data->regs->baud, chip->baud); + bfin_write(&drv_data->regs->baud, hz_to_spi_baud(transfer->speed_hz)); bfin_write(&drv_data->regs->stat, BIT_STAT_CLR); bfin_spi_cs_active(drv_data, chip); -- cgit v1.2.3-59-g8ed1b From c15f6ed3a18f10cdc33f64906ab353f17a6df114 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Mon, 17 Aug 2015 11:52:54 +0800 Subject: spi: bitbang: Replace spinlock by mutex chipselect (in the case of spi-gpio: spi_gpio_chipselect, which calls gpiod_set_raw_value_cansleep) can sleep, so we should not hold a spinlock while calling it from spi_bitbang_setup. This issue was introduced by this commit, which converted spi-gpio to cansleep variants: d9dda5a191 "spi: spi-gpio: Use 'cansleep' variants to access GPIO" Replacing the lock variable by a mutex fixes the issue: This is safe as all instances where the lock is used are called from contexts that can sleep. Finally, update spi-ppc4xx and and spi-s3c24xx to use mutex functions, as they directly hold the lock for similar purpose. Signed-off-by: Nicolas Boichat Signed-off-by: Mark Brown --- drivers/spi/spi-bitbang.c | 17 +++++++---------- drivers/spi/spi-ppc4xx.c | 4 ++-- drivers/spi/spi-s3c24xx.c | 4 ++-- include/linux/spi/spi_bitbang.h | 2 +- 4 files changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 840a4984d365..ef43ef507c9a 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi) { struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang *bitbang; - unsigned long flags; bitbang = spi_master_get_devdata(spi->master); @@ -210,12 +209,12 @@ int spi_bitbang_setup(struct spi_device *spi) */ /* deselect chip (low or high) */ - spin_lock_irqsave(&bitbang->lock, flags); + mutex_lock(&bitbang->lock); if (!bitbang->busy) { bitbang->chipselect(spi, BITBANG_CS_INACTIVE); ndelay(cs->nsecs); } - spin_unlock_irqrestore(&bitbang->lock, flags); + mutex_unlock(&bitbang->lock); return 0; } @@ -255,13 +254,12 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) static int spi_bitbang_prepare_hardware(struct spi_master *spi) { struct spi_bitbang *bitbang; - unsigned long flags; bitbang = spi_master_get_devdata(spi); - spin_lock_irqsave(&bitbang->lock, flags); + mutex_lock(&bitbang->lock); bitbang->busy = 1; - spin_unlock_irqrestore(&bitbang->lock, flags); + mutex_unlock(&bitbang->lock); return 0; } @@ -378,13 +376,12 @@ static int spi_bitbang_transfer_one(struct spi_master *master, static int spi_bitbang_unprepare_hardware(struct spi_master *spi) { struct spi_bitbang *bitbang; - unsigned long flags; bitbang = spi_master_get_devdata(spi); - spin_lock_irqsave(&bitbang->lock, flags); + mutex_lock(&bitbang->lock); bitbang->busy = 0; - spin_unlock_irqrestore(&bitbang->lock, flags); + mutex_unlock(&bitbang->lock); return 0; } @@ -427,7 +424,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) if (!master || !bitbang->chipselect) return -EINVAL; - spin_lock_init(&bitbang->lock); + mutex_init(&bitbang->lock); if (!master->mode_bits) master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 54fb984a3e17..dd3d0a218d8b 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -210,12 +210,12 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t) if (in_8(&hw->regs->cdm) != cdm) out_8(&hw->regs->cdm, cdm); - spin_lock(&hw->bitbang.lock); + mutex_lock(&hw->bitbang.lock); if (!hw->bitbang.busy) { hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); /* Need to ndelay here? */ } - spin_unlock(&hw->bitbang.lock); + mutex_unlock(&hw->bitbang.lock); return 0; } diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index f36bc320a807..4e7d1bfed7e6 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c @@ -198,12 +198,12 @@ static int s3c24xx_spi_setup(struct spi_device *spi) if (ret) return ret; - spin_lock(&hw->bitbang.lock); + mutex_lock(&hw->bitbang.lock); if (!hw->bitbang.busy) { hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); /* need to ndelay for 0.5 clocktick ? */ } - spin_unlock(&hw->bitbang.lock); + mutex_unlock(&hw->bitbang.lock); return 0; } diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index 85578d4be034..154788ed218c 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -4,7 +4,7 @@ #include struct spi_bitbang { - spinlock_t lock; + struct mutex lock; u8 busy; u8 use_dma; u8 flags; /* extra spi->mode support */ -- cgit v1.2.3-59-g8ed1b From e30d8f23926b70a003d9fb16b49bfe23f01269da Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 29 Sep 2015 23:09:33 +0200 Subject: spi: bitbang: remove unneeded check Remove an unneeded check. The SPI core (__spi_validate) takes care that these fields are always populated. Signed-off-by: Heiner Kallweit Signed-off-by: Mark Brown --- drivers/spi/spi-bitbang.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index ef43ef507c9a..ad3168dc45e7 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -272,7 +272,6 @@ static int spi_bitbang_transfer_one(struct spi_master *master, struct spi_transfer *t = NULL; unsigned cs_change; int status; - int do_setup = -1; struct spi_device *spi = m->spi; bitbang = spi_master_get_devdata(master); @@ -288,19 +287,10 @@ static int spi_bitbang_transfer_one(struct spi_master *master, list_for_each_entry(t, &m->transfers, transfer_list) { - /* override speed or wordsize? */ - if (t->speed_hz || t->bits_per_word) - do_setup = 1; - - /* init (-1) or override (1) transfer params */ - if (do_setup != 0) { - if (bitbang->setup_transfer) { - status = bitbang->setup_transfer(spi, t); - if (status < 0) - break; - } - if (do_setup == -1) - do_setup = 0; + if (bitbang->setup_transfer) { + status = bitbang->setup_transfer(spi, t); + if (status < 0) + break; } /* set up default clock polarity, and activate chip; -- cgit v1.2.3-59-g8ed1b From 0037686596832572bbca05ab168d9884d7d704c1 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 29 Sep 2015 23:15:53 +0200 Subject: spi: bitbang: switch to the generic implementation of transfer_one_message Change the bitbang driver to use the generic implementation of transfer_one_message. This simplifies the bitbang driver code and provides benefits like the statistics in the generic implementation. Successfully tested on a IMX6-based system (spi-imx) and on a MIPS-based router (OpenWRT with spi-ath79). Signed-off-by: Heiner Kallweit Signed-off-by: Mark Brown --- drivers/spi/spi-bitbang.c | 125 +++++++++++++--------------------------------- 1 file changed, 36 insertions(+), 89 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index ad3168dc45e7..3aa9e6e3dac8 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -24,6 +24,8 @@ #include #include +#define SPI_BITBANG_CS_DELAY 100 + /*----------------------------------------------------------------------*/ @@ -265,100 +267,28 @@ static int spi_bitbang_prepare_hardware(struct spi_master *spi) } static int spi_bitbang_transfer_one(struct spi_master *master, - struct spi_message *m) + struct spi_device *spi, + struct spi_transfer *transfer) { - struct spi_bitbang *bitbang; - unsigned nsecs; - struct spi_transfer *t = NULL; - unsigned cs_change; - int status; - struct spi_device *spi = m->spi; - - bitbang = spi_master_get_devdata(master); - - /* FIXME this is made-up ... the correct value is known to - * word-at-a-time bitbang code, and presumably chipselect() - * should enforce these requirements too? - */ - nsecs = 100; - - cs_change = 1; - status = 0; - - list_for_each_entry(t, &m->transfers, transfer_list) { - - if (bitbang->setup_transfer) { - status = bitbang->setup_transfer(spi, t); - if (status < 0) - break; - } - - /* set up default clock polarity, and activate chip; - * this implicitly updates clock and spi modes as - * previously recorded for this device via setup(). - * (and also deselects any other chip that might be - * selected ...) - */ - if (cs_change) { - bitbang->chipselect(spi, BITBANG_CS_ACTIVE); - ndelay(nsecs); - } - cs_change = t->cs_change; - if (!t->tx_buf && !t->rx_buf && t->len) { - status = -EINVAL; - break; - } - - /* transfer data. the lower level code handles any - * new dma mappings it needs. our caller always gave - * us dma-safe buffers. - */ - if (t->len) { - /* REVISIT dma API still needs a designated - * DMA_ADDR_INVALID; ~0 might be better. - */ - if (!m->is_dma_mapped) - t->rx_dma = t->tx_dma = 0; - status = bitbang->txrx_bufs(spi, t); - } - if (status > 0) - m->actual_length += status; - if (status != t->len) { - /* always report some kind of error */ - if (status >= 0) - status = -EREMOTEIO; - break; - } - status = 0; + struct spi_bitbang *bitbang = spi_master_get_devdata(master); + int status = 0; - /* protocol tweaks before next transfer */ - if (t->delay_usecs) - udelay(t->delay_usecs); - - if (cs_change && - !list_is_last(&t->transfer_list, &m->transfers)) { - /* sometimes a short mid-message deselect of the chip - * may be needed to terminate a mode or command - */ - ndelay(nsecs); - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(nsecs); - } + if (bitbang->setup_transfer) { + status = bitbang->setup_transfer(spi, transfer); + if (status < 0) + goto out; } - m->status = status; + if (transfer->len) + status = bitbang->txrx_bufs(spi, transfer); - /* normally deactivate chipselect ... unless no error and - * cs_change has hinted that the next message will probably - * be for this chip too. - */ - if (!(status == 0 && cs_change)) { - ndelay(nsecs); - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(nsecs); - } + if (status == transfer->len) + status = 0; + else if (status >= 0) + status = -EREMOTEIO; - spi_finalize_current_message(master); +out: + spi_finalize_current_transfer(master); return status; } @@ -376,6 +306,22 @@ static int spi_bitbang_unprepare_hardware(struct spi_master *spi) return 0; } +static void spi_bitbang_set_cs(struct spi_device *spi, bool enable) +{ + struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master); + + /* SPI core provides CS high / low, but bitbang driver + * expects CS active + * spi device driver takes care of handling SPI_CS_HIGH + */ + enable = (!!(spi->mode & SPI_CS_HIGH) == enable); + + ndelay(SPI_BITBANG_CS_DELAY); + bitbang->chipselect(spi, enable ? BITBANG_CS_ACTIVE : + BITBANG_CS_INACTIVE); + ndelay(SPI_BITBANG_CS_DELAY); +} + /*----------------------------------------------------------------------*/ /** @@ -424,7 +370,8 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) master->prepare_transfer_hardware = spi_bitbang_prepare_hardware; master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware; - master->transfer_one_message = spi_bitbang_transfer_one; + master->transfer_one = spi_bitbang_transfer_one; + master->set_cs = spi_bitbang_set_cs; if (!bitbang->txrx_bufs) { bitbang->use_dma = 0; -- cgit v1.2.3-59-g8ed1b From 682b5280bf00c0618606ecb26cf4a9342d5e282e Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Mon, 12 Oct 2015 12:24:21 +0200 Subject: spi/bcm63xx: fix standard accessors and compile guard Use the correct guard CONFIG_CPU_BIG_ENDIAN and the *be accessors to follow native endianness on big endian systems. Signed-off-by: Jonas Gorski Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index ef05387c1341..461891fbc198 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -62,8 +62,8 @@ static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs, static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs, unsigned int offset) { -#ifdef CONFIG_BIG_ENDIAN - return ioread16(bs->regs + bcm63xx_spireg(offset)); +#ifdef CONFIG_CPU_BIG_ENDIAN + return ioread16be(bs->regs + bcm63xx_spireg(offset)); #else return readw(bs->regs + bcm63xx_spireg(offset)); #endif @@ -78,8 +78,8 @@ static inline void bcm_spi_writeb(struct bcm63xx_spi *bs, static inline void bcm_spi_writew(struct bcm63xx_spi *bs, u16 value, unsigned int offset) { -#ifdef CONFIG_BIG_ENDIAN - iowrite16(value, bs->regs + bcm63xx_spireg(offset)); +#ifdef CONFIG_CPU_BIG_ENDIAN + iowrite16be(value, bs->regs + bcm63xx_spireg(offset)); #else writew(value, bs->regs + bcm63xx_spireg(offset)); #endif -- cgit v1.2.3-59-g8ed1b From f13a5e8a856cda0626da316d853a71952f14b1d7 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Mon, 12 Oct 2015 12:24:22 +0200 Subject: spi/bcm63xx: move message control word description to register offsets Make the message control word parameters part of the register offsets array so we have them all in one struct. Signed-off-by: Jonas Gorski Signed-off-by: Mark Brown --- arch/mips/bcm63xx/dev-spi.c | 20 ++------------------ arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | 16 +++++++--------- drivers/spi/spi-bcm63xx.c | 7 +++---- 3 files changed, 12 insertions(+), 31 deletions(-) (limited to 'drivers/spi') diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c index ad448e41e3bd..b21225647e03 100644 --- a/arch/mips/bcm63xx/dev-spi.c +++ b/arch/mips/bcm63xx/dev-spi.c @@ -53,19 +53,11 @@ static struct resource spi_resources[] = { }, }; -static struct bcm63xx_spi_pdata spi_pdata = { - .bus_num = 0, - .num_chipselect = 8, -}; - static struct platform_device bcm63xx_spi_device = { .name = "bcm63xx-spi", .id = -1, .num_resources = ARRAY_SIZE(spi_resources), .resource = spi_resources, - .dev = { - .platform_data = &spi_pdata, - }, }; int __init bcm63xx_spi_register(void) @@ -77,20 +69,12 @@ int __init bcm63xx_spi_register(void) spi_resources[0].end = spi_resources[0].start; spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI); - if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { + if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) spi_resources[0].end += BCM_6348_RSET_SPI_SIZE - 1; - spi_pdata.fifo_size = SPI_6348_MSG_DATA_SIZE; - spi_pdata.msg_type_shift = SPI_6348_MSG_TYPE_SHIFT; - spi_pdata.msg_ctl_width = SPI_6348_MSG_CTL_WIDTH; - } if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6362() || - BCMCPU_IS_6368()) { + BCMCPU_IS_6368()) spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; - spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; - spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT; - spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH; - } bcm63xx_spi_regs_init(); diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h index 25737655d141..1d121fd5b6f5 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h @@ -7,14 +7,6 @@ int __init bcm63xx_spi_register(void); -struct bcm63xx_spi_pdata { - unsigned int fifo_size; - unsigned int msg_type_shift; - unsigned int msg_ctl_width; - int bus_num; - int num_chipselect; -}; - enum bcm63xx_regs_spi { SPI_CMD, SPI_INT_STATUS, @@ -28,6 +20,9 @@ enum bcm63xx_regs_spi { SPI_MSG_CTL, SPI_MSG_DATA, SPI_RX_DATA, + SPI_MSG_TYPE_SHIFT, + SPI_MSG_CTL_WIDTH, + SPI_MSG_DATA_SIZE, }; #define __GEN_SPI_REGS_TABLE(__cpu) \ @@ -42,7 +37,10 @@ enum bcm63xx_regs_spi { [SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \ [SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \ [SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \ - [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA, + [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA, \ + [SPI_MSG_TYPE_SHIFT] = SPI_## __cpu ##_MSG_TYPE_SHIFT, \ + [SPI_MSG_CTL_WIDTH] = SPI_## __cpu ##_MSG_CTL_WIDTH, \ + [SPI_MSG_DATA_SIZE] = SPI_## __cpu ##_MSG_DATA_SIZE, static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg) { diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 461891fbc198..b3da04494fa9 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -329,7 +329,6 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) { struct resource *r; struct device *dev = &pdev->dev; - struct bcm63xx_spi_pdata *pdata = dev_get_platdata(&pdev->dev); int irq; struct spi_master *master; struct clk *clk; @@ -369,7 +368,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) bs->irq = irq; bs->clk = clk; - bs->fifo_size = pdata->fifo_size; + bs->fifo_size = bcm63xx_spireg(SPI_MSG_DATA_SIZE); ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0, pdev->name, master); @@ -384,8 +383,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) master->mode_bits = MODEBITS; master->bits_per_word_mask = SPI_BPW_MASK(8); master->auto_runtime_pm = true; - bs->msg_type_shift = pdata->msg_type_shift; - bs->msg_ctl_width = pdata->msg_ctl_width; + bs->msg_type_shift = bcm63xx_spireg(SPI_MSG_TYPE_SHIFT); + bs->msg_ctl_width = bcm63xx_spireg(SPI_MSG_CTL_WIDTH); bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); -- cgit v1.2.3-59-g8ed1b From 44d8fb30941d85800fbde0a1e3454b1fb23c5ecd Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Mon, 12 Oct 2015 12:24:23 +0200 Subject: spi/bcm63xx: move register definitions into the driver Move all register definitions and structs into the driver. This allows us dropping the platform_data struct and drop any arch specific includes. Make use of different device names to identify the version of the block we have. Since we now have full control over the message width, we can drop the size check, which was broken anyway, since it never set ret to any error code. Also since we now have no arch depedendent resources, we can now allow compiling it for any arch, hidden behind COMPILE_TEST. Signed-off-by: Jonas Gorski Signed-off-by: Mark Brown --- arch/mips/bcm63xx/dev-spi.c | 34 +--- .../include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | 42 ----- drivers/spi/Kconfig | 2 +- drivers/spi/spi-bcm63xx.c | 197 ++++++++++++++++++--- 4 files changed, 181 insertions(+), 94 deletions(-) (limited to 'drivers/spi') diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c index b21225647e03..232385441e46 100644 --- a/arch/mips/bcm63xx/dev-spi.c +++ b/arch/mips/bcm63xx/dev-spi.c @@ -18,29 +18,6 @@ #include #include -/* - * register offsets - */ -static const unsigned long bcm6348_regs_spi[] = { - __GEN_SPI_REGS_TABLE(6348) -}; - -static const unsigned long bcm6358_regs_spi[] = { - __GEN_SPI_REGS_TABLE(6358) -}; - -const unsigned long *bcm63xx_regs_spi; -EXPORT_SYMBOL(bcm63xx_regs_spi); - -static __init void bcm63xx_spi_regs_init(void) -{ - if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) - bcm63xx_regs_spi = bcm6348_regs_spi; - if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || - BCMCPU_IS_6362() || BCMCPU_IS_6368()) - bcm63xx_regs_spi = bcm6358_regs_spi; -} - static struct resource spi_resources[] = { { .start = -1, /* filled at runtime */ @@ -54,7 +31,6 @@ static struct resource spi_resources[] = { }; static struct platform_device bcm63xx_spi_device = { - .name = "bcm63xx-spi", .id = -1, .num_resources = ARRAY_SIZE(spi_resources), .resource = spi_resources, @@ -69,14 +45,16 @@ int __init bcm63xx_spi_register(void) spi_resources[0].end = spi_resources[0].start; spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI); - if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) + if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { + bcm63xx_spi_device.name = "bcm6348-spi", spi_resources[0].end += BCM_6348_RSET_SPI_SIZE - 1; + } if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6362() || - BCMCPU_IS_6368()) + BCMCPU_IS_6368()) { + bcm63xx_spi_device.name = "bcm6358-spi", spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; - - bcm63xx_spi_regs_init(); + } return platform_device_register(&bcm63xx_spi_device); } diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h index 1d121fd5b6f5..dd299548860d 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h @@ -7,46 +7,4 @@ int __init bcm63xx_spi_register(void); -enum bcm63xx_regs_spi { - SPI_CMD, - SPI_INT_STATUS, - SPI_INT_MASK_ST, - SPI_INT_MASK, - SPI_ST, - SPI_CLK_CFG, - SPI_FILL_BYTE, - SPI_MSG_TAIL, - SPI_RX_TAIL, - SPI_MSG_CTL, - SPI_MSG_DATA, - SPI_RX_DATA, - SPI_MSG_TYPE_SHIFT, - SPI_MSG_CTL_WIDTH, - SPI_MSG_DATA_SIZE, -}; - -#define __GEN_SPI_REGS_TABLE(__cpu) \ - [SPI_CMD] = SPI_## __cpu ##_CMD, \ - [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \ - [SPI_INT_MASK_ST] = SPI_## __cpu ##_INT_MASK_ST, \ - [SPI_INT_MASK] = SPI_## __cpu ##_INT_MASK, \ - [SPI_ST] = SPI_## __cpu ##_ST, \ - [SPI_CLK_CFG] = SPI_## __cpu ##_CLK_CFG, \ - [SPI_FILL_BYTE] = SPI_## __cpu ##_FILL_BYTE, \ - [SPI_MSG_TAIL] = SPI_## __cpu ##_MSG_TAIL, \ - [SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \ - [SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \ - [SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \ - [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA, \ - [SPI_MSG_TYPE_SHIFT] = SPI_## __cpu ##_MSG_TYPE_SHIFT, \ - [SPI_MSG_CTL_WIDTH] = SPI_## __cpu ##_MSG_CTL_WIDTH, \ - [SPI_MSG_DATA_SIZE] = SPI_## __cpu ##_MSG_DATA_SIZE, - -static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg) -{ - extern const unsigned long *bcm63xx_regs_spi; - - return bcm63xx_regs_spi[reg]; -} - #endif /* BCM63XX_DEV_SPI_H */ diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4887f317ea58..5c1db987beff 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -125,7 +125,7 @@ config SPI_BCM53XX config SPI_BCM63XX tristate "Broadcom BCM63xx SPI controller" - depends on BCM63XX + depends on BCM63XX || COMPILE_TEST help Enable support for the SPI controller on the Broadcom BCM63xx SoCs. diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index b3da04494fa9..06858e04ec59 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -27,7 +27,111 @@ #include #include -#include +/* BCM 6338/6348 SPI core */ +#define SPI_6348_RSET_SIZE 64 +#define SPI_6348_CMD 0x00 /* 16-bits register */ +#define SPI_6348_INT_STATUS 0x02 +#define SPI_6348_INT_MASK_ST 0x03 +#define SPI_6348_INT_MASK 0x04 +#define SPI_6348_ST 0x05 +#define SPI_6348_CLK_CFG 0x06 +#define SPI_6348_FILL_BYTE 0x07 +#define SPI_6348_MSG_TAIL 0x09 +#define SPI_6348_RX_TAIL 0x0b +#define SPI_6348_MSG_CTL 0x40 /* 8-bits register */ +#define SPI_6348_MSG_CTL_WIDTH 8 +#define SPI_6348_MSG_DATA 0x41 +#define SPI_6348_MSG_DATA_SIZE 0x3f +#define SPI_6348_RX_DATA 0x80 +#define SPI_6348_RX_DATA_SIZE 0x3f + +/* BCM 3368/6358/6262/6368 SPI core */ +#define SPI_6358_RSET_SIZE 1804 +#define SPI_6358_MSG_CTL 0x00 /* 16-bits register */ +#define SPI_6358_MSG_CTL_WIDTH 16 +#define SPI_6358_MSG_DATA 0x02 +#define SPI_6358_MSG_DATA_SIZE 0x21e +#define SPI_6358_RX_DATA 0x400 +#define SPI_6358_RX_DATA_SIZE 0x220 +#define SPI_6358_CMD 0x700 /* 16-bits register */ +#define SPI_6358_INT_STATUS 0x702 +#define SPI_6358_INT_MASK_ST 0x703 +#define SPI_6358_INT_MASK 0x704 +#define SPI_6358_ST 0x705 +#define SPI_6358_CLK_CFG 0x706 +#define SPI_6358_FILL_BYTE 0x707 +#define SPI_6358_MSG_TAIL 0x709 +#define SPI_6358_RX_TAIL 0x70B + +/* Shared SPI definitions */ + +/* Message configuration */ +#define SPI_FD_RW 0x00 +#define SPI_HD_W 0x01 +#define SPI_HD_R 0x02 +#define SPI_BYTE_CNT_SHIFT 0 +#define SPI_6348_MSG_TYPE_SHIFT 6 +#define SPI_6358_MSG_TYPE_SHIFT 14 + +/* Command */ +#define SPI_CMD_NOOP 0x00 +#define SPI_CMD_SOFT_RESET 0x01 +#define SPI_CMD_HARD_RESET 0x02 +#define SPI_CMD_START_IMMEDIATE 0x03 +#define SPI_CMD_COMMAND_SHIFT 0 +#define SPI_CMD_COMMAND_MASK 0x000f +#define SPI_CMD_DEVICE_ID_SHIFT 4 +#define SPI_CMD_PREPEND_BYTE_CNT_SHIFT 8 +#define SPI_CMD_ONE_BYTE_SHIFT 11 +#define SPI_CMD_ONE_WIRE_SHIFT 12 +#define SPI_DEV_ID_0 0 +#define SPI_DEV_ID_1 1 +#define SPI_DEV_ID_2 2 +#define SPI_DEV_ID_3 3 + +/* Interrupt mask */ +#define SPI_INTR_CMD_DONE 0x01 +#define SPI_INTR_RX_OVERFLOW 0x02 +#define SPI_INTR_TX_UNDERFLOW 0x04 +#define SPI_INTR_TX_OVERFLOW 0x08 +#define SPI_INTR_RX_UNDERFLOW 0x10 +#define SPI_INTR_CLEAR_ALL 0x1f + +/* Status */ +#define SPI_RX_EMPTY 0x02 +#define SPI_CMD_BUSY 0x04 +#define SPI_SERIAL_BUSY 0x08 + +/* Clock configuration */ +#define SPI_CLK_20MHZ 0x00 +#define SPI_CLK_0_391MHZ 0x01 +#define SPI_CLK_0_781MHZ 0x02 /* default */ +#define SPI_CLK_1_563MHZ 0x03 +#define SPI_CLK_3_125MHZ 0x04 +#define SPI_CLK_6_250MHZ 0x05 +#define SPI_CLK_12_50MHZ 0x06 +#define SPI_CLK_MASK 0x07 +#define SPI_SSOFFTIME_MASK 0x38 +#define SPI_SSOFFTIME_SHIFT 3 +#define SPI_BYTE_SWAP 0x80 + +enum bcm63xx_regs_spi { + SPI_CMD, + SPI_INT_STATUS, + SPI_INT_MASK_ST, + SPI_INT_MASK, + SPI_ST, + SPI_CLK_CFG, + SPI_FILL_BYTE, + SPI_MSG_TAIL, + SPI_RX_TAIL, + SPI_MSG_CTL, + SPI_MSG_DATA, + SPI_RX_DATA, + SPI_MSG_TYPE_SHIFT, + SPI_MSG_CTL_WIDTH, + SPI_MSG_DATA_SIZE, +}; #define BCM63XX_SPI_MAX_PREPEND 15 @@ -41,6 +145,7 @@ struct bcm63xx_spi { int irq; /* Platform data */ + const unsigned long *reg_offsets; unsigned fifo_size; unsigned int msg_type_shift; unsigned int msg_ctl_width; @@ -54,34 +159,34 @@ struct bcm63xx_spi { }; static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs, - unsigned int offset) + unsigned int offset) { - return readb(bs->regs + bcm63xx_spireg(offset)); + return readb(bs->regs + bs->reg_offsets[offset]); } static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs, unsigned int offset) { #ifdef CONFIG_CPU_BIG_ENDIAN - return ioread16be(bs->regs + bcm63xx_spireg(offset)); + return ioread16be(bs->regs + bs->reg_offsets[offset]); #else - return readw(bs->regs + bcm63xx_spireg(offset)); + return readw(bs->regs + bs->reg_offsets[offset]); #endif } static inline void bcm_spi_writeb(struct bcm63xx_spi *bs, u8 value, unsigned int offset) { - writeb(value, bs->regs + bcm63xx_spireg(offset)); + writeb(value, bs->regs + bs->reg_offsets[offset]); } static inline void bcm_spi_writew(struct bcm63xx_spi *bs, u16 value, unsigned int offset) { #ifdef CONFIG_CPU_BIG_ENDIAN - iowrite16be(value, bs->regs + bcm63xx_spireg(offset)); + iowrite16be(value, bs->regs + bs->reg_offsets[offset]); #else - writew(value, bs->regs + bcm63xx_spireg(offset)); + writew(value, bs->regs + bs->reg_offsets[offset]); #endif } @@ -324,10 +429,59 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static const unsigned long bcm6348_spi_reg_offsets[] = { + [SPI_CMD] = SPI_6348_CMD, + [SPI_INT_STATUS] = SPI_6348_INT_STATUS, + [SPI_INT_MASK_ST] = SPI_6348_INT_MASK_ST, + [SPI_INT_MASK] = SPI_6348_INT_MASK, + [SPI_ST] = SPI_6348_ST, + [SPI_CLK_CFG] = SPI_6348_CLK_CFG, + [SPI_FILL_BYTE] = SPI_6348_FILL_BYTE, + [SPI_MSG_TAIL] = SPI_6348_MSG_TAIL, + [SPI_RX_TAIL] = SPI_6348_RX_TAIL, + [SPI_MSG_CTL] = SPI_6348_MSG_CTL, + [SPI_MSG_DATA] = SPI_6348_MSG_DATA, + [SPI_RX_DATA] = SPI_6348_RX_DATA, + [SPI_MSG_TYPE_SHIFT] = SPI_6348_MSG_TYPE_SHIFT, + [SPI_MSG_CTL_WIDTH] = SPI_6348_MSG_CTL_WIDTH, + [SPI_MSG_DATA_SIZE] = SPI_6348_MSG_DATA_SIZE, +}; + +static const unsigned long bcm6358_spi_reg_offsets[] = { + [SPI_CMD] = SPI_6358_CMD, + [SPI_INT_STATUS] = SPI_6358_INT_STATUS, + [SPI_INT_MASK_ST] = SPI_6358_INT_MASK_ST, + [SPI_INT_MASK] = SPI_6358_INT_MASK, + [SPI_ST] = SPI_6358_ST, + [SPI_CLK_CFG] = SPI_6358_CLK_CFG, + [SPI_FILL_BYTE] = SPI_6358_FILL_BYTE, + [SPI_MSG_TAIL] = SPI_6358_MSG_TAIL, + [SPI_RX_TAIL] = SPI_6358_RX_TAIL, + [SPI_MSG_CTL] = SPI_6358_MSG_CTL, + [SPI_MSG_DATA] = SPI_6358_MSG_DATA, + [SPI_RX_DATA] = SPI_6358_RX_DATA, + [SPI_MSG_TYPE_SHIFT] = SPI_6358_MSG_TYPE_SHIFT, + [SPI_MSG_CTL_WIDTH] = SPI_6358_MSG_CTL_WIDTH, + [SPI_MSG_DATA_SIZE] = SPI_6358_MSG_DATA_SIZE, +}; + +static const struct platform_device_id bcm63xx_spi_dev_match[] = { + { + .name = "bcm6348-spi", + .driver_data = (unsigned long)bcm6348_spi_reg_offsets, + }, + { + .name = "bcm6358-spi", + .driver_data = (unsigned long)bcm6358_spi_reg_offsets, + }, + { + }, +}; static int bcm63xx_spi_probe(struct platform_device *pdev) { struct resource *r; + const unsigned long *bcm63xx_spireg; struct device *dev = &pdev->dev; int irq; struct spi_master *master; @@ -335,6 +489,11 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) struct bcm63xx_spi *bs; int ret; + if (!pdev->id_entry->driver_data) + return -EINVAL; + + bcm63xx_spireg = (const unsigned long *)pdev->id_entry->driver_data; + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "no irq\n"); @@ -368,7 +527,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) bs->irq = irq; bs->clk = clk; - bs->fifo_size = bcm63xx_spireg(SPI_MSG_DATA_SIZE); + bs->reg_offsets = bcm63xx_spireg; + bs->fifo_size = bs->reg_offsets[SPI_MSG_DATA_SIZE]; ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0, pdev->name, master); @@ -383,20 +543,10 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) master->mode_bits = MODEBITS; master->bits_per_word_mask = SPI_BPW_MASK(8); master->auto_runtime_pm = true; - bs->msg_type_shift = bcm63xx_spireg(SPI_MSG_TYPE_SHIFT); - bs->msg_ctl_width = bcm63xx_spireg(SPI_MSG_CTL_WIDTH); - bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); - bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); - - switch (bs->msg_ctl_width) { - case 8: - case 16: - break; - default: - dev_err(dev, "unsupported MSG_CTL width: %d\n", - bs->msg_ctl_width); - goto out_err; - } + bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT]; + bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH]; + bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]); + bs->rx_io = (const u8 *)(bs->regs + bs->reg_offsets[SPI_RX_DATA]); /* Initialize hardware */ ret = clk_prepare_enable(bs->clk); @@ -476,6 +626,7 @@ static struct platform_driver bcm63xx_spi_driver = { .name = "bcm63xx-spi", .pm = &bcm63xx_spi_pm_ops, }, + .id_table = bcm63xx_spi_dev_match, .probe = bcm63xx_spi_probe, .remove = bcm63xx_spi_remove, }; -- cgit v1.2.3-59-g8ed1b