diff mbox

drm/tilcdc: Set framebuffer DMA address to HW only if CRTC is enabled

Message ID 1489253107-20438-1-git-send-email-jsarha@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jyri Sarha March 11, 2017, 5:25 p.m. UTC
Touching HW while clocks are off is a serious error and for instance
breaks suspend functionality. After this patch tilcdc_crtc_update_fb()
always updates the primary plane's framebuffer pointer, increases fb's
reference count and stores vblank event. tilcdc_crtc_update_fb() only
writes the fb's DMA address to HW if the crtc is enabled, as
tilcdc_crtc_enable() takes care of writing the address on enable.

This patch also refactors the tilcdc_crtc_update_fb() a bit. Number of
subsequent small changes to had made it almost unreadable. There
should be no other functional changes but checking the CRTC's enable
state. However, the locking goes a bit differently and some of the
redundant checks have been removed in this new version.

The enable_lock should be enough to protect the access to
tilcdc_crtc->enabled. The irq_lock protects the access to last_vblank
and next_fb. The check for vrefresh and last_vblank being valid is
redundant, as the vrefresh should be always valid if the CRTC is
enabled and now last_vblank should be too, because it is initialized
to current time when CRTC raster is enabled. If for some reason the
values are not corretly initialized the division by zero waning is
quite appropriate.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 37 +++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

Comments

kernel test robot March 12, 2017, 8:08 p.m. UTC | #1
Hi Jyri,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.11-rc1 next-20170310]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Jyri-Sarha/drm-tilcdc-Set-framebuffer-DMA-address-to-HW-only-if-CRTC-is-enabled/20170312-201749
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: arm-davinci_all_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All error/warnings (new ones prefixed by >>):

   drivers/gpu/drm/tilcdc/tilcdc_crtc.c:2:4: error: return type defaults to 'int' [-Werror=return-type]
     * Copyright (C) 2012 Texas Instruments
       ^~~~~~~~~
>> drivers/gpu/drm/tilcdc/tilcdc_crtc.c:2:4: error: function declaration isn't a prototype [-Werror=strict-prototypes]
   drivers/gpu/drm/tilcdc/tilcdc_crtc.c: In function 'Copyright':
>> drivers/gpu/drm/tilcdc/tilcdc_crtc.c:2:18: error: expected declaration specifiers before numeric constant
     * Copyright (C) 2012 Texas Instruments
                     ^~~~
>> drivers/gpu/drm/tilcdc/tilcdc_crtc.c:3:32: error: stray '@' in program
     * Author: Rob Clark <robdclark@gmail.com>
                                   ^
>> drivers/gpu/drm/tilcdc/tilcdc_crtc.c:5:35: error: unknown type name 'you'
     * This program is free software; you can redistribute it and/or modify it
                                      ^~~
>> drivers/gpu/drm/tilcdc/tilcdc_crtc.c:5:43: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'redistribute'
     * This program is free software; you can redistribute it and/or modify it
                                              ^~~~~~~~~~~~
>> drivers/gpu/drm/tilcdc/tilcdc_crtc.c:10:18: error: unknown type name 'without'
     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                     ^~~~~~~
>> drivers/gpu/drm/tilcdc/tilcdc_crtc.c:10:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'the'
     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                                  ^~~
   In file included from include/asm-generic/int-ll64.h:10:0,
                    from arch/arm/include/uapi/asm/types.h:4,
                    from include/uapi/linux/types.h:4,
                    from include/linux/types.h:5,
                    from include/linux/mod_devicetable.h:11,
                    from include/linux/i2c.h:29,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
>> include/uapi/asm-generic/int-ll64.h:20:23: error: storage class specified for parameter '__u8'
    typedef unsigned char __u8;
                          ^~~~
>> include/uapi/asm-generic/int-ll64.h:22:26: error: storage class specified for parameter '__s16'
    typedef __signed__ short __s16;
                             ^~~~~
>> include/uapi/asm-generic/int-ll64.h:23:24: error: storage class specified for parameter '__u16'
    typedef unsigned short __u16;
                           ^~~~~
>> include/uapi/asm-generic/int-ll64.h:25:24: error: storage class specified for parameter '__s32'
    typedef __signed__ int __s32;
                           ^~~~~
>> include/uapi/asm-generic/int-ll64.h:26:22: error: storage class specified for parameter '__u32'
    typedef unsigned int __u32;
                         ^~~~~
