[PATCH v3 06/12] s3c-fb: Add wait for VSYNC ioctl

Pawel Osciak p.osciak at samsung.com
Fri Jul 2 10:39:38 EDT 2010


>Ben Dooks <mailto:ben at simtec.co.uk> wrote:
>On 28/06/10 09:08, Pawel Osciak wrote:
>> @@ -801,6 +825,124 @@ static int s3c_fb_pan_display(struct fb_var_screeninfo *var,
>>  	return 0;
>>  }
>>
>> +/**
>> + * s3c_fb_enable_irq() - enable framebuffer interrupts
>> + * @sfb: main hardware state
>> + */
>> +static void s3c_fb_enable_irq(struct s3c_fb *sfb)
>> +{
>> +	void __iomem *regs = sfb->regs;
>> +	u32 irq_ctrl_reg;
>> +
>> +	if (!test_and_set_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) {
>> +		/* IRQ disabled, enable it */
>> +		irq_ctrl_reg = readl(regs + VIDINTCON0);
>> +
>> +		irq_ctrl_reg |= VIDINTCON0_INT_ENABLE;
>> +		irq_ctrl_reg |= VIDINTCON0_INT_FRAME;
>> +
>> +		irq_ctrl_reg &= ~VIDINTCON0_FRAMESEL0_MASK;
>> +		irq_ctrl_reg |= VIDINTCON0_FRAMESEL0_VSYNC;
>> +		irq_ctrl_reg &= ~VIDINTCON0_FRAMESEL1_MASK;
>> +		irq_ctrl_reg |= VIDINTCON0_FRAMESEL1_NONE;
>> +
>> +		writel(irq_ctrl_reg, regs + VIDINTCON0);
>> +	}
>> +}
>
>there should probably be some form of locking so that an irq
>doesn't come through and disable this. possibly in the call
>that queues the request to reduce the likelyhood of any races.
>

Swapping the count and enable_irq below will fix this.

>> +
>> +/**
>> + * s3c_fb_disable_irq() - disable framebuffer interrupts
>> + * @sfb: main hardware state
>> + */
>> +static void s3c_fb_disable_irq(struct s3c_fb *sfb)
>> +{
>> +	void __iomem *regs = sfb->regs;
>> +	u32 irq_ctrl_reg;
>> +
>> +	if (test_and_clear_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) {
>> +		/* IRQ enabled, disable it */
>> +		irq_ctrl_reg = readl(regs + VIDINTCON0);
>> +
>> +		irq_ctrl_reg &= ~VIDINTCON0_INT_FRAME;
>> +		irq_ctrl_reg &= ~VIDINTCON0_INT_ENABLE;
>> +
>> +		writel(irq_ctrl_reg, regs + VIDINTCON0);
>> +	}
>> +}
>> +
>> +static irqreturn_t s3c_fb_irq(int irq, void *dev_id)
>> +{
>> +	struct s3c_fb *sfb = dev_id;
>> +	void __iomem  *regs = sfb->regs;
>> +	u32 irq_sts_reg;
>> +
>> +	irq_sts_reg = readl(regs + VIDINTCON1);
>> +
>> +	if (irq_sts_reg & VIDINTCON1_INT_FRAME) {
>> +
>> +		/* VSYNC interrupt, accept it */
>> +		writel(VIDINTCON1_INT_FRAME, regs + VIDINTCON1);
>> +
>> +		sfb->vsync_info.count++;
>> +		wake_up_interruptible(&sfb->vsync_info.wait);
>> +	}
>> +
>> +	/* We only support waiting for VSYNC for now, so it's safe
>> +	 * to always disable irqs here.
>> +	 */
>> +	s3c_fb_disable_irq(sfb);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>> +/**
>> + * s3c_fb_wait_for_vsync() - sleep until next VSYNC interrupt or timeout
>> + * @sfb: main hardware state
>> + * @crtc: head index.
>> + */
>> +static int s3c_fb_wait_for_vsync(struct s3c_fb *sfb, u32 crtc)
>> +{
>> +	unsigned long count;
>> +	int ret;
>> +
>> +	if (crtc != 0)
>> +		return -ENODEV;
>> +
>> +	s3c_fb_enable_irq(sfb);
>> +	count = sfb->vsync_info.count;
>
>possibly doing count before enabling the irq.
>

yes... can't get my head around to what I've been thinking when writing this,
it's been a year ago... I remember being quite sure that it'd work that way
then though, as ridiculous as it looks right now...
Will swap them.

>> +	ret = wait_event_interruptible_timeout(sfb->vsync_info.wait,
>> +				       count != sfb->vsync_info.count,
>> +				       msecs_to_jiffies(VSYNC_TIMEOUT_MSEC));
>> +	if (ret == 0)
>> +		return -ETIMEDOUT;
>> +
>> +	return 0;
>> +}
>> +
>> +static int s3c_fb_ioctl(struct fb_info *info, unsigned int cmd,
>> +			unsigned long arg)
>> +{
>> +	struct s3c_fb_win *win = info->par;
>> +	struct s3c_fb *sfb = win->parent;
>> +	int ret;
>> +	u32 crtc;
>> +
>> +	switch (cmd) {
>> +	case FBIO_WAITFORVSYNC:
>> +		if (get_user(crtc, (u32 __user *)arg)) {
>> +			ret = -EFAULT;
>> +			break;
>> +		}
>
>can't find any info on what the argument is meant to be.
>

Head number, i.e. crt no I believe. Not sure though.

>> +
>> +		ret = s3c_fb_wait_for_vsync(sfb, crtc);
>> +		break;
>> +	default:
>> +		ret = -ENOTTY;
>
>Can someone else confirm this is the correct err?
>

Linux Device Drivers 3, page 140, or see the online version here:
http://www.makelinux.net/ldd3/chp-6-sect-1.shtml
section 6.1.2. The Return Value

man ioctl:
ENOTTY 
The specified request does not apply to the kind of object that the
descriptor d references.

>> @@ -1370,6 +1534,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210
>__devinitdata = {
>>  			[3] = 0x3000,
>>  			[4] = 0x3400,
>>  		},
>> +
>>  	},
>
>oops, added whitespace.
>

will fix.


Best regards
--
Pawel Osciak
Linux Platform Group
Samsung Poland R&D Center









More information about the linux-arm-kernel mailing list