devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Ivan T. Ivanov" <iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
To: dsneddon-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org
Cc: broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	inux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	alokc-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
	gavidov-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
	kgunda-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
	sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org
Subject: Re: Fwd: [PATCH 2/2] spi: Add Qualcomm QUP SPI controller support
Date: Mon, 10 Feb 2014 17:54:11 +0200	[thread overview]
Message-ID: <1392047651.2853.19.camel@iivanov-dev> (raw)
In-Reply-To: <214fe9fc7e62ab30bdfbb4ac5d1ee250.squirrel-mMfbam+mt9083fI46fginR2eb7JE58TQ@public.gmane.org>


Hi Daniel,

On Fri, 2014-02-07 at 16:34 +0000, dsneddon-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org wrote: 
> > From: "Ivan T. Ivanov" <iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>


<snip>

> > +
> > +static int spi_qup_set_state(struct spi_qup *controller, u32 state)
> > +{
> > +       unsigned long loop = 0;
> > +       u32 cur_state;
> > +
> > +       cur_state = readl_relaxed(controller->base + QUP_STATE);
> Make sure the state is valid before you read the current state.

Why? Controller is always left in valid state (after probe and every
transaction)? I know that CAF code contain this check, but now driver
is little bit different. I have made some tests and controller is
always in valid state in this point.

> > +       /*
> > +        * Per spec: for PAUSE_STATE to RESET_STATE, two writes
> > +        * of (b10) are required
> > +        */
> > +       if (((cur_state & QUP_STATE_MASK) == QUP_STATE_PAUSE) &&
> > +           (state == QUP_STATE_RESET)) {
> > +               writel_relaxed(QUP_STATE_CLEAR, controller->base +
> > QUP_STATE);
> > +               writel_relaxed(QUP_STATE_CLEAR, controller->base +
> > QUP_STATE);
> > +       } else {
> Make sure you don't transition from RESET to PAUSE.

I don't see this to be handled in CAF code. Could you give me
more details, please?

Right now possible state transactions are:

* if everything is fine:
  RESET -> RUN -> PAUSE -> RUN -> RESET 
* in case of error: 
  RESET -> RUN -> RESET 
  RESET -> RUN -> PAUSE -> RESET

Please correct me if I am wrong.

> > +
> > +static void spi_qup_fifo_read(struct spi_qup *controller,
> > +                             struct spi_transfer *xfer)
> > +{
> > +       u8 *rx_buf = xfer->rx_buf;
> > +       u32 word, state;
> > +       int idx, shift;
> > +
> > +       while (controller->rx_bytes < xfer->len) {
> > +
> > +               state = readl_relaxed(controller->base + QUP_OPERATIONAL);
> > +               if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY))
> > +                       break;
> > +
> > +               word = readl_relaxed(controller->base + QUP_INPUT_FIFO);
> > +
> > +               for (idx = 0; idx < controller->bytes_per_word &&
> > +                    controller->rx_bytes < xfer->len; idx++,
> > +                    controller->rx_bytes++) {
> > +
> > +                       if (!rx_buf)
> > +                               continue;
> If there is no rx_buf just set rx_bytes to xfer->len and skip the loop
> entirely.

Well, FIFO buffer still should be drained, right?
Anyway. I am looking for better way to handle this.
Same applies for filling FIFO buffer.

> > +                       /*
> > +                        * The data format depends on bytes_per_word:
> > +                        *  4 bytes: 0x12345678
> > +                        *  2 bytes: 0x00001234
> > +                        *  1 byte : 0x00000012
> > +                        */
> > +                       shift = BITS_PER_BYTE;
> > +                       shift *= (controller->bytes_per_word - idx - 1);
> > +                       rx_buf[controller->rx_bytes] = word >> shift;
> > +               }
> > +       }
> > +}

<snip>

> > +static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
> > +{
> > +       struct spi_qup *controller = dev_id;
> > +       struct spi_transfer *xfer;
> > +       u32 opflags, qup_err, spi_err;
> > +
> > +       xfer = controller->xfer;
> > +
> > +       qup_err = readl_relaxed(controller->base + QUP_ERROR_FLAGS);
> > +       spi_err = readl_relaxed(controller->base + SPI_ERROR_FLAGS);
> > +       opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
> > +
> > +       writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS);
> > +       writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS);
> > +       writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
> > +
> > +       if (!xfer)
> > +               return IRQ_HANDLED;
> > +
> > +       if (qup_err) {
> > +               if (qup_err & QUP_ERROR_OUTPUT_OVER_RUN)
> > +                       dev_warn(controller->dev, "OUTPUT_OVER_RUN\n");
> > +               if (qup_err & QUP_ERROR_INPUT_UNDER_RUN)
> > +                       dev_warn(controller->dev, "INPUT_UNDER_RUN\n");
> > +               if (qup_err & QUP_ERROR_OUTPUT_UNDER_RUN)
> > +                       dev_warn(controller->dev, "OUTPUT_UNDER_RUN\n");
> > +               if (qup_err & QUP_ERROR_INPUT_OVER_RUN)
> > +                       dev_warn(controller->dev, "INPUT_OVER_RUN\n");
> > +
> > +               controller->error = -EIO;
> > +       }
> > +
> > +       if (spi_err) {
> > +               if (spi_err & SPI_ERROR_CLK_OVER_RUN)
> > +                       dev_warn(controller->dev, "CLK_OVER_RUN\n");
> > +               if (spi_err & SPI_ERROR_CLK_UNDER_RUN)
> > +                       dev_warn(controller->dev, "CLK_UNDER_RUN\n");
> > +
> > +               controller->error = -EIO;
> > +       }
> > +
> > +       if (opflags & QUP_OP_IN_SERVICE_FLAG) {
> > +               writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
> > +                      controller->base + QUP_OPERATIONAL);
> Write is not necessary since already cleared above.
> > +               spi_qup_fifo_read(controller, xfer);
> > +       }
> > +
> > +       if (opflags & QUP_OP_OUT_SERVICE_FLAG) {
> > +               writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
> > +                      controller->base + QUP_OPERATIONAL);
> Write is not necessary since already cleared above.

