All of lore.kernel.org
 help / color / mirror / Atom feed
From: Carlos Chinea <carlos.chinea@nokia.com>
To: ext Sebastien Jan <s-jan@ti.com>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>
Subject: Re: [RFC PATCHv2 2/7] OMAP SSI: Introducing OMAP SSI driver
Date: Tue, 18 May 2010 12:07:20 +0300	[thread overview]
Message-ID: <1274173640.7755.22703.camel@localhost> (raw)
In-Reply-To: <201005141641.59244.s-jan@ti.com>

On Fri, 2010-05-14 at 16:41 +0200, ext Sebastien Jan wrote:
> Hi Carlos,
> 
> Please see my comments inlined.
> 
> On Friday 07 May 2010 17:18:32 Carlos Chinea wrote:
> [strip]
> > diff --git a/drivers/hsi/controllers/omap_ssi.c
> [strip]
> > +
> > +/**
> > + * struct omap_ssm_ctx - OMAP synchronous serial module (TX/RX) context
> > + * @mode: Bit transmission mode
> > + * @channels: Number of channels
> > + * @framesize: Frame size in bits
> > + * @timeout: RX frame timeout
> > + * @divisot: TX divider
> 
> Typo: s/divisot/divisor
> 
> > + * @arb_mode: Arbitration mode for TX frame (Round robin, priority)
> > + */
> > +struct omap_ssm_ctx {
> > +       u32     mode;
> > +       u32     channels;
> > +       u32     frame_size;
> > +       union   {
> > +                       u32     timeout; /* Rx Only */
> > +                       struct  {
> > +                                       u32     arb_mode;
> > +                                       u32     divisor;
> > +                       }; /* Tx only */
> > +       };
> > +};
> > +
> > +/**
> > + * struct omap_ssi_port - OMAP SSI port data
> > + * @dev: device associated to the port (HSI port)
> > + * @sst_dma: SSI transmitter physical base address
> > + * @ssr_dma: SSI receiver physical base address
> > + * @sst_base: SSI transmitter base address
> > + * @ssr_base: SSI receiver base address
> 
> wk_lock description is missing here
> 
> > + * @lock: Spin lock to serialize access to the SSI port
> > + * @channels: Current number of channels configured (1,2,4 or 8)
> > + * @txqueue: TX message queues
> > + * @rxqueue: RX message queues
> > + * @brkqueue: Queue of incoming HWBREAK requests (FRAME mode)
> > + * @irq: IRQ number
> > + * @wake_irq: IRQ number for incoming wake line (-1 if none)
> > + * @pio_tasklet: Bottom half for PIO transfers and events
> > + * @wake_tasklet: Bottom half for incoming wake events
> > + * @wkin_cken: Keep track of clock references due to the incoming wake
> >  line
> >  + * @wake_refcount: Reference count for output wake line
>  
> s/wake_refcount/wk_refcount
> 
> > + * @sys_mpu_enable: Context for the interrupt enable register for irq 0
> > + * @sst: Context for the synchronous serial transmitter
> > + * @ssr: Context for the synchronous serial receiver
> > + */
> > +struct omap_ssi_port {
> > +       struct device           *dev;
> > +       dma_addr_t              sst_dma;
> > +       dma_addr_t              ssr_dma;
> > +       unsigned long           sst_base;
> > +       unsigned long           ssr_base;
> > +       spinlock_t              wk_lock;
> > +       spinlock_t              lock;
> > +       unsigned int            channels;
> > +       struct list_head        txqueue[SSI_MAX_CHANNELS];
> > +       struct list_head        rxqueue[SSI_MAX_CHANNELS];
> > +       struct list_head        brkqueue;
> > +       unsigned int            irq;
> > +       int                     wake_irq;
> > +       struct tasklet_struct   pio_tasklet;
> > +       struct tasklet_struct   wake_tasklet;
> > +       unsigned int            wkin_cken:1; /* Workaround */
> > +       int                     wk_refcount;
> > +       /* OMAP SSI port context */
> > +       u32                     sys_mpu_enable; /* We use only one irq */
> > +       struct omap_ssm_ctx     sst;
> > +       struct omap_ssm_ctx     ssr;
> > +};
> > +
> 
> [strip]
> 
> > +
> > +static void ssi_pio_complete(struct hsi_port *port, struct list_head
> >  *queue) +{
> > +       struct hsi_controller *ssi =
> >  to_hsi_controller(port->device.parent); +       struct omap_ssi_controller
> >  *omap_ssi = hsi_controller_drvdata(ssi); +       struct omap_ssi_port
> >  *omap_port = hsi_port_drvdata(port);
> > +       struct hsi_msg *msg;
> > +       u32 *buf;
> > +       u32 val;
> > +
> > +       spin_lock(&omap_port->lock);
> > +       msg = list_first_entry(queue, struct hsi_msg, link);
> > +       if ((!msg->sgt.nents) || (!msg->sgt.sgl->length)) {
> > +               msg->actual_len = 0;
> > +               msg->status = HSI_STATUS_PENDING;
> > +       }
> > +       if (msg->status == HSI_STATUS_PROCEDING) {
> > +               buf = sg_virt(msg->sgt.sgl) + msg->actual_len;
> > +               if (msg->ttype == HSI_MSG_WRITE)
> > +                       __raw_writel(*buf, omap_port->sst_base +
> > +                                      
> >  SSI_SST_BUFFER_CH_REG(msg->channel)); +                else
> > +                       *buf = __raw_readl(omap_port->ssr_base +
> > +                                      
> >  SSI_SSR_BUFFER_CH_REG(msg->channel)); +              
> >  dev_dbg(&port->device, "ch %d ttype %d 0x%08x\n", msg->channel, +         
> >                                               msg->ttype, *buf); +         
> >       msg->actual_len += sizeof(*buf);
> > +               if (msg->actual_len >= msg->sgt.sgl->length)
> > +                       msg->status = HSI_STATUS_COMPLETED;
> > +               /*
> > +                * Wait for the last written frame to be really sent before
> > +                * we call the complete callback
> > +                */
> > +               if ((msg->status == HSI_STATUS_PROCEDING) ||
> > +                       ((msg->status == HSI_STATUS_COMPLETED) &&
> > +                               (msg->ttype == HSI_MSG_WRITE)))
> > +                       goto out;
> > +
> > +       }
> > +       if (msg->status == HSI_STATUS_PROCEDING)
> > +               goto out;
> > +       /* Transfer completed at this point */
> > +       val = __raw_readl(omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num,
> >  0)); +       if (msg->ttype == HSI_MSG_WRITE) {
> > +               val &= ~SSI_DATAACCEPT(msg->channel);
> > +               ssi_clk_disable(ssi); /* Release clocks for write transfer
> >  */ +       } else {
> > +               val &= ~SSI_DATAAVAILABLE(msg->channel);
> > +       }
> > +       __raw_writel(val, omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num,
> >  0)); +       list_del(&msg->link);
> > +       spin_unlock(&omap_port->lock);
> > +       msg->complete(msg);
> > +       spin_lock(&omap_port->lock);
> > +       ssi_start_transfer(queue);
> > +out:
> > +       spin_unlock(&omap_port->lock);
> > +}
> > +
> > +static void ssi_gdd_complete(struct hsi_controller *ssi, unsigned int lch)
> > +{
> > +       struct omap_ssi_controller *omap_ssi = hsi_controller_drvdata(ssi);
> > +       struct hsi_msg *msg = omap_ssi->gdd_trn[lch].msg;
> > +       struct hsi_port *port = to_hsi_port(msg->cl->device.parent);
> > +       unsigned int dir;
> > +       u32 csr;
> > +       u32 val;
> > +
> > +       spin_lock(&omap_ssi->lock);
> > +
> > +       val = __raw_readl(omap_ssi->sys + SSI_GDD_MPU_IRQ_ENABLE_REG);
> > +       val &= ~SSI_GDD_LCH(lch);
> > +       __raw_writel(val, omap_ssi->sys + SSI_GDD_MPU_IRQ_ENABLE_REG);
> > +
> > +       if (msg->ttype == HSI_MSG_READ) {
> > +               dir = DMA_FROM_DEVICE;
> > +               val = SSI_DATAAVAILABLE(msg->channel);
> > +               ssi_clk_disable(ssi);
> > +       } else {
> > +               dir = DMA_TO_DEVICE;
> > +               val = SSI_DATAACCEPT(msg->channel);
> > +               /* Keep clocks reference for write pio event */
> > +       }
> > +       dma_unmap_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents, dir);
> > +       csr = __raw_readw(omap_ssi->gdd + SSI_GDD_CSR_REG(lch));
> > +       omap_ssi->gdd_trn[lch].msg = NULL; /* release GDD lch */
> > +       if (csr & SSI_CSR_TOUR) { /* Timeout error */
> > +               msg->status = HSI_STATUS_ERROR;
> > +               msg->actual_len = 0;
> > +               list_del(&msg->link); /* Dequeue msg */
> > +               spin_unlock(&omap_ssi->lock);
> > +               msg->complete(msg);
> > +               return;
> > +       }
> > +
> > +       val |= __raw_readl(omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num,
> >  0)); +       __raw_writel(val, omap_ssi->sys +
> >  SSI_MPU_ENABLE_REG(port->num, 0)); +
> > +       msg->status = HSI_STATUS_COMPLETED;
> > +       msg->actual_len = sg_dma_len(msg->sgt.sgl);
> > +       spin_unlock(&omap_ssi->lock);
> > +}
> 
> Don't you need to check the queue related to this transfer at this point, to 
> start the potentially next queued transfer on the same channel? (calling 
> ssi_start_transfer(), like in ssi_pio_complete()?)
> 