>> include/uapi/asm-generic/int-ll64.h:29:1: error: expected declaration specifiers before '__extension__'
    __extension__ typedef __signed__ long long __s64;
    ^~~~~~~~~~~~~
   include/uapi/asm-generic/int-ll64.h:30:1: error: expected declaration specifiers before '__extension__'
    __extension__ typedef unsigned long long __u64;
    ^~~~~~~~~~~~~
   In file included from arch/arm/include/uapi/asm/types.h:4:0,
                    from include/uapi/linux/types.h:4,
                    from include/linux/types.h:5,
                    from include/linux/mod_devicetable.h:11,
                    from include/linux/i2c.h:29,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
>> include/asm-generic/int-ll64.h:15:21: error: storage class specified for parameter 's8'
    typedef signed char s8;
                        ^~
>> include/asm-generic/int-ll64.h:16:23: error: storage class specified for parameter 'u8'
    typedef unsigned char u8;
                          ^~
>> include/asm-generic/int-ll64.h:18:22: error: storage class specified for parameter 's16'
    typedef signed short s16;
                         ^~~
>> include/asm-generic/int-ll64.h:19:24: error: storage class specified for parameter 'u16'
    typedef unsigned short u16;
                           ^~~
>> include/asm-generic/int-ll64.h:21:20: error: storage class specified for parameter 's32'
    typedef signed int s32;
                       ^~~
>> include/asm-generic/int-ll64.h:22:22: error: storage class specified for parameter 'u32'
    typedef unsigned int u32;
                         ^~~
>> include/asm-generic/int-ll64.h:24:26: error: storage class specified for parameter 's64'
    typedef signed long long s64;
                             ^~~

vim +2 drivers/gpu/drm/tilcdc/tilcdc_crtc.c

244d17e7 Jyri Sarha 2017-03-11   1  *
16ea975e Rob Clark  2013-01-08  @2   * Copyright (C) 2012 Texas Instruments
16ea975e Rob Clark  2013-01-08  @3   * Author: Rob Clark <robdclark@gmail.com>
16ea975e Rob Clark  2013-01-08   4   *
16ea975e Rob Clark  2013-01-08  @5   * This program is free software; you can redistribute it and/or modify it
16ea975e Rob Clark  2013-01-08   6   * under the terms of the GNU General Public License version 2 as published by
16ea975e Rob Clark  2013-01-08   7   * the Free Software Foundation.
16ea975e Rob Clark  2013-01-08   8   *
16ea975e Rob Clark  2013-01-08   9   * This program is distributed in the hope that it will be useful, but WITHOUT
16ea975e Rob Clark  2013-01-08 @10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16ea975e Rob Clark  2013-01-08  11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16ea975e Rob Clark  2013-01-08  12   * more details.
16ea975e Rob Clark  2013-01-08  13   *

:::::: The code at line 2 was first introduced by commit
:::::: 16ea975eac671fa40a78594a116a44fef8e3f4a9 drm/tilcdc: add TI LCD Controller DRM driver (v4)

