[PATCH v2] [media] at91: add Atmel Image Sensor Interface (ISI) support
Wu, Josh
Josh.wu at atmel.com
Fri Jun 3 04:52:38 EDT 2011
Hi, Jean-Christophe
Thank you for the review.
Jean-Christophe PLAGNIOL-VILLARD wrote on Friday, May 27, 2011 8:06 PM:
>> +/* ISI interrupt service routine */
>> +static irqreturn_t isi_interrupt(int irq, void *dev_id) {
>> + struct atmel_isi *isi = dev_id;
>> + u32 status, mask, pending;
>> + irqreturn_t ret = IRQ_NONE;
>> +
>> + spin_lock(&isi->lock);
>> +
>> + status = isi_readl(isi, ISI_STATUS);
>> + mask = isi_readl(isi, ISI_INTMASK);
>> + pending = status & mask;
>> +
>> + if (pending & ISI_CTRL_SRST) {
>> + complete(&isi->isi_complete);
>> + isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
>> + ret = IRQ_HANDLED;
>> + }
>> + if (pending & ISI_CTRL_DIS) {
>> + complete(&isi->isi_complete);
>> + isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
>> + ret = IRQ_HANDLED;
>> + }
> no else here?
>> +
>> + if (pending & ISI_SR_VSYNC) {
>> + switch (isi->state) {
>> + case ISI_STATE_IDLE:
>> + isi->state = ISI_STATE_READY;
>> + wake_up_interruptible(&isi->capture_wq);
>> + break;
>> + }
> really switch here?
I will remove the switch here.
I think this part of IRQ handling code need to refine a little bit. The SRST and DIS_DONE is more independent. And other interrupts can compose together.
Following is the latest code, I think is more reasonable.
if (pending & ISI_CTRL_SRST) {
complete(&isi->complete);
isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
ret = IRQ_HANDLED;
} else if (pending & ISI_CTRL_DIS) {
complete(&isi->complete);
isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
ret = IRQ_HANDLED;
} else {
if ((pending & ISI_SR_VSYNC) &&
(isi->state == ISI_STATE_IDLE)) {
isi->state = ISI_STATE_READY;
wake_up_interruptible(&isi->vsync_wq);
ret = IRQ_HANDLED;
}
if (likely(pending & ISI_SR_CXFR_DONE))
ret = atmel_isi_handle_streaming(isi);
}
>> + } else if (likely(pending & ISI_SR_CXFR_DONE)) {
>> + ret = atmel_isi_handle_streaming(isi);
>> + }
>> +
>> + spin_unlock(&isi->lock);
>> +
>> + return ret;
>> +}
>> +
>> +#define WAIT_ISI_RESET 1
>> +#define WAIT_ISI_DISABLE 0
>> +static int atmel_isi_wait_status(int wait_reset, struct atmel_isi
>> +*isi)
>I thinkhave teh atmel_isti first parameter is better
I will fix it.
>> +{
>> + unsigned long timeout;
>> + /*
>> + * The reset or disable will only succeed if we have a
>> + * pixel clock from the camera.
>> + */
>> + init_completion(&isi->isi_complete);
>> +
>> + if (wait_reset) {
>> + isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST);
>> + isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST);
>> + } else {
>> + isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS);
>> + isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
>> + }
>> +
>> + timeout = wait_for_completion_timeout(&isi->isi_complete,
>> + msecs_to_jiffies(100));
>> + if (timeout == 0)
>> + return -ETIMEDOUT;
>> +
>> + return 0;
>> +}
>> +
>> +/* ------------------------------------------------------------------
>> + Videobuf operations
>> +
>> +------------------------------------------------------------------*/
>> +static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
>> + unsigned int *nplanes, unsigned long sizes[],
>> + void *alloc_ctxs[])
>> +{
>> + struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
>> + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
>> + struct atmel_isi *isi = ici->priv;
>> + unsigned long size;
>> + int ret, bytes_per_line;
>> +
>> + /* Reset ISI */
>> + ret = atmel_isi_wait_status(WAIT_ISI_RESET, isi);
>> + if (ret < 0) {
>> + dev_err(icd->dev.parent, "Reset ISI timed out\n");
>> + return ret;
>> + }
>> + /* Disable all interrupts */
>> + isi_writel(isi, ISI_INTDIS, ~0UL);
>> +
>> + bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
>> + icd->current_fmt->host_fmt);
>> +
>> + if (bytes_per_line < 0)
>> + return bytes_per_line;
>> +
>> + size = bytes_per_line * icd->user_height;
>> +
>> + if (*nbuffers == 0)
>> + *nbuffers = MAX_BUFFER_NUMS;
>> + if (*nbuffers > MAX_BUFFER_NUMS)
> else here
I will add it.
>> + *nbuffers = MAX_BUFFER_NUMS;
>> +
>> + if (size * *nbuffers > VID_LIMIT_BYTES)
>> + *nbuffers = VID_LIMIT_BYTES / size;
>> +
>> + *nplanes = 1;
>> + sizes[0] = size;
>> + alloc_ctxs[0] = isi->alloc_ctx;
>> +
>> + isi->sequence = 0;
>> + isi->active = NULL;
>> +
>> + dev_dbg(icd->dev.parent, "%s, count=%d, size=%ld\n", __func__,
>> + *nbuffers, size);
>> +
>> + return 0;
>> +}
>> +
>> +static int buffer_init(struct vb2_buffer *vb) {
>> + struct frame_buffer *buf = container_of(vb, struct frame_buffer,
>> +vb);
>> +
>> + buf->p_fb_desc = NULL;
>> + buf->fb_desc_phys = 0;
> memset 0?
OK.
>> + INIT_LIST_HEAD(&buf->list);
>> +
>> + return 0;
>> +}
>> +
>otherwise the patch look good
>if you fix the upper issue
>Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
Thank you very much. I will send out version3 soon.
Best Regards,
Josh Wu
More information about the linux-arm-kernel
mailing list