No this is done in ssi_pio_complete(). Notice that we do not call the
complete callback at any point here. We just arm the pio interrupt for
that channel and transfer direction. AFAIK, this is the SW logic
expected by the OMAP SSI HW.

Br,
-- 
Carlos Chinea <carlos.chinea@nokia.com>


  reply	other threads:[~2010-05-18  9:05 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-07 15:18 [RFC PATCHv2 0/7] HSI framework and drivers Carlos Chinea
2010-05-07 15:18 ` [RFC PATCHv2 1/7] HSI: Introducing HSI framework Carlos Chinea
2010-05-07 15:26   ` Randy Dunlap
2010-05-07 16:11     ` Carlos Chinea
2010-05-07 16:18       ` Randy Dunlap
2010-05-14 14:22   ` Sebastien Jan
2010-05-18  8:37     ` Carlos Chinea
2010-05-07 15:18 ` [RFC PATCHv2 2/7] OMAP SSI: Introducing OMAP SSI driver Carlos Chinea
2010-05-14 14:41   ` Sebastien Jan
2010-05-18  9:07     ` Carlos Chinea [this message]
2010-05-18 14:05       ` Sebastien Jan
2010-05-26  7:27         ` Carlos Chinea
2010-05-07 15:18 ` [RFC PATCHv2 3/7] OMAP SSI: Add OMAP SSI to the kernel configuration Carlos Chinea
2010-05-07 15:18 ` [RFC PATCHv2 4/7] HSI CHAR: Add HSI char device driver Carlos Chinea
2010-05-07 15:18 ` [RFC PATCHv2 5/7] HSI CHAR: Add HSI char device kernel configuration Carlos Chinea
2010-05-07 15:18 ` [RFC PATCHv2 6/7] HSI: Add HSI API documentation Carlos Chinea
2010-05-07 15:18 ` [RFC PATCHv2 7/7] HSI CHAR: Update ioctl-number.txt Carlos Chinea

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=1274173640.7755.22703.camel@localhost \
    --to=carlos.chinea@nokia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=s-jan@ti.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.