:::::: TO: Rob Clark <robdclark@gmail.com>
:::::: CC: Rob Clark <robdclark@gmail.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot March 13, 2017, 2:40 a.m. UTC | #2
Hi Jyri,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.11-rc2 next-20170310]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Jyri-Sarha/drm-tilcdc-Set-framebuffer-DMA-address-to-HW-only-if-CRTC-is-enabled/20170312-201749
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All error/warnings (new ones prefixed by >>):

                                                ^~~~~~~~~~~~~~~
   include/linux/string.h:42:12: error: storage class specified for parameter 'strcmp'
    extern int strcmp(const char *,const char *);
               ^~~~~~
   include/linux/string.h:45:46: error: expected declaration specifiers or '...' before '__kernel_size_t'
    extern int strncmp(const char *,const char *,__kernel_size_t);
                                                 ^~~~~~~~~~~~~~~
   include/linux/string.h:48:12: error: storage class specified for parameter 'strcasecmp'
    extern int strcasecmp(const char *s1, const char *s2);
               ^~~~~~~~~~
   include/linux/string.h:51:56: error: unknown type name 'size_t'
    extern int strncasecmp(const char *s1, const char *s2, size_t n);
                                                           ^~~~~~
   include/linux/string.h:57:15: error: storage class specified for parameter 'strchrnul'
    extern char * strchrnul(const char *,int);
                  ^~~~~~~~~
   include/linux/string.h:60:37: error: unknown type name 'size_t'
    extern char * strnchr(const char *, size_t, int);
                                        ^~~~~~
   include/linux/string.h:65:28: error: storage class specified for parameter 'skip_spaces'
    extern char * __must_check skip_spaces(const char *);
                               ^~~~~~~~~~~
   include/linux/string.h:67:14: error: storage class specified for parameter 'strim'
    extern char *strim(char *);
                 ^~~~~
   include/linux/string.h:70:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   include/linux/string.h:75:15: error: storage class specified for parameter 'strstr'
    extern char * strstr(const char *, const char *);
                  ^~~~~~
   include/linux/string.h:78:51: error: unknown type name 'size_t'
    extern char * strnstr(const char *, const char *, size_t);
                                                      ^~~~~~
   include/linux/string.h:81:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'strlen'
    extern __kernel_size_t strlen(const char *);
                           ^~~~~~
   include/linux/string.h:84:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'strnlen'
    extern __kernel_size_t strnlen(const char *,__kernel_size_t);
                           ^~~~~~~
   include/linux/string.h:87:15: error: storage class specified for parameter 'strpbrk'
    extern char * strpbrk(const char *,const char *);
                  ^~~~~~~
   include/linux/string.h:90:15: error: storage class specified for parameter 'strsep'
    extern char * strsep(char **,const char *);
                  ^~~~~~
   include/linux/string.h:93:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'strspn'
    extern __kernel_size_t strspn(const char *,const char *);
                           ^~~~~~
   include/linux/string.h:96:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'strcspn'
    extern __kernel_size_t strcspn(const char *,const char *);
                           ^~~~~~~
   include/linux/string.h:109:34: error: expected declaration specifiers or '...' before '__kernel_size_t'
    extern void * memscan(void *,int,__kernel_size_t);
                                     ^~~~~~~~~~~~~~~
   include/linux/string.h:112:45: error: expected declaration specifiers or '...' before '__kernel_size_t'
    extern int memcmp(const void *,const void *,__kernel_size_t);
                                                ^~~~~~~~~~~~~~~
   include/linux/string.h:117:40: error: unknown type name 'size_t'
    void *memchr_inv(const void *s, int c, size_t n);
                                           ^~~~~~
   include/linux/string.h:120:13: error: storage class specified for parameter 'kfree_const'
    extern void kfree_const(const void *x);
                ^~~~~~~~~~~
   include/linux/string.h:122:37: error: expected declaration specifiers or '...' before 'gfp_t'
    extern char *kstrdup(const char *s, gfp_t gfp) __malloc;
                                        ^~~~~
   include/linux/string.h:123:49: error: expected declaration specifiers or '...' before 'gfp_t'
    extern const char *kstrdup_const(const char *s, gfp_t gfp);
                                                    ^~~~~
   include/linux/string.h:124:38: error: unknown type name 'size_t'
    extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
                                         ^~~~~~
   include/linux/string.h:124:50: error: expected declaration specifiers or '...' before 'gfp_t'
    extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
                                                     ^~~~~
   include/linux/string.h:125:39: error: unknown type name 'size_t'
    extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
                                          ^~~~~~
   include/linux/string.h:125:51: error: expected declaration specifiers or '...' before 'gfp_t'
    extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
                                                      ^~~~~
   include/linux/string.h:127:26: error: expected declaration specifiers or '...' before 'gfp_t'
    extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
                             ^~~~~
   include/linux/string.h:128:13: error: storage class specified for parameter 'argv_free'
    extern void argv_free(char **argv);
                ^~~~~~~~~
   include/linux/string.h:130:13: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'sysfs_streq'
    extern bool sysfs_streq(const char *s1, const char *s2);
                ^~~~~~~~~~~
   include/linux/string.h:131:38: error: expected declaration specifiers or '...' before 'bool'
    extern int kstrtobool(const char *s, bool *res);
                                         ^~~~
   include/linux/string.h:132:44: error: expected declaration specifiers or '...' before 'bool'
    static inline int strtobool(const char *s, bool *res)
                                               ^~~~
   include/linux/string.h:137:45: error: unknown type name 'size_t'
    int match_string(const char * const *array, size_t n, const char *string);
                                                ^~~~~~
>> include/linux/string.h:140:17: error: expected declaration specifiers or '...' before 'u32'
    int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
                    ^~~
   include/linux/string.h:140:31: error: unknown type name 'size_t'
    int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
                                  ^~~~~~
>> include/linux/string.h:140:61: error: unknown type name 'va_list'
    int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
                                                                ^~~~~~~
   include/linux/string.h:141:28: error: unknown type name 'size_t'
    int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
                               ^~~~~~
>> include/linux/string.h:141:64: error: type defaults to 'int' in declaration of 'u32' [-Werror=implicit-int]
    int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
                                                                   ^~~
