From: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
To: Sebastian Andrzej Siewior
<bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Cc: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org,
sodaville-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org,
Dirk Brandewie
<dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: Re: [PATCH 7/9] spi/pxa2xx: Add chipselect support for Sodaville
Date: Wed, 29 Dec 2010 01:11:54 -0700 [thread overview]
Message-ID: <20101229081154.GT8172@angua.secretlab.ca> (raw)
In-Reply-To: <1291312057-7933-8-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
On Thu, Dec 02, 2010 at 06:47:35PM +0100, Sebastian Andrzej Siewior wrote:
> The SPI core on Sodaville supports chip selects. Its configuration
> moved into the SSSR register at bit 0 and 1. Thus Sodaville can be hooked
> up with up to 4 devices.
> This patch ensures that the bits which are otherwiese reserved are only
> touched on Sodaville and not on any other PXAs. Also it makes sure that
> the status register does not lose the CS information while clearing the
> ROR bit.
>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
> Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
picked up for -next via merge
g.
> ---
> drivers/spi/pxa2xx_spi.c | 93 ++++++++++++++++++++++++++++++++------------
> include/linux/pxa2xx_ssp.h | 2 +
> 2 files changed, 70 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
> index 81cfbbc..a54685b 100644
> --- a/drivers/spi/pxa2xx_spi.c
> +++ b/drivers/spi/pxa2xx_spi.c
> @@ -163,7 +163,10 @@ struct chip_data {
> u8 enable_dma;
> u8 bits_per_word;
> u32 speed_hz;
> - int gpio_cs;
> + union {
> + int gpio_cs;
> + unsigned int frm;
> + };
> int gpio_cs_inverted;
> int (*write)(struct driver_data *drv_data);
> int (*read)(struct driver_data *drv_data);
> @@ -176,6 +179,11 @@ static void cs_assert(struct driver_data *drv_data)
> {
> struct chip_data *chip = drv_data->cur_chip;
>
> + if (drv_data->ssp_type == CE4100_SSP) {
> + write_SSSR(drv_data->cur_chip->frm, drv_data->ioaddr);
> + return;
> + }
> +
> if (chip->cs_control) {
> chip->cs_control(PXA2XX_CS_ASSERT);
> return;
> @@ -189,6 +197,9 @@ static void cs_deassert(struct driver_data *drv_data)
> {
> struct chip_data *chip = drv_data->cur_chip;
>
> + if (drv_data->ssp_type == CE4100_SSP)
> + return;
> +
> if (chip->cs_control) {
> chip->cs_control(PXA2XX_CS_DEASSERT);
> return;
> @@ -198,6 +209,25 @@ static void cs_deassert(struct driver_data *drv_data)
> gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted);
> }
>
> +static void write_SSSR_CS(struct driver_data *drv_data, u32 val)
> +{
> + void __iomem *reg = drv_data->ioaddr;
> +
> + if (drv_data->ssp_type == CE4100_SSP)
> + val |= read_SSSR(reg) & SSSR_ALT_FRM_MASK;
> +
> + write_SSSR(val, reg);
> +}
> +
> +static int pxa25x_ssp_comp(struct driver_data *drv_data)
> +{
> + if (drv_data->ssp_type == PXA25x_SSP)
> + return 1;
> + if (drv_data->ssp_type == CE4100_SSP)
> + return 1;
> + return 0;
> +}
> +
> static int flush(struct driver_data *drv_data)
> {
> unsigned long limit = loops_per_jiffy << 1;
> @@ -209,7 +239,7 @@ static int flush(struct driver_data *drv_data)
> read_SSDR(reg);
> }
> } while ((read_SSSR(reg) & SSSR_BSY) && --limit);
> - write_SSSR(SSSR_ROR, reg);
> + write_SSSR_CS(drv_data, SSSR_ROR);
>
> return limit;
> }
> @@ -502,9 +532,9 @@ static void dma_error_stop(struct driver_data *drv_data, const char *msg)
> /* Stop and reset */
> DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
> DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
> - write_SSSR(drv_data->clear_sr, reg);
> + write_SSSR_CS(drv_data, drv_data->clear_sr);
> write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
> - if (drv_data->ssp_type != PXA25x_SSP)
> + if (!pxa25x_ssp_comp(drv_data))
> write_SSTO(0, reg);
> flush(drv_data);
> write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
> @@ -524,7 +554,7 @@ static void dma_transfer_complete(struct driver_data *drv_data)
>
> /* Clear and disable interrupts on SSP and DMA channels*/
> write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
> - write_SSSR(drv_data->clear_sr, reg);
> + write_SSSR_CS(drv_data, drv_data->clear_sr);
> DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
> DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
>
> @@ -617,7 +647,7 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
>
> /* Clear and disable timeout interrupt, do the rest in
> * dma_transfer_complete */
> - if (drv_data->ssp_type != PXA25x_SSP)
> + if (!pxa25x_ssp_comp(drv_data))
> write_SSTO(0, reg);
>
> /* finish this transfer, start the next */
> @@ -635,9 +665,9 @@ static void int_error_stop(struct driver_data *drv_data, const char* msg)
> void __iomem *reg = drv_data->ioaddr;
>
> /* Stop and reset SSP */
> - write_SSSR(drv_data->clear_sr, reg);
> + write_SSSR_CS(drv_data, drv_data->clear_sr);
> write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
> - if (drv_data->ssp_type != PXA25x_SSP)
> + if (!pxa25x_ssp_comp(drv_data))
> write_SSTO(0, reg);
> flush(drv_data);
> write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
> @@ -653,9 +683,9 @@ static void int_transfer_complete(struct driver_data *drv_data)
> void __iomem *reg = drv_data->ioaddr;
>
> /* Stop SSP */
> - write_SSSR(drv_data->clear_sr, reg);
> + write_SSSR_CS(drv_data, drv_data->clear_sr);
> write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
> - if (drv_data->ssp_type != PXA25x_SSP)
> + if (!pxa25x_ssp_comp(drv_data))
> write_SSTO(0, reg);
>
> /* Update total byte transfered return count actual bytes read */
> @@ -711,7 +741,7 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
> if (drv_data->tx == drv_data->tx_end) {
> write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg);
> /* PXA25x_SSP has no timeout, read trailing bytes */
> - if (drv_data->ssp_type == PXA25x_SSP) {
> + if (pxa25x_ssp_comp(drv_data)) {
> if (!wait_ssp_rx_stall(reg))
> {
> int_error_stop(drv_data, "interrupt_transfer: "
> @@ -754,9 +784,9 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
>
> write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
> write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
> - if (drv_data->ssp_type != PXA25x_SSP)
> + if (!pxa25x_ssp_comp(drv_data))
> write_SSTO(0, reg);
> - write_SSSR(drv_data->clear_sr, reg);
> + write_SSSR_CS(drv_data, drv_data->clear_sr);
>
> dev_err(&drv_data->pdev->dev, "bad message state "
> "in interrupt handler\n");
> @@ -869,7 +899,7 @@ static unsigned int ssp_get_clk_div(struct ssp_device *ssp, int rate)
> {
> unsigned long ssp_clk = clk_get_rate(ssp->clk);
>
> - if (ssp->type == PXA25x_SSP)
> + if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP)
> return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8;
> else
> return ((ssp_clk / rate - 1) & 0xfff) << 8;
> @@ -1095,7 +1125,7 @@ static void pump_transfers(unsigned long data)
>
> /* Clear status */
> cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1;
> - write_SSSR(drv_data->clear_sr, reg);
> + write_SSSR_CS(drv_data, drv_data->clear_sr);
> }
>
> /* see if we need to reload the config registers */
> @@ -1105,7 +1135,7 @@ static void pump_transfers(unsigned long data)
>
> /* stop the SSP, and update the other bits */
> write_SSCR0(cr0 & ~SSCR0_SSE, reg);
> - if (drv_data->ssp_type != PXA25x_SSP)
> + if (!pxa25x_ssp_comp(drv_data))
> write_SSTO(chip->timeout, reg);
> /* first set CR1 without interrupt and service enables */
> write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg);
> @@ -1113,7 +1143,7 @@ static void pump_transfers(unsigned long data)
> write_SSCR0(cr0, reg);
>
> } else {
> - if (drv_data->ssp_type != PXA25x_SSP)
> + if (!pxa25x_ssp_comp(drv_data))
> write_SSTO(chip->timeout, reg);
> }
>
> @@ -1240,14 +1270,13 @@ static int setup(struct spi_device *spi)
> uint tx_thres = TX_THRESH_DFLT;
> uint rx_thres = RX_THRESH_DFLT;
>
> - if (drv_data->ssp_type != PXA25x_SSP
> + if (!pxa25x_ssp_comp(drv_data)
> && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) {
> dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d "
> "b/w not 4-32 for type non-PXA25x_SSP\n",
> drv_data->ssp_type, spi->bits_per_word);
> return -EINVAL;
> - }
> - else if (drv_data->ssp_type == PXA25x_SSP
> + } else if (pxa25x_ssp_comp(drv_data)
> && (spi->bits_per_word < 4
> || spi->bits_per_word > 16)) {
> dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d "
> @@ -1266,7 +1295,17 @@ static int setup(struct spi_device *spi)
> return -ENOMEM;
> }
>
> - chip->gpio_cs = -1;
> + if (drv_data->ssp_type == CE4100_SSP) {
> + if (spi->chip_select > 4) {
> + dev_err(&spi->dev, "failed setup: "
> + "cs number must not be > 4.\n");
> + kfree(chip);
> + return -EINVAL;
> + }
> +
> + chip->frm = spi->chip_select;
> + } else
> + chip->gpio_cs = -1;
> chip->enable_dma = 0;
> chip->timeout = TIMOUT_DFLT;
> chip->dma_burst_size = drv_data->master_info->enable_dma ?
> @@ -1322,7 +1361,7 @@ static int setup(struct spi_device *spi)
> | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0);
>
> /* NOTE: PXA25x_SSP _could_ use external clocking ... */
> - if (drv_data->ssp_type != PXA25x_SSP)
> + if (!pxa25x_ssp_comp(drv_data))
> dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
> clk_get_rate(ssp->clk)
> / (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)),
> @@ -1357,17 +1396,21 @@ static int setup(struct spi_device *spi)
>
> spi_set_ctldata(spi, chip);
>
> + if (drv_data->ssp_type == CE4100_SSP)
> + return 0;
> +
> return setup_cs(spi, chip, chip_info);
> }
>
> static void cleanup(struct spi_device *spi)
> {
> struct chip_data *chip = spi_get_ctldata(spi);
> + struct driver_data *drv_data = spi_master_get_devdata(spi->master);
>
> if (!chip)
> return;
>
> - if (gpio_is_valid(chip->gpio_cs))
> + if (drv_data->ssp_type != CE4100_SSP && gpio_is_valid(chip->gpio_cs))
> gpio_free(chip->gpio_cs);
>
> kfree(chip);
> @@ -1507,7 +1550,7 @@ static int __devinit pxa2xx_spi_probe(struct platform_device *pdev)
>
> drv_data->ioaddr = ssp->mmio_base;
> drv_data->ssdr_physical = ssp->phys_base + SSDR;
> - if (ssp->type == PXA25x_SSP) {
> + if (pxa25x_ssp_comp(drv_data)) {
> drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
> drv_data->dma_cr1 = 0;
> drv_data->clear_sr = SSSR_ROR;
> @@ -1569,7 +1612,7 @@ static int __devinit pxa2xx_spi_probe(struct platform_device *pdev)
> | SSCR0_Motorola
> | SSCR0_DataSize(8),
> drv_data->ioaddr);
> - if (drv_data->ssp_type != PXA25x_SSP)
> + if (!pxa25x_ssp_comp(drv_data))
> write_SSTO(0, drv_data->ioaddr);
> write_SSPSP(0, drv_data->ioaddr);
>
> diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h
> index c3aa334..2f691e4 100644
> --- a/include/linux/pxa2xx_ssp.h
> +++ b/include/linux/pxa2xx_ssp.h
> @@ -72,6 +72,7 @@
> #define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */
> #define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */
>
> +#define SSSR_ALT_FRM_MASK 3 /* Masks the SFRM signal number */
> #define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */
> #define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */
> #define SSSR_BSY (1 << 4) /* SSP Busy */
> @@ -160,6 +161,7 @@ enum pxa_ssp_type {
> PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
> PXA27x_SSP,
> PXA168_SSP,
> + CE4100_SSP,
> };
>
> struct ssp_device {
> --
> 1.7.3.2
>
------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and,
should the need arise, upgrade to a full multi-node Oracle RAC database
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
next prev parent reply other threads:[~2010-12-29 8:11 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-02 17:47 SPI support for CE4100, v2 Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-02 17:47 ` [PATCH 1/9] spi/pxa2xx: register driver properly Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-2-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:11 ` Grant Likely
2010-12-29 17:00 ` David Brownell
2010-12-29 21:26 ` Sebastian Andrzej Siewior
[not found] ` <20101229212635.GA31347-Hfxr4Dq0UpYb1SvskN2V4Q@public.gmane.org>
2010-12-29 21:40 ` Grant Likely
[not found] ` <20101229214054.GB15198-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-12-30 1:55 ` David Brownell
[not found] ` <349566.41372.qm-g47maUHHHF+ORdMXk8NaZPu2YVrzzGjVVpNB7YpNyf8@public.gmane.org>
2010-12-29 21:36 ` Grant Likely
2010-12-02 17:47 ` [PATCH 2/9] spi/pxa2xx: add support for shared IRQ handler Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-3-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:11 ` Grant Likely
2010-12-02 17:47 ` [PATCH 3/9] spi/pxa2xx: Use define for SSSR_TFL_MASK instead of plain numbers Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-4-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:11 ` Grant Likely
2010-12-02 17:47 ` [PATCH 4/9] arm/pxa2xx: reorgazine SSP and SPI header files Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-5-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:11 ` Grant Likely
2010-12-02 17:47 ` [PATCH 5/9] spi/pxa2xx: Add CE4100 support Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-6-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:11 ` Grant Likely
2010-12-02 17:47 ` [PATCH 6/9] spi/pxa2xx: Consider CE4100's FIFO depth Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-7-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:11 ` Grant Likely
2010-12-02 17:47 ` [PATCH 7/9] spi/pxa2xx: Add chipselect support for Sodaville Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-8-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:11 ` Grant Likely [this message]
2010-12-02 17:47 ` [PATCH 8/9] spi/pxa2xx: Modify RX-Tresh instead of busy-loop for the remaining RX bytes Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-9-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:12 ` Grant Likely
2010-12-02 17:47 ` [PATCH 9/9] spi/pxa2xx: pass of_node to spi device and set a parent device Sebastian Andrzej Siewior
[not found] ` <1291312057-7933-10-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:11 ` Grant Likely
2010-12-09 16:43 ` [sodaville] SPI support for CE4100, v2 Sebastian Andrzej Siewior
[not found] ` <4D01074A.2020106-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-12-29 8:10 ` Grant Likely
-- strict thread matches above, loose matches on Subject: below --
2010-11-24 11:13 SPI support for Sodaville Sebastian Andrzej Siewior
[not found] ` <1290597207-29838-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2010-11-24 11:13 ` [PATCH 7/9] spi/pxa2xx: Add chipselect " Sebastian Andrzej Siewior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101229081154.GT8172@angua.secretlab.ca \
--to=grant.likely-s3s/wqlpoipyb63q8fvjnq@public.gmane.org \
--cc=bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org \
--cc=dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org \
--cc=sodaville-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org \
--cc=spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).