True. I have forgot to remove these writes. Will fix.

Regards,
Ivan

> > +               spi_qup_fifo_write(controller, xfer);
> > +       }
> > +
> > +       if (controller->rx_bytes == xfer->len ||
> > +           controller->error)
> > +               complete(&controller->done);
> > +
> > +       return IRQ_HANDLED;
> > +}
> > +


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2014-02-10 15:54 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-06 16:57 [PATCH 0/2] spi: Add Qualcomm QUP SPI controller support Ivan T. Ivanov
2014-02-06 16:57 ` [PATCH 1/2] spi: qup: Add device tree bindings information Ivan T. Ivanov
     [not found]   ` <1391705868-20091-2-git-send-email-iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-02-07  7:43     ` Andy Gross
2014-02-06 16:57 ` [PATCH 2/2] spi: Add Qualcomm QUP SPI controller support Ivan T. Ivanov
2014-02-07  7:39   ` Andy Gross
     [not found]     ` <20140207073952.GA2610-zC7DfRvBq/JWk0Htik3J/w@public.gmane.org>
2014-02-07  9:52       ` Ivan T. Ivanov
2014-02-07 17:32         ` Andy Gross
2014-02-07 17:52           ` Mark Brown
     [not found]             ` <20140207175234.GJ1757-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2014-02-07 19:12               ` Andy Gross
2014-02-10 16:55           ` Ivan T. Ivanov
2014-02-10 17:47             ` Andy Gross
     [not found]               ` <20140210174738.GA31596-zC7DfRvBq/JWk0Htik3J/w@public.gmane.org>
2014-02-10 19:41                 ` Ivan T. Ivanov
2014-02-10 20:29                   ` Courtney Cavin
2014-02-10 20:59                     ` Ivan T. Ivanov
2014-02-10 21:40                       ` Mark Brown
     [not found]                     ` <20140210202926.GV1706-/MT0OVThwyLZJqsBc5GL+g@public.gmane.org>
2014-02-11 15:46                       ` Ivan T. Ivanov
2014-02-07 16:51     ` Josh Cartwright
     [not found]       ` <20140207165127.GV20228-OP5zVEFNDbfdOxZ39nK119BPR1lH4CV8@public.gmane.org>
2014-02-07 17:18         ` Mark Brown
2014-02-07 17:20           ` Josh Cartwright
     [not found]             ` <20140207172051.GW20228-OP5zVEFNDbfdOxZ39nK119BPR1lH4CV8@public.gmane.org>
2014-02-07 17:31               ` Mark Brown
     [not found]                 ` <20140207173108.GH1757-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2014-02-07 17:46                   ` Josh Cartwright
2014-02-07 17:57                     ` Mark Brown
     [not found]   ` <CACceFXdUobQvN2hcv5kh+QL=o8bWM_PVkAtrOx+euZSeVDm8hQ@mail.gmail.com>
2014-02-07 16:34     ` Fwd: " dsneddon
2014-02-07 17:16       ` Mark Brown
     [not found]       ` <214fe9fc7e62ab30bdfbb4ac5d1ee250.squirrel-mMfbam+mt9083fI46fginR2eb7JE58TQ@public.gmane.org>
2014-02-10 15:54         ` Ivan T. Ivanov [this message]
2014-02-10 16:21           ` dsneddon
     [not found]             ` <3388d68dc907e9190d997fad95830d74.squirrel-mMfbam+mt9083fI46fginR2eb7JE58TQ@public.gmane.org>
2014-02-10 17:11               ` Ivan T. Ivanov
2014-02-10 17:41                 ` dsneddon
     [not found]   ` <1391705868-20091-3-git-send-email-iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-02-07 17:12     ` Mark Brown
     [not found]       ` <20140207171202.GD1757-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2014-02-10 16:29         ` Ivan T. Ivanov
2014-02-10 17:09           ` Mark Brown
2014-02-06 17:50 ` [PATCH 0/2] " Mark Brown
2014-02-07  7:43   ` [PATCH RESEND 1/2] spi: qup: Add device tree bindings information Ivan T. Ivanov
2014-02-07 12:27     ` Mark Brown
2014-02-07 13:00       ` Ivan T. Ivanov
2014-02-07 13:13         ` Mark Brown
2014-02-07 13:35           ` Ivan T. Ivanov

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=1392047651.2853.19.camel@iivanov-dev \
    --to=iivanov-neyub+7iv8pqt0dzr+alfa@public.gmane.org \
    --cc=alokc-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=dsneddon-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=gavidov-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=inux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=kgunda-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=sdharia-sgV2jX0FEOL9JmXXK+q4OQ@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).