>> include/linux/string.h:141:68: error: expected ';', ',' or ')' before '*' token
    int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
                                                                       ^
   include/linux/string.h:142:13: error: expected declaration specifiers or '...' before 'u32'
    int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
                ^~~
   include/linux/string.h:142:27: error: unknown type name 'size_t'
    int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
                              ^~~~~~
   include/linux/string.h:145:8: error: unknown type name 'ssize_t'
    extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
           ^~~~~~~
   include/linux/string.h:145:50: error: unknown type name 'size_t'
    extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
                                                     ^~~~~~
   include/linux/string.h:145:64: error: unknown type name 'loff_t'
    extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
                                                                   ^~~~~~
   include/linux/string.h:146:30: error: unknown type name 'size_t'
               const void *from, size_t available);
                                 ^~~~~~
   include/linux/string.h:153:20: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'strstarts'
    static inline bool strstarts(const char *str, const char *prefix)
                       ^~~~~~~~~
   include/linux/string.h:158:1: error: unknown type name 'size_t'
    size_t memweight(const void *ptr, size_t bytes);
    ^~~~~~
   include/linux/string.h:158:35: error: unknown type name 'size_t'
    size_t memweight(const void *ptr, size_t bytes);
                                      ^~~~~~
   include/linux/string.h:159:32: error: unknown type name 'size_t'
    void memzero_explicit(void *s, size_t count);
                                   ^~~~~~
   include/linux/string.h:167:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   In file included from include/linux/uuid.h:19:0,
                    from include/linux/mod_devicetable.h:12,
                    from include/linux/i2c.h:29,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   include/uapi/linux/uuid.h:24:2: error: expected specifier-qualifier-list before '__u8'
     __u8 b[16];
     ^~~~
   include/uapi/linux/uuid.h:25:3: error: storage class specified for parameter 'uuid_le'
    } uuid_le;
      ^~~~~~~
   include/uapi/linux/uuid.h:28:2: error: expected specifier-qualifier-list before '__u8'
     __u8 b[16];
     ^~~~
   include/uapi/linux/uuid.h:29:3: error: storage class specified for parameter 'uuid_be'
    } uuid_be;
      ^~~~~~~
   In file included from include/linux/mod_devicetable.h:12:0,
                    from include/linux/i2c.h:29,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   include/linux/uuid.h:30:2: error: unknown type name '__be32'
     __be32  time_low;   /* low part of timestamp */
     ^~~~~~
   include/linux/uuid.h:31:2: error: unknown type name '__be16'
     __be16  time_mid;   /* mid part of timestamp */
     ^~~~~~
   include/linux/uuid.h:32:2: error: unknown type name '__be16'
     __be16  time_hi_and_version;  /* high part of timestamp and version  */
     ^~~~~~
   include/linux/uuid.h:38:2: error: expected specifier-qualifier-list before 'u8'
     u8  clock_seq_hi_and_reserved; /* clock seq hi and variant */
     ^~
   include/linux/uuid.h:29:1: error: empty declaration [-Werror]
    struct uuid_v1 {
    ^~~~~~
   include/linux/uuid.h:51:37: error: type defaults to 'int' in declaration of 'uuid_le' [-Werror=implicit-int]
    static inline int uuid_le_cmp(const uuid_le u1, const uuid_le u2)
                                        ^~~~~~~
   include/linux/uuid.h:51:45: error: expected ';', ',' or ')' before 'u1'
    static inline int uuid_le_cmp(const uuid_le u1, const uuid_le u2)
                                                ^~
   include/linux/uuid.h:56:37: error: type defaults to 'int' in declaration of 'uuid_be' [-Werror=implicit-int]
    static inline int uuid_be_cmp(const uuid_be u1, const uuid_be u2)
                                        ^~~~~~~
   include/linux/uuid.h:56:45: error: expected ';', ',' or ')' before 'u1'
    static inline int uuid_be_cmp(const uuid_be u1, const uuid_be u2)
                                                ^~
   include/linux/uuid.h:63:25: error: expected declaration specifiers or '...' before 'uuid_le'
    extern void uuid_le_gen(uuid_le *u);
                            ^~~~~~~
   include/linux/uuid.h:64:25: error: expected declaration specifiers or '...' before 'uuid_be'
    extern void uuid_be_gen(uuid_be *u);
                            ^~~~~~~
   include/linux/uuid.h:66:1: error: expected declaration specifiers before 'bool'
    bool __must_check uuid_is_valid(const char *uuid);
    ^~~~
   include/linux/uuid.h:68:17: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'uuid_le_index'
    extern const u8 uuid_le_index[16];
                    ^~~~~~~~~~~~~
   include/linux/uuid.h:69:17: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'uuid_be_index'
    extern const u8 uuid_be_index[16];
                    ^~~~~~~~~~~~~
--
   include/linux/ioport.h:272:29: error: expected ')' before 'void'
          int (*func)(u64, u64, void *));
                                ^~~~
   include/linux/ioport.h:274:62: error: expected declaration specifiers or '...' before 'u64'
    walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
                                                                 ^~~
   include/linux/ioport.h:274:73: error: expected declaration specifiers or '...' before 'u64'
    walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
                                                                            ^~~
   include/linux/ioport.h:275:40: error: expected ')' before 'void'
          void *arg, int (*func)(u64, u64, void *));
                                           ^~~~
   include/linux/ioport.h:278:20: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'resource_overlaps'
    static inline bool resource_overlaps(struct resource *r1, struct resource *r2)
                       ^~~~~~~~~~~~~~~~~
   In file included from include/linux/linkage.h:6:0,
                    from include/linux/kernel.h:6,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   include/linux/export.h:27:1: error: empty declaration [-Werror]
    struct kernel_symbol
    ^~~~~~
   include/linux/export.h:34:22: error: storage class specified for parameter '__this_module'
    extern struct module __this_module;
                         ^~~~~~~~~~~~~
   In file included from include/linux/kernel.h:10:0,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   include/linux/bitops.h:27:21: error: storage class specified for parameter '__sw_hweight8'
    extern unsigned int __sw_hweight8(unsigned int w);
                        ^~~~~~~~~~~~~
   include/linux/bitops.h:28:21: error: storage class specified for parameter '__sw_hweight16'
    extern unsigned int __sw_hweight16(unsigned int w);
                        ^~~~~~~~~~~~~~
   include/linux/bitops.h:29:21: error: storage class specified for parameter '__sw_hweight32'
    extern unsigned int __sw_hweight32(unsigned int w);
                        ^~~~~~~~~~~~~~
   include/linux/bitops.h:30:37: error: unknown type name '__u64'
    extern unsigned long __sw_hweight64(__u64 w);
                                        ^~~~~
   In file included from arch/arm/include/uapi/asm/ptrace.h:13:0,
                    from arch/arm/include/asm/ptrace.h:13,
                    from arch/arm/include/asm/irqflags.h:6,
                    from include/linux/irqflags.h:15,
                    from arch/arm/include/asm/bitops.h:27,
                    from include/linux/bitops.h:36,
                    from include/linux/kernel.h:10,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   arch/arm/include/asm/hwcap.h:13:21: error: storage class specified for parameter 'elf_hwcap'
    extern unsigned int elf_hwcap, elf_hwcap2;
                        ^~~~~~~~~
   arch/arm/include/asm/hwcap.h:13:32: error: storage class specified for parameter 'elf_hwcap2'
    extern unsigned int elf_hwcap, elf_hwcap2;
                                   ^~~~~~~~~~
   In file included from arch/arm/include/asm/irqflags.h:6:0,
                    from include/linux/irqflags.h:15,
                    from arch/arm/include/asm/bitops.h:27,
                    from include/linux/bitops.h:36,
                    from include/linux/kernel.h:10,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   arch/arm/include/asm/ptrace.h:18:1: error: empty declaration [-Werror]
    struct pt_regs {
    ^~~~~~
   arch/arm/include/asm/ptrace.h:24:2: error: expected specifier-qualifier-list before 'u32'
     u32 dacr;
     ^~~
   arch/arm/include/asm/ptrace.h:22:1: error: empty declaration [-Werror]
    struct svc_pt_regs {
    ^~~~~~
   arch/arm/include/asm/ptrace.h:61:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/ptrace.h:91:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/ptrace.h:105:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
>> arch/arm/include/asm/ptrace.h:110:22: error: storage class specified for parameter 'profile_pc'
    extern unsigned long profile_pc(struct pt_regs *regs);
                         ^~~~~~~~~~
   arch/arm/include/asm/ptrace.h:133:12: error: storage class specified for parameter 'regs_query_register_offset'
    extern int regs_query_register_offset(const char *name);
               ^~~~~~~~~~~~~~~~~~~~~~~~~~
   arch/arm/include/asm/ptrace.h:134:20: error: storage class specified for parameter 'regs_query_register_name'
    extern const char *regs_query_register_name(unsigned int offset);
                       ^~~~~~~~~~~~~~~~~~~~~~~~
   arch/arm/include/asm/ptrace.h:135:13: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'regs_within_kernel_stack'
    extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
                ^~~~~~~~~~~~~~~~~~~~~~~~
   arch/arm/include/asm/ptrace.h:136:22: error: storage class specified for parameter 'regs_get_kernel_stack_nth'
    extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
                         ^~~~~~~~~~~~~~~~~~~~~~~~~
   arch/arm/include/asm/ptrace.h:150:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/ptrace.h:158:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/ptrace.h:163:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   In file included from include/linux/irqflags.h:15:0,
                    from arch/arm/include/asm/bitops.h:27,
                    from include/linux/bitops.h:36,
                    from include/linux/kernel.h:10,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   arch/arm/include/asm/irqflags.h:25:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/irqflags.h:37:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/irqflags.h:47:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/irqflags.h:156:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/irqflags.h:169:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/irqflags.h:179:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   In file included from arch/arm/include/asm/irqflags.h:183:0,
                    from include/linux/irqflags.h:15,
                    from arch/arm/include/asm/bitops.h:27,
                    from include/linux/bitops.h:36,
                    from include/linux/kernel.h:10,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   include/asm-generic/irqflags.h:61:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   In file included from arch/arm/include/asm/bitops.h:27:0,
                    from include/linux/bitops.h:36,
                    from include/linux/kernel.h:10,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
>> include/linux/irqflags.h:18:15: error: storage class specified for parameter 'trace_softirqs_on'
      extern void trace_softirqs_on(unsigned long ip);
                  ^~~~~~~~~~~~~~~~~
>> include/linux/irqflags.h:19:15: error: storage class specified for parameter 'trace_softirqs_off'
      extern void trace_softirqs_off(unsigned long ip);
                  ^~~~~~~~~~~~~~~~~~
>> include/linux/irqflags.h:20:15: error: storage class specified for parameter 'trace_hardirqs_on'
      extern void trace_hardirqs_on(void);
                  ^~~~~~~~~~~~~~~~~
>> include/linux/irqflags.h:21:15: error: storage class specified for parameter 'trace_hardirqs_off'
      extern void trace_hardirqs_off(void);
                  ^~~~~~~~~~~~~~~~~~
>> include/linux/irqflags.h:49:14: error: storage class specified for parameter 'stop_critical_timings'
     extern void stop_critical_timings(void);
                 ^~~~~~~~~~~~~~~~~~~~~
>> include/linux/irqflags.h:50:14: error: storage class specified for parameter 'start_critical_timings'
     extern void start_critical_timings(void);
                 ^~~~~~~~~~~~~~~~~~~~~~
   In file included from arch/arm/include/asm/bitops.h:28:0,
                    from include/linux/bitops.h:36,
                    from include/linux/kernel.h:10,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
>> arch/arm/include/asm/barrier.h:40:15: error: storage class specified for parameter 'soc_mb'
    extern void (*soc_mb)(void);
                  ^~~~~~
>> arch/arm/include/asm/barrier.h:41:13: error: storage class specified for parameter 'arm_heavy_mb'
    extern void arm_heavy_mb(void);
                ^~~~~~~~~~~~
   In file included from include/linux/bitops.h:36:0,
                    from include/linux/kernel.h:10,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   arch/arm/include/asm/bitops.h:36:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/bitops.h:48:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/bitops.h:60:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/bitops.h:73:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/bitops.h:90:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   arch/arm/include/asm/bitops.h:107:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   In file included from arch/arm/include/asm/bitops.h:122:0,
                    from include/linux/bitops.h:36,
                    from include/linux/kernel.h:10,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   include/asm-generic/bitops/non-atomic.h:16:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   include/asm-generic/bitops/non-atomic.h:24:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   include/asm-generic/bitops/non-atomic.h:41:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   include/asm-generic/bitops/non-atomic.h:58:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   include/asm-generic/bitops/non-atomic.h:77:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   include/asm-generic/bitops/non-atomic.h:89:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   include/asm-generic/bitops/non-atomic.h:104:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    {
    ^
   In file included from include/linux/bitops.h:36:0,
                    from include/linux/kernel.h:10,
                    from include/linux/list.h:8,
                    from include/linux/kobject.h:20,
                    from include/linux/device.h:17,
                    from include/linux/i2c.h:30,
                    from include/drm/drm_crtc.h:28,
                    from include/drm/drm_atomic.h:31,
                    from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:18:
   arch/arm/include/asm/bitops.h:152:13: error: storage class specified for parameter '_set_bit'
    extern void _set_bit(int nr, volatile unsigned long * p);
                ^~~~~~~~
   arch/arm/include/asm/bitops.h:153:13: error: storage class specified for parameter '_clear_bit'
    extern void _clear_bit(int nr, volatile unsigned long * p);
                ^~~~~~~~~~
   arch/arm/include/asm/bitops.h:154:13: error: storage class specified for parameter '_change_bit'
    extern void _change_bit(int nr, volatile unsigned long * p);
                ^~~~~~~~~~~
   arch/arm/include/asm/bitops.h:155:12: error: storage class specified for parameter '_test_and_set_bit'
    extern int _test_and_set_bit(int nr, volatile unsigned long * p);
               ^~~~~~~~~~~~~~~~~
   arch/arm/include/asm/bitops.h:156:12: error: storage class specified for parameter '_test_and_clear_bit'
    extern int _test_and_clear_bit(int nr, volatile unsigned long * p);
               ^~~~~~~~~~~~~~~~~~~
   arch/arm/include/asm/bitops.h:157:12: error: storage class specified for parameter '_test_and_change_bit'
    extern int _test_and_change_bit(int nr, volatile unsigned long * p);
               ^~~~~~~~~~~~~~~~~~~~
   arch/arm/include/asm/bitops.h:162:12: error: storage class specified for parameter '_find_first_zero_bit_le'
    extern int _find_first_zero_bit_le(const void * p, unsigned size);
               ^~~~~~~~~~~~~~~~~~~~~~~
   arch/arm/include/asm/bitops.h:163:12: error: storage class specified for parameter '_find_next_zero_bit_le'
    extern int _find_next_zero_bit_le(const void * p, int size, int offset);
               ^~~~~~~~~~~~~~~~~~~~~~
   arch/arm/include/asm/bitops.h:164:12: error: storage class specified for parameter '_find_first_bit_le'
    extern int _find_first_bit_le(const unsigned long *p, unsigned size);
               ^~~~~~~~~~~~~~~~~~
   arch/arm/include/asm/bitops.h:165:12: error: storage class specified for parameter '_find_next_bit_le'
    extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
               ^~~~~~~~~~~~~~~~~
   arch/arm/include/asm/bitops.h:170:12: error: storage class specified for parameter '_find_first_zero_bit_be'
..

vim +140 include/linux/string.h

1a2f67b4 Alexey Dobriyan     2006-09-30  125  extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
543537bd Paulo Marques       2005-06-23  126  
d84d1cc7 Jeremy Fitzhardinge 2007-07-17  127  extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
d84d1cc7 Jeremy Fitzhardinge 2007-07-17  128  extern void argv_free(char **argv);
d84d1cc7 Jeremy Fitzhardinge 2007-07-17  129  
34990cf7 David Brownell      2008-05-01  130  extern bool sysfs_streq(const char *s1, const char *s2);
ef951599 Kees Cook           2016-03-17 @131  extern int kstrtobool(const char *s, bool *res);
ef951599 Kees Cook           2016-03-17  132  static inline int strtobool(const char *s, bool *res)
ef951599 Kees Cook           2016-03-17  133  {
ef951599 Kees Cook           2016-03-17  134  	return kstrtobool(s, res);
ef951599 Kees Cook           2016-03-17  135  }
34990cf7 David Brownell      2008-05-01  136  
56b06081 Andy Shevchenko     2016-03-17 @137  int match_string(const char * const *array, size_t n, const char *string);
56b06081 Andy Shevchenko     2016-03-17  138  
4370aa4a Lai Jiangshan       2009-03-06  139  #ifdef CONFIG_BINARY_PRINTF
4370aa4a Lai Jiangshan       2009-03-06 @140  int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
4370aa4a Lai Jiangshan       2009-03-06 @141  int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
4370aa4a Lai Jiangshan       2009-03-06  142  int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
4370aa4a Lai Jiangshan       2009-03-06  143  #endif
4370aa4a Lai Jiangshan       2009-03-06  144  

:::::: The code at line 140 was first introduced by commit
:::::: 4370aa4aa75391a5e2e06bccb0919109f725ed8e vsprintf: add binary printf

:::::: TO: Lai Jiangshan <laijs@cn.fujitsu.com>
:::::: CC: Ingo Molnar <mingo@elte.hu>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Jyri Sarha March 13, 2017, 8:25 a.m. UTC | #3
On 03/11/17 19:25, Jyri Sarha wrote:
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> index f80bf93..bd92c89 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> @@ -1,4 +1,4 @@
> -/*
> +*
>   * Copyright (C) 2012 Texas Instruments
>   * Author: Rob Clark <robdclark@gmail.com>
>   *
> @@ -464,6 +464,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)

Sorry, I have no idea how this little change slipped into the patch.
Anyway, the rest of the patch is still good so I won't send a new
version just because of that.

Best regards,
Jyri
Tomi Valkeinen March 13, 2017, 8:29 a.m. UTC | #4
On 11/03/17 19:25, Jyri Sarha wrote:
> Touching HW while clocks are off is a serious error and for instance
> breaks suspend functionality. After this patch tilcdc_crtc_update_fb()
> always updates the primary plane's framebuffer pointer, increases fb's
> reference count and stores vblank event. tilcdc_crtc_update_fb() only
> writes the fb's DMA address to HW if the crtc is enabled, as
> tilcdc_crtc_enable() takes care of writing the address on enable.
> 
> This patch also refactors the tilcdc_crtc_update_fb() a bit. Number of
> subsequent small changes to had made it almost unreadable. There

Something is missing from the line above...

> should be no other functional changes but checking the CRTC's enable
> state. However, the locking goes a bit differently and some of the
> redundant checks have been removed in this new version.
> 
> The enable_lock should be enough to protect the access to
> tilcdc_crtc->enabled. The irq_lock protects the access to last_vblank
> and next_fb. The check for vrefresh and last_vblank being valid is
> redundant, as the vrefresh should be always valid if the CRTC is
> enabled and now last_vblank should be too, because it is initialized
> to current time when CRTC raster is enabled. If for some reason the
> values are not corretly initialized the division by zero waning is

2 typoes above.

> quite appropriate.
> 
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
>  drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 37 +++++++++++++++++++++++-------------
>  1 file changed, 24 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> index f80bf93..bd92c89 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> @@ -1,4 +1,4 @@
> -/*
> +*

This breaks the compilation of the whole driver...

 Tomi
diff mbox

Patch

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index f80bf93..bd92c89 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -1,4 +1,4 @@ 
-/*
+*
  * Copyright (C) 2012 Texas Instruments
  * Author: Rob Clark <robdclark@gmail.com>
  *
@@ -464,6 +464,7 @@  static void tilcdc_crtc_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
+	unsigned long flags;
 
 	WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
 	mutex_lock(&tilcdc_crtc->enable_lock);
@@ -484,7 +485,17 @@  static void tilcdc_crtc_enable(struct drm_crtc *crtc)
 	tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG,
 			  LCDC_PALETTE_LOAD_MODE(DATA_ONLY),
 			  LCDC_PALETTE_LOAD_MODE_MASK);
+
+	/* There is no real chance for a race here as the time stamp
+	 * is taken before the raster DMA is started. The spin-lock is
+	 * taken to have a memory barrier after taking the time-stamp
+	 * and to avoid a context switch between taking the stamp and
+	 * enabling the raster.
+	 */
+	spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
+	tilcdc_crtc->last_vblank = ktime_get();
 	tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+	spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags);
 
 	drm_crtc_vblank_on(crtc);
 
@@ -539,7 +550,6 @@  static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)
 	}
 
 	drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq);
