linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sourav Poddar <sourav.poddar@ti.com>
To: <balbi@ti.com>
Cc: <broonie@kernel.org>, <spi-devel-general@lists.sourceforge.net>,
	<grant.likely@linaro.org>, <linux-omap@vger.kernel.org>,
	<rnayak@ti.com>
Subject: Re: [PATCHv7 1/2] drivers: spi: Add qspi flash controller
Date: Wed, 31 Jul 2013 15:10:40 +0530	[thread overview]
Message-ID: <51F8DB98.70709@ti.com> (raw)
In-Reply-To: <20130731092008.GC14517@radagast>

On Wednesday 31 July 2013 02:50 PM, Felipe Balbi wrote:
> Hi,
>
> On Wed, Jul 31, 2013 at 02:40:51PM +0530, Sourav Poddar wrote:
>>>> +#define	QSPI_FRAME_MAX			0xfff
>>> Frame max is 4096, 0x1000, right ?
>> Yes,
>> this macro was used initially to fill the register bits, where 4095 =
>> 4096 words.
>> Will change it to now.
> you can make this something like:
>
> #define QSPI_FRAME(n)		(((n) - 1)&  0xfff)
>
Yes, but now its only used in a clamp function, where I should
provide the exact value 4096. Will use your previous suggestion.
#define    QSPI_FRAME_MAX            0x1000
>>>> +static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t)
>>>> +{
>>>> +	const u8 *txbuf;
>>>> +	int wlen, count, ret;
>>>> +
>>>> +	count = t->len;
>>>> +	txbuf = t->tx_buf;
>>>> +	wlen = t->bits_per_word;
>>>> +
>>>> +	while (count--) {
>>> you're decrementing count by one, but in some cases you write 4 bytes or
>>> 2 bytes... This will blow up very soon. I can already see overflows
>>> happening...
>> we write 2 bytes and 4 bytes for 16 bits_per_word and 32 bits_per_word case.
>> count is t->len, which is the total number of words to transfer. This
> t->len is total number of bytes as you can see from the documentation in
> the header:
>
> * @len: size of rx and tx buffers (in bytes)
>
> As I said before, please read the documentation.
>
>> words can be of any length (1, 2 or 4) bytes. So, I think it should be
>> decremented by 1 only.
> this is wrong.
>
hmm..got the point.
I will pass the count address also to ti_qspi_read_data/write_data and make
use of the switch statement to decrement the count.
>>>> +static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t)
>>>> +{
>>>> +	int ret;
>>>> +
>>>> +	if (t->tx_buf) {
>>>> +		ret = qspi_write_msg(qspi, t);
>>>> +		if (ret) {
>>>> +			dev_dbg(qspi->dev, "Error while writing\n");
>>>> +			return -EINVAL;
>>> why do you change the return value from qspi_write_msg() ?
>>>
>> I  was not sure about this, I thought I had signals an ETIMEOUT during
>> timeout, So signal a invalid transfer here.
>> Do you suggest keeping ETIMEOUT here also?
> yeah, so we tell whoever called us that the transfer timed out. If you
> return -EINVAL you're telling your clients they gave you an invalid
> spi_transfer, which is not the case.
>
Ok.
>>>> +static int ti_qspi_start_transfer_one(struct spi_master *master,
>>>> +		struct spi_message *m)
>>>> +{
>>>> +	struct ti_qspi *qspi = spi_master_get_devdata(master);
>>>> +	struct spi_device *spi = m->spi;
>>>> +	struct spi_transfer *t;
>>>> +	int status = 0, ret;
>>>> +	int frame_length;
>>>> +
>>>> +	/* setup device control reg */
>>>> +	qspi->dc = 0;
>>>> +
>>>> +	if (spi->mode&   SPI_CPHA)
>>>> +		qspi->dc |= QSPI_CKPHA(spi->chip_select);
>>>> +	if (spi->mode&   SPI_CPOL)
>>>> +		qspi->dc |= QSPI_CKPOL(spi->chip_select);
>>>> +	if (spi->mode&   SPI_CS_HIGH)
>>>> +		qspi->dc |= QSPI_CSPOL(spi->chip_select);
>>>> +
>>>> +	frame_length = (m->frame_length<<   3) / spi->bits_per_word;
>>>> +
>>>> +	frame_length = clamp(frame_length, 0, QSPI_FRAME_MAX);
>>>> +
>>>> +	/* setup command reg */
>>>> +	qspi->cmd = 0;
>>>> +	qspi->cmd |= QSPI_EN_CS(spi->chip_select);
>>>> +	qspi->cmd |= QSPI_FLEN(frame_length);
>>>> +	qspi->cmd |= QSPI_WC_CMD_INT_EN;
>>>> +
>>>> +	ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG);
>>>> +
>>>> +	list_for_each_entry(t,&m->transfers, transfer_list) {
>>> no locking around list traversal ?
>>>
>> hmm..can put a spin_lock around "qspi_transfer_msg" ?
> no dude, you need to protect the access to the list. So it needs to be
> around list_for_each_entry().
>
Ok.
>>>> +static irqreturn_t ti_qspi_isr(int irq, void *dev_id)
>>>> +{
>>>> +	struct ti_qspi *qspi = dev_id;
>>>> +	u16 stat;
>>>> +
>>>> +	irqreturn_t ret = IRQ_HANDLED;
>>>> +
>>>> +	spin_lock(&qspi->lock);
>>>> +
>>>> +	stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR);
>>>> +
>>>> +	if (!stat) {
>>>> +		dev_dbg(qspi->dev, "No IRQ triggered\n");
>>>> +		return IRQ_NONE;
>>> leaving lock held.
>>>
>> Will add a unlock before returning.
> there's a very nice C statement, goto, which you can use here.
>
Ok.
>>>> +static irqreturn_t ti_qspi_threaded_isr(int this_irq, void *dev_id)
>>>> +{
>>>> +	struct ti_qspi *qspi = dev_id;
>>>> +	unsigned long flags;
>>>> +
>>>> +	spin_lock_irqsave(&qspi->lock, flags);
>>>> +
>>>> +	complete(&qspi->transfer_complete);
>>> you need to check if your word completion is actually set. Don't assume
>>> it's set because we might want to change the code later.
>>>
>> hmm..something like this.?
>>    if (ti_qspi_read(qspi, QSPI_SPI_STATUS_REG)&  WC)
>>          complete(&qspi->transfer_complete);
> I rather:
>
> stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG);
>
> if (stat&  WC)
> 	complete()
>
> then, if we want to add frame interrupt handling later, we don't need to
> read status register again. In fact, to avoid reading the status
> register here, you could even cache the returned value you read in your
> hardirq handler inside your qspi struct.
>
Ok.


  reply	other threads:[~2013-07-31  9:40 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-31  5:47 [PATCHv7 0/2] Add ti qspi controller Sourav Poddar
     [not found] ` <1375249673-2585-1-git-send-email-sourav.poddar-l0cyMroinI0@public.gmane.org>
2013-07-31  5:47   ` [PATCHv7 1/2] drivers: spi: Add qspi flash controller Sourav Poddar
2013-07-31  7:49     ` Felipe Balbi
2013-07-31  9:10       ` Sourav Poddar
2013-07-31  9:20         ` Felipe Balbi
2013-07-31  9:40           ` Sourav Poddar [this message]
2013-07-31  9:48             ` Felipe Balbi
2013-07-31  9:53               ` Sourav Poddar
2013-07-31 18:39     ` Trent Piepho
     [not found]       ` <CA+7tXijn2V7LMCKuOKxcda6r6a=JFBeSFNqGqNtYZuTF=irF1g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-08-01  4:15         ` Sourav Poddar
2013-07-31  5:47 ` [RFC/PATCH 2/2] driver: spi: Add quad spi read support Sourav Poddar

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=51F8DB98.70709@ti.com \
    --to=sourav.poddar@ti.com \
    --cc=balbi@ti.com \
    --cc=broonie@kernel.org \
    --cc=grant.likely@linaro.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=rnayak@ti.com \
    --cc=spi-devel-general@lists.sourceforge.net \
    /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).