-	tilcdc_crtc->last_vblank = 0;
 
 	tilcdc_crtc->enabled = false;
 	mutex_unlock(&tilcdc_crtc->enable_lock);
@@ -602,7 +612,6 @@  int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
 {
 	struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
-	unsigned long flags;
 
 	WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
 
@@ -614,28 +623,30 @@  int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
 	drm_framebuffer_reference(fb);
 
 	crtc->primary->fb = fb;
+	tilcdc_crtc->event = event;
 
-	spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
+	mutex_lock(&tilcdc_crtc->enable_lock);
 
-	if (crtc->hwmode.vrefresh && ktime_to_ns(tilcdc_crtc->last_vblank)) {
+	if (tilcdc_crtc->enabled) {
+		unsigned long flags;
 		ktime_t next_vblank;
 		s64 tdiff;
 
+		spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
+
 		next_vblank = ktime_add_us(tilcdc_crtc->last_vblank,
-			1000000 / crtc->hwmode.vrefresh);
-
+					   1000000 / crtc->hwmode.vrefresh);
 		tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get()));
 
 		if (tdiff < TILCDC_VBLANK_SAFETY_THRESHOLD_US)
 			tilcdc_crtc->next_fb = fb;
+		else
+			set_scanout(crtc, fb);
+
+		spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags);
 	}
 
-	if (tilcdc_crtc->next_fb != fb)
-		set_scanout(crtc, fb);
-
-	tilcdc_crtc->event = event;
-
-	spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags);
+	mutex_unlock(&tilcdc_crtc->enable_lock);
 
 	return 0;
 }