diff options
Diffstat (limited to 'include')
188 files changed, 8737 insertions, 4150 deletions
diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h new file mode 100644 index 000000000000..43199a049da5 --- /dev/null +++ b/include/asm-generic/export.h @@ -0,0 +1,94 @@ +#ifndef __ASM_GENERIC_EXPORT_H +#define __ASM_GENERIC_EXPORT_H + +#ifndef KSYM_FUNC +#define KSYM_FUNC(x) x +#endif +#ifdef CONFIG_64BIT +#define __put .quad +#ifndef KSYM_ALIGN +#define KSYM_ALIGN 8 +#endif +#ifndef KCRC_ALIGN +#define KCRC_ALIGN 8 +#endif +#else +#define __put .long +#ifndef KSYM_ALIGN +#define KSYM_ALIGN 4 +#endif +#ifndef KCRC_ALIGN +#define KCRC_ALIGN 4 +#endif +#endif + +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX +#define KSYM(name) _##name +#else +#define KSYM(name) name +#endif + +/* + * note on .section use: @progbits vs %progbits nastiness doesn't matter, + * since we immediately emit into those sections anyway. + */ +.macro ___EXPORT_SYMBOL name,val,sec +#ifdef CONFIG_MODULES + .globl KSYM(__ksymtab_\name) + .section ___ksymtab\sec+\name,"a" + .balign KSYM_ALIGN +KSYM(__ksymtab_\name): + __put \val, KSYM(__kstrtab_\name) + .previous + .section __ksymtab_strings,"a" +KSYM(__kstrtab_\name): +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX + .asciz "_\name" +#else + .asciz "\name" +#endif + .previous +#ifdef CONFIG_MODVERSIONS + .section ___kcrctab\sec+\name,"a" + .balign KCRC_ALIGN +KSYM(__kcrctab_\name): + __put KSYM(__crc_\name) + .weak KSYM(__crc_\name) + .previous +#endif +#endif +.endm +#undef __put + +#if defined(__KSYM_DEPS__) + +#define __EXPORT_SYMBOL(sym, val, sec) === __KSYM_##sym === + +#elif defined(CONFIG_TRIM_UNUSED_KSYMS) + +#include <linux/kconfig.h> +#include <generated/autoksyms.h> + +#define __EXPORT_SYMBOL(sym, val, sec) \ + __cond_export_sym(sym, val, sec, config_enabled(__KSYM_##sym)) +#define __cond_export_sym(sym, val, sec, conf) \ + ___cond_export_sym(sym, val, sec, conf) +#define ___cond_export_sym(sym, val, sec, enabled) \ + __cond_export_sym_##enabled(sym, val, sec) +#define __cond_export_sym_1(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec +#define __cond_export_sym_0(sym, val, sec) /* nothing */ + +#else +#define __EXPORT_SYMBOL(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec +#endif + +#define EXPORT_SYMBOL(name) \ + __EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)),) +#define EXPORT_SYMBOL_GPL(name) \ + __EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)), _gpl) +#define EXPORT_DATA_SYMBOL(name) \ + __EXPORT_SYMBOL(name, KSYM(name),) +#define EXPORT_DATA_SYMBOL_GPL(name) \ + __EXPORT_SYMBOL(name, KSYM(name),_gpl) + +#endif diff --git a/include/asm-generic/libata-portmap.h b/include/asm-generic/libata-portmap.h deleted file mode 100644 index cf14f2ff40b6..000000000000 --- a/include/asm-generic/libata-portmap.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H -#define __ASM_GENERIC_LIBATA_PORTMAP_H - -#define ATA_PRIMARY_IRQ(dev) 14 -#define ATA_SECONDARY_IRQ(dev) 15 - -#endif diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 4d9f233c4ba8..40e887068da2 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -65,6 +65,11 @@ extern void setup_per_cpu_areas(void); #define PER_CPU_DEF_ATTRIBUTES #endif +#define raw_cpu_generic_read(pcp) \ +({ \ + *raw_cpu_ptr(&(pcp)); \ +}) + #define raw_cpu_generic_to_op(pcp, val, op) \ do { \ *raw_cpu_ptr(&(pcp)) op val; \ @@ -72,34 +77,39 @@ do { \ #define raw_cpu_generic_add_return(pcp, val) \ ({ \ - raw_cpu_add(pcp, val); \ - raw_cpu_read(pcp); \ + typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \ + \ + *__p += val; \ + *__p; \ }) #define raw_cpu_generic_xchg(pcp, nval) \ ({ \ + typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \ typeof(pcp) __ret; \ - __ret = raw_cpu_read(pcp); \ - raw_cpu_write(pcp, nval); \ + __ret = *__p; \ + *__p = nval; \ __ret; \ }) #define raw_cpu_generic_cmpxchg(pcp, oval, nval) \ ({ \ + typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \ typeof(pcp) __ret; \ - __ret = raw_cpu_read(pcp); \ + __ret = *__p; \ if (__ret == (oval)) \ - raw_cpu_write(pcp, nval); \ + *__p = nval; \ __ret; \ }) #define raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ ({ \ + typeof(&(pcp1)) __p1 = raw_cpu_ptr(&(pcp1)); \ + typeof(&(pcp2)) __p2 = raw_cpu_ptr(&(pcp2)); \ int __ret = 0; \ - if (raw_cpu_read(pcp1) == (oval1) && \ - raw_cpu_read(pcp2) == (oval2)) { \ - raw_cpu_write(pcp1, nval1); \ - raw_cpu_write(pcp2, nval2); \ + if (*__p1 == (oval1) && *__p2 == (oval2)) { \ + *__p1 = nval1; \ + *__p2 = nval2; \ __ret = 1; \ } \ (__ret); \ @@ -109,7 +119,7 @@ do { \ ({ \ typeof(pcp) __ret; \ preempt_disable(); \ - __ret = *this_cpu_ptr(&(pcp)); \ + __ret = raw_cpu_generic_read(pcp); \ preempt_enable(); \ __ret; \ }) @@ -118,17 +128,17 @@ do { \ do { \ unsigned long __flags; \ raw_local_irq_save(__flags); \ - *raw_cpu_ptr(&(pcp)) op val; \ + raw_cpu_generic_to_op(pcp, val, op); \ raw_local_irq_restore(__flags); \ } while (0) + #define this_cpu_generic_add_return(pcp, val) \ ({ \ typeof(pcp) __ret; \ unsigned long __flags; \ raw_local_irq_save(__flags); \ - raw_cpu_add(pcp, val); \ - __ret = raw_cpu_read(pcp); \ + __ret = raw_cpu_generic_add_return(pcp, val); \ raw_local_irq_restore(__flags); \ __ret; \ }) @@ -138,8 +148,7 @@ do { \ typeof(pcp) __ret; \ unsigned long __flags; \ raw_local_irq_save(__flags); \ - __ret = raw_cpu_read(pcp); \ - raw_cpu_write(pcp, nval); \ + __ret = raw_cpu_generic_xchg(pcp, nval); \ raw_local_irq_restore(__flags); \ __ret; \ }) @@ -149,9 +158,7 @@ do { \ typeof(pcp) __ret; \ unsigned long __flags; \ raw_local_irq_save(__flags); \ - __ret = raw_cpu_read(pcp); \ - if (__ret == (oval)) \ - raw_cpu_write(pcp, nval); \ + __ret = raw_cpu_generic_cmpxchg(pcp, oval, nval); \ raw_local_irq_restore(__flags); \ __ret; \ }) @@ -168,16 +175,16 @@ do { \ }) #ifndef raw_cpu_read_1 -#define raw_cpu_read_1(pcp) (*raw_cpu_ptr(&(pcp))) +#define raw_cpu_read_1(pcp) raw_cpu_generic_read(pcp) #endif #ifndef raw_cpu_read_2 -#define raw_cpu_read_2(pcp) (*raw_cpu_ptr(&(pcp))) +#define raw_cpu_read_2(pcp) raw_cpu_generic_read(pcp) #endif #ifndef raw_cpu_read_4 -#define raw_cpu_read_4(pcp) (*raw_cpu_ptr(&(pcp))) +#define raw_cpu_read_4(pcp) raw_cpu_generic_read(pcp) #endif #ifndef raw_cpu_read_8 -#define raw_cpu_read_8(pcp) (*raw_cpu_ptr(&(pcp))) +#define raw_cpu_read_8(pcp) raw_cpu_generic_read(pcp) #endif #ifndef raw_cpu_write_1 diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h index 6df9b0749671..cc6bb319e464 100644 --- a/include/asm-generic/uaccess.h +++ b/include/asm-generic/uaccess.h @@ -69,10 +69,6 @@ struct exception_table_entry unsigned long insn, fixup; }; -/* Returns 0 if exception not found and fixup otherwise. */ -extern unsigned long search_exception_table(unsigned long); - - /* * architectures with an MMU should override these two */ diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 3e42bcdd014b..30747960bc54 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -196,9 +196,14 @@ *(.dtb.init.rodata) \ VMLINUX_SYMBOL(__dtb_end) = .; -/* .data section */ +/* + * .data section + * LD_DEAD_CODE_DATA_ELIMINATION option enables -fdata-sections generates + * .data.identifier which needs to be pulled in with .data, but don't want to + * pull in .data..stuff which has its own requirements. Same for bss. + */ #define DATA_DATA \ - *(.data) \ + *(.data .data.[0-9a-zA-Z_]*) \ *(.ref.data) \ *(.data..shared_aligned) /* percpu related */ \ MEM_KEEP(init.data) \ @@ -320,76 +325,76 @@ /* Kernel symbol table: Normal symbols */ \ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab) = .; \ - *(SORT(___ksymtab+*)) \ + KEEP(*(SORT(___ksymtab+*))) \ VMLINUX_SYMBOL(__stop___ksymtab) = .; \ } \ \ /* Kernel symbol table: GPL-only symbols */ \ __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \ - *(SORT(___ksymtab_gpl+*)) \ + KEEP(*(SORT(___ksymtab_gpl+*))) \ VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ } \ \ /* Kernel symbol table: Normal unused symbols */ \ __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \ - *(SORT(___ksymtab_unused+*)) \ + KEEP(*(SORT(___ksymtab_unused+*))) \ VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \ } \ \ /* Kernel symbol table: GPL-only unused symbols */ \ __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \ - *(SORT(___ksymtab_unused_gpl+*)) \ + KEEP(*(SORT(___ksymtab_unused_gpl+*))) \ VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \ } \ \ /* Kernel symbol table: GPL-future-only symbols */ \ __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \ - *(SORT(___ksymtab_gpl_future+*)) \ + KEEP(*(SORT(___ksymtab_gpl_future+*))) \ VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \ } \ \ /* Kernel symbol table: Normal symbols */ \ __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab) = .; \ - *(SORT(___kcrctab+*)) \ + KEEP(*(SORT(___kcrctab+*))) \ VMLINUX_SYMBOL(__stop___kcrctab) = .; \ } \ \ /* Kernel symbol table: GPL-only symbols */ \ __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab_gpl) = .; \ - *(SORT(___kcrctab_gpl+*)) \ + KEEP(*(SORT(___kcrctab_gpl+*))) \ VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \ } \ \ /* Kernel symbol table: Normal unused symbols */ \ __kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab_unused) = .; \ - *(SORT(___kcrctab_unused+*)) \ + KEEP(*(SORT(___kcrctab_unused+*))) \ VMLINUX_SYMBOL(__stop___kcrctab_unused) = .; \ } \ \ /* Kernel symbol table: GPL-only unused symbols */ \ __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \ - *(SORT(___kcrctab_unused_gpl+*)) \ + KEEP(*(SORT(___kcrctab_unused_gpl+*))) \ VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \ } \ \ /* Kernel symbol table: GPL-future-only symbols */ \ __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \ - *(SORT(___kcrctab_gpl_future+*)) \ + KEEP(*(SORT(___kcrctab_gpl_future+*))) \ VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \ } \ \ /* Kernel symbol table: strings */ \ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ - *(__ksymtab_strings) \ + KEEP(*(__ksymtab_strings)) \ } \ \ /* __*init sections */ \ @@ -424,12 +429,17 @@ #define SECURITY_INIT \ .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__security_initcall_start) = .; \ - *(.security_initcall.init) \ + KEEP(*(.security_initcall.init)) \ VMLINUX_SYMBOL(__security_initcall_end) = .; \ } /* .text section. Map to function alignment to avoid address changes - * during second ld run in second ld pass when generating System.map */ + * during second ld run in second ld pass when generating System.map + * LD_DEAD_CODE_DATA_ELIMINATION option enables -ffunction-sections generates + * .text.identifier which needs to be pulled in with .text , but some + * architectures define .text.foo which is not intended to be pulled in here. + * Those enabling LD_DEAD_CODE_DATA_ELIMINATION must ensure they don't have + * conflicting section names, and must pull in .text.[0-9a-zA-Z_]* */ #define TEXT_TEXT \ ALIGN_FUNCTION(); \ *(.text.hot .text .text.fixup .text.unlikely) \ @@ -533,6 +543,7 @@ /* init and exit section handling */ #define INIT_DATA \ + KEEP(*(SORT(___kentry+*))) \ *(.init.data) \ MEM_DISCARD(init.data) \ KERNEL_CTORS() \ @@ -599,7 +610,7 @@ BSS_FIRST_SECTIONS \ *(.bss..page_aligned) \ *(.dynbss) \ - *(.bss) \ + *(.bss .bss.[0-9a-zA-Z_]*) \ *(COMMON) \ } @@ -682,12 +693,12 @@ #define INIT_CALLS_LEVEL(level) \ VMLINUX_SYMBOL(__initcall##level##_start) = .; \ - *(.initcall##level##.init) \ - *(.initcall##level##s.init) \ + KEEP(*(.initcall##level##.init)) \ + KEEP(*(.initcall##level##s.init)) \ #define INIT_CALLS \ VMLINUX_SYMBOL(__initcall_start) = .; \ - *(.initcallearly.init) \ + KEEP(*(.initcallearly.init)) \ INIT_CALLS_LEVEL(0) \ INIT_CALLS_LEVEL(1) \ INIT_CALLS_LEVEL(2) \ @@ -701,21 +712,21 @@ #define CON_INITCALL \ VMLINUX_SYMBOL(__con_initcall_start) = .; \ - *(.con_initcall.init) \ + KEEP(*(.con_initcall.init)) \ VMLINUX_SYMBOL(__con_initcall_end) = .; #define SECURITY_INITCALL \ VMLINUX_SYMBOL(__security_initcall_start) = .; \ - *(.security_initcall.init) \ + KEEP(*(.security_initcall.init)) \ VMLINUX_SYMBOL(__security_initcall_end) = .; #ifdef CONFIG_BLK_DEV_INITRD #define INIT_RAM_FS \ . = ALIGN(4); \ VMLINUX_SYMBOL(__initramfs_start) = .; \ - *(.init.ramfs) \ + KEEP(*(.init.ramfs)) \ . = ALIGN(8); \ - *(.init.ramfs.info) + KEEP(*(.init.ramfs.info)) #else #define INIT_RAM_FS #endif diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 8637cdfe382a..404e9558e879 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -15,7 +15,6 @@ #include <linux/crypto.h> #include <linux/list.h> #include <linux/kernel.h> -#include <linux/kthread.h> #include <linux/skbuff.h> struct crypto_aead; @@ -129,75 +128,6 @@ struct ablkcipher_walk { unsigned int blocksize; }; -#define ENGINE_NAME_LEN 30 -/* - * struct crypto_engine - crypto hardware engine - * @name: the engine name - * @idling: the engine is entering idle state - * @busy: request pump is busy - * @running: the engine is on working - * @cur_req_prepared: current request is prepared - * @list: link with the global crypto engine list - * @queue_lock: spinlock to syncronise access to request queue - * @queue: the crypto queue of the engine - * @rt: whether this queue is set to run as a realtime task - * @prepare_crypt_hardware: a request will soon arrive from the queue - * so the subsystem requests the driver to prepare the hardware - * by issuing this call - * @unprepare_crypt_hardware: there are currently no more requests on the - * queue so the subsystem notifies the driver that it may relax the - * hardware by issuing this call - * @prepare_request: do some prepare if need before handle the current request - * @unprepare_request: undo any work done by prepare_message() - * @crypt_one_request: do encryption for current request - * @kworker: thread struct for request pump - * @kworker_task: pointer to task for request pump kworker thread - * @pump_requests: work struct for scheduling work to the request pump - * @priv_data: the engine private data - * @cur_req: the current request which is on processing - */ -struct crypto_engine { - char name[ENGINE_NAME_LEN]; - bool idling; - bool busy; - bool running; - bool cur_req_prepared; - - struct list_head list; - spinlock_t queue_lock; - struct crypto_queue queue; - - bool rt; - - int (*prepare_crypt_hardware)(struct crypto_engine *engine); - int (*unprepare_crypt_hardware)(struct crypto_engine *engine); - - int (*prepare_request)(struct crypto_engine *engine, - struct ablkcipher_request *req); - int (*unprepare_request)(struct crypto_engine *engine, - struct ablkcipher_request *req); - int (*crypt_one_request)(struct crypto_engine *engine, - struct ablkcipher_request *req); - - struct kthread_worker kworker; - struct task_struct *kworker_task; - struct kthread_work pump_requests; - - void *priv_data; - struct ablkcipher_request *cur_req; -}; - -int crypto_transfer_request(struct crypto_engine *engine, - struct ablkcipher_request *req, bool need_pump); -int crypto_transfer_request_to_engine(struct crypto_engine *engine, - struct ablkcipher_request *req); -void crypto_finalize_request(struct crypto_engine *engine, - struct ablkcipher_request *req, int err); -int crypto_engine_start(struct crypto_engine *engine); -int crypto_engine_stop(struct crypto_engine *engine); -struct crypto_engine *crypto_engine_alloc_init(struct device *dev, bool rt); -int crypto_engine_exit(struct crypto_engine *engine); - extern const struct crypto_type crypto_ablkcipher_type; extern const struct crypto_type crypto_blkcipher_type; diff --git a/include/crypto/engine.h b/include/crypto/engine.h new file mode 100644 index 000000000000..04eb5c77addd --- /dev/null +++ b/include/crypto/engine.h @@ -0,0 +1,107 @@ +/* + * Crypto engine API + * + * Copyright (c) 2016 Baolin Wang <baolin.wang@linaro.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#ifndef _CRYPTO_ENGINE_H +#define _CRYPTO_ENGINE_H + +#include <linux/crypto.h> +#include <linux/list.h> +#include <linux/kernel.h> +#include <linux/kthread.h> +#include <crypto/algapi.h> +#include <crypto/hash.h> + +#define ENGINE_NAME_LEN 30 +/* + * struct crypto_engine - crypto hardware engine + * @name: the engine name + * @idling: the engine is entering idle state + * @busy: request pump is busy + * @running: the engine is on working + * @cur_req_prepared: current request is prepared + * @list: link with the global crypto engine list + * @queue_lock: spinlock to syncronise access to request queue + * @queue: the crypto queue of the engine + * @rt: whether this queue is set to run as a realtime task + * @prepare_crypt_hardware: a request will soon arrive from the queue + * so the subsystem requests the driver to prepare the hardware + * by issuing this call + * @unprepare_crypt_hardware: there are currently no more requests on the + * queue so the subsystem notifies the driver that it may relax the + * hardware by issuing this call + * @prepare_cipher_request: do some prepare if need before handle the current request + * @unprepare_cipher_request: undo any work done by prepare_cipher_request() + * @cipher_one_request: do encryption for current request + * @prepare_hash_request: do some prepare if need before handle the current request + * @unprepare_hash_request: undo any work done by prepare_hash_request() + * @hash_one_request: do hash for current request + * @kworker: thread struct for request pump + * @kworker_task: pointer to task for request pump kworker thread + * @pump_requests: work struct for scheduling work to the request pump + * @priv_data: the engine private data + * @cur_req: the current request which is on processing + */ +struct crypto_engine { + char name[ENGINE_NAME_LEN]; + bool idling; + bool busy; + bool running; + bool cur_req_prepared; + + struct list_head list; + spinlock_t queue_lock; + struct crypto_queue queue; + + bool rt; + + int (*prepare_crypt_hardware)(struct crypto_engine *engine); + int (*unprepare_crypt_hardware)(struct crypto_engine *engine); + + int (*prepare_cipher_request)(struct crypto_engine *engine, + struct ablkcipher_request *req); + int (*unprepare_cipher_request)(struct crypto_engine *engine, + struct ablkcipher_request *req); + int (*prepare_hash_request)(struct crypto_engine *engine, + struct ahash_request *req); + int (*unprepare_hash_request)(struct crypto_engine *engine, + struct ahash_request *req); + int (*cipher_one_request)(struct crypto_engine *engine, + struct ablkcipher_request *req); + int (*hash_one_request)(struct crypto_engine *engine, + struct ahash_request *req); + + struct kthread_worker kworker; + struct task_struct *kworker_task; + struct kthread_work pump_requests; + + void *priv_data; + struct crypto_async_request *cur_req; +}; + +int crypto_transfer_cipher_request(struct crypto_engine *engine, + struct ablkcipher_request *req, + bool need_pump); +int crypto_transfer_cipher_request_to_engine(struct crypto_engine *engine, + struct ablkcipher_request *req); +int crypto_transfer_hash_request(struct crypto_engine *engine, + struct ahash_request *req, bool need_pump); +int crypto_transfer_hash_request_to_engine(struct crypto_engine *engine, + struct ahash_request *req); +void crypto_finalize_cipher_request(struct crypto_engine *engine, + struct ablkcipher_request *req, int err); +void crypto_finalize_hash_request(struct crypto_engine *engine, + struct ahash_request *req, int err); +int crypto_engine_start(struct crypto_engine *engine); +int crypto_engine_stop(struct crypto_engine *engine); +struct crypto_engine *crypto_engine_alloc_init(struct device *dev, bool rt); +int crypto_engine_exit(struct crypto_engine *engine); + +#endif /* _CRYPTO_ENGINE_H */ diff --git a/include/crypto/ghash.h b/include/crypto/ghash.h new file mode 100644 index 000000000000..2a61c9bbab8f --- /dev/null +++ b/include/crypto/ghash.h @@ -0,0 +1,23 @@ +/* + * Common values for GHASH algorithms + */ + +#ifndef __CRYPTO_GHASH_H__ +#define __CRYPTO_GHASH_H__ + +#include <linux/types.h> +#include <crypto/gf128mul.h> + +#define GHASH_BLOCK_SIZE 16 +#define GHASH_DIGEST_SIZE 16 + +struct ghash_ctx { + struct gf128mul_4k *gf128; +}; + +struct ghash_desc_ctx { + u8 buffer[GHASH_BLOCK_SIZE]; + u32 bytes; +}; + +#endif diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 261b86d20e77..f6f0c062205c 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -38,6 +38,10 @@ struct analogix_dp_plat_data { struct drm_connector *); }; +int analogix_dp_psr_supported(struct device *dev); +int analogix_dp_enable_psr(struct device *dev); +int analogix_dp_disable_psr(struct device *dev); + int analogix_dp_resume(struct device *dev); int analogix_dp_suspend(struct device *dev); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d3778652e462..672644031bd5 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -51,6 +51,7 @@ #include <linux/platform_device.h> #include <linux/poll.h> #include <linux/ratelimit.h> +#include <linux/rbtree.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/types.h> @@ -127,6 +128,7 @@ struct dma_buf_attachment; * run-time by echoing the debug value in its sysfs node: * # echo 0xf > /sys/module/drm/parameters/debug */ +#define DRM_UT_NONE 0x00 #define DRM_UT_CORE 0x01 #define DRM_UT_DRIVER 0x02 #define DRM_UT_KMS 0x04 @@ -134,11 +136,14 @@ struct dma_buf_attachment; #define DRM_UT_ATOMIC 0x10 #define DRM_UT_VBL 0x20 -extern __printf(2, 3) -void drm_ut_debug_printk(const char *function_name, - const char *format, ...); -extern __printf(1, 2) -void drm_err(const char *format, ...); +extern __printf(6, 7) +void drm_dev_printk(const struct device *dev, const char *level, + unsigned int category, const char *function_name, + const char *prefix, const char *format, ...); + +extern __printf(3, 4) +void drm_printk(const char *level, unsigned int category, + const char *format, ...); /***********************************************************************/ /** \name DRM template customization defaults */ @@ -146,6 +151,7 @@ void drm_err(const char *format, ...); /* driver capabilities and requirements mask */ #define DRIVER_USE_AGP 0x1 +#define DRIVER_LEGACY 0x2 #define DRIVER_PCI_DMA 0x8 #define DRIVER_SG 0x10 #define DRIVER_HAVE_DMA 0x20 @@ -162,14 +168,37 @@ void drm_err(const char *format, ...); /** \name Macros to make printk easier */ /*@{*/ +#define _DRM_PRINTK(once, level, fmt, ...) \ + do { \ + printk##once(KERN_##level "[" DRM_NAME "] " fmt, \ + ##__VA_ARGS__); \ + } while (0) + +#define DRM_INFO(fmt, ...) \ + _DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__) +#define DRM_NOTE(fmt, ...) \ + _DRM_PRINTK(, NOTICE, fmt, ##__VA_ARGS__) +#define DRM_WARN(fmt, ...) \ + _DRM_PRINTK(, WARNING, fmt, ##__VA_ARGS__) + +#define DRM_INFO_ONCE(fmt, ...) \ + _DRM_PRINTK(_once, INFO, fmt, ##__VA_ARGS__) +#define DRM_NOTE_ONCE(fmt, ...) \ + _DRM_PRINTK(_once, NOTICE, fmt, ##__VA_ARGS__) +#define DRM_WARN_ONCE(fmt, ...) \ + _DRM_PRINTK(_once, WARNING, fmt, ##__VA_ARGS__) + /** * Error output. * * \param fmt printf() like format string. * \param arg arguments */ -#define DRM_ERROR(fmt, ...) \ - drm_err(fmt, ##__VA_ARGS__) +#define DRM_DEV_ERROR(dev, fmt, ...) \ + drm_dev_printk(dev, KERN_ERR, DRM_UT_NONE, __func__, " *ERROR*",\ + fmt, ##__VA_ARGS__) +#define DRM_ERROR(fmt, ...) \ + drm_printk(KERN_ERR, DRM_UT_NONE, fmt, ##__VA_ARGS__) /** * Rate limited error output. Like DRM_ERROR() but won't flood the log. @@ -177,21 +206,30 @@ void drm_err(const char *format, ...); * \param fmt printf() like format string. * \param arg arguments */ -#define DRM_ERROR_RATELIMITED(fmt, ...) \ +#define DRM_DEV_ERROR_RATELIMITED(dev, fmt, ...) \ ({ \ static DEFINE_RATELIMIT_STATE(_rs, \ DEFAULT_RATELIMIT_INTERVAL, \ DEFAULT_RATELIMIT_BURST); \ \ if (__ratelimit(&_rs)) \ - drm_err(fmt, ##__VA_ARGS__); \ + DRM_DEV_ERROR(dev, fmt, ##__VA_ARGS__); \ }) +#define DRM_ERROR_RATELIMITED(fmt, ...) \ + DRM_DEV_ERROR_RATELIMITED(NULL, fmt, ##__VA_ARGS__) -#define DRM_INFO(fmt, ...) \ - printk(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__) +#define DRM_DEV_INFO(dev, fmt, ...) \ + drm_dev_printk(dev, KERN_INFO, DRM_UT_NONE, __func__, "", fmt, \ + ##__VA_ARGS__) -#define DRM_INFO_ONCE(fmt, ...) \ - printk_once(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__) +#define DRM_DEV_INFO_ONCE(dev, fmt, ...) \ +({ \ + static bool __print_once __read_mostly; \ + if (!__print_once) { \ + __print_once = true; \ + DRM_DEV_INFO(dev, fmt, ##__VA_ARGS__); \ + } \ +}) /** * Debug output. @@ -199,37 +237,74 @@ void drm_err(const char *format, ...); * \param fmt printf() like format string. * \param arg arguments */ -#define DRM_DEBUG(fmt, args...) \ - do { \ - if (unlikely(drm_debug & DRM_UT_CORE)) \ - drm_ut_debug_printk(__func__, fmt, ##args); \ - } while (0) +#define DRM_DEV_DEBUG(dev, fmt, args...) \ + drm_dev_printk(dev, KERN_DEBUG, DRM_UT_CORE, __func__, "", fmt, \ + ##args) +#define DRM_DEBUG(fmt, ...) \ + drm_printk(KERN_DEBUG, DRM_UT_CORE, fmt, ##__VA_ARGS__) + +#define DRM_DEV_DEBUG_DRIVER(dev, fmt, args...) \ + drm_dev_printk(dev, KERN_DEBUG, DRM_UT_DRIVER, __func__, "", \ + fmt, ##args) +#define DRM_DEBUG_DRIVER(fmt, ...) \ + drm_printk(KERN_DEBUG, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) + +#define DRM_DEV_DEBUG_KMS(dev, fmt, args...) \ + drm_dev_printk(dev, KERN_DEBUG, DRM_UT_KMS, __func__, "", fmt, \ + ##args) +#define DRM_DEBUG_KMS(fmt, ...) \ + drm_printk(KERN_DEBUG, DRM_UT_KMS, fmt, ##__VA_ARGS__) + +#define DRM_DEV_DEBUG_PRIME(dev, fmt, args...) \ + drm_dev_printk(dev, KERN_DEBUG, DRM_UT_PRIME, __func__, "", \ + fmt, ##args) +#define DRM_DEBUG_PRIME(fmt, ...) \ + drm_printk(KERN_DEBUG, DRM_UT_PRIME, fmt, ##__VA_ARGS__) + +#define DRM_DEV_DEBUG_ATOMIC(dev, fmt, args...) \ + drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ATOMIC, __func__, "", \ + fmt, ##args) +#define DRM_DEBUG_ATOMIC(fmt, ...) \ + drm_printk(KERN_DEBUG, DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) + +#define DRM_DEV_DEBUG_VBL(dev, fmt, args...) \ + drm_dev_printk(dev, KERN_DEBUG, DRM_UT_VBL, __func__, "", fmt, \ + ##args) +#define DRM_DEBUG_VBL(fmt, ...) \ + drm_printk(KERN_DEBUG, DRM_UT_VBL, fmt, ##__VA_ARGS__) + +#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \ +({ \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + if (__ratelimit(&_rs)) \ + drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ ## level, \ + __func__, "", fmt, ##args); \ +}) -#define DRM_DEBUG_DRIVER(fmt, args...) \ - do { \ - if (unlikely(drm_debug & DRM_UT_DRIVER)) \ - drm_ut_debug_printk(__func__, fmt, ##args); \ - } while (0) -#define DRM_DEBUG_KMS(fmt, args...) \ - do { \ - if (unlikely(drm_debug & DRM_UT_KMS)) \ - drm_ut_debug_printk(__func__, fmt, ##args); \ - } while (0) -#define DRM_DEBUG_PRIME(fmt, args...) \ - do { \ - if (unlikely(drm_debug & DRM_UT_PRIME)) \ - drm_ut_debug_printk(__func__, fmt, ##args); \ - } while (0) -#define DRM_DEBUG_ATOMIC(fmt, args...) \ - do { \ - if (unlikely(drm_debug & DRM_UT_ATOMIC)) \ - drm_ut_debug_printk(__func__, fmt, ##args); \ - } while (0) -#define DRM_DEBUG_VBL(fmt, args...) \ - do { \ - if (unlikely(drm_debug & DRM_UT_VBL)) \ - drm_ut_debug_printk(__func__, fmt, ##args); \ - } while (0) +/** + * Rate limited debug output. Like DRM_DEBUG() but won't flood the log. + * + * \param fmt printf() like format string. + * \param arg arguments + */ +#define DRM_DEV_DEBUG_RATELIMITED(dev, fmt, args...) \ + DEV__DRM_DEFINE_DEBUG_RATELIMITED(dev, CORE, fmt, ##args) +#define DRM_DEBUG_RATELIMITED(fmt, args...) \ + DRM_DEV_DEBUG_RATELIMITED(NULL, fmt, ##args) +#define DRM_DEV_DEBUG_DRIVER_RATELIMITED(dev, fmt, args...) \ + _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRIVER, fmt, ##args) +#define DRM_DEBUG_DRIVER_RATELIMITED(fmt, args...) \ + DRM_DEV_DEBUG_DRIVER_RATELIMITED(NULL, fmt, ##args) +#define DRM_DEV_DEBUG_KMS_RATELIMITED(dev, fmt, args...) \ + _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, KMS, fmt, ##args) +#define DRM_DEBUG_KMS_RATELIMITED(fmt, args...) \ + DRM_DEV_DEBUG_KMS_RATELIMITED(NULL, fmt, ##args) +#define DRM_DEV_DEBUG_PRIME_RATELIMITED(dev, fmt, args...) \ + _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, PRIME, fmt, ##args) +#define DRM_DEBUG_PRIME_RATELIMITED(fmt, args...) \ + DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##args) /*@}*/ @@ -295,10 +370,10 @@ struct drm_pending_event { we deliver the event, for tracing only */ }; -/* initial implementaton using a linked list - todo hashtab */ struct drm_prime_file_private { - struct list_head head; struct mutex lock; + struct rb_root dmabufs; + struct rb_root handles; }; /** File private data */ @@ -320,7 +395,6 @@ struct drm_file { unsigned is_master:1; struct pid *pid; - kuid_t uid; drm_magic_t magic; struct list_head lhead; struct drm_minor *minor; @@ -642,7 +716,7 @@ struct drm_driver { }; enum drm_minor_type { - DRM_MINOR_LEGACY, + DRM_MINOR_PRIMARY, DRM_MINOR_CONTROL, DRM_MINOR_RENDER, DRM_MINOR_CNT, @@ -856,7 +930,7 @@ static inline bool drm_is_control_client(const struct drm_file *file_priv) static inline bool drm_is_primary_client(const struct drm_file *file_priv) { - return file_priv->minor->type == DRM_MINOR_LEGACY; + return file_priv->minor->type == DRM_MINOR_PRIMARY; } /******************************************************************/ @@ -937,8 +1011,11 @@ static inline int drm_debugfs_remove_files(const struct drm_info_list *files, } #endif +struct dma_buf_export_info; + extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, - struct drm_gem_object *obj, int flags); + struct drm_gem_object *obj, + int flags); extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd); @@ -946,6 +1023,8 @@ extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, struct drm_file *file_priv, int prime_fd, uint32_t *handle); +struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev, + struct dma_buf_export_info *exp_info); extern void drm_gem_dmabuf_release(struct dma_buf *dma_buf); extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 856a9c85a838..9701f2dfb784 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -30,6 +30,160 @@ #include <drm/drm_crtc.h> +/** + * struct drm_crtc_commit - track modeset commits on a CRTC + * + * This structure is used to track pending modeset changes and atomic commit on + * a per-CRTC basis. Since updating the list should never block this structure + * is reference counted to allow waiters to safely wait on an event to complete, + * without holding any locks. + * + * It has 3 different events in total to allow a fine-grained synchronization + * between outstanding updates:: + * + * atomic commit thread hardware + * + * write new state into hardware ----> ... + * signal hw_done + * switch to new state on next + * ... v/hblank + * + * wait for buffers to show up ... + * + * ... send completion irq + * irq handler signals flip_done + * cleanup old buffers + * + * signal cleanup_done + * + * wait for flip_done <---- + * clean up atomic state + * + * The important bit to know is that cleanup_done is the terminal event, but the + * ordering between flip_done and hw_done is entirely up to the specific driver + * and modeset state change. + * + * For an implementation of how to use this look at + * drm_atomic_helper_setup_commit() from the atomic helper library. + */ +struct drm_crtc_commit { + /** + * @crtc: + * + * DRM CRTC for this commit. + */ + struct drm_crtc *crtc; + + /** + * @ref: + * + * Reference count for this structure. Needed to allow blocking on + * completions without the risk of the completion disappearing + * meanwhile. + */ + struct kref ref; + + /** + * @flip_done: + * + * Will be signaled when the hardware has flipped to the new set of + * buffers. Signals at the same time as when the drm event for this + * commit is sent to userspace, or when an out-fence is singalled. Note + * that for most hardware, in most cases this happens after @hw_done is + * signalled. + */ + struct completion flip_done; + + /** + * @hw_done: + * + * Will be signalled when all hw register changes for this commit have + * been written out. Especially when disabling a pipe this can be much + * later than than @flip_done, since that can signal already when the + * screen goes black, whereas to fully shut down a pipe more register + * I/O is required. + * + * Note that this does not need to include separately reference-counted + * resources like backing storage buffer pinning, or runtime pm + * management. + */ + struct completion hw_done; + + /** + * @cleanup_done: + * + * Will be signalled after old buffers have been cleaned up by calling + * drm_atomic_helper_cleanup_planes(). Since this can only happen after + * a vblank wait completed it might be a bit later. This completion is + * useful to throttle updates and avoid hardware updates getting ahead + * of the buffer cleanup too much. + */ + struct completion cleanup_done; + + /** + * @commit_entry: + * + * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock. + */ + struct list_head commit_entry; + + /** + * @event: + * + * &drm_pending_vblank_event pointer to clean up private events. + */ + struct drm_pending_vblank_event *event; +}; + +struct __drm_planes_state { + struct drm_plane *ptr; + struct drm_plane_state *state; +}; + +struct __drm_crtcs_state { + struct drm_crtc *ptr; + struct drm_crtc_state *state; + struct drm_crtc_commit *commit; +}; + +struct __drm_connnectors_state { + struct drm_connector *ptr; + struct drm_connector_state *state; +}; + +/** + * struct drm_atomic_state - the global state object for atomic updates + * @dev: parent DRM device + * @allow_modeset: allow full modeset + * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics + * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL. + * @planes: pointer to array of structures with per-plane data + * @crtcs: pointer to array of CRTC pointers + * @num_connector: size of the @connectors and @connector_states arrays + * @connectors: pointer to array of structures with per-connector data + * @acquire_ctx: acquire context for this atomic modeset state update + */ +struct drm_atomic_state { + struct drm_device *dev; + bool allow_modeset : 1; + bool legacy_cursor_update : 1; + bool legacy_set_config : 1; + struct __drm_planes_state *planes; + struct __drm_crtcs_state *crtcs; + int num_connector; + struct __drm_connnectors_state *connectors; + + struct drm_modeset_acquire_ctx *acquire_ctx; + + /** + * @commit_work: + * + * Work item which can be used by the driver or helpers to execute the + * commit without blocking. + */ + struct work_struct commit_work; +}; + void drm_crtc_commit_put(struct drm_crtc_commit *commit); static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit) { diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index d86ae5dcd7b4..7ff92b09fd9c 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -29,6 +29,8 @@ #define DRM_ATOMIC_HELPER_H_ #include <drm/drm_crtc.h> +#include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_modeset_helper.h> struct drm_atomic_state; @@ -43,8 +45,9 @@ int drm_atomic_helper_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock); -void drm_atomic_helper_wait_for_fences(struct drm_device *dev, - struct drm_atomic_state *state); +int drm_atomic_helper_wait_for_fences(struct drm_device *dev, + struct drm_atomic_state *state, + bool pre_swap); bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev, struct drm_atomic_state *old_state, struct drm_crtc *crtc); @@ -63,14 +66,19 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, int drm_atomic_helper_prepare_planes(struct drm_device *dev, struct drm_atomic_state *state); + +#define DRM_PLANE_COMMIT_ACTIVE_ONLY BIT(0) +#define DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET BIT(1) + void drm_atomic_helper_commit_planes(struct drm_device *dev, struct drm_atomic_state *state, - bool active_only); + uint32_t flags); void drm_atomic_helper_cleanup_planes(struct drm_device *dev, struct drm_atomic_state *old_state); void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state); -void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc, - bool atomic); +void +drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state, + bool atomic); void drm_atomic_helper_swap_state(struct drm_atomic_state *state, bool stall); diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h new file mode 100644 index 000000000000..36baa175de99 --- /dev/null +++ b/include/drm/drm_blend.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_BLEND_H__ +#define __DRM_BLEND_H__ + +#include <linux/list.h> +#include <linux/ctype.h> + +struct drm_device; +struct drm_atomic_state; + +/* + * Rotation property bits. DRM_ROTATE_<degrees> rotates the image by the + * specified amount in degrees in counter clockwise direction. DRM_REFLECT_X and + * DRM_REFLECT_Y reflects the image along the specified axis prior to rotation + * + * WARNING: These defines are UABI since they're exposed in the rotation + * property. + */ +#define DRM_ROTATE_0 BIT(0) +#define DRM_ROTATE_90 BIT(1) +#define DRM_ROTATE_180 BIT(2) +#define DRM_ROTATE_270 BIT(3) +#define DRM_ROTATE_MASK (DRM_ROTATE_0 | DRM_ROTATE_90 | \ + DRM_ROTATE_180 | DRM_ROTATE_270) +#define DRM_REFLECT_X BIT(4) +#define DRM_REFLECT_Y BIT(5) +#define DRM_REFLECT_MASK (DRM_REFLECT_X | DRM_REFLECT_Y) + +struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, + unsigned int supported_rotations); +unsigned int drm_rotation_simplify(unsigned int rotation, + unsigned int supported_rotations); + +int drm_plane_create_zpos_property(struct drm_plane *plane, + unsigned int zpos, + unsigned int min, unsigned int max); +int drm_plane_create_zpos_immutable_property(struct drm_plane *plane, + unsigned int zpos); +int drm_atomic_normalize_zpos(struct drm_device *dev, + struct drm_atomic_state *state); +#endif diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h new file mode 100644 index 000000000000..530a1d6e8cde --- /dev/null +++ b/include/drm/drm_bridge.h @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_BRIDGE_H__ +#define __DRM_BRIDGE_H__ + +#include <linux/list.h> +#include <linux/ctype.h> +#include <drm/drm_mode_object.h> +#include <drm/drm_modes.h> + +struct drm_bridge; + +/** + * struct drm_bridge_funcs - drm_bridge control functions + */ +struct drm_bridge_funcs { + /** + * @attach: + * + * This callback is invoked whenever our bridge is being attached to a + * &drm_encoder. + * + * The attach callback is optional. + * + * RETURNS: + * + * Zero on success, error code on failure. + */ + int (*attach)(struct drm_bridge *bridge); + + /** + * @detach: + * + * This callback is invoked whenever our bridge is being detached from a + * &drm_encoder. + * + * The detach callback is optional. + */ + void (*detach)(struct drm_bridge *bridge); + + /** + * @mode_fixup: + * + * This callback is used to validate and adjust a mode. The paramater + * mode is the display mode that should be fed to the next element in + * the display chain, either the final &drm_connector or the next + * &drm_bridge. The parameter adjusted_mode is the input mode the bridge + * requires. It can be modified by this callback and does not need to + * match mode. + * + * This is the only hook that allows a bridge to reject a modeset. If + * this function passes all other callbacks must succeed for this + * configuration. + * + * The mode_fixup callback is optional. + * + * NOTE: + * + * This function is called in the check phase of atomic modesets, which + * can be aborted for any reason (including on userspace's request to + * just check whether a configuration would be possible). Drivers MUST + * NOT touch any persistent state (hardware or software) or data + * structures except the passed in @state parameter. + * + * RETURNS: + * + * True if an acceptable configuration is possible, false if the modeset + * operation should be rejected. + */ + bool (*mode_fixup)(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + /** + * @disable: + * + * This callback should disable the bridge. It is called right before + * the preceding element in the display pipe is disabled. If the + * preceding element is a bridge this means it's called before that + * bridge's ->disable() function. If the preceding element is a + * &drm_encoder it's called right before the encoder's ->disable(), + * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * + * The bridge can assume that the display pipe (i.e. clocks and timing + * signals) feeding it is still running when this callback is called. + * + * The disable callback is optional. + */ + void (*disable)(struct drm_bridge *bridge); + + /** + * @post_disable: + * + * This callback should disable the bridge. It is called right after + * the preceding element in the display pipe is disabled. If the + * preceding element is a bridge this means it's called after that + * bridge's ->post_disable() function. If the preceding element is a + * &drm_encoder it's called right after the encoder's ->disable(), + * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * + * The bridge must assume that the display pipe (i.e. clocks and timing + * singals) feeding it is no longer running when this callback is + * called. + * + * The post_disable callback is optional. + */ + void (*post_disable)(struct drm_bridge *bridge); + + /** + * @mode_set: + * + * This callback should set the given mode on the bridge. It is called + * after the ->mode_set() callback for the preceding element in the + * display pipeline has been called already. The display pipe (i.e. + * clocks and timing signals) is off when this function is called. + */ + void (*mode_set)(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + /** + * @pre_enable: + * + * This callback should enable the bridge. It is called right before + * the preceding element in the display pipe is enabled. If the + * preceding element is a bridge this means it's called before that + * bridge's ->pre_enable() function. If the preceding element is a + * &drm_encoder it's called right before the encoder's ->enable(), + * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * + * The display pipe (i.e. clocks and timing signals) feeding this bridge + * will not yet be running when this callback is called. The bridge must + * not enable the display link feeding the next bridge in the chain (if + * there is one) when this callback is called. + * + * The pre_enable callback is optional. + */ + void (*pre_enable)(struct drm_bridge *bridge); + + /** + * @enable: + * + * This callback should enable the bridge. It is called right after + * the preceding element in the display pipe is enabled. If the + * preceding element is a bridge this means it's called after that + * bridge's ->enable() function. If the preceding element is a + * &drm_encoder it's called right after the encoder's ->enable(), + * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * + * The bridge can assume that the display pipe (i.e. clocks and timing + * signals) feeding it is running when this callback is called. This + * callback must enable the display link feeding the next bridge in the + * chain if there is one. + * + * The enable callback is optional. + */ + void (*enable)(struct drm_bridge *bridge); +}; + +/** + * struct drm_bridge - central DRM bridge control structure + * @dev: DRM device this bridge belongs to + * @encoder: encoder to which this bridge is connected + * @next: the next bridge in the encoder chain + * @of_node: device node pointer to the bridge + * @list: to keep track of all added bridges + * @funcs: control functions + * @driver_private: pointer to the bridge driver's internal context + */ +struct drm_bridge { + struct drm_device *dev; + struct drm_encoder *encoder; + struct drm_bridge *next; +#ifdef CONFIG_OF + struct device_node *of_node; +#endif + struct list_head list; + + const struct drm_bridge_funcs *funcs; + void *driver_private; +}; + +int drm_bridge_add(struct drm_bridge *bridge); +void drm_bridge_remove(struct drm_bridge *bridge); +struct drm_bridge *of_drm_find_bridge(struct device_node *np); +int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge); +void drm_bridge_detach(struct drm_bridge *bridge); + +bool drm_bridge_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +void drm_bridge_disable(struct drm_bridge *bridge); +void drm_bridge_post_disable(struct drm_bridge *bridge); +void drm_bridge_mode_set(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +void drm_bridge_pre_enable(struct drm_bridge *bridge); +void drm_bridge_enable(struct drm_bridge *bridge); + +#endif diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h new file mode 100644 index 000000000000..c767238ac9d5 --- /dev/null +++ b/include/drm/drm_color_mgmt.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_COLOR_MGMT_H__ +#define __DRM_COLOR_MGMT_H__ + +#include <linux/ctype.h> + +void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, + uint degamma_lut_size, + bool has_ctm, + uint gamma_lut_size); + +int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, + int gamma_size); + +/** + * drm_color_lut_extract - clamp&round LUT entries + * @user_input: input value + * @bit_precision: number of bits the hw LUT supports + * + * Extract a degamma/gamma LUT value provided by user (in the form of + * &drm_color_lut entries) and round it to the precision supported by the + * hardware. + */ +static inline uint32_t drm_color_lut_extract(uint32_t user_input, + uint32_t bit_precision) +{ + uint32_t val = user_input; + uint32_t max = 0xffff >> (16 - bit_precision); + + /* Round only if we're not using full precision. */ + if (bit_precision < 16) { + val += 1UL << (16 - bit_precision - 1); + val >>= 16 - bit_precision; + } + + return clamp_val(val, 0, max); +} + + +#endif diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h new file mode 100644 index 000000000000..ac9d7d8e0e43 --- /dev/null +++ b/include/drm/drm_connector.h @@ -0,0 +1,778 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_CONNECTOR_H__ +#define __DRM_CONNECTOR_H__ + +#include <linux/list.h> +#include <linux/ctype.h> +#include <drm/drm_mode_object.h> + +#include <uapi/drm/drm_mode.h> + +struct drm_device; + +struct drm_connector_helper_funcs; +struct drm_device; +struct drm_crtc; +struct drm_encoder; +struct drm_property; +struct drm_property_blob; +struct edid; + +enum drm_connector_force { + DRM_FORCE_UNSPECIFIED, + DRM_FORCE_OFF, + DRM_FORCE_ON, /* force on analog part normally */ + DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */ +}; + +/** + * enum drm_connector_status - status for a &drm_connector + * + * This enum is used to track the connector status. There are no separate + * #defines for the uapi! + */ +enum drm_connector_status { + /** + * @connector_status_connected: The connector is definitely connected to + * a sink device, and can be enabled. + */ + connector_status_connected = 1, + /** + * @connector_status_disconnected: The connector isn't connected to a + * sink device which can be autodetect. For digital outputs like DP or + * HDMI (which can be realiable probed) this means there's really + * nothing there. It is driver-dependent whether a connector with this + * status can be lit up or not. + */ + connector_status_disconnected = 2, + /** + * @connector_status_unknown: The connector's status could not be + * reliably detected. This happens when probing would either cause + * flicker (like load-detection when the connector is in use), or when a + * hardware resource isn't available (like when load-detection needs a + * free CRTC). It should be possible to light up the connector with one + * of the listed fallback modes. For default configuration userspace + * should only try to light up connectors with unknown status when + * there's not connector with @connector_status_connected. + */ + connector_status_unknown = 3, +}; + +enum subpixel_order { + SubPixelUnknown = 0, + SubPixelHorizontalRGB, + SubPixelHorizontalBGR, + SubPixelVerticalRGB, + SubPixelVerticalBGR, + SubPixelNone, +}; + +/** + * struct drm_display_info - runtime data about the connected sink + * + * Describes a given display (e.g. CRT or flat panel) and its limitations. For + * fixed display sinks like built-in panels there's not much difference between + * this and struct &drm_connector. But for sinks with a real cable this + * structure is meant to describe all the things at the other end of the cable. + * + * For sinks which provide an EDID this can be filled out by calling + * drm_add_edid_modes(). + */ +struct drm_display_info { + /** + * @name: Name of the display. + */ + char name[DRM_DISPLAY_INFO_LEN]; + + /** + * @width_mm: Physical width in mm. + */ + unsigned int width_mm; + /** + * @height_mm: Physical height in mm. + */ + unsigned int height_mm; + + /** + * @pixel_clock: Maximum pixel clock supported by the sink, in units of + * 100Hz. This mismatches the clok in &drm_display_mode (which is in + * kHZ), because that's what the EDID uses as base unit. + */ + unsigned int pixel_clock; + /** + * @bpc: Maximum bits per color channel. Used by HDMI and DP outputs. + */ + unsigned int bpc; + + /** + * @subpixel_order: Subpixel order of LCD panels. + */ + enum subpixel_order subpixel_order; + +#define DRM_COLOR_FORMAT_RGB444 (1<<0) +#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) +#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) + + /** + * @color_formats: HDMI Color formats, selects between RGB and YCrCb + * modes. Used DRM_COLOR_FORMAT\_ defines, which are _not_ the same ones + * as used to describe the pixel format in framebuffers, and also don't + * match the formats in @bus_formats which are shared with v4l. + */ + u32 color_formats; + + /** + * @bus_formats: Pixel data format on the wire, somewhat redundant with + * @color_formats. Array of size @num_bus_formats encoded using + * MEDIA_BUS_FMT\_ defines shared with v4l and media drivers. + */ + const u32 *bus_formats; + /** + * @num_bus_formats: Size of @bus_formats array. + */ + unsigned int num_bus_formats; + +#define DRM_BUS_FLAG_DE_LOW (1<<0) +#define DRM_BUS_FLAG_DE_HIGH (1<<1) +/* drive data on pos. edge */ +#define DRM_BUS_FLAG_PIXDATA_POSEDGE (1<<2) +/* drive data on neg. edge */ +#define DRM_BUS_FLAG_PIXDATA_NEGEDGE (1<<3) + + /** + * @bus_flags: Additional information (like pixel signal polarity) for + * the pixel data on the bus, using DRM_BUS_FLAGS\_ defines. + */ + u32 bus_flags; + + /** + * @max_tmds_clock: Maximum TMDS clock rate supported by the + * sink in kHz. 0 means undefined. + */ + int max_tmds_clock; + + /** + * @dvi_dual: Dual-link DVI sink? + */ + bool dvi_dual; + + /** + * @edid_hdmi_dc_modes: Mask of supported hdmi deep color modes. Even + * more stuff redundant with @bus_formats. + */ + u8 edid_hdmi_dc_modes; + + /** + * @cea_rev: CEA revision of the HDMI sink. + */ + u8 cea_rev; +}; + +int drm_display_info_set_bus_formats(struct drm_display_info *info, + const u32 *formats, + unsigned int num_formats); + +/** + * struct drm_connector_state - mutable connector state + * @connector: backpointer to the connector + * @best_encoder: can be used by helpers and drivers to select the encoder + * @state: backpointer to global drm_atomic_state + */ +struct drm_connector_state { + struct drm_connector *connector; + + /** + * @crtc: CRTC to connect connector to, NULL if disabled. + * + * Do not change this directly, use drm_atomic_set_crtc_for_connector() + * instead. + */ + struct drm_crtc *crtc; + + struct drm_encoder *best_encoder; + + struct drm_atomic_state *state; +}; + +/** + * struct drm_connector_funcs - control connectors on a given device + * + * Each CRTC may have one or more connectors attached to it. The functions + * below allow the core DRM code to control connectors, enumerate available modes, + * etc. + */ +struct drm_connector_funcs { + /** + * @dpms: + * + * Legacy entry point to set the per-connector DPMS state. Legacy DPMS + * is exposed as a standard property on the connector, but diverted to + * this callback in the drm core. Note that atomic drivers don't + * implement the 4 level DPMS support on the connector any more, but + * instead only have an on/off "ACTIVE" property on the CRTC object. + * + * Drivers implementing atomic modeset should use + * drm_atomic_helper_connector_dpms() to implement this hook. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ + int (*dpms)(struct drm_connector *connector, int mode); + + /** + * @reset: + * + * Reset connector hardware and software state to off. This function isn't + * called by the core directly, only through drm_mode_config_reset(). + * It's not a helper hook only for historical reasons. + * + * Atomic drivers can use drm_atomic_helper_connector_reset() to reset + * atomic state using this hook. + */ + void (*reset)(struct drm_connector *connector); + + /** + * @detect: + * + * Check to see if anything is attached to the connector. The parameter + * force is set to false whilst polling, true when checking the + * connector due to a user request. force can be used by the driver to + * avoid expensive, destructive operations during automated probing. + * + * FIXME: + * + * Note that this hook is only called by the probe helper. It's not in + * the helper library vtable purely for historical reasons. The only DRM + * core entry point to probe connector state is @fill_modes. + * + * RETURNS: + * + * drm_connector_status indicating the connector's status. + */ + enum drm_connector_status (*detect)(struct drm_connector *connector, + bool force); + + /** + * @force: + * + * This function is called to update internal encoder state when the + * connector is forced to a certain state by userspace, either through + * the sysfs interfaces or on the kernel cmdline. In that case the + * @detect callback isn't called. + * + * FIXME: + * + * Note that this hook is only called by the probe helper. It's not in + * the helper library vtable purely for historical reasons. The only DRM + * core entry point to probe connector state is @fill_modes. + */ + void (*force)(struct drm_connector *connector); + + /** + * @fill_modes: + * + * Entry point for output detection and basic mode validation. The + * driver should reprobe the output if needed (e.g. when hotplug + * handling is unreliable), add all detected modes to connector->modes + * and filter out any the device can't support in any configuration. It + * also needs to filter out any modes wider or higher than the + * parameters max_width and max_height indicate. + * + * The drivers must also prune any modes no longer valid from + * connector->modes. Furthermore it must update connector->status and + * connector->edid. If no EDID has been received for this output + * connector->edid must be NULL. + * + * Drivers using the probe helpers should use + * drm_helper_probe_single_connector_modes() or + * drm_helper_probe_single_connector_modes_nomerge() to implement this + * function. + * + * RETURNS: + * + * The number of modes detected and filled into connector->modes. + */ + int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); + + /** + * @set_property: + * + * This is the legacy entry point to update a property attached to the + * connector. + * + * Drivers implementing atomic modeset should use + * drm_atomic_helper_connector_set_property() to implement this hook. + * + * This callback is optional if the driver does not support any legacy + * driver-private properties. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ + int (*set_property)(struct drm_connector *connector, struct drm_property *property, + uint64_t val); + + /** + * @late_register: + * + * This optional hook can be used to register additional userspace + * interfaces attached to the connector, light backlight control, i2c, + * DP aux or similar interfaces. It is called late in the driver load + * sequence from drm_connector_register() when registering all the + * core drm connector interfaces. Everything added from this callback + * should be unregistered in the early_unregister callback. + * + * Returns: + * + * 0 on success, or a negative error code on failure. + */ + int (*late_register)(struct drm_connector *connector); + + /** + * @early_unregister: + * + * This optional hook should be used to unregister the additional + * userspace interfaces attached to the connector from + * late_register(). It is called from drm_connector_unregister(), + * early in the driver unload sequence to disable userspace access + * before data structures are torndown. + */ + void (*early_unregister)(struct drm_connector *connector); + + /** + * @destroy: + * + * Clean up connector resources. This is called at driver unload time + * through drm_mode_config_cleanup(). It can also be called at runtime + * when a connector is being hot-unplugged for drivers that support + * connector hotplugging (e.g. DisplayPort MST). + */ + void (*destroy)(struct drm_connector *connector); + + /** + * @atomic_duplicate_state: + * + * Duplicate the current atomic state for this connector and return it. + * The core and helpers guarantee that any atomic state duplicated with + * this hook and still owned by the caller (i.e. not transferred to the + * driver by calling ->atomic_commit() from struct + * &drm_mode_config_funcs) will be cleaned up by calling the + * @atomic_destroy_state hook in this structure. + * + * Atomic drivers which don't subclass struct &drm_connector_state should use + * drm_atomic_helper_connector_duplicate_state(). Drivers that subclass the + * state structure to extend it with driver-private state should use + * __drm_atomic_helper_connector_duplicate_state() to make sure shared state is + * duplicated in a consistent fashion across drivers. + * + * It is an error to call this hook before connector->state has been + * initialized correctly. + * + * NOTE: + * + * If the duplicate state references refcounted resources this hook must + * acquire a reference for each of them. The driver must release these + * references again in @atomic_destroy_state. + * + * RETURNS: + * + * Duplicated atomic state or NULL when the allocation failed. + */ + struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector); + + /** + * @atomic_destroy_state: + * + * Destroy a state duplicated with @atomic_duplicate_state and release + * or unreference all resources it references + */ + void (*atomic_destroy_state)(struct drm_connector *connector, + struct drm_connector_state *state); + + /** + * @atomic_set_property: + * + * Decode a driver-private property value and store the decoded value + * into the passed-in state structure. Since the atomic core decodes all + * standardized properties (even for extensions beyond the core set of + * properties which might not be implemented by all drivers) this + * requires drivers to subclass the state structure. + * + * Such driver-private properties should really only be implemented for + * truly hardware/vendor specific state. Instead it is preferred to + * standardize atomic extension and decode the properties used to expose + * such an extension in the core. + * + * Do not call this function directly, use + * drm_atomic_connector_set_property() instead. + * + * This callback is optional if the driver does not support any + * driver-private atomic properties. + * + * NOTE: + * + * This function is called in the state assembly phase of atomic + * modesets, which can be aborted for any reason (including on + * userspace's request to just check whether a configuration would be + * possible). Drivers MUST NOT touch any persistent state (hardware or + * software) or data structures except the passed in @state parameter. + * + * Also since userspace controls in which order properties are set this + * function must not do any input validation (since the state update is + * incomplete and hence likely inconsistent). Instead any such input + * validation must be done in the various atomic_check callbacks. + * + * RETURNS: + * + * 0 if the property has been found, -EINVAL if the property isn't + * implemented by the driver (which shouldn't ever happen, the core only + * asks for properties attached to this connector). No other validation + * is allowed by the driver. The core already checks that the property + * value is within the range (integer, valid enum value, ...) the driver + * set when registering the property. + */ + int (*atomic_set_property)(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val); + + /** + * @atomic_get_property: + * + * Reads out the decoded driver-private property. This is used to + * implement the GETCONNECTOR IOCTL. + * + * Do not call this function directly, use + * drm_atomic_connector_get_property() instead. + * + * This callback is optional if the driver does not support any + * driver-private atomic properties. + * + * RETURNS: + * + * 0 on success, -EINVAL if the property isn't implemented by the + * driver (which shouldn't ever happen, the core only asks for + * properties attached to this connector). + */ + int (*atomic_get_property)(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val); +}; + +/* mode specified on the command line */ +struct drm_cmdline_mode { + bool specified; + bool refresh_specified; + bool bpp_specified; + int xres, yres; + int bpp; + int refresh; + bool rb; + bool interlace; + bool cvt; + bool margins; + enum drm_connector_force force; +}; + +/** + * struct drm_connector - central DRM connector control structure + * @dev: parent DRM device + * @kdev: kernel device for sysfs attributes + * @attr: sysfs attributes + * @head: list management + * @base: base KMS object + * @name: human readable name, can be overwritten by the driver + * @connector_type: one of the DRM_MODE_CONNECTOR_<foo> types from drm_mode.h + * @connector_type_id: index into connector type enum + * @interlace_allowed: can this connector handle interlaced modes? + * @doublescan_allowed: can this connector handle doublescan? + * @stereo_allowed: can this connector handle stereo modes? + * @registered: is this connector exposed (registered) with userspace? + * @modes: modes available on this connector (from fill_modes() + user) + * @status: one of the drm_connector_status enums (connected, not, or unknown) + * @probed_modes: list of modes derived directly from the display + * @funcs: connector control functions + * @edid_blob_ptr: DRM property containing EDID if present + * @properties: property tracking for this connector + * @dpms: current dpms state + * @helper_private: mid-layer private data + * @cmdline_mode: mode line parsed from the kernel cmdline for this connector + * @force: a DRM_FORCE_<foo> state for forced mode sets + * @override_edid: has the EDID been overwritten through debugfs for testing? + * @encoder_ids: valid encoders for this connector + * @encoder: encoder driving this connector, if any + * @eld: EDID-like data, if present + * @latency_present: AV delay info from ELD, if found + * @video_latency: video latency info from ELD, if found + * @audio_latency: audio latency info from ELD, if found + * @null_edid_counter: track sinks that give us all zeros for the EDID + * @bad_edid_counter: track sinks that give us an EDID with invalid checksum + * @edid_corrupt: indicates whether the last read EDID was corrupt + * @debugfs_entry: debugfs directory for this connector + * @state: current atomic state for this connector + * @has_tile: is this connector connected to a tiled monitor + * @tile_group: tile group for the connected monitor + * @tile_is_single_monitor: whether the tile is one monitor housing + * @num_h_tile: number of horizontal tiles in the tile group + * @num_v_tile: number of vertical tiles in the tile group + * @tile_h_loc: horizontal location of this tile + * @tile_v_loc: vertical location of this tile + * @tile_h_size: horizontal size of this tile. + * @tile_v_size: vertical size of this tile. + * + * Each connector may be connected to one or more CRTCs, or may be clonable by + * another connector if they can share a CRTC. Each connector also has a specific + * position in the broader display (referred to as a 'screen' though it could + * span multiple monitors). + */ +struct drm_connector { + struct drm_device *dev; + struct device *kdev; + struct device_attribute *attr; + struct list_head head; + + struct drm_mode_object base; + + char *name; + + /** + * @index: Compacted connector index, which matches the position inside + * the mode_config.list for drivers not supporting hot-add/removing. Can + * be used as an array index. It is invariant over the lifetime of the + * connector. + */ + unsigned index; + + int connector_type; + int connector_type_id; + bool interlace_allowed; + bool doublescan_allowed; + bool stereo_allowed; + bool registered; + struct list_head modes; /* list of modes on this connector */ + + enum drm_connector_status status; + + /* these are modes added by probing with DDC or the BIOS */ + struct list_head probed_modes; + + /** + * @display_info: Display information is filled from EDID information + * when a display is detected. For non hot-pluggable displays such as + * flat panels in embedded systems, the driver should initialize the + * display_info.width_mm and display_info.height_mm fields with the + * physical size of the display. + */ + struct drm_display_info display_info; + const struct drm_connector_funcs *funcs; + + struct drm_property_blob *edid_blob_ptr; + struct drm_object_properties properties; + + /** + * @path_blob_ptr: + * + * DRM blob property data for the DP MST path property. + */ + struct drm_property_blob *path_blob_ptr; + + /** + * @tile_blob_ptr: + * + * DRM blob property data for the tile property (used mostly by DP MST). + * This is meant for screens which are driven through separate display + * pipelines represented by &drm_crtc, which might not be running with + * genlocked clocks. For tiled panels which are genlocked, like + * dual-link LVDS or dual-link DSI, the driver should try to not expose + * the tiling and virtualize both &drm_crtc and &drm_plane if needed. + */ + struct drm_property_blob *tile_blob_ptr; + +/* should we poll this connector for connects and disconnects */ +/* hot plug detectable */ +#define DRM_CONNECTOR_POLL_HPD (1 << 0) +/* poll for connections */ +#define DRM_CONNECTOR_POLL_CONNECT (1 << 1) +/* can cleanly poll for disconnections without flickering the screen */ +/* DACs should rarely do this without a lot of testing */ +#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2) + + /** + * @polled: + * + * Connector polling mode, a combination of + * + * DRM_CONNECTOR_POLL_HPD + * The connector generates hotplug events and doesn't need to be + * periodically polled. The CONNECT and DISCONNECT flags must not + * be set together with the HPD flag. + * + * DRM_CONNECTOR_POLL_CONNECT + * Periodically poll the connector for connection. + * + * DRM_CONNECTOR_POLL_DISCONNECT + * Periodically poll the connector for disconnection. + * + * Set to 0 for connectors that don't support connection status + * discovery. + */ + uint8_t polled; + + /* requested DPMS state */ + int dpms; + + const struct drm_connector_helper_funcs *helper_private; + + /* forced on connector */ + struct drm_cmdline_mode cmdline_mode; + enum drm_connector_force force; + bool override_edid; + +#define DRM_CONNECTOR_MAX_ENCODER 3 + uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; + struct drm_encoder *encoder; /* currently active encoder */ + +#define MAX_ELD_BYTES 128 + /* EDID bits */ + uint8_t eld[MAX_ELD_BYTES]; + bool latency_present[2]; + int video_latency[2]; /* [0]: progressive, [1]: interlaced */ + int audio_latency[2]; + int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */ + unsigned bad_edid_counter; + + /* Flag for raw EDID header corruption - used in Displayport + * compliance testing - * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6 + */ + bool edid_corrupt; + + struct dentry *debugfs_entry; + + struct drm_connector_state *state; + + /* DisplayID bits */ + bool has_tile; + struct drm_tile_group *tile_group; + bool tile_is_single_monitor; + + uint8_t num_h_tile, num_v_tile; + uint8_t tile_h_loc, tile_v_loc; + uint16_t tile_h_size, tile_v_size; +}; + +#define obj_to_connector(x) container_of(x, struct drm_connector, base) + +int drm_connector_init(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type); +int drm_connector_register(struct drm_connector *connector); +void drm_connector_unregister(struct drm_connector *connector); +int drm_mode_connector_attach_encoder(struct drm_connector *connector, + struct drm_encoder *encoder); + +void drm_connector_cleanup(struct drm_connector *connector); +static inline unsigned drm_connector_index(struct drm_connector *connector) +{ + return connector->index; +} + +/** + * drm_connector_lookup - lookup connector object + * @dev: DRM device + * @id: connector object id + * + * This function looks up the connector object specified by id + * add takes a reference to it. + */ +static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev, + uint32_t id) +{ + struct drm_mode_object *mo; + mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR); + return mo ? obj_to_connector(mo) : NULL; +} + +/** + * drm_connector_reference - incr the connector refcnt + * @connector: connector + * + * This function increments the connector's refcount. + */ +static inline void drm_connector_reference(struct drm_connector *connector) +{ + drm_mode_object_reference(&connector->base); +} + +/** + * drm_connector_unreference - unref a connector + * @connector: connector to unref + * + * This function decrements the connector's refcount and frees it if it drops to zero. + */ +static inline void drm_connector_unreference(struct drm_connector *connector) +{ + drm_mode_object_unreference(&connector->base); +} + +const char *drm_get_connector_status_name(enum drm_connector_status status); +const char *drm_get_subpixel_order_name(enum subpixel_order order); +const char *drm_get_dpms_name(int val); +const char *drm_get_dvi_i_subconnector_name(int val); +const char *drm_get_dvi_i_select_name(int val); +const char *drm_get_tv_subconnector_name(int val); +const char *drm_get_tv_select_name(int val); + +int drm_mode_create_dvi_i_properties(struct drm_device *dev); +int drm_mode_create_tv_properties(struct drm_device *dev, + unsigned int num_modes, + const char * const modes[]); +int drm_mode_create_scaling_mode_property(struct drm_device *dev); +int drm_mode_create_aspect_ratio_property(struct drm_device *dev); +int drm_mode_create_suggested_offset_properties(struct drm_device *dev); + +int drm_mode_connector_set_path_property(struct drm_connector *connector, + const char *path); +int drm_mode_connector_set_tile_property(struct drm_connector *connector); +int drm_mode_connector_update_edid_property(struct drm_connector *connector, + const struct edid *edid); + +/** + * drm_for_each_connector - iterate over all connectors + * @connector: the loop cursor + * @dev: the DRM device + * + * Iterate over all connectors of @dev. + */ +#define drm_for_each_connector(connector, dev) \ + for (assert_drm_connector_list_read_locked(&(dev)->mode_config), \ + connector = list_first_entry(&(dev)->mode_config.connector_list, \ + struct drm_connector, head); \ + &connector->head != (&(dev)->mode_config.connector_list); \ + connector = list_next_entry(connector, head)) + +#endif diff --git a/include/drm/drm_core.h b/include/drm/drm_core.h deleted file mode 100644 index 4e7523863a4b..000000000000 --- a/include/drm/drm_core.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2004 Jon Smirl <jonsmirl@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#define CORE_AUTHOR "Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl" - -#define CORE_NAME "drm" -#define CORE_DESC "DRM shared core routines" -#define CORE_DATE "20060810" - -#define DRM_IF_MAJOR 1 -#define DRM_IF_MINOR 4 - -#define CORE_MAJOR 1 -#define CORE_MINOR 1 -#define CORE_PATCHLEVEL 0 diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 44e070800b6d..0aa292526567 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -35,40 +35,27 @@ #include <uapi/drm/drm_mode.h> #include <uapi/drm/drm_fourcc.h> #include <drm/drm_modeset_lock.h> +#include <drm/drm_rect.h> +#include <drm/drm_mode_object.h> +#include <drm/drm_framebuffer.h> +#include <drm/drm_modes.h> +#include <drm/drm_connector.h> +#include <drm/drm_encoder.h> +#include <drm/drm_property.h> +#include <drm/drm_bridge.h> +#include <drm/drm_edid.h> +#include <drm/drm_plane.h> +#include <drm/drm_blend.h> +#include <drm/drm_color_mgmt.h> struct drm_device; struct drm_mode_set; -struct drm_framebuffer; -struct drm_object_properties; struct drm_file; struct drm_clip_rect; struct device_node; struct fence; struct edid; -struct drm_mode_object { - uint32_t id; - uint32_t type; - struct drm_object_properties *properties; - struct kref refcount; - void (*free_cb)(struct kref *kref); -}; - -#define DRM_OBJECT_MAX_PROPERTY 24 -struct drm_object_properties { - int count, atomic_count; - /* NOTE: if we ever start dynamically destroying properties (ie. - * not at drm_mode_config_cleanup() time), then we'd have to do - * a better job of detaching property from mode objects to avoid - * dangling property pointers: - */ - struct drm_property *properties[DRM_OBJECT_MAX_PROPERTY]; - /* do not read/write values directly, but use drm_object_property_get_value() - * and drm_object_property_set_value(): - */ - uint64_t values[DRM_OBJECT_MAX_PROPERTY]; -}; - static inline int64_t U642I64(uint64_t val) { return (int64_t)*((int64_t *)&val); @@ -78,84 +65,6 @@ static inline uint64_t I642U64(int64_t val) return (uint64_t)*((uint64_t *)&val); } -/* - * Rotation property bits. DRM_ROTATE_<degrees> rotates the image by the - * specified amount in degrees in counter clockwise direction. DRM_REFLECT_X and - * DRM_REFLECT_Y reflects the image along the specified axis prior to rotation - */ -#define DRM_ROTATE_MASK 0x0f -#define DRM_ROTATE_0 0 -#define DRM_ROTATE_90 1 -#define DRM_ROTATE_180 2 -#define DRM_ROTATE_270 3 -#define DRM_REFLECT_MASK (~DRM_ROTATE_MASK) -#define DRM_REFLECT_X 4 -#define DRM_REFLECT_Y 5 - -enum drm_connector_force { - DRM_FORCE_UNSPECIFIED, - DRM_FORCE_OFF, - DRM_FORCE_ON, /* force on analog part normally */ - DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */ -}; - -#include <drm/drm_modes.h> - -enum drm_connector_status { - connector_status_connected = 1, - connector_status_disconnected = 2, - connector_status_unknown = 3, -}; - -enum subpixel_order { - SubPixelUnknown = 0, - SubPixelHorizontalRGB, - SubPixelHorizontalBGR, - SubPixelVerticalRGB, - SubPixelVerticalBGR, - SubPixelNone, -}; - -#define DRM_COLOR_FORMAT_RGB444 (1<<0) -#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) -#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) - -#define DRM_BUS_FLAG_DE_LOW (1<<0) -#define DRM_BUS_FLAG_DE_HIGH (1<<1) -/* drive data on pos. edge */ -#define DRM_BUS_FLAG_PIXDATA_POSEDGE (1<<2) -/* drive data on neg. edge */ -#define DRM_BUS_FLAG_PIXDATA_NEGEDGE (1<<3) - -/* - * Describes a given display (e.g. CRT or flat panel) and its limitations. - */ -struct drm_display_info { - char name[DRM_DISPLAY_INFO_LEN]; - - /* Physical size */ - unsigned int width_mm; - unsigned int height_mm; - - /* Clock limits FIXME: storage format */ - unsigned int min_vfreq, max_vfreq; - unsigned int min_hfreq, max_hfreq; - unsigned int pixel_clock; - unsigned int bpc; - - enum subpixel_order subpixel_order; - u32 color_formats; - - const u32 *bus_formats; - unsigned int num_bus_formats; - u32 bus_flags; - - /* Mask of supported hdmi deep color modes */ - u8 edid_hdmi_dc_modes; - - u8 cea_rev; -}; - /* data corresponds to displayid vend/prod/serial */ struct drm_tile_group { struct kref refcount; @@ -164,130 +73,7 @@ struct drm_tile_group { u8 group_data[8]; }; -/** - * struct drm_framebuffer_funcs - framebuffer hooks - */ -struct drm_framebuffer_funcs { - /** - * @destroy: - * - * Clean up framebuffer resources, specifically also unreference the - * backing storage. The core guarantees to call this function for every - * framebuffer successfully created by ->fb_create() in - * &drm_mode_config_funcs. Drivers must also call - * drm_framebuffer_cleanup() to release DRM core resources for this - * framebuffer. - */ - void (*destroy)(struct drm_framebuffer *framebuffer); - - /** - * @create_handle: - * - * Create a buffer handle in the driver-specific buffer manager (either - * GEM or TTM) valid for the passed-in struct &drm_file. This is used by - * the core to implement the GETFB IOCTL, which returns (for - * sufficiently priviledged user) also a native buffer handle. This can - * be used for seamless transitions between modesetting clients by - * copying the current screen contents to a private buffer and blending - * between that and the new contents. - * - * GEM based drivers should call drm_gem_handle_create() to create the - * handle. - * - * RETURNS: - * - * 0 on success or a negative error code on failure. - */ - int (*create_handle)(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle); - /** - * @dirty: - * - * Optional callback for the dirty fb IOCTL. - * - * Userspace can notify the driver via this callback that an area of the - * framebuffer has changed and should be flushed to the display - * hardware. This can also be used internally, e.g. by the fbdev - * emulation, though that's not the case currently. - * - * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd - * for more information as all the semantics and arguments have a one to - * one mapping on this function. - * - * RETURNS: - * - * 0 on success or a negative error code on failure. - */ - int (*dirty)(struct drm_framebuffer *framebuffer, - struct drm_file *file_priv, unsigned flags, - unsigned color, struct drm_clip_rect *clips, - unsigned num_clips); -}; - -struct drm_framebuffer { - struct drm_device *dev; - /* - * Note that the fb is refcounted for the benefit of driver internals, - * for example some hw, disabling a CRTC/plane is asynchronous, and - * scanout does not actually complete until the next vblank. So some - * cleanup (like releasing the reference(s) on the backing GEM bo(s)) - * should be deferred. In cases like this, the driver would like to - * hold a ref to the fb even though it has already been removed from - * userspace perspective. - * The refcount is stored inside the mode object. - */ - /* - * Place on the dev->mode_config.fb_list, access protected by - * dev->mode_config.fb_lock. - */ - struct list_head head; - struct drm_mode_object base; - const struct drm_framebuffer_funcs *funcs; - unsigned int pitches[4]; - unsigned int offsets[4]; - uint64_t modifier[4]; - unsigned int width; - unsigned int height; - /* depth can be 15 or 16 */ - unsigned int depth; - int bits_per_pixel; - int flags; - uint32_t pixel_format; /* fourcc format */ - int hot_x; - int hot_y; - struct list_head filp_head; -}; - -struct drm_property_blob { - struct drm_mode_object base; - struct drm_device *dev; - struct list_head head_global; - struct list_head head_file; - size_t length; - unsigned char data[]; -}; - -struct drm_property_enum { - uint64_t value; - struct list_head head; - char name[DRM_PROP_NAME_LEN]; -}; - -struct drm_property { - struct list_head head; - struct drm_mode_object base; - uint32_t flags; - char name[DRM_PROP_NAME_LEN]; - uint32_t num_values; - uint64_t *values; - struct drm_device *dev; - - struct list_head enum_list; -}; - struct drm_crtc; -struct drm_connector; struct drm_encoder; struct drm_pending_vblank_event; struct drm_plane; @@ -296,7 +82,6 @@ struct drm_atomic_state; struct drm_crtc_helper_funcs; struct drm_encoder_helper_funcs; -struct drm_connector_helper_funcs; struct drm_plane_helper_funcs; /** @@ -324,8 +109,6 @@ struct drm_plane_helper_funcs; * @ctm: Transformation matrix * @gamma_lut: Lookup table for converting pixel data after the * conversion matrix - * @event: optional pointer to a DRM event to signal upon completion of the - * state update * @state: backpointer to global drm_atomic_state * * Note that the distinction between @enable and @active is rather subtile: @@ -374,6 +157,46 @@ struct drm_crtc_state { struct drm_property_blob *ctm; struct drm_property_blob *gamma_lut; + /** + * @event: + * + * Optional pointer to a DRM event to signal upon completion of the + * state update. The driver must send out the event when the atomic + * commit operation completes. There are two cases: + * + * - The event is for a CRTC which is being disabled through this + * atomic commit. In that case the event can be send out any time + * after the hardware has stopped scanning out the current + * framebuffers. It should contain the timestamp and counter for the + * last vblank before the display pipeline was shut off. + * + * - For a CRTC which is enabled at the end of the commit (even when it + * undergoes an full modeset) the vblank timestamp and counter must + * be for the vblank right before the first frame that scans out the + * new set of buffers. Again the event can only be sent out after the + * hardware has stopped scanning out the old buffers. + * + * - Events for disabled CRTCs are not allowed, and drivers can ignore + * that case. + * + * This can be handled by the drm_crtc_send_vblank_event() function, + * which the driver should call on the provided event upon completion of + * the atomic commit. Note that if the driver supports vblank signalling + * and timestamping the vblank counters and timestamps must agree with + * the ones returned from page flip events. With the current vblank + * helper infrastructure this can be achieved by holding a vblank + * reference while the page flip is pending, acquired through + * drm_crtc_vblank_get() and released with drm_crtc_vblank_put(). + * Drivers are free to implement their own vblank counter and timestamp + * tracking though, e.g. if they have accurate timestamp registers in + * hardware. + * + * For hardware which supports some means to synchronize vblank + * interrupt delivery with committing display state there's also + * drm_crtc_arm_vblank_event(). See the documentation of that function + * for a detailed discussion of the constraints it needs to be used + * safely. + */ struct drm_pending_vblank_event *event; struct drm_atomic_state *state; @@ -545,16 +368,6 @@ struct drm_crtc_funcs { * counter and timestamp tracking though, e.g. if they have accurate * timestamp registers in hardware. * - * FIXME: - * - * Up to that point drivers need to manage events themselves and can use - * even->base.list freely for that. Specifically they need to ensure - * that they don't send out page flip (or vblank) events for which the - * corresponding drm file has been closed already. The drm core - * unfortunately does not (yet) take care of that. Therefore drivers - * currently must clean up and release pending events in their - * ->preclose driver function. - * * This callback is optional. * * NOTE: @@ -581,6 +394,24 @@ struct drm_crtc_funcs { uint32_t flags); /** + * @page_flip_target: + * + * Same as @page_flip but with an additional parameter specifying the + * absolute target vertical blank period (as reported by + * drm_crtc_vblank_count()) when the flip should take effect. + * + * Note that the core code calls drm_crtc_vblank_get before this entry + * point, and will call drm_crtc_vblank_put if this entry point returns + * any non-0 error code. It's the driver's responsibility to call + * drm_crtc_vblank_put after this entry point returns 0, typically when + * the flip completes. + */ + int (*page_flip_target)(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t flags, uint32_t target); + + /** * @set_property: * * This is the legacy entry point to update a property attached to the @@ -852,1201 +683,6 @@ struct drm_crtc { }; /** - * struct drm_connector_state - mutable connector state - * @connector: backpointer to the connector - * @crtc: CRTC to connect connector to, NULL if disabled - * @best_encoder: can be used by helpers and drivers to select the encoder - * @state: backpointer to global drm_atomic_state - */ -struct drm_connector_state { - struct drm_connector *connector; - - struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_connector() */ - - struct drm_encoder *best_encoder; - - struct drm_atomic_state *state; -}; - -/** - * struct drm_connector_funcs - control connectors on a given device - * - * Each CRTC may have one or more connectors attached to it. The functions - * below allow the core DRM code to control connectors, enumerate available modes, - * etc. - */ -struct drm_connector_funcs { - /** - * @dpms: - * - * Legacy entry point to set the per-connector DPMS state. Legacy DPMS - * is exposed as a standard property on the connector, but diverted to - * this callback in the drm core. Note that atomic drivers don't - * implement the 4 level DPMS support on the connector any more, but - * instead only have an on/off "ACTIVE" property on the CRTC object. - * - * Drivers implementing atomic modeset should use - * drm_atomic_helper_connector_dpms() to implement this hook. - * - * RETURNS: - * - * 0 on success or a negative error code on failure. - */ - int (*dpms)(struct drm_connector *connector, int mode); - - /** - * @reset: - * - * Reset connector hardware and software state to off. This function isn't - * called by the core directly, only through drm_mode_config_reset(). - * It's not a helper hook only for historical reasons. - * - * Atomic drivers can use drm_atomic_helper_connector_reset() to reset - * atomic state using this hook. - */ - void (*reset)(struct drm_connector *connector); - - /** - * @detect: - * - * Check to see if anything is attached to the connector. The parameter - * force is set to false whilst polling, true when checking the - * connector due to a user request. force can be used by the driver to - * avoid expensive, destructive operations during automated probing. - * - * FIXME: - * - * Note that this hook is only called by the probe helper. It's not in - * the helper library vtable purely for historical reasons. The only DRM - * core entry point to probe connector state is @fill_modes. - * - * RETURNS: - * - * drm_connector_status indicating the connector's status. - */ - enum drm_connector_status (*detect)(struct drm_connector *connector, - bool force); - - /** - * @force: - * - * This function is called to update internal encoder state when the - * connector is forced to a certain state by userspace, either through - * the sysfs interfaces or on the kernel cmdline. In that case the - * @detect callback isn't called. - * - * FIXME: - * - * Note that this hook is only called by the probe helper. It's not in - * the helper library vtable purely for historical reasons. The only DRM - * core entry point to probe connector state is @fill_modes. - */ - void (*force)(struct drm_connector *connector); - - /** - * @fill_modes: - * - * Entry point for output detection and basic mode validation. The - * driver should reprobe the output if needed (e.g. when hotplug - * handling is unreliable), add all detected modes to connector->modes - * and filter out any the device can't support in any configuration. It - * also needs to filter out any modes wider or higher than the - * parameters max_width and max_height indicate. - * - * The drivers must also prune any modes no longer valid from - * connector->modes. Furthermore it must update connector->status and - * connector->edid. If no EDID has been received for this output - * connector->edid must be NULL. - * - * Drivers using the probe helpers should use - * drm_helper_probe_single_connector_modes() or - * drm_helper_probe_single_connector_modes_nomerge() to implement this - * function. - * - * RETURNS: - * - * The number of modes detected and filled into connector->modes. - */ - int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); - - /** - * @set_property: - * - * This is the legacy entry point to update a property attached to the - * connector. - * - * Drivers implementing atomic modeset should use - * drm_atomic_helper_connector_set_property() to implement this hook. - * - * This callback is optional if the driver does not support any legacy - * driver-private properties. - * - * RETURNS: - * - * 0 on success or a negative error code on failure. - */ - int (*set_property)(struct drm_connector *connector, struct drm_property *property, - uint64_t val); - - /** - * @late_register: - * - * This optional hook can be used to register additional userspace - * interfaces attached to the connector, light backlight control, i2c, - * DP aux or similar interfaces. It is called late in the driver load - * sequence from drm_connector_register() when registering all the - * core drm connector interfaces. Everything added from this callback - * should be unregistered in the early_unregister callback. - * - * Returns: - * - * 0 on success, or a negative error code on failure. - */ - int (*late_register)(struct drm_connector *connector); - - /** - * @early_unregister: - * - * This optional hook should be used to unregister the additional - * userspace interfaces attached to the connector from - * late_unregister(). It is called from drm_connector_unregister(), - * early in the driver unload sequence to disable userspace access - * before data structures are torndown. - */ - void (*early_unregister)(struct drm_connector *connector); - - /** - * @destroy: - * - * Clean up connector resources. This is called at driver unload time - * through drm_mode_config_cleanup(). It can also be called at runtime - * when a connector is being hot-unplugged for drivers that support - * connector hotplugging (e.g. DisplayPort MST). - */ - void (*destroy)(struct drm_connector *connector); - - /** - * @atomic_duplicate_state: - * - * Duplicate the current atomic state for this connector and return it. - * The core and helpers gurantee that any atomic state duplicated with - * this hook and still owned by the caller (i.e. not transferred to the - * driver by calling ->atomic_commit() from struct - * &drm_mode_config_funcs) will be cleaned up by calling the - * @atomic_destroy_state hook in this structure. - * - * Atomic drivers which don't subclass struct &drm_connector_state should use - * drm_atomic_helper_connector_duplicate_state(). Drivers that subclass the - * state structure to extend it with driver-private state should use - * __drm_atomic_helper_connector_duplicate_state() to make sure shared state is - * duplicated in a consistent fashion across drivers. - * - * It is an error to call this hook before connector->state has been - * initialized correctly. - * - * NOTE: - * - * If the duplicate state references refcounted resources this hook must - * acquire a reference for each of them. The driver must release these - * references again in @atomic_destroy_state. - * - * RETURNS: - * - * Duplicated atomic state or NULL when the allocation failed. - */ - struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector); - - /** - * @atomic_destroy_state: - * - * Destroy a state duplicated with @atomic_duplicate_state and release - * or unreference all resources it references - */ - void (*atomic_destroy_state)(struct drm_connector *connector, - struct drm_connector_state *state); - - /** - * @atomic_set_property: - * - * Decode a driver-private property value and store the decoded value - * into the passed-in state structure. Since the atomic core decodes all - * standardized properties (even for extensions beyond the core set of - * properties which might not be implemented by all drivers) this - * requires drivers to subclass the state structure. - * - * Such driver-private properties should really only be implemented for - * truly hardware/vendor specific state. Instead it is preferred to - * standardize atomic extension and decode the properties used to expose - * such an extension in the core. - * - * Do not call this function directly, use - * drm_atomic_connector_set_property() instead. - * - * This callback is optional if the driver does not support any - * driver-private atomic properties. - * - * NOTE: - * - * This function is called in the state assembly phase of atomic - * modesets, which can be aborted for any reason (including on - * userspace's request to just check whether a configuration would be - * possible). Drivers MUST NOT touch any persistent state (hardware or - * software) or data structures except the passed in @state parameter. - * - * Also since userspace controls in which order properties are set this - * function must not do any input validation (since the state update is - * incomplete and hence likely inconsistent). Instead any such input - * validation must be done in the various atomic_check callbacks. - * - * RETURNS: - * - * 0 if the property has been found, -EINVAL if the property isn't - * implemented by the driver (which shouldn't ever happen, the core only - * asks for properties attached to this connector). No other validation - * is allowed by the driver. The core already checks that the property - * value is within the range (integer, valid enum value, ...) the driver - * set when registering the property. - */ - int (*atomic_set_property)(struct drm_connector *connector, - struct drm_connector_state *state, - struct drm_property *property, - uint64_t val); - - /** - * @atomic_get_property: - * - * Reads out the decoded driver-private property. This is used to - * implement the GETCONNECTOR IOCTL. - * - * Do not call this function directly, use - * drm_atomic_connector_get_property() instead. - * - * This callback is optional if the driver does not support any - * driver-private atomic properties. - * - * RETURNS: - * - * 0 on success, -EINVAL if the property isn't implemented by the - * driver (which shouldn't ever happen, the core only asks for - * properties attached to this connector). - */ - int (*atomic_get_property)(struct drm_connector *connector, - const struct drm_connector_state *state, - struct drm_property *property, - uint64_t *val); -}; - -/** - * struct drm_encoder_funcs - encoder controls - * - * Encoders sit between CRTCs and connectors. - */ -struct drm_encoder_funcs { - /** - * @reset: - * - * Reset encoder hardware and software state to off. This function isn't - * called by the core directly, only through drm_mode_config_reset(). - * It's not a helper hook only for historical reasons. - */ - void (*reset)(struct drm_encoder *encoder); - - /** - * @destroy: - * - * Clean up encoder resources. This is only called at driver unload time - * through drm_mode_config_cleanup() since an encoder cannot be - * hotplugged in DRM. - */ - void (*destroy)(struct drm_encoder *encoder); - - /** - * @late_register: - * - * This optional hook can be used to register additional userspace - * interfaces attached to the encoder like debugfs interfaces. - * It is called late in the driver load sequence from drm_dev_register(). - * Everything added from this callback should be unregistered in - * the early_unregister callback. - * - * Returns: - * - * 0 on success, or a negative error code on failure. - */ - int (*late_register)(struct drm_encoder *encoder); - - /** - * @early_unregister: - * - * This optional hook should be used to unregister the additional - * userspace interfaces attached to the encoder from - * late_unregister(). It is called from drm_dev_unregister(), - * early in the driver unload sequence to disable userspace access - * before data structures are torndown. - */ - void (*early_unregister)(struct drm_encoder *encoder); -}; - -#define DRM_CONNECTOR_MAX_ENCODER 3 - -/** - * struct drm_encoder - central DRM encoder structure - * @dev: parent DRM device - * @head: list management - * @base: base KMS object - * @name: human readable name, can be overwritten by the driver - * @encoder_type: one of the %DRM_MODE_ENCODER_<foo> types in drm_mode.h - * @possible_crtcs: bitmask of potential CRTC bindings - * @possible_clones: bitmask of potential sibling encoders for cloning - * @crtc: currently bound CRTC - * @bridge: bridge associated to the encoder - * @funcs: control functions - * @helper_private: mid-layer private data - * - * CRTCs drive pixels to encoders, which convert them into signals - * appropriate for a given connector or set of connectors. - */ -struct drm_encoder { - struct drm_device *dev; - struct list_head head; - - struct drm_mode_object base; - char *name; - int encoder_type; - - /** - * @index: Position inside the mode_config.list, can be used as an array - * index. It is invariant over the lifetime of the encoder. - */ - unsigned index; - - uint32_t possible_crtcs; - uint32_t possible_clones; - - struct drm_crtc *crtc; - struct drm_bridge *bridge; - const struct drm_encoder_funcs *funcs; - const struct drm_encoder_helper_funcs *helper_private; -}; - -/* should we poll this connector for connects and disconnects */ -/* hot plug detectable */ -#define DRM_CONNECTOR_POLL_HPD (1 << 0) -/* poll for connections */ -#define DRM_CONNECTOR_POLL_CONNECT (1 << 1) -/* can cleanly poll for disconnections without flickering the screen */ -/* DACs should rarely do this without a lot of testing */ -#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2) - -#define MAX_ELD_BYTES 128 - -/** - * struct drm_connector - central DRM connector control structure - * @dev: parent DRM device - * @kdev: kernel device for sysfs attributes - * @attr: sysfs attributes - * @head: list management - * @base: base KMS object - * @name: human readable name, can be overwritten by the driver - * @connector_type: one of the %DRM_MODE_CONNECTOR_<foo> types from drm_mode.h - * @connector_type_id: index into connector type enum - * @interlace_allowed: can this connector handle interlaced modes? - * @doublescan_allowed: can this connector handle doublescan? - * @stereo_allowed: can this connector handle stereo modes? - * @registered: is this connector exposed (registered) with userspace? - * @modes: modes available on this connector (from fill_modes() + user) - * @status: one of the drm_connector_status enums (connected, not, or unknown) - * @probed_modes: list of modes derived directly from the display - * @display_info: information about attached display (e.g. from EDID) - * @funcs: connector control functions - * @edid_blob_ptr: DRM property containing EDID if present - * @properties: property tracking for this connector - * @polled: a %DRM_CONNECTOR_POLL_<foo> value for core driven polling - * @dpms: current dpms state - * @helper_private: mid-layer private data - * @cmdline_mode: mode line parsed from the kernel cmdline for this connector - * @force: a %DRM_FORCE_<foo> state for forced mode sets - * @override_edid: has the EDID been overwritten through debugfs for testing? - * @encoder_ids: valid encoders for this connector - * @encoder: encoder driving this connector, if any - * @eld: EDID-like data, if present - * @dvi_dual: dual link DVI, if found - * @max_tmds_clock: max clock rate, if found - * @latency_present: AV delay info from ELD, if found - * @video_latency: video latency info from ELD, if found - * @audio_latency: audio latency info from ELD, if found - * @null_edid_counter: track sinks that give us all zeros for the EDID - * @bad_edid_counter: track sinks that give us an EDID with invalid checksum - * @edid_corrupt: indicates whether the last read EDID was corrupt - * @debugfs_entry: debugfs directory for this connector - * @state: current atomic state for this connector - * @has_tile: is this connector connected to a tiled monitor - * @tile_group: tile group for the connected monitor - * @tile_is_single_monitor: whether the tile is one monitor housing - * @num_h_tile: number of horizontal tiles in the tile group - * @num_v_tile: number of vertical tiles in the tile group - * @tile_h_loc: horizontal location of this tile - * @tile_v_loc: vertical location of this tile - * @tile_h_size: horizontal size of this tile. - * @tile_v_size: vertical size of this tile. - * - * Each connector may be connected to one or more CRTCs, or may be clonable by - * another connector if they can share a CRTC. Each connector also has a specific - * position in the broader display (referred to as a 'screen' though it could - * span multiple monitors). - */ -struct drm_connector { - struct drm_device *dev; - struct device *kdev; - struct device_attribute *attr; - struct list_head head; - - struct drm_mode_object base; - - char *name; - - /** - * @index: Compacted connector index, which matches the position inside - * the mode_config.list for drivers not supporting hot-add/removing. Can - * be used as an array index. It is invariant over the lifetime of the - * connector. - */ - unsigned index; - - int connector_type; - int connector_type_id; - bool interlace_allowed; - bool doublescan_allowed; - bool stereo_allowed; - bool registered; - struct list_head modes; /* list of modes on this connector */ - - enum drm_connector_status status; - - /* these are modes added by probing with DDC or the BIOS */ - struct list_head probed_modes; - - struct drm_display_info display_info; - const struct drm_connector_funcs *funcs; - - struct drm_property_blob *edid_blob_ptr; - struct drm_object_properties properties; - - /** - * @path_blob_ptr: - * - * DRM blob property data for the DP MST path property. - */ - struct drm_property_blob *path_blob_ptr; - - /** - * @tile_blob_ptr: - * - * DRM blob property data for the tile property (used mostly by DP MST). - * This is meant for screens which are driven through separate display - * pipelines represented by &drm_crtc, which might not be running with - * genlocked clocks. For tiled panels which are genlocked, like - * dual-link LVDS or dual-link DSI, the driver should try to not expose - * the tiling and virtualize both &drm_crtc and &drm_plane if needed. - */ - struct drm_property_blob *tile_blob_ptr; - - uint8_t polled; /* DRM_CONNECTOR_POLL_* */ - - /* requested DPMS state */ - int dpms; - - const struct drm_connector_helper_funcs *helper_private; - - /* forced on connector */ - struct drm_cmdline_mode cmdline_mode; - enum drm_connector_force force; - bool override_edid; - uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; - struct drm_encoder *encoder; /* currently active encoder */ - - /* EDID bits */ - uint8_t eld[MAX_ELD_BYTES]; - bool dvi_dual; - int max_tmds_clock; /* in MHz */ - bool latency_present[2]; - int video_latency[2]; /* [0]: progressive, [1]: interlaced */ - int audio_latency[2]; - int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */ - unsigned bad_edid_counter; - - /* Flag for raw EDID header corruption - used in Displayport - * compliance testing - * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6 - */ - bool edid_corrupt; - - struct dentry *debugfs_entry; - - struct drm_connector_state *state; - - /* DisplayID bits */ - bool has_tile; - struct drm_tile_group *tile_group; - bool tile_is_single_monitor; - - uint8_t num_h_tile, num_v_tile; - uint8_t tile_h_loc, tile_v_loc; - uint16_t tile_h_size, tile_v_size; -}; - -/** - * struct drm_plane_state - mutable plane state - * @plane: backpointer to the plane - * @crtc: currently bound CRTC, NULL if disabled - * @fb: currently bound framebuffer - * @fence: optional fence to wait for before scanning out @fb - * @crtc_x: left position of visible portion of plane on crtc - * @crtc_y: upper position of visible portion of plane on crtc - * @crtc_w: width of visible portion of plane on crtc - * @crtc_h: height of visible portion of plane on crtc - * @src_x: left position of visible portion of plane within - * plane (in 16.16) - * @src_y: upper position of visible portion of plane within - * plane (in 16.16) - * @src_w: width of visible portion of plane (in 16.16) - * @src_h: height of visible portion of plane (in 16.16) - * @rotation: rotation of the plane - * @zpos: priority of the given plane on crtc (optional) - * @normalized_zpos: normalized value of zpos: unique, range from 0 to N-1 - * where N is the number of active planes for given crtc - * @state: backpointer to global drm_atomic_state - */ -struct drm_plane_state { - struct drm_plane *plane; - - struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_plane() */ - struct drm_framebuffer *fb; /* do not write directly, use drm_atomic_set_fb_for_plane() */ - struct fence *fence; - - /* Signed dest location allows it to be partially off screen */ - int32_t crtc_x, crtc_y; - uint32_t crtc_w, crtc_h; - - /* Source values are 16.16 fixed point */ - uint32_t src_x, src_y; - uint32_t src_h, src_w; - - /* Plane rotation */ - unsigned int rotation; - - /* Plane zpos */ - unsigned int zpos; - unsigned int normalized_zpos; - - struct drm_atomic_state *state; -}; - - -/** - * struct drm_plane_funcs - driver plane control functions - */ -struct drm_plane_funcs { - /** - * @update_plane: - * - * This is the legacy entry point to enable and configure the plane for - * the given CRTC and framebuffer. It is never called to disable the - * plane, i.e. the passed-in crtc and fb paramters are never NULL. - * - * The source rectangle in frame buffer memory coordinates is given by - * the src_x, src_y, src_w and src_h parameters (as 16.16 fixed point - * values). Devices that don't support subpixel plane coordinates can - * ignore the fractional part. - * - * The destination rectangle in CRTC coordinates is given by the - * crtc_x, crtc_y, crtc_w and crtc_h parameters (as integer values). - * Devices scale the source rectangle to the destination rectangle. If - * scaling is not supported, and the source rectangle size doesn't match - * the destination rectangle size, the driver must return a - * -<errorname>EINVAL</errorname> error. - * - * Drivers implementing atomic modeset should use - * drm_atomic_helper_update_plane() to implement this hook. - * - * RETURNS: - * - * 0 on success or a negative error code on failure. - */ - int (*update_plane)(struct drm_plane *plane, - struct drm_crtc *crtc, struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h); - - /** - * @disable_plane: - * - * This is the legacy entry point to disable the plane. The DRM core - * calls this method in response to a DRM_IOCTL_MODE_SETPLANE IOCTL call - * with the frame buffer ID set to 0. Disabled planes must not be - * processed by the CRTC. - * - * Drivers implementing atomic modeset should use - * drm_atomic_helper_disable_plane() to implement this hook. - * - * RETURNS: - * - * 0 on success or a negative error code on failure. - */ - int (*disable_plane)(struct drm_plane *plane); - - /** - * @destroy: - * - * Clean up plane resources. This is only called at driver unload time - * through drm_mode_config_cleanup() since a plane cannot be hotplugged - * in DRM. - */ - void (*destroy)(struct drm_plane *plane); - - /** - * @reset: - * - * Reset plane hardware and software state to off. This function isn't - * called by the core directly, only through drm_mode_config_reset(). - * It's not a helper hook only for historical reasons. - * - * Atomic drivers can use drm_atomic_helper_plane_reset() to reset - * atomic state using this hook. - */ - void (*reset)(struct drm_plane *plane); - - /** - * @set_property: - * - * This is the legacy entry point to update a property attached to the - * plane. - * - * Drivers implementing atomic modeset should use - * drm_atomic_helper_plane_set_property() to implement this hook. - * - * This callback is optional if the driver does not support any legacy - * driver-private properties. - * - * RETURNS: - * - * 0 on success or a negative error code on failure. - */ - int (*set_property)(struct drm_plane *plane, - struct drm_property *property, uint64_t val); - - /** - * @atomic_duplicate_state: - * - * Duplicate the current atomic state for this plane and return it. - * The core and helpers gurantee that any atomic state duplicated with - * this hook and still owned by the caller (i.e. not transferred to the - * driver by calling ->atomic_commit() from struct - * &drm_mode_config_funcs) will be cleaned up by calling the - * @atomic_destroy_state hook in this structure. - * - * Atomic drivers which don't subclass struct &drm_plane_state should use - * drm_atomic_helper_plane_duplicate_state(). Drivers that subclass the - * state structure to extend it with driver-private state should use - * __drm_atomic_helper_plane_duplicate_state() to make sure shared state is - * duplicated in a consistent fashion across drivers. - * - * It is an error to call this hook before plane->state has been - * initialized correctly. - * - * NOTE: - * - * If the duplicate state references refcounted resources this hook must - * acquire a reference for each of them. The driver must release these - * references again in @atomic_destroy_state. - * - * RETURNS: - * - * Duplicated atomic state or NULL when the allocation failed. - */ - struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane); - - /** - * @atomic_destroy_state: - * - * Destroy a state duplicated with @atomic_duplicate_state and release - * or unreference all resources it references - */ - void (*atomic_destroy_state)(struct drm_plane *plane, - struct drm_plane_state *state); - - /** - * @atomic_set_property: - * - * Decode a driver-private property value and store the decoded value - * into the passed-in state structure. Since the atomic core decodes all - * standardized properties (even for extensions beyond the core set of - * properties which might not be implemented by all drivers) this - * requires drivers to subclass the state structure. - * - * Such driver-private properties should really only be implemented for - * truly hardware/vendor specific state. Instead it is preferred to - * standardize atomic extension and decode the properties used to expose - * such an extension in the core. - * - * Do not call this function directly, use - * drm_atomic_plane_set_property() instead. - * - * This callback is optional if the driver does not support any - * driver-private atomic properties. - * - * NOTE: - * - * This function is called in the state assembly phase of atomic - * modesets, which can be aborted for any reason (including on - * userspace's request to just check whether a configuration would be - * possible). Drivers MUST NOT touch any persistent state (hardware or - * software) or data structures except the passed in @state parameter. - * - * Also since userspace controls in which order properties are set this - * function must not do any input validation (since the state update is - * incomplete and hence likely inconsistent). Instead any such input - * validation must be done in the various atomic_check callbacks. - * - * RETURNS: - * - * 0 if the property has been found, -EINVAL if the property isn't - * implemented by the driver (which shouldn't ever happen, the core only - * asks for properties attached to this plane). No other validation is - * allowed by the driver. The core already checks that the property - * value is within the range (integer, valid enum value, ...) the driver - * set when registering the property. - */ - int (*atomic_set_property)(struct drm_plane *plane, - struct drm_plane_state *state, - struct drm_property *property, - uint64_t val); - - /** - * @atomic_get_property: - * - * Reads out the decoded driver-private property. This is used to - * implement the GETPLANE IOCTL. - * - * Do not call this function directly, use - * drm_atomic_plane_get_property() instead. - * - * This callback is optional if the driver does not support any - * driver-private atomic properties. - * - * RETURNS: - * - * 0 on success, -EINVAL if the property isn't implemented by the - * driver (which should never happen, the core only asks for - * properties attached to this plane). - */ - int (*atomic_get_property)(struct drm_plane *plane, - const struct drm_plane_state *state, - struct drm_property *property, - uint64_t *val); - /** - * @late_register: - * - * This optional hook can be used to register additional userspace - * interfaces attached to the plane like debugfs interfaces. - * It is called late in the driver load sequence from drm_dev_register(). - * Everything added from this callback should be unregistered in - * the early_unregister callback. - * - * Returns: - * - * 0 on success, or a negative error code on failure. - */ - int (*late_register)(struct drm_plane *plane); - - /** - * @early_unregister: - * - * This optional hook should be used to unregister the additional - * userspace interfaces attached to the plane from - * late_unregister(). It is called from drm_dev_unregister(), - * early in the driver unload sequence to disable userspace access - * before data structures are torndown. - */ - void (*early_unregister)(struct drm_plane *plane); -}; - -enum drm_plane_type { - DRM_PLANE_TYPE_OVERLAY, - DRM_PLANE_TYPE_PRIMARY, - DRM_PLANE_TYPE_CURSOR, -}; - - -/** - * struct drm_plane - central DRM plane control structure - * @dev: DRM device this plane belongs to - * @head: for list management - * @name: human readable name, can be overwritten by the driver - * @base: base mode object - * @possible_crtcs: pipes this plane can be bound to - * @format_types: array of formats supported by this plane - * @format_count: number of formats supported - * @format_default: driver hasn't supplied supported formats for the plane - * @crtc: currently bound CRTC - * @fb: currently bound fb - * @old_fb: Temporary tracking of the old fb while a modeset is ongoing. Used by - * drm_mode_set_config_internal() to implement correct refcounting. - * @funcs: helper functions - * @properties: property tracking for this plane - * @type: type of plane (overlay, primary, cursor) - * @state: current atomic state for this plane - * @zpos_property: zpos property for this plane - * @helper_private: mid-layer private data - */ -struct drm_plane { - struct drm_device *dev; - struct list_head head; - - char *name; - - /** - * @mutex: - * - * Protects modeset plane state, together with the mutex of &drm_crtc - * this plane is linked to (when active, getting actived or getting - * disabled). - */ - struct drm_modeset_lock mutex; - - struct drm_mode_object base; - - uint32_t possible_crtcs; - uint32_t *format_types; - unsigned int format_count; - bool format_default; - - struct drm_crtc *crtc; - struct drm_framebuffer *fb; - - struct drm_framebuffer *old_fb; - - const struct drm_plane_funcs *funcs; - - struct drm_object_properties properties; - - enum drm_plane_type type; - - /** - * @index: Position inside the mode_config.list, can be used as an array - * index. It is invariant over the lifetime of the plane. - */ - unsigned index; - - const struct drm_plane_helper_funcs *helper_private; - - struct drm_plane_state *state; - - struct drm_property *zpos_property; -}; - -/** - * struct drm_bridge_funcs - drm_bridge control functions - * @attach: Called during drm_bridge_attach - */ -struct drm_bridge_funcs { - int (*attach)(struct drm_bridge *bridge); - - /** - * @mode_fixup: - * - * This callback is used to validate and adjust a mode. The paramater - * mode is the display mode that should be fed to the next element in - * the display chain, either the final &drm_connector or the next - * &drm_bridge. The parameter adjusted_mode is the input mode the bridge - * requires. It can be modified by this callback and does not need to - * match mode. - * - * This is the only hook that allows a bridge to reject a modeset. If - * this function passes all other callbacks must succeed for this - * configuration. - * - * NOTE: - * - * This function is called in the check phase of atomic modesets, which - * can be aborted for any reason (including on userspace's request to - * just check whether a configuration would be possible). Drivers MUST - * NOT touch any persistent state (hardware or software) or data - * structures except the passed in @state parameter. - * - * RETURNS: - * - * True if an acceptable configuration is possible, false if the modeset - * operation should be rejected. - */ - bool (*mode_fixup)(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - /** - * @disable: - * - * This callback should disable the bridge. It is called right before - * the preceding element in the display pipe is disabled. If the - * preceding element is a bridge this means it's called before that - * bridge's ->disable() function. If the preceding element is a - * &drm_encoder it's called right before the encoder's ->disable(), - * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. - * - * The bridge can assume that the display pipe (i.e. clocks and timing - * signals) feeding it is still running when this callback is called. - * - * The disable callback is optional. - */ - void (*disable)(struct drm_bridge *bridge); - - /** - * @post_disable: - * - * This callback should disable the bridge. It is called right after - * the preceding element in the display pipe is disabled. If the - * preceding element is a bridge this means it's called after that - * bridge's ->post_disable() function. If the preceding element is a - * &drm_encoder it's called right after the encoder's ->disable(), - * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. - * - * The bridge must assume that the display pipe (i.e. clocks and timing - * singals) feeding it is no longer running when this callback is - * called. - * - * The post_disable callback is optional. - */ - void (*post_disable)(struct drm_bridge *bridge); - - /** - * @mode_set: - * - * This callback should set the given mode on the bridge. It is called - * after the ->mode_set() callback for the preceding element in the - * display pipeline has been called already. The display pipe (i.e. - * clocks and timing signals) is off when this function is called. - */ - void (*mode_set)(struct drm_bridge *bridge, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - /** - * @pre_enable: - * - * This callback should enable the bridge. It is called right before - * the preceding element in the display pipe is enabled. If the - * preceding element is a bridge this means it's called before that - * bridge's ->pre_enable() function. If the preceding element is a - * &drm_encoder it's called right before the encoder's ->enable(), - * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. - * - * The display pipe (i.e. clocks and timing signals) feeding this bridge - * will not yet be running when this callback is called. The bridge must - * not enable the display link feeding the next bridge in the chain (if - * there is one) when this callback is called. - * - * The pre_enable callback is optional. - */ - void (*pre_enable)(struct drm_bridge *bridge); - - /** - * @enable: - * - * This callback should enable the bridge. It is called right after - * the preceding element in the display pipe is enabled. If the - * preceding element is a bridge this means it's called after that - * bridge's ->enable() function. If the preceding element is a - * &drm_encoder it's called right after the encoder's ->enable(), - * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. - * - * The bridge can assume that the display pipe (i.e. clocks and timing - * signals) feeding it is running when this callback is called. This - * callback must enable the display link feeding the next bridge in the - * chain if there is one. - * - * The enable callback is optional. - */ - void (*enable)(struct drm_bridge *bridge); -}; - -/** - * struct drm_bridge - central DRM bridge control structure - * @dev: DRM device this bridge belongs to - * @encoder: encoder to which this bridge is connected - * @next: the next bridge in the encoder chain - * @of_node: device node pointer to the bridge - * @list: to keep track of all added bridges - * @funcs: control functions - * @driver_private: pointer to the bridge driver's internal context - */ -struct drm_bridge { - struct drm_device *dev; - struct drm_encoder *encoder; - struct drm_bridge *next; -#ifdef CONFIG_OF - struct device_node *of_node; -#endif - struct list_head list; - - const struct drm_bridge_funcs *funcs; - void *driver_private; -}; - -/** - * struct drm_crtc_commit - track modeset commits on a CRTC - * - * This structure is used to track pending modeset changes and atomic commit on - * a per-CRTC basis. Since updating the list should never block this structure - * is reference counted to allow waiters to safely wait on an event to complete, - * without holding any locks. - * - * It has 3 different events in total to allow a fine-grained synchronization - * between outstanding updates:: - * - * atomic commit thread hardware - * - * write new state into hardware ----> ... - * signal hw_done - * switch to new state on next - * ... v/hblank - * - * wait for buffers to show up ... - * - * ... send completion irq - * irq handler signals flip_done - * cleanup old buffers - * - * signal cleanup_done - * - * wait for flip_done <---- - * clean up atomic state - * - * The important bit to know is that cleanup_done is the terminal event, but the - * ordering between flip_done and hw_done is entirely up to the specific driver - * and modeset state change. - * - * For an implementation of how to use this look at - * drm_atomic_helper_setup_commit() from the atomic helper library. - */ -struct drm_crtc_commit { - /** - * @crtc: - * - * DRM CRTC for this commit. - */ - struct drm_crtc *crtc; - - /** - * @ref: - * - * Reference count for this structure. Needed to allow blocking on - * completions without the risk of the completion disappearing - * meanwhile. - */ - struct kref ref; - - /** - * @flip_done: - * - * Will be signaled when the hardware has flipped to the new set of - * buffers. Signals at the same time as when the drm event for this - * commit is sent to userspace, or when an out-fence is singalled. Note - * that for most hardware, in most cases this happens after @hw_done is - * signalled. - */ - struct completion flip_done; - - /** - * @hw_done: - * - * Will be signalled when all hw register changes for this commit have - * been written out. Especially when disabling a pipe this can be much - * later than than @flip_done, since that can signal already when the - * screen goes black, whereas to fully shut down a pipe more register - * I/O is required. - * - * Note that this does not need to include separately reference-counted - * resources like backing storage buffer pinning, or runtime pm - * management. - */ - struct completion hw_done; - - /** - * @cleanup_done: - * - * Will be signalled after old buffers have been cleaned up by calling - * drm_atomic_helper_cleanup_planes(). Since this can only happen after - * a vblank wait completed it might be a bit later. This completion is - * useful to throttle updates and avoid hardware updates getting ahead - * of the buffer cleanup too much. - */ - struct completion cleanup_done; - - /** - * @commit_entry: - * - * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock. - */ - struct list_head commit_entry; - - /** - * @event: - * - * &drm_pending_vblank_event pointer to clean up private events. - */ - struct drm_pending_vblank_event *event; -}; - -struct __drm_planes_state { - struct drm_plane *ptr; - struct drm_plane_state *state; -}; - -struct __drm_crtcs_state { - struct drm_crtc *ptr; - struct drm_crtc_state *state; - struct drm_crtc_commit *commit; -}; - -struct __drm_connnectors_state { - struct drm_connector *ptr; - struct drm_connector_state *state; -}; - -/** - * struct drm_atomic_state - the global state object for atomic updates - * @dev: parent DRM device - * @allow_modeset: allow full modeset - * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics - * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL. - * @planes: pointer to array of structures with per-plane data - * @crtcs: pointer to array of CRTC pointers - * @num_connector: size of the @connectors and @connector_states arrays - * @connectors: pointer to array of structures with per-connector data - * @acquire_ctx: acquire context for this atomic modeset state update - */ -struct drm_atomic_state { - struct drm_device *dev; - bool allow_modeset : 1; - bool legacy_cursor_update : 1; - bool legacy_set_config : 1; - struct __drm_planes_state *planes; - struct __drm_crtcs_state *crtcs; - int num_connector; - struct __drm_connnectors_state *connectors; - - struct drm_modeset_acquire_ctx *acquire_ctx; - - /** - * @commit_work: - * - * Work item which can be used by the driver or helpers to execute the - * commit without blocking. - */ - struct work_struct commit_work; -}; - - -/** * struct drm_mode_set - new values for a CRTC config change * @fb: framebuffer to use for new config * @crtc: CRTC whose configuration we're about to change @@ -2237,17 +873,9 @@ struct drm_mode_config_funcs { * CRTC index supplied in &drm_event to userspace. * * The drm core will supply a struct &drm_event in the event - * member of each CRTC's &drm_crtc_state structure. This can be handled by the - * drm_crtc_send_vblank_event() function, which the driver should call on - * the provided event upon completion of the atomic commit. Note that if - * the driver supports vblank signalling and timestamping the vblank - * counters and timestamps must agree with the ones returned from page - * flip events. With the current vblank helper infrastructure this can - * be achieved by holding a vblank reference while the page flip is - * pending, acquired through drm_crtc_vblank_get() and released with - * drm_crtc_vblank_put(). Drivers are free to implement their own vblank - * counter and timestamp tracking though, e.g. if they have accurate - * timestamp registers in hardware. + * member of each CRTC's &drm_crtc_state structure. See the + * documentation for &drm_crtc_state for more details about the precise + * semantics of this event. * * NOTE: * @@ -2636,12 +1264,6 @@ struct drm_mode_config { */ struct drm_property *aspect_ratio_property; /** - * @dirty_info_property: Optional connector property to give userspace a - * hint that the DIRTY_FB ioctl should be used. - */ - struct drm_property *dirty_info_property; - - /** * @degamma_lut_property: Optional CRTC property to set the LUT used to * convert the framebuffer's colors to linear gamma. */ @@ -2702,43 +1324,7 @@ struct drm_mode_config { struct drm_mode_config_helper_funcs *helper_private; }; -/** - * drm_for_each_plane_mask - iterate over planes specified by bitmask - * @plane: the loop cursor - * @dev: the DRM device - * @plane_mask: bitmask of plane indices - * - * Iterate over all planes specified by bitmask. - */ -#define drm_for_each_plane_mask(plane, dev, plane_mask) \ - list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \ - for_each_if ((plane_mask) & (1 << drm_plane_index(plane))) - -/** - * drm_for_each_encoder_mask - iterate over encoders specified by bitmask - * @encoder: the loop cursor - * @dev: the DRM device - * @encoder_mask: bitmask of encoder indices - * - * Iterate over all encoders specified by bitmask. - */ -#define drm_for_each_encoder_mask(encoder, dev, encoder_mask) \ - list_for_each_entry((encoder), &(dev)->mode_config.encoder_list, head) \ - for_each_if ((encoder_mask) & (1 << drm_encoder_index(encoder))) - #define obj_to_crtc(x) container_of(x, struct drm_crtc, base) -#define obj_to_connector(x) container_of(x, struct drm_connector, base) -#define obj_to_encoder(x) container_of(x, struct drm_encoder, base) -#define obj_to_mode(x) container_of(x, struct drm_display_mode, base) -#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base) -#define obj_to_property(x) container_of(x, struct drm_property, base) -#define obj_to_blob(x) container_of(x, struct drm_property_blob, base) -#define obj_to_plane(x) container_of(x, struct drm_plane, base) - -struct drm_prop_enum_list { - int type; - char *name; -}; extern __printf(6, 7) int drm_crtc_init_with_planes(struct drm_device *dev, @@ -2756,7 +1342,7 @@ extern void drm_crtc_cleanup(struct drm_crtc *crtc); * Given a registered CRTC, return the index of that CRTC within a DRM * device's list of CRTCs. */ -static inline unsigned int drm_crtc_index(struct drm_crtc *crtc) +static inline unsigned int drm_crtc_index(const struct drm_crtc *crtc) { return crtc->index; } @@ -2773,184 +1359,17 @@ static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc) return 1 << drm_crtc_index(crtc); } -int drm_connector_init(struct drm_device *dev, - struct drm_connector *connector, - const struct drm_connector_funcs *funcs, - int connector_type); -int drm_connector_register(struct drm_connector *connector); -void drm_connector_unregister(struct drm_connector *connector); - -extern void drm_connector_cleanup(struct drm_connector *connector); -static inline unsigned drm_connector_index(struct drm_connector *connector) -{ - return connector->index; -} - -extern __printf(5, 6) -int drm_encoder_init(struct drm_device *dev, - struct drm_encoder *encoder, - const struct drm_encoder_funcs *funcs, - int encoder_type, const char *name, ...); - -/** - * drm_encoder_index - find the index of a registered encoder - * @encoder: encoder to find index for - * - * Given a registered encoder, return the index of that encoder within a DRM - * device's list of encoders. - */ -static inline unsigned int drm_encoder_index(struct drm_encoder *encoder) -{ - return encoder->index; -} - -/** - * drm_encoder_crtc_ok - can a given crtc drive a given encoder? - * @encoder: encoder to test - * @crtc: crtc to test - * - * Return false if @encoder can't be driven by @crtc, true otherwise. - */ -static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder, - struct drm_crtc *crtc) -{ - return !!(encoder->possible_crtcs & drm_crtc_mask(crtc)); -} - -extern __printf(8, 9) -int drm_universal_plane_init(struct drm_device *dev, - struct drm_plane *plane, - unsigned long possible_crtcs, - const struct drm_plane_funcs *funcs, - const uint32_t *formats, - unsigned int format_count, - enum drm_plane_type type, - const char *name, ...); -extern int drm_plane_init(struct drm_device *dev, - struct drm_plane *plane, - unsigned long possible_crtcs, - const struct drm_plane_funcs *funcs, - const uint32_t *formats, unsigned int format_count, - bool is_primary); -extern void drm_plane_cleanup(struct drm_plane *plane); - -/** - * drm_plane_index - find the index of a registered plane - * @plane: plane to find index for - * - * Given a registered plane, return the index of that plane within a DRM - * device's list of planes. - */ -static inline unsigned int drm_plane_index(struct drm_plane *plane) -{ - return plane->index; -} -extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx); -extern void drm_plane_force_disable(struct drm_plane *plane); extern void drm_crtc_get_hv_timing(const struct drm_display_mode *mode, int *hdisplay, int *vdisplay); extern int drm_crtc_force_disable(struct drm_crtc *crtc); extern int drm_crtc_force_disable_all(struct drm_device *dev); -extern void drm_encoder_cleanup(struct drm_encoder *encoder); - -extern const char *drm_get_connector_status_name(enum drm_connector_status status); -extern const char *drm_get_subpixel_order_name(enum subpixel_order order); -extern const char *drm_get_dpms_name(int val); -extern const char *drm_get_dvi_i_subconnector_name(int val); -extern const char *drm_get_dvi_i_select_name(int val); -extern const char *drm_get_tv_subconnector_name(int val); -extern const char *drm_get_tv_select_name(int val); extern void drm_mode_config_init(struct drm_device *dev); extern void drm_mode_config_reset(struct drm_device *dev); extern void drm_mode_config_cleanup(struct drm_device *dev); -extern int drm_mode_connector_set_path_property(struct drm_connector *connector, - const char *path); -int drm_mode_connector_set_tile_property(struct drm_connector *connector); -extern int drm_mode_connector_update_edid_property(struct drm_connector *connector, - const struct edid *edid); - -extern int drm_display_info_set_bus_formats(struct drm_display_info *info, - const u32 *formats, - unsigned int num_formats); - -static inline bool drm_property_type_is(struct drm_property *property, - uint32_t type) -{ - /* instanceof for props.. handles extended type vs original types: */ - if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) - return (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) == type; - return property->flags & type; -} - -extern int drm_object_property_set_value(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t val); -extern int drm_object_property_get_value(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t *value); -extern int drm_framebuffer_init(struct drm_device *dev, - struct drm_framebuffer *fb, - const struct drm_framebuffer_funcs *funcs); -extern struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, - uint32_t id); -extern void drm_framebuffer_remove(struct drm_framebuffer *fb); -extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb); -extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); - -extern void drm_object_attach_property(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t init_val); -extern struct drm_property *drm_property_create(struct drm_device *dev, int flags, - const char *name, int num_values); -extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, - const char *name, - const struct drm_prop_enum_list *props, - int num_values); -struct drm_property *drm_property_create_bitmask(struct drm_device *dev, - int flags, const char *name, - const struct drm_prop_enum_list *props, - int num_props, - uint64_t supported_bits); -struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, - const char *name, - uint64_t min, uint64_t max); -struct drm_property *drm_property_create_signed_range(struct drm_device *dev, - int flags, const char *name, - int64_t min, int64_t max); -struct drm_property *drm_property_create_object(struct drm_device *dev, - int flags, const char *name, uint32_t type); -struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags, - const char *name); -struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, - size_t length, - const void *data); -struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev, - uint32_t id); -struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob); -void drm_property_unreference_blob(struct drm_property_blob *blob); -extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property); -extern int drm_property_add_enum(struct drm_property *property, int index, - uint64_t value, const char *name); -extern int drm_mode_create_dvi_i_properties(struct drm_device *dev); -extern int drm_mode_create_tv_properties(struct drm_device *dev, - unsigned int num_modes, - const char * const modes[]); -extern int drm_mode_create_scaling_mode_property(struct drm_device *dev); -extern int drm_mode_create_aspect_ratio_property(struct drm_device *dev); -extern int drm_mode_create_dirty_info_property(struct drm_device *dev); -extern int drm_mode_create_suggested_offset_properties(struct drm_device *dev); - -extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, - struct drm_encoder *encoder); -extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, - int gamma_size); - extern int drm_mode_set_config_internal(struct drm_mode_set *set); -extern uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); - extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev, char topology[8]); extern struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev, @@ -2958,40 +1377,7 @@ extern struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev, extern void drm_mode_put_tile_group(struct drm_device *dev, struct drm_tile_group *tg); -extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane, - struct drm_property *property, - uint64_t value); - -extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, - unsigned int supported_rotations); -extern unsigned int drm_rotation_simplify(unsigned int rotation, - unsigned int supported_rotations); -extern void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, - uint degamma_lut_size, - bool has_ctm, - uint gamma_lut_size); - -int drm_plane_create_zpos_property(struct drm_plane *plane, - unsigned int zpos, - unsigned int min, unsigned int max); - -int drm_plane_create_zpos_immutable_property(struct drm_plane *plane, - unsigned int zpos); - /* Helpers */ -struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, - uint32_t id, uint32_t type); -void drm_mode_object_reference(struct drm_mode_object *obj); -void drm_mode_object_unreference(struct drm_mode_object *obj); - -static inline struct drm_plane *drm_plane_find(struct drm_device *dev, - uint32_t id) -{ - struct drm_mode_object *mo; - mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PLANE); - return mo ? obj_to_plane(mo) : NULL; -} - static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev, uint32_t id) { @@ -3000,120 +1386,6 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev, return mo ? obj_to_crtc(mo) : NULL; } -static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev, - uint32_t id) -{ - struct drm_mode_object *mo; - mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); - return mo ? obj_to_encoder(mo) : NULL; -} - -/** - * drm_connector_lookup - lookup connector object - * @dev: DRM device - * @id: connector object id - * - * This function looks up the connector object specified by id - * add takes a reference to it. - */ -static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev, - uint32_t id) -{ - struct drm_mode_object *mo; - mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR); - return mo ? obj_to_connector(mo) : NULL; -} - -static inline struct drm_property *drm_property_find(struct drm_device *dev, - uint32_t id) -{ - struct drm_mode_object *mo; - mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY); - return mo ? obj_to_property(mo) : NULL; -} - -/* - * Extract a degamma/gamma LUT value provided by user and round it to the - * precision supported by the hardware. - */ -static inline uint32_t drm_color_lut_extract(uint32_t user_input, - uint32_t bit_precision) -{ - uint32_t val = user_input; - uint32_t max = 0xffff >> (16 - bit_precision); - - /* Round only if we're not using full precision. */ - if (bit_precision < 16) { - val += 1UL << (16 - bit_precision - 1); - val >>= 16 - bit_precision; - } - - return clamp_val(val, 0, max); -} - -/** - * drm_framebuffer_reference - incr the fb refcnt - * @fb: framebuffer - * - * This functions increments the fb's refcount. - */ -static inline void drm_framebuffer_reference(struct drm_framebuffer *fb) -{ - drm_mode_object_reference(&fb->base); -} - -/** - * drm_framebuffer_unreference - unref a framebuffer - * @fb: framebuffer to unref - * - * This functions decrements the fb's refcount and frees it if it drops to zero. - */ -static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb) -{ - drm_mode_object_unreference(&fb->base); -} - -/** - * drm_framebuffer_read_refcount - read the framebuffer reference count. - * @fb: framebuffer - * - * This functions returns the framebuffer's reference count. - */ -static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb) -{ - return atomic_read(&fb->base.refcount.refcount); -} - -/** - * drm_connector_reference - incr the connector refcnt - * @connector: connector - * - * This function increments the connector's refcount. - */ -static inline void drm_connector_reference(struct drm_connector *connector) -{ - drm_mode_object_reference(&connector->base); -} - -/** - * drm_connector_unreference - unref a connector - * @connector: connector to unref - * - * This function decrements the connector's refcount and frees it if it drops to zero. - */ -static inline void drm_connector_unreference(struct drm_connector *connector) -{ - drm_mode_object_unreference(&connector->base); -} - -/* Plane list iterator for legacy (overlay only) planes. */ -#define drm_for_each_legacy_plane(plane, dev) \ - list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \ - for_each_if (plane->type == DRM_PLANE_TYPE_OVERLAY) - -#define drm_for_each_plane(plane, dev) \ - list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) - #define drm_for_each_crtc(crtc, dev) \ list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head) @@ -3131,67 +1403,4 @@ assert_drm_connector_list_read_locked(struct drm_mode_config *mode_config) !drm_modeset_is_locked(&mode_config->connection_mutex)); } -#define drm_for_each_connector(connector, dev) \ - for (assert_drm_connector_list_read_locked(&(dev)->mode_config), \ - connector = list_first_entry(&(dev)->mode_config.connector_list, \ - struct drm_connector, head); \ - &connector->head != (&(dev)->mode_config.connector_list); \ - connector = list_next_entry(connector, head)) - -#define drm_for_each_encoder(encoder, dev) \ - list_for_each_entry(encoder, &(dev)->mode_config.encoder_list, head) - -#define drm_for_each_fb(fb, dev) \ - for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \ - fb = list_first_entry(&(dev)->mode_config.fb_list, \ - struct drm_framebuffer, head); \ - &fb->head != (&(dev)->mode_config.fb_list); \ - fb = list_next_entry(fb, head)) - -/* drm_edid.c */ -bool drm_probe_ddc(struct i2c_adapter *adapter); -struct edid *drm_get_edid(struct drm_connector *connector, - struct i2c_adapter *adapter); -struct edid *drm_get_edid_switcheroo(struct drm_connector *connector, - struct i2c_adapter *adapter); -struct edid *drm_edid_duplicate(const struct edid *edid); -int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); - -u8 drm_match_cea_mode(const struct drm_display_mode *to_match); -enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code); -bool drm_detect_hdmi_monitor(struct edid *edid); -bool drm_detect_monitor_audio(struct edid *edid); -bool drm_rgb_quant_range_selectable(struct edid *edid); -int drm_add_modes_noedid(struct drm_connector *connector, - int hdisplay, int vdisplay); -void drm_set_preferred_mode(struct drm_connector *connector, - int hpref, int vpref); - -int drm_edid_header_is_valid(const u8 *raw_edid); -bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid, - bool *edid_corrupt); -bool drm_edid_is_valid(struct edid *edid); -void drm_edid_get_monitor_name(struct edid *edid, char *name, - int buflen); -struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, - int hsize, int vsize, int fresh, - bool rb); - -/* drm_bridge.c */ -extern int drm_bridge_add(struct drm_bridge *bridge); -extern void drm_bridge_remove(struct drm_bridge *bridge); -extern struct drm_bridge *of_drm_find_bridge(struct device_node *np); -extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge); - -bool drm_bridge_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -void drm_bridge_disable(struct drm_bridge *bridge); -void drm_bridge_post_disable(struct drm_bridge *bridge); -void drm_bridge_mode_set(struct drm_bridge *bridge, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -void drm_bridge_pre_enable(struct drm_bridge *bridge); -void drm_bridge_enable(struct drm_bridge *bridge); - #endif /* __DRM_CRTC_H__ */ diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 4b37afa2b73b..982c299e435a 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -41,6 +41,7 @@ #include <drm/drm_crtc.h> #include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_modeset_helper.h> extern void drm_helper_disable_unused_functions(struct drm_device *dev); extern int drm_crtc_helper_set_config(struct drm_mode_set *set); @@ -53,11 +54,6 @@ extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder); extern int drm_helper_connector_dpms(struct drm_connector *connector, int mode); -extern void drm_helper_move_panel_connectors_to_head(struct drm_device *); - -extern void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, - const struct drm_mode_fb_cmd2 *mode_cmd); - extern void drm_helper_resume_force_mode(struct drm_device *dev); int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, diff --git a/include/drm/drm_dp_aux_dev.h b/include/drm/drm_dp_aux_dev.h deleted file mode 100644 index 1b76d990d8ab..000000000000 --- a/include/drm/drm_dp_aux_dev.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright © 2015 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Rafael Antognolli <rafael.antognolli@intel.com> - * - */ - -#ifndef DRM_DP_AUX_DEV -#define DRM_DP_AUX_DEV - -#include <drm/drm_dp_helper.h> - -#ifdef CONFIG_DRM_DP_AUX_CHARDEV - -int drm_dp_aux_dev_init(void); -void drm_dp_aux_dev_exit(void); -int drm_dp_aux_register_devnode(struct drm_dp_aux *aux); -void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux); - -#else - -static inline int drm_dp_aux_dev_init(void) -{ - return 0; -} - -static inline void drm_dp_aux_dev_exit(void) -{ -} - -static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux) -{ - return 0; -} - -static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux) -{ -} - -#endif - -#endif diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 63b8bd502444..2a79882cb68e 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -211,14 +211,16 @@ # define DP_DS_PORT_TYPE_DVI 2 # define DP_DS_PORT_TYPE_HDMI 3 # define DP_DS_PORT_TYPE_NON_EDID 4 +# define DP_DS_PORT_TYPE_DP_DUALMODE 5 +# define DP_DS_PORT_TYPE_WIRELESS 6 # define DP_DS_PORT_HPD (1 << 3) /* offset 1 for VGA is maximum megapixels per second / 8 */ /* offset 2 */ -# define DP_DS_VGA_MAX_BPC_MASK (3 << 0) -# define DP_DS_VGA_8BPC 0 -# define DP_DS_VGA_10BPC 1 -# define DP_DS_VGA_12BPC 2 -# define DP_DS_VGA_16BPC 3 +# define DP_DS_MAX_BPC_MASK (3 << 0) +# define DP_DS_8BPC 0 +# define DP_DS_10BPC 1 +# define DP_DS_12BPC 2 +# define DP_DS_16BPC 3 /* link configuration */ #define DP_LINK_BW_SET 0x100 @@ -443,6 +445,9 @@ #define DP_SOURCE_OUI 0x300 #define DP_SINK_OUI 0x400 #define DP_BRANCH_OUI 0x500 +#define DP_BRANCH_ID 0x503 +#define DP_BRANCH_HW_REV 0x509 +#define DP_BRANCH_SW_REV 0x50A #define DP_SET_POWER 0x600 # define DP_SET_POWER_D0 0x1 @@ -813,6 +818,13 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); +int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4]); +int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4]); +int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]); +void drm_dp_downstream_debug(struct seq_file *m, const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4], struct drm_dp_aux *aux); void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux); diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 919933d1beb4..c3a7d440bc11 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -25,6 +25,9 @@ #include <linux/types.h> +struct drm_device; +struct i2c_adapter; + #define EDID_LENGTH 128 #define DDC_ADDR 0x50 #define DDC_ADDR2 0x52 /* E-DDC 1.2 - where DisplayID can hide */ @@ -423,9 +426,36 @@ static inline u8 drm_eld_get_conn_type(const uint8_t *eld) return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK; } +bool drm_probe_ddc(struct i2c_adapter *adapter); struct edid *drm_do_get_edid(struct drm_connector *connector, int (*get_edid_block)(void *data, u8 *buf, unsigned int block, size_t len), void *data); +struct edid *drm_get_edid(struct drm_connector *connector, + struct i2c_adapter *adapter); +struct edid *drm_get_edid_switcheroo(struct drm_connector *connector, + struct i2c_adapter *adapter); +struct edid *drm_edid_duplicate(const struct edid *edid); +int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); + +u8 drm_match_cea_mode(const struct drm_display_mode *to_match); +enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code); +bool drm_detect_hdmi_monitor(struct edid *edid); +bool drm_detect_monitor_audio(struct edid *edid); +bool drm_rgb_quant_range_selectable(struct edid *edid); +int drm_add_modes_noedid(struct drm_connector *connector, + int hdisplay, int vdisplay); +void drm_set_preferred_mode(struct drm_connector *connector, + int hpref, int vpref); + +int drm_edid_header_is_valid(const u8 *raw_edid); +bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid, + bool *edid_corrupt); +bool drm_edid_is_valid(struct edid *edid); +void drm_edid_get_monitor_name(struct edid *edid, char *name, + int buflen); +struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, + int hsize, int vsize, int fresh, + bool rb); #endif /* __DRM_EDID_H__ */ diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h new file mode 100644 index 000000000000..387e33a4d6ee --- /dev/null +++ b/include/drm/drm_encoder.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_ENCODER_H__ +#define __DRM_ENCODER_H__ + +#include <linux/list.h> +#include <linux/ctype.h> +#include <drm/drm_mode_object.h> + +/** + * struct drm_encoder_funcs - encoder controls + * + * Encoders sit between CRTCs and connectors. + */ +struct drm_encoder_funcs { + /** + * @reset: + * + * Reset encoder hardware and software state to off. This function isn't + * called by the core directly, only through drm_mode_config_reset(). + * It's not a helper hook only for historical reasons. + */ + void (*reset)(struct drm_encoder *encoder); + + /** + * @destroy: + * + * Clean up encoder resources. This is only called at driver unload time + * through drm_mode_config_cleanup() since an encoder cannot be + * hotplugged in DRM. + */ + void (*destroy)(struct drm_encoder *encoder); + + /** + * @late_register: + * + * This optional hook can be used to register additional userspace + * interfaces attached to the encoder like debugfs interfaces. + * It is called late in the driver load sequence from drm_dev_register(). + * Everything added from this callback should be unregistered in + * the early_unregister callback. + * + * Returns: + * + * 0 on success, or a negative error code on failure. + */ + int (*late_register)(struct drm_encoder *encoder); + + /** + * @early_unregister: + * + * This optional hook should be used to unregister the additional + * userspace interfaces attached to the encoder from + * late_unregister(). It is called from drm_dev_unregister(), + * early in the driver unload sequence to disable userspace access + * before data structures are torndown. + */ + void (*early_unregister)(struct drm_encoder *encoder); +}; + +/** + * struct drm_encoder - central DRM encoder structure + * @dev: parent DRM device + * @head: list management + * @base: base KMS object + * @name: human readable name, can be overwritten by the driver + * @crtc: currently bound CRTC + * @bridge: bridge associated to the encoder + * @funcs: control functions + * @helper_private: mid-layer private data + * + * CRTCs drive pixels to encoders, which convert them into signals + * appropriate for a given connector or set of connectors. + */ +struct drm_encoder { + struct drm_device *dev; + struct list_head head; + + struct drm_mode_object base; + char *name; + /** + * @encoder_type: + * + * One of the DRM_MODE_ENCODER_<foo> types in drm_mode.h. The following + * encoder types are defined thus far: + * + * - DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A. + * + * - DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort. + * + * - DRM_MODE_ENCODER_LVDS for display panels, or in general any panel + * with a proprietary parallel connector. + * + * - DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video, + * Component, SCART). + * + * - DRM_MODE_ENCODER_VIRTUAL for virtual machine displays + * + * - DRM_MODE_ENCODER_DSI for panels connected using the DSI serial bus. + * + * - DRM_MODE_ENCODER_DPI for panels connected using the DPI parallel + * bus. + * + * - DRM_MODE_ENCODER_DPMST for special fake encoders used to allow + * mutliple DP MST streams to share one physical encoder. + */ + int encoder_type; + + /** + * @index: Position inside the mode_config.list, can be used as an array + * index. It is invariant over the lifetime of the encoder. + */ + unsigned index; + + /** + * @possible_crtcs: Bitmask of potential CRTC bindings, using + * drm_crtc_index() as the index into the bitfield. The driver must set + * the bits for all &drm_crtc objects this encoder can be connected to + * before calling drm_encoder_init(). + * + * In reality almost every driver gets this wrong. + * + * Note that since CRTC objects can't be hotplugged the assigned indices + * are stable and hence known before registering all objects. + */ + uint32_t possible_crtcs; + + /** + * @possible_clones: Bitmask of potential sibling encoders for cloning, + * using drm_encoder_index() as the index into the bitfield. The driver + * must set the bits for all &drm_encoder objects which can clone a + * &drm_crtc together with this encoder before calling + * drm_encoder_init(). Drivers should set the bit representing the + * encoder itself, too. Cloning bits should be set such that when two + * encoders can be used in a cloned configuration, they both should have + * each another bits set. + * + * In reality almost every driver gets this wrong. + * + * Note that since encoder objects can't be hotplugged the assigned indices + * are stable and hence known before registering all objects. + */ + uint32_t possible_clones; + + struct drm_crtc *crtc; + struct drm_bridge *bridge; + const struct drm_encoder_funcs *funcs; + const struct drm_encoder_helper_funcs *helper_private; +}; + +#define obj_to_encoder(x) container_of(x, struct drm_encoder, base) + +__printf(5, 6) +int drm_encoder_init(struct drm_device *dev, + struct drm_encoder *encoder, + const struct drm_encoder_funcs *funcs, + int encoder_type, const char *name, ...); + +/** + * drm_encoder_index - find the index of a registered encoder + * @encoder: encoder to find index for + * + * Given a registered encoder, return the index of that encoder within a DRM + * device's list of encoders. + */ +static inline unsigned int drm_encoder_index(struct drm_encoder *encoder) +{ + return encoder->index; +} + +/* FIXME: We have an include file mess still, drm_crtc.h needs untangling. */ +static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc); + +/** + * drm_encoder_crtc_ok - can a given crtc drive a given encoder? + * @encoder: encoder to test + * @crtc: crtc to test + * + * Returns false if @encoder can't be driven by @crtc, true otherwise. + */ +static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder, + struct drm_crtc *crtc) +{ + return !!(encoder->possible_crtcs & drm_crtc_mask(crtc)); +} + +/** + * drm_encoder_find - find a &drm_encoder + * @dev: DRM device + * @id: encoder id + * + * Returns the encoder with @id, NULL if it doesn't exist. Simple wrapper around + * drm_mode_object_find(). + */ +static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev, + uint32_t id) +{ + struct drm_mode_object *mo; + + mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); + + return mo ? obj_to_encoder(mo) : NULL; +} + +void drm_encoder_cleanup(struct drm_encoder *encoder); + +/** + * drm_for_each_encoder_mask - iterate over encoders specified by bitmask + * @encoder: the loop cursor + * @dev: the DRM device + * @encoder_mask: bitmask of encoder indices + * + * Iterate over all encoders specified by bitmask. + */ +#define drm_for_each_encoder_mask(encoder, dev, encoder_mask) \ + list_for_each_entry((encoder), &(dev)->mode_config.encoder_list, head) \ + for_each_if ((encoder_mask) & (1 << drm_encoder_index(encoder))) + +/** + * drm_for_each_encoder - iterate over all encoders + * @encoder: the loop cursor + * @dev: the DRM device + * + * Iterate over all encoders of @dev. + */ +#define drm_for_each_encoder(encoder, dev) \ + list_for_each_entry(encoder, &(dev)->mode_config.encoder_list, head) + +#endif diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index db8d4780eaa2..ed8edfef75b2 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -32,6 +32,7 @@ struct drm_fb_helper; +#include <drm/drm_crtc.h> #include <linux/kgdb.h> enum mode_set_atomic { @@ -176,6 +177,7 @@ struct drm_fb_helper_connector { * the screen buffer * @dirty_lock: spinlock protecting @dirty_clip * @dirty_work: worker used to flush the framebuffer + * @resume_work: worker used during resume if the console lock is already taken * * This is the main structure used by the fbdev helpers. Drivers supporting * fbdev emulation should embedded this into their overall driver structure. @@ -196,6 +198,7 @@ struct drm_fb_helper { struct drm_clip_rect dirty_clip; spinlock_t dirty_lock; struct work_struct dirty_work; + struct work_struct resume_work; /** * @kernel_fb_list: @@ -214,8 +217,20 @@ struct drm_fb_helper { bool delayed_hotplug; }; +/** + * define DRM_FB_HELPER_DEFAULT_OPS - helper define for drm drivers + * + * Helper define to register default implementations of drm_fb_helper + * functions. To be used in struct fb_ops of drm drivers. + */ +#define DRM_FB_HELPER_DEFAULT_OPS \ + .fb_check_var = drm_fb_helper_check_var, \ + .fb_set_par = drm_fb_helper_set_par, \ + .fb_setcmap = drm_fb_helper_setcmap, \ + .fb_blank = drm_fb_helper_blank, \ + .fb_pan_display = drm_fb_helper_pan_display + #ifdef CONFIG_DRM_FBDEV_EMULATION -int drm_fb_helper_modinit(void); void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, const struct drm_fb_helper_funcs *funcs); int drm_fb_helper_init(struct drm_device *dev, @@ -263,7 +278,9 @@ void drm_fb_helper_cfb_copyarea(struct fb_info *info, void drm_fb_helper_cfb_imageblit(struct fb_info *info, const struct fb_image *image); -void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state); +void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend); +void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, + bool suspend); int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); @@ -283,11 +300,6 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector); #else -static inline int drm_fb_helper_modinit(void) -{ - return 0; -} - static inline void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, const struct drm_fb_helper_funcs *funcs) @@ -417,7 +429,12 @@ static inline void drm_fb_helper_cfb_imageblit(struct fb_info *info, } static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, - int state) + bool suspend) +{ +} + +static inline void +drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend) { } @@ -475,5 +492,18 @@ drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, { return 0; } + +#endif + +static inline int +drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) +{ +#if IS_REACHABLE(CONFIG_FB) + return remove_conflicting_framebuffers(a, name, primary); +#else + return 0; #endif +} + #endif diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h index 7f90a396cf2b..30c30fa87ee8 100644 --- a/include/drm/drm_fourcc.h +++ b/include/drm/drm_fourcc.h @@ -25,6 +25,7 @@ #include <linux/types.h> #include <uapi/drm/drm_fourcc.h> +uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp); int drm_format_num_planes(uint32_t format); int drm_format_plane_cpp(uint32_t format, int plane); @@ -32,6 +33,6 @@ int drm_format_horz_chroma_subsampling(uint32_t format); int drm_format_vert_chroma_subsampling(uint32_t format); int drm_format_plane_width(int width, uint32_t format, int plane); int drm_format_plane_height(int height, uint32_t format, int plane); -const char *drm_get_format_name(uint32_t format); +char *drm_get_format_name(uint32_t format) __malloc; #endif /* __DRM_FOURCC_H__ */ diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h new file mode 100644 index 000000000000..f5ae1f436a4b --- /dev/null +++ b/include/drm/drm_framebuffer.h @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_FRAMEBUFFER_H__ +#define __DRM_FRAMEBUFFER_H__ + +#include <linux/list.h> +#include <linux/ctype.h> +#include <drm/drm_mode_object.h> + +struct drm_framebuffer; +struct drm_file; +struct drm_device; + +/** + * struct drm_framebuffer_funcs - framebuffer hooks + */ +struct drm_framebuffer_funcs { + /** + * @destroy: + * + * Clean up framebuffer resources, specifically also unreference the + * backing storage. The core guarantees to call this function for every + * framebuffer successfully created by ->fb_create() in + * &drm_mode_config_funcs. Drivers must also call + * drm_framebuffer_cleanup() to release DRM core resources for this + * framebuffer. + */ + void (*destroy)(struct drm_framebuffer *framebuffer); + + /** + * @create_handle: + * + * Create a buffer handle in the driver-specific buffer manager (either + * GEM or TTM) valid for the passed-in struct &drm_file. This is used by + * the core to implement the GETFB IOCTL, which returns (for + * sufficiently priviledged user) also a native buffer handle. This can + * be used for seamless transitions between modesetting clients by + * copying the current screen contents to a private buffer and blending + * between that and the new contents. + * + * GEM based drivers should call drm_gem_handle_create() to create the + * handle. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ + int (*create_handle)(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned int *handle); + /** + * @dirty: + * + * Optional callback for the dirty fb IOCTL. + * + * Userspace can notify the driver via this callback that an area of the + * framebuffer has changed and should be flushed to the display + * hardware. This can also be used internally, e.g. by the fbdev + * emulation, though that's not the case currently. + * + * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd + * for more information as all the semantics and arguments have a one to + * one mapping on this function. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ + int (*dirty)(struct drm_framebuffer *framebuffer, + struct drm_file *file_priv, unsigned flags, + unsigned color, struct drm_clip_rect *clips, + unsigned num_clips); +}; + +/** + * struct drm_framebuffer - frame buffer object + * + * Note that the fb is refcounted for the benefit of driver internals, + * for example some hw, disabling a CRTC/plane is asynchronous, and + * scanout does not actually complete until the next vblank. So some + * cleanup (like releasing the reference(s) on the backing GEM bo(s)) + * should be deferred. In cases like this, the driver would like to + * hold a ref to the fb even though it has already been removed from + * userspace perspective. See drm_framebuffer_reference() and + * drm_framebuffer_unreference(). + * + * The refcount is stored inside the mode object @base. + */ +struct drm_framebuffer { + /** + * @dev: DRM device this framebuffer belongs to + */ + struct drm_device *dev; + /** + * @head: Place on the dev->mode_config.fb_list, access protected by + * dev->mode_config.fb_lock. + */ + struct list_head head; + + /** + * @base: base modeset object structure, contains the reference count. + */ + struct drm_mode_object base; + /** + * @funcs: framebuffer vfunc table + */ + const struct drm_framebuffer_funcs *funcs; + /** + * @pitches: Line stride per buffer. For userspace created object this + * is copied from drm_mode_fb_cmd2. + */ + unsigned int pitches[4]; + /** + * @offsets: Offset from buffer start to the actual pixel data in bytes, + * per buffer. For userspace created object this is copied from + * drm_mode_fb_cmd2. + * + * Note that this is a linear offset and does not take into account + * tiling or buffer laytou per @modifier. It meant to be used when the + * actual pixel data for this framebuffer plane starts at an offset, + * e.g. when multiple planes are allocated within the same backing + * storage buffer object. For tiled layouts this generally means it + * @offsets must at least be tile-size aligned, but hardware often has + * stricter requirements. + * + * This should not be used to specifiy x/y pixel offsets into the buffer + * data (even for linear buffers). Specifying an x/y pixel offset is + * instead done through the source rectangle in struct &drm_plane_state. + */ + unsigned int offsets[4]; + /** + * @modifier: Data layout modifier, per buffer. This is used to describe + * tiling, or also special layouts (like compression) of auxiliary + * buffers. For userspace created object this is copied from + * drm_mode_fb_cmd2. + */ + uint64_t modifier[4]; + /** + * @width: Logical width of the visible area of the framebuffer, in + * pixels. + */ + unsigned int width; + /** + * @height: Logical height of the visible area of the framebuffer, in + * pixels. + */ + unsigned int height; + /** + * @depth: Depth in bits per pixel for RGB formats. 0 for everything + * else. Legacy information derived from @pixel_format, it's suggested to use + * the DRM FOURCC codes and helper functions directly instead. + */ + unsigned int depth; + /** + * @bits_per_pixel: Storage used bits per pixel for RGB formats. 0 for + * everything else. Legacy information derived from @pixel_format, it's + * suggested to use the DRM FOURCC codes and helper functions directly + * instead. + */ + int bits_per_pixel; + /** + * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or + * DRM_MODE_FB_MODIFIERS. + */ + int flags; + /** + * @pixel_format: DRM FOURCC code describing the pixel format. + */ + uint32_t pixel_format; /* fourcc format */ + /** + * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor + * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR + * universal plane. + */ + int hot_x; + /** + * @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor + * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR + * universal plane. + */ + int hot_y; + /** + * @filp_head: Placed on struct &drm_file fbs list_head, protected by + * fbs_lock in the same structure. + */ + struct list_head filp_head; +}; + +#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base) + +int drm_framebuffer_init(struct drm_device *dev, + struct drm_framebuffer *fb, + const struct drm_framebuffer_funcs *funcs); +struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, + uint32_t id); +void drm_framebuffer_remove(struct drm_framebuffer *fb); +void drm_framebuffer_cleanup(struct drm_framebuffer *fb); +void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); + +/** + * drm_framebuffer_reference - incr the fb refcnt + * @fb: framebuffer + * + * This functions increments the fb's refcount. + */ +static inline void drm_framebuffer_reference(struct drm_framebuffer *fb) +{ + drm_mode_object_reference(&fb->base); +} + +/** + * drm_framebuffer_unreference - unref a framebuffer + * @fb: framebuffer to unref + * + * This functions decrements the fb's refcount and frees it if it drops to zero. + */ +static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb) +{ + drm_mode_object_unreference(&fb->base); +} + +/** + * drm_framebuffer_read_refcount - read the framebuffer reference count. + * @fb: framebuffer + * + * This functions returns the framebuffer's reference count. + */ +static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb) +{ + return atomic_read(&fb->base.refcount.refcount); +} + +/** + * drm_for_each_fb - iterate over all framebuffers + * @fb: the loop cursor + * @dev: the DRM device + * + * Iterate over all framebuffers of @dev. User must hold the fb_lock from + * &drm_mode_config. + */ +#define drm_for_each_fb(fb, dev) \ + for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \ + fb = list_first_entry(&(dev)->mode_config.fb_list, \ + struct drm_framebuffer, head); \ + &fb->head != (&(dev)->mode_config.fb_list); \ + fb = list_next_entry(fb, head)) +#endif diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index fca1cd1b9c26..9f63736e6163 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -210,8 +210,8 @@ drm_gem_object_reference(struct drm_gem_object *obj) * drm_gem_object_unreference_unlocked(). * * Drivers should never call this directly in their code. Instead they should - * wrap it up into a driver_gem_object_unreference(struct driver_gem_object - * *obj) wrapper function, and use that. Shared code should never call this, to + * wrap it up into a ``driver_gem_object_unreference(struct driver_gem_object + * *obj)`` wrapper function, and use that. Shared code should never call this, to * avoid breaking drivers by accident which still depend upon dev->struct_mutex * locking. */ diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 47ac92584d76..4fef19064b0f 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -265,11 +265,15 @@ int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, u16 end); int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, u16 end); -int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline); int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, enum mipi_dsi_dcs_tear_mode mode); int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format); +int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline); +int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, + u16 brightness); +int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, + u16 *brightness); /** * struct mipi_dsi_driver - DSI driver diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index fc65118e5077..205ddcf6d55d 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -37,6 +37,7 @@ * Generic range manager structs */ #include <linux/bug.h> +#include <linux/rbtree.h> #include <linux/kernel.h> #include <linux/list.h> #include <linux/spinlock.h> @@ -61,6 +62,7 @@ enum drm_mm_allocator_flags { struct drm_mm_node { struct list_head node_list; struct list_head hole_stack; + struct rb_node rb; unsigned hole_follows : 1; unsigned scanned_block : 1; unsigned scanned_prev_free : 1; @@ -70,6 +72,7 @@ struct drm_mm_node { unsigned long color; u64 start; u64 size; + u64 __subtree_last; struct drm_mm *mm; }; @@ -79,6 +82,9 @@ struct drm_mm { /* head_node.node_list is the list of all memory nodes, ordered * according to the (increasing) start address of the memory node. */ struct drm_mm_node head_node; + /* Keep an interval_tree for fast lookup of drm_mm_nodes by address. */ + struct rb_root interval_tree; + unsigned int scan_check_range : 1; unsigned scan_alignment; unsigned long scan_color; @@ -295,6 +301,12 @@ void drm_mm_init(struct drm_mm *mm, void drm_mm_takedown(struct drm_mm *mm); bool drm_mm_clean(struct drm_mm *mm); +struct drm_mm_node * +drm_mm_interval_first(struct drm_mm *mm, u64 start, u64 last); + +struct drm_mm_node * +drm_mm_interval_next(struct drm_mm_node *node, u64 start, u64 last); + void drm_mm_init_scan(struct drm_mm *mm, u64 size, unsigned alignment, diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h new file mode 100644 index 000000000000..43460b21d112 --- /dev/null +++ b/include/drm/drm_mode_object.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_MODESET_H__ +#define __DRM_MODESET_H__ + +#include <linux/kref.h> +struct drm_object_properties; +struct drm_property; +struct drm_device; + +/** + * struct drm_mode_object - base structure for modeset objects + * @id: userspace visible identifier + * @type: type of the object, one of DRM_MODE_OBJECT\_\* + * @properties: properties attached to this object, including values + * @refcount: reference count for objects which with dynamic lifetime + * @free_cb: free function callback, only set for objects with dynamic lifetime + * + * Base structure for modeset objects visible to userspace. Objects can be + * looked up using drm_mode_object_find(). Besides basic uapi interface + * properties like @id and @type it provides two services: + * + * - It tracks attached properties and their values. This is used by &drm_crtc, + * &drm_plane and &drm_connector. Properties are attached by calling + * drm_object_attach_property() before the object is visible to userspace. + * + * - For objects with dynamic lifetimes (as indicated by a non-NULL @free_cb) it + * provides reference counting through drm_mode_object_reference() and + * drm_mode_object_unreference(). This is used by &drm_framebuffer, + * &drm_connector and &drm_property_blob. These objects provide specialized + * reference counting wrappers. + */ +struct drm_mode_object { + uint32_t id; + uint32_t type; + struct drm_object_properties *properties; + struct kref refcount; + void (*free_cb)(struct kref *kref); +}; + +#define DRM_OBJECT_MAX_PROPERTY 24 +/** + * struct drm_object_properties - property tracking for &drm_mode_object + */ +struct drm_object_properties { + /** + * @count: number of valid properties, must be less than or equal to + * DRM_OBJECT_MAX_PROPERTY. + */ + + int count; + /** + * @properties: Array of pointers to &drm_property. + * + * NOTE: if we ever start dynamically destroying properties (ie. + * not at drm_mode_config_cleanup() time), then we'd have to do + * a better job of detaching property from mode objects to avoid + * dangling property pointers: + */ + struct drm_property *properties[DRM_OBJECT_MAX_PROPERTY]; + + /** + * @values: Array to store the property values, matching @properties. Do + * not read/write values directly, but use + * drm_object_property_get_value() and drm_object_property_set_value(). + * + * Note that atomic drivers do not store mutable properties in this + * array, but only the decoded values in the corresponding state + * structure. The decoding is done using the ->atomic_get_property and + * ->atomic_set_property hooks of the corresponding object. Hence atomic + * drivers should not use drm_object_property_set_value() and + * drm_object_property_get_value() on mutable objects, i.e. those + * without the DRM_MODE_PROP_IMMUTABLE flag set. + */ + uint64_t values[DRM_OBJECT_MAX_PROPERTY]; +}; + +/* Avoid boilerplate. I'm tired of typing. */ +#define DRM_ENUM_NAME_FN(fnname, list) \ + const char *fnname(int val) \ + { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(list); i++) { \ + if (list[i].type == val) \ + return list[i].name; \ + } \ + return "(unknown)"; \ + } + +struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, + uint32_t id, uint32_t type); +void drm_mode_object_reference(struct drm_mode_object *obj); +void drm_mode_object_unreference(struct drm_mode_object *obj); + +int drm_object_property_set_value(struct drm_mode_object *obj, + struct drm_property *property, + uint64_t val); +int drm_object_property_get_value(struct drm_mode_object *obj, + struct drm_property *property, + uint64_t *value); + +void drm_object_attach_property(struct drm_mode_object *obj, + struct drm_property *property, + uint64_t init_val); +#endif diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index ff481770d76b..9934d91619c1 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -27,6 +27,13 @@ #ifndef __DRM_MODES_H__ #define __DRM_MODES_H__ +#include <linux/hdmi.h> + +#include <drm/drm_mode_object.h> +#include <drm/drm_connector.h> + +struct videomode; + /* * Note on terminology: here, for brevity and convenience, we refer to connector * control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS, @@ -400,20 +407,7 @@ struct drm_display_mode { enum hdmi_picture_aspect picture_aspect_ratio; }; -/* mode specified on the command line */ -struct drm_cmdline_mode { - bool specified; - bool refresh_specified; - bool bpp_specified; - int xres, yres; - int bpp; - int refresh; - bool rb; - bool interlace; - bool cvt; - bool margins; - enum drm_connector_force force; -}; +#define obj_to_mode(x) container_of(x, struct drm_display_mode, base) /** * drm_mode_is_stereo - check for stereo mode flags @@ -434,7 +428,7 @@ struct drm_cmdline_mode; struct drm_display_mode *drm_mode_create(struct drm_device *dev); void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out, - const struct drm_display_mode *in); + const struct drm_display_mode *in); int drm_mode_convert_umode(struct drm_display_mode *out, const struct drm_mode_modeinfo *in); void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); @@ -457,8 +451,9 @@ void drm_display_mode_from_videomode(const struct videomode *vm, struct drm_display_mode *dmode); void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, struct videomode *vm); +void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags); int of_get_drm_display_mode(struct device_node *np, - struct drm_display_mode *dmode, + struct drm_display_mode *dmode, u32 *bus_flags, int index); void drm_mode_set_name(struct drm_display_mode *mode); diff --git a/include/drm/drm_modeset_helper.h b/include/drm/drm_modeset_helper.h new file mode 100644 index 000000000000..b8051d5abe10 --- /dev/null +++ b/include/drm/drm_modeset_helper.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_KMS_HELPER_H__ +#define __DRM_KMS_HELPER_H__ + +#include <drm/drmP.h> + +void drm_helper_move_panel_connectors_to_head(struct drm_device *); + +void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, + const struct drm_mode_fb_cmd2 *mode_cmd); + +int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, + const struct drm_crtc_funcs *funcs); + +#endif diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index b55f21857a98..10e449c86dbd 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -266,6 +266,8 @@ struct drm_crtc_helper_funcs { * disable anything at the CRTC level. To ensure that runtime PM * handling (using either DPMS or the new "ACTIVE" property) works * @disable must be the inverse of @enable for atomic drivers. + * Atomic drivers should consider to use @atomic_disable instead of + * this one. * * NOTE: * @@ -391,6 +393,28 @@ struct drm_crtc_helper_funcs { */ void (*atomic_flush)(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); + + /** + * @atomic_disable: + * + * This callback should be used to disable the CRTC. With the atomic + * drivers it is called after all encoders connected to this CRTC have + * been shut off already using their own ->disable hook. If that + * sequence is too simple drivers can just add their own hooks and call + * it from this CRTC callback here by looping over all encoders + * connected to it using for_each_encoder_on_crtc(). + * + * This hook is used only by atomic helpers. Atomic drivers don't + * need to implement it if there's no need to disable anything at the + * CRTC level. + * + * Comparing to @disable, this one provides the additional input + * parameter @old_crtc_state which could be used to access the old + * state. Atomic drivers should consider to use this one instead + * of @disable. + */ + void (*atomic_disable)(struct drm_crtc *crtc, + struct drm_crtc_state *old_crtc_state); }; /** @@ -523,12 +547,41 @@ struct drm_encoder_helper_funcs { * * This callback is used both by the legacy CRTC helpers and the atomic * modeset helpers. It is optional in the atomic helpers. + * + * NOTE: + * + * If the driver uses the atomic modeset helpers and needs to inspect + * the connector state or connector display info during mode setting, + * @atomic_mode_set can be used instead. */ void (*mode_set)(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); /** + * @atomic_mode_set: + * + * This callback is used to update the display mode of an encoder. + * + * Note that the display pipe is completely off when this function is + * called. Drivers which need hardware to be running before they program + * the new display mode (because they implement runtime PM) should not + * use this hook, because the helper library calls it only once and not + * every time the display pipeline is suspended using either DPMS or the + * new "ACTIVE" property. Such drivers should instead move all their + * encoder setup into the ->enable() callback. + * + * This callback is used by the atomic modeset helpers in place of the + * @mode_set callback, if set by the driver. It is optional and should + * be used instead of @mode_set if the driver needs to inspect the + * connector state or display info, since there is no direct way to + * go from the encoder to the current connector. + */ + void (*atomic_mode_set)(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state); + + /** * @get_crtc: * * This callback is used by the legacy CRTC helpers to work around @@ -826,7 +879,7 @@ struct drm_plane_helper_funcs { * everything else must complete successfully. */ int (*prepare_fb)(struct drm_plane *plane, - const struct drm_plane_state *new_state); + struct drm_plane_state *new_state); /** * @cleanup_fb: * @@ -837,7 +890,7 @@ struct drm_plane_helper_funcs { * transitional plane helpers, but it is optional. */ void (*cleanup_fb)(struct drm_plane *plane, - const struct drm_plane_state *old_state); + struct drm_plane_state *old_state); /** * @atomic_check: diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h new file mode 100644 index 000000000000..43cf193e54d6 --- /dev/null +++ b/include/drm/drm_plane.h @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_PLANE_H__ +#define __DRM_PLANE_H__ + +#include <linux/list.h> +#include <linux/ctype.h> +#include <drm/drm_mode_object.h> + +struct drm_crtc; + +/** + * struct drm_plane_state - mutable plane state + * @plane: backpointer to the plane + * @crtc: currently bound CRTC, NULL if disabled + * @fb: currently bound framebuffer + * @fence: optional fence to wait for before scanning out @fb + * @crtc_x: left position of visible portion of plane on crtc + * @crtc_y: upper position of visible portion of plane on crtc + * @crtc_w: width of visible portion of plane on crtc + * @crtc_h: height of visible portion of plane on crtc + * @src_x: left position of visible portion of plane within + * plane (in 16.16) + * @src_y: upper position of visible portion of plane within + * plane (in 16.16) + * @src_w: width of visible portion of plane (in 16.16) + * @src_h: height of visible portion of plane (in 16.16) + * @rotation: rotation of the plane + * @zpos: priority of the given plane on crtc (optional) + * @normalized_zpos: normalized value of zpos: unique, range from 0 to N-1 + * where N is the number of active planes for given crtc + * @src: clipped source coordinates of the plane (in 16.16) + * @dst: clipped destination coordinates of the plane + * @visible: visibility of the plane + * @state: backpointer to global drm_atomic_state + */ +struct drm_plane_state { + struct drm_plane *plane; + + struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_plane() */ + struct drm_framebuffer *fb; /* do not write directly, use drm_atomic_set_fb_for_plane() */ + struct fence *fence; + + /* Signed dest location allows it to be partially off screen */ + int32_t crtc_x, crtc_y; + uint32_t crtc_w, crtc_h; + + /* Source values are 16.16 fixed point */ + uint32_t src_x, src_y; + uint32_t src_h, src_w; + + /* Plane rotation */ + unsigned int rotation; + + /* Plane zpos */ + unsigned int zpos; + unsigned int normalized_zpos; + + /* Clipped coordinates */ + struct drm_rect src, dst; + + /* + * Is the plane actually visible? Can be false even + * if fb!=NULL and crtc!=NULL, due to clipping. + */ + bool visible; + + struct drm_atomic_state *state; +}; + + +/** + * struct drm_plane_funcs - driver plane control functions + */ +struct drm_plane_funcs { + /** + * @update_plane: + * + * This is the legacy entry point to enable and configure the plane for + * the given CRTC and framebuffer. It is never called to disable the + * plane, i.e. the passed-in crtc and fb paramters are never NULL. + * + * The source rectangle in frame buffer memory coordinates is given by + * the src_x, src_y, src_w and src_h parameters (as 16.16 fixed point + * values). Devices that don't support subpixel plane coordinates can + * ignore the fractional part. + * + * The destination rectangle in CRTC coordinates is given by the + * crtc_x, crtc_y, crtc_w and crtc_h parameters (as integer values). + * Devices scale the source rectangle to the destination rectangle. If + * scaling is not supported, and the source rectangle size doesn't match + * the destination rectangle size, the driver must return a + * -<errorname>EINVAL</errorname> error. + * + * Drivers implementing atomic modeset should use + * drm_atomic_helper_update_plane() to implement this hook. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ + int (*update_plane)(struct drm_plane *plane, + struct drm_crtc *crtc, struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h); + + /** + * @disable_plane: + * + * This is the legacy entry point to disable the plane. The DRM core + * calls this method in response to a DRM_IOCTL_MODE_SETPLANE IOCTL call + * with the frame buffer ID set to 0. Disabled planes must not be + * processed by the CRTC. + * + * Drivers implementing atomic modeset should use + * drm_atomic_helper_disable_plane() to implement this hook. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ + int (*disable_plane)(struct drm_plane *plane); + + /** + * @destroy: + * + * Clean up plane resources. This is only called at driver unload time + * through drm_mode_config_cleanup() since a plane cannot be hotplugged + * in DRM. + */ + void (*destroy)(struct drm_plane *plane); + + /** + * @reset: + * + * Reset plane hardware and software state to off. This function isn't + * called by the core directly, only through drm_mode_config_reset(). + * It's not a helper hook only for historical reasons. + * + * Atomic drivers can use drm_atomic_helper_plane_reset() to reset + * atomic state using this hook. + */ + void (*reset)(struct drm_plane *plane); + + /** + * @set_property: + * + * This is the legacy entry point to update a property attached to the + * plane. + * + * Drivers implementing atomic modeset should use + * drm_atomic_helper_plane_set_property() to implement this hook. + * + * This callback is optional if the driver does not support any legacy + * driver-private properties. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ + int (*set_property)(struct drm_plane *plane, + struct drm_property *property, uint64_t val); + + /** + * @atomic_duplicate_state: + * + * Duplicate the current atomic state for this plane and return it. + * The core and helpers gurantee that any atomic state duplicated with + * this hook and still owned by the caller (i.e. not transferred to the + * driver by calling ->atomic_commit() from struct + * &drm_mode_config_funcs) will be cleaned up by calling the + * @atomic_destroy_state hook in this structure. + * + * Atomic drivers which don't subclass struct &drm_plane_state should use + * drm_atomic_helper_plane_duplicate_state(). Drivers that subclass the + * state structure to extend it with driver-private state should use + * __drm_atomic_helper_plane_duplicate_state() to make sure shared state is + * duplicated in a consistent fashion across drivers. + * + * It is an error to call this hook before plane->state has been + * initialized correctly. + * + * NOTE: + * + * If the duplicate state references refcounted resources this hook must + * acquire a reference for each of them. The driver must release these + * references again in @atomic_destroy_state. + * + * RETURNS: + * + * Duplicated atomic state or NULL when the allocation failed. + */ + struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane); + + /** + * @atomic_destroy_state: + * + * Destroy a state duplicated with @atomic_duplicate_state and release + * or unreference all resources it references + */ + void (*atomic_destroy_state)(struct drm_plane *plane, + struct drm_plane_state *state); + + /** + * @atomic_set_property: + * + * Decode a driver-private property value and store the decoded value + * into the passed-in state structure. Since the atomic core decodes all + * standardized properties (even for extensions beyond the core set of + * properties which might not be implemented by all drivers) this + * requires drivers to subclass the state structure. + * + * Such driver-private properties should really only be implemented for + * truly hardware/vendor specific state. Instead it is preferred to + * standardize atomic extension and decode the properties used to expose + * such an extension in the core. + * + * Do not call this function directly, use + * drm_atomic_plane_set_property() instead. + * + * This callback is optional if the driver does not support any + * driver-private atomic properties. + * + * NOTE: + * + * This function is called in the state assembly phase of atomic + * modesets, which can be aborted for any reason (including on + * userspace's request to just check whether a configuration would be + * possible). Drivers MUST NOT touch any persistent state (hardware or + * software) or data structures except the passed in @state parameter. + * + * Also since userspace controls in which order properties are set this + * function must not do any input validation (since the state update is + * incomplete and hence likely inconsistent). Instead any such input + * validation must be done in the various atomic_check callbacks. + * + * RETURNS: + * + * 0 if the property has been found, -EINVAL if the property isn't + * implemented by the driver (which shouldn't ever happen, the core only + * asks for properties attached to this plane). No other validation is + * allowed by the driver. The core already checks that the property + * value is within the range (integer, valid enum value, ...) the driver + * set when registering the property. + */ + int (*atomic_set_property)(struct drm_plane *plane, + struct drm_plane_state *state, + struct drm_property *property, + uint64_t val); + + /** + * @atomic_get_property: + * + * Reads out the decoded driver-private property. This is used to + * implement the GETPLANE IOCTL. + * + * Do not call this function directly, use + * drm_atomic_plane_get_property() instead. + * + * This callback is optional if the driver does not support any + * driver-private atomic properties. + * + * RETURNS: + * + * 0 on success, -EINVAL if the property isn't implemented by the + * driver (which should never happen, the core only asks for + * properties attached to this plane). + */ + int (*atomic_get_property)(struct drm_plane *plane, + const struct drm_plane_state *state, + struct drm_property *property, + uint64_t *val); + /** + * @late_register: + * + * This optional hook can be used to register additional userspace + * interfaces attached to the plane like debugfs interfaces. + * It is called late in the driver load sequence from drm_dev_register(). + * Everything added from this callback should be unregistered in + * the early_unregister callback. + * + * Returns: + * + * 0 on success, or a negative error code on failure. + */ + int (*late_register)(struct drm_plane *plane); + + /** + * @early_unregister: + * + * This optional hook should be used to unregister the additional + * userspace interfaces attached to the plane from + * late_unregister(). It is called from drm_dev_unregister(), + * early in the driver unload sequence to disable userspace access + * before data structures are torndown. + */ + void (*early_unregister)(struct drm_plane *plane); +}; + +/** + * enum drm_plane_type - uapi plane type enumeration + * + * For historical reasons not all planes are made the same. This enumeration is + * used to tell the different types of planes apart to implement the different + * uapi semantics for them. For userspace which is universal plane aware and + * which is using that atomic IOCTL there's no difference between these planes + * (beyong what the driver and hardware can support of course). + * + * For compatibility with legacy userspace, only overlay planes are made + * available to userspace by default. Userspace clients may set the + * DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate that they + * wish to receive a universal plane list containing all plane types. See also + * drm_for_each_legacy_plane(). + * + * WARNING: The values of this enum is UABI since they're exposed in the "type" + * property. + */ +enum drm_plane_type { + /** + * @DRM_PLANE_TYPE_OVERLAY: + * + * Overlay planes represent all non-primary, non-cursor planes. Some + * drivers refer to these types of planes as "sprites" internally. + */ + DRM_PLANE_TYPE_OVERLAY, + + /** + * @DRM_PLANE_TYPE_PRIMARY: + * + * Primary planes represent a "main" plane for a CRTC. Primary planes + * are the planes operated upon by CRTC modesetting and flipping + * operations described in the page_flip and set_config hooks in struct + * &drm_crtc_funcs. + */ + DRM_PLANE_TYPE_PRIMARY, + + /** + * @DRM_PLANE_TYPE_CURSOR: + * + * Cursor planes represent a "cursor" plane for a CRTC. Cursor planes + * are the planes operated upon by the DRM_IOCTL_MODE_CURSOR and + * DRM_IOCTL_MODE_CURSOR2 IOCTLs. + */ + DRM_PLANE_TYPE_CURSOR, +}; + + +/** + * struct drm_plane - central DRM plane control structure + * @dev: DRM device this plane belongs to + * @head: for list management + * @name: human readable name, can be overwritten by the driver + * @base: base mode object + * @possible_crtcs: pipes this plane can be bound to + * @format_types: array of formats supported by this plane + * @format_count: number of formats supported + * @format_default: driver hasn't supplied supported formats for the plane + * @crtc: currently bound CRTC + * @fb: currently bound fb + * @old_fb: Temporary tracking of the old fb while a modeset is ongoing. Used by + * drm_mode_set_config_internal() to implement correct refcounting. + * @funcs: helper functions + * @properties: property tracking for this plane + * @type: type of plane (overlay, primary, cursor) + * @state: current atomic state for this plane + * @zpos_property: zpos property for this plane + * @helper_private: mid-layer private data + */ +struct drm_plane { + struct drm_device *dev; + struct list_head head; + + char *name; + + /** + * @mutex: + * + * Protects modeset plane state, together with the mutex of &drm_crtc + * this plane is linked to (when active, getting actived or getting + * disabled). + */ + struct drm_modeset_lock mutex; + + struct drm_mode_object base; + + uint32_t possible_crtcs; + uint32_t *format_types; + unsigned int format_count; + bool format_default; + + struct drm_crtc *crtc; + struct drm_framebuffer *fb; + + struct drm_framebuffer *old_fb; + + const struct drm_plane_funcs *funcs; + + struct drm_object_properties properties; + + enum drm_plane_type type; + + /** + * @index: Position inside the mode_config.list, can be used as an array + * index. It is invariant over the lifetime of the plane. + */ + unsigned index; + + const struct drm_plane_helper_funcs *helper_private; + + struct drm_plane_state *state; + + struct drm_property *zpos_property; +}; + +#define obj_to_plane(x) container_of(x, struct drm_plane, base) + +extern __printf(8, 9) +int drm_universal_plane_init(struct drm_device *dev, + struct drm_plane *plane, + unsigned long possible_crtcs, + const struct drm_plane_funcs *funcs, + const uint32_t *formats, + unsigned int format_count, + enum drm_plane_type type, + const char *name, ...); +extern int drm_plane_init(struct drm_device *dev, + struct drm_plane *plane, + unsigned long possible_crtcs, + const struct drm_plane_funcs *funcs, + const uint32_t *formats, unsigned int format_count, + bool is_primary); +extern void drm_plane_cleanup(struct drm_plane *plane); + +/** + * drm_plane_index - find the index of a registered plane + * @plane: plane to find index for + * + * Given a registered plane, return the index of that plane within a DRM + * device's list of planes. + */ +static inline unsigned int drm_plane_index(struct drm_plane *plane) +{ + return plane->index; +} +extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx); +extern void drm_plane_force_disable(struct drm_plane *plane); + +int drm_mode_plane_set_obj_prop(struct drm_plane *plane, + struct drm_property *property, + uint64_t value); + +/** + * drm_plane_find - find a &drm_plane + * @dev: DRM device + * @id: plane id + * + * Returns the plane with @id, NULL if it doesn't exist. Simple wrapper around + * drm_mode_object_find(). + */ +static inline struct drm_plane *drm_plane_find(struct drm_device *dev, + uint32_t id) +{ + struct drm_mode_object *mo; + mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PLANE); + return mo ? obj_to_plane(mo) : NULL; +} + +/** + * drm_for_each_plane_mask - iterate over planes specified by bitmask + * @plane: the loop cursor + * @dev: the DRM device + * @plane_mask: bitmask of plane indices + * + * Iterate over all planes specified by bitmask. + */ +#define drm_for_each_plane_mask(plane, dev, plane_mask) \ + list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \ + for_each_if ((plane_mask) & (1 << drm_plane_index(plane))) + +/** + * drm_for_each_legacy_plane - iterate over all planes for legacy userspace + * @plane: the loop cursor + * @dev: the DRM device + * + * Iterate over all legacy planes of @dev, excluding primary and cursor planes. + * This is useful for implementing userspace apis when userspace is not + * universal plane aware. See also enum &drm_plane_type. + */ +#define drm_for_each_legacy_plane(plane, dev) \ + list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \ + for_each_if (plane->type == DRM_PLANE_TYPE_OVERLAY) + +/** + * drm_for_each_plane - iterate over all planes + * @plane: the loop cursor + * @dev: the DRM device + * + * Iterate over all planes of @dev, include primary and cursor planes. + */ +#define drm_for_each_plane(plane, dev) \ + list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) + + +#endif diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index 0e0c3573cce0..c18959685c06 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -27,6 +27,7 @@ #include <drm/drm_rect.h> #include <drm/drm_crtc.h> #include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_modeset_helper.h> /* * Drivers that don't allow primary plane scaling may pass this macro in place @@ -37,9 +38,11 @@ */ #define DRM_PLANE_HELPER_NO_SCALING (1<<16) -int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, - const struct drm_crtc_funcs *funcs); - +int drm_plane_helper_check_state(struct drm_plane_state *state, + const struct drm_rect *clip, + int min_scale, int max_scale, + bool can_position, + bool can_update_disabled); int drm_plane_helper_check_update(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h new file mode 100644 index 000000000000..43c4b6a2046d --- /dev/null +++ b/include/drm/drm_property.h @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_PROPERTY_H__ +#define __DRM_PROPERTY_H__ + +#include <linux/list.h> +#include <linux/ctype.h> +#include <drm/drm_mode_object.h> + +/** + * struct drm_property_enum - symbolic values for enumerations + * @value: numeric property value for this enum entry + * @head: list of enum values, linked to enum_list in &drm_property + * @name: symbolic name for the enum + * + * For enumeration and bitmask properties this structure stores the symbolic + * decoding for each value. This is used for example for the rotation property. + */ +struct drm_property_enum { + uint64_t value; + struct list_head head; + char name[DRM_PROP_NAME_LEN]; +}; + +/** + * struct drm_property - modeset object property + * + * This structure represent a modeset object property. It combines both the name + * of the property with the set of permissible values. This means that when a + * driver wants to use a property with the same name on different objects, but + * with different value ranges, then it must create property for each one. An + * example would be rotation of &drm_plane, when e.g. the primary plane cannot + * be rotated. But if both the name and the value range match, then the same + * property structure can be instantiated multiple times for the same object. + * Userspace must be able to cope with this and cannot assume that the same + * symbolic property will have the same modeset object ID on all modeset + * objects. + * + * Properties are created by one of the special functions, as explained in + * detail in the @flags structure member. + * + * To actually expose a property it must be attached to each object using + * drm_object_attach_property(). Currently properties can only be attached to + * &drm_connector, &drm_crtc and &drm_plane. + * + * Properties are also used as the generic metadatatransport for the atomic + * IOCTL. Everything that was set directly in structures in the legacy modeset + * IOCTLs (like the plane source or destination windows, or e.g. the links to + * the CRTC) is exposed as a property with the DRM_MODE_PROP_ATOMIC flag set. + */ +struct drm_property { + /** + * @head: per-device list of properties, for cleanup. + */ + struct list_head head; + + /** + * @base: base KMS object + */ + struct drm_mode_object base; + + /** + * @flags: + * + * Property flags and type. A property needs to be one of the following + * types: + * + * DRM_MODE_PROP_RANGE + * Range properties report their minimum and maximum admissible unsigned values. + * The KMS core verifies that values set by application fit in that + * range. The range is unsigned. Range properties are created using + * drm_property_create_range(). + * + * DRM_MODE_PROP_SIGNED_RANGE + * Range properties report their minimum and maximum admissible unsigned values. + * The KMS core verifies that values set by application fit in that + * range. The range is signed. Range properties are created using + * drm_property_create_signed_range(). + * + * DRM_MODE_PROP_ENUM + * Enumerated properties take a numerical value that ranges from 0 to + * the number of enumerated values defined by the property minus one, + * and associate a free-formed string name to each value. Applications + * can retrieve the list of defined value-name pairs and use the + * numerical value to get and set property instance values. Enum + * properties are created using drm_property_create_enum(). + * + * DRM_MODE_PROP_BITMASK + * Bitmask properties are enumeration properties that additionally + * restrict all enumerated values to the 0..63 range. Bitmask property + * instance values combine one or more of the enumerated bits defined + * by the property. Bitmask properties are created using + * drm_property_create_bitmask(). + * + * DRM_MODE_PROB_OBJECT + * Object properties are used to link modeset objects. This is used + * extensively in the atomic support to create the display pipeline, + * by linking &drm_framebuffer to &drm_plane, &drm_plane to + * &drm_crtc and &drm_connector to &drm_crtc. An object property can + * only link to a specific type of &drm_mode_object, this limit is + * enforced by the core. Object properties are created using + * drm_property_create_object(). + * + * Object properties work like blob properties, but in a more + * general fashion. They are limited to atomic drivers and must have + * the DRM_MODE_PROP_ATOMIC flag set. + * + * DRM_MODE_PROP_BLOB + * Blob properties store a binary blob without any format restriction. + * The binary blobs are created as KMS standalone objects, and blob + * property instance values store the ID of their associated blob + * object. Blob properties are created by calling + * drm_property_create() with DRM_MODE_PROP_BLOB as the type. + * + * Actual blob objects to contain blob data are created using + * drm_property_create_blob(), or through the corresponding IOCTL. + * + * Besides the built-in limit to only accept blob objects blob + * properties work exactly like object properties. The only reasons + * blob properties exist is backwards compatibility with existing + * userspace. + * + * In addition a property can have any combination of the below flags: + * + * DRM_MODE_PROP_ATOMIC + * Set for properties which encode atomic modeset state. Such + * properties are not exposed to legacy userspace. + * + * DRM_MODE_PROP_IMMUTABLE + * Set for properties where userspace cannot be changed by + * userspace. The kernel is allowed to update the value of these + * properties. This is generally used to expose probe state to + * usersapce, e.g. the EDID, or the connector path property on DP + * MST sinks. + */ + uint32_t flags; + + /** + * @name: symbolic name of the properties + */ + char name[DRM_PROP_NAME_LEN]; + + /** + * @num_values: size of the @values array. + */ + uint32_t num_values; + + /** + * @values: + * + * Array with limits and values for the property. The + * interpretation of these limits is dependent upon the type per @flags. + */ + uint64_t *values; + + /** + * @dev: DRM device + */ + struct drm_device *dev; + + /** + * @enum_list: + * + * List of &drm_prop_enum_list structures with the symbolic names for + * enum and bitmask values. + */ + struct list_head enum_list; +}; + +/** + * struct drm_property_blob - Blob data for &drm_property + * @base: base KMS object + * @dev: DRM device + * @head_global: entry on the global blob list in &drm_mode_config + * property_blob_list. + * @head_file: entry on the per-file blob list in &drm_file blobs list. + * @length: size of the blob in bytes, invariant over the lifetime of the object + * @data: actual data, embedded at the end of this structure + * + * Blobs are used to store bigger values than what fits directly into the 64 + * bits available for a &drm_property. + * + * Blobs are reference counted using drm_property_reference_blob() and + * drm_property_unreference_blob(). They are created using + * drm_property_create_blob(). + */ +struct drm_property_blob { + struct drm_mode_object base; + struct drm_device *dev; + struct list_head head_global; + struct list_head head_file; + size_t length; + unsigned char data[]; +}; + +struct drm_prop_enum_list { + int type; + char *name; +}; + +#define obj_to_property(x) container_of(x, struct drm_property, base) +#define obj_to_blob(x) container_of(x, struct drm_property_blob, base) + +/** + * drm_property_type_is - check the type of a property + * @property: property to check + * @type: property type to compare with + * + * This is a helper function becauase the uapi encoding of property types is + * a bit special for historical reasons. + */ +static inline bool drm_property_type_is(struct drm_property *property, + uint32_t type) +{ + /* instanceof for props.. handles extended type vs original types: */ + if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) + return (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) == type; + return property->flags & type; +} + +struct drm_property *drm_property_create(struct drm_device *dev, int flags, + const char *name, int num_values); +struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, + const char *name, + const struct drm_prop_enum_list *props, + int num_values); +struct drm_property *drm_property_create_bitmask(struct drm_device *dev, + int flags, const char *name, + const struct drm_prop_enum_list *props, + int num_props, + uint64_t supported_bits); +struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, + const char *name, + uint64_t min, uint64_t max); +struct drm_property *drm_property_create_signed_range(struct drm_device *dev, + int flags, const char *name, + int64_t min, int64_t max); +struct drm_property *drm_property_create_object(struct drm_device *dev, + int flags, const char *name, uint32_t type); +struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags, + const char *name); +int drm_property_add_enum(struct drm_property *property, int index, + uint64_t value, const char *name); +void drm_property_destroy(struct drm_device *dev, struct drm_property *property); + +struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, + size_t length, + const void *data); +struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev, + uint32_t id); +int drm_property_replace_global_blob(struct drm_device *dev, + struct drm_property_blob **replace, + size_t length, + const void *data, + struct drm_mode_object *obj_holds_id, + struct drm_property *prop_holds_id); +struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob); +void drm_property_unreference_blob(struct drm_property_blob *blob); + +/** + * drm_connector_find - find property object + * @dev: DRM device + * @id: property object id + * + * This function looks up the property object specified by id and returns it. + */ +static inline struct drm_property *drm_property_find(struct drm_device *dev, + uint32_t id) +{ + struct drm_mode_object *mo; + mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY); + return mo ? obj_to_property(mo) : NULL; +} + +#endif diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index 269039722f91..01a8436ccb0a 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -60,9 +60,35 @@ struct drm_simple_display_pipe_funcs { * * This function is called when the underlying plane state is updated. * This hook is optional. + * + * This is the function drivers should submit the + * &drm_pending_vblank_event from. Using either + * drm_crtc_arm_vblank_event(), when the driver supports vblank + * interrupt handling, or drm_crtc_send_vblank_event() directly in case + * the hardware lacks vblank support entirely. */ void (*update)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state); + + /** + * @prepare_fb: + * + * Optional, called by struct &drm_plane_helper_funcs ->prepare_fb . + * Please read the documentation for the ->prepare_fb hook in + * struct &drm_plane_helper_funcs for more details. + */ + int (*prepare_fb)(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *plane_state); + + /** + * @cleanup_fb: + * + * Optional, called by struct &drm_plane_helper_funcs ->cleanup_fb . + * Please read the documentation for the ->cleanup_fb hook in + * struct &drm_plane_helper_funcs for more details. + */ + void (*cleanup_fb)(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *plane_state); }; /** @@ -85,6 +111,11 @@ struct drm_simple_display_pipe { const struct drm_simple_display_pipe_funcs *funcs; }; +int drm_simple_display_pipe_attach_bridge(struct drm_simple_display_pipe *pipe, + struct drm_bridge *bridge); + +void drm_simple_display_pipe_detach_bridge(struct drm_simple_display_pipe *pipe); + int drm_simple_display_pipe_init(struct drm_device *dev, struct drm_simple_display_pipe *pipe, const struct drm_simple_display_pipe_funcs *funcs, diff --git a/include/drm/drm_vma_manager.h b/include/drm/drm_vma_manager.h index 06ea8e077ec2..9c03895dc479 100644 --- a/include/drm/drm_vma_manager.h +++ b/include/drm/drm_vma_manager.h @@ -24,29 +24,28 @@ */ #include <drm/drm_mm.h> -#include <linux/fs.h> #include <linux/mm.h> #include <linux/module.h> #include <linux/rbtree.h> #include <linux/spinlock.h> #include <linux/types.h> +struct drm_file; + struct drm_vma_offset_file { struct rb_node vm_rb; - struct file *vm_filp; + struct drm_file *vm_tag; unsigned long vm_count; }; struct drm_vma_offset_node { rwlock_t vm_lock; struct drm_mm_node vm_node; - struct rb_node vm_rb; struct rb_root vm_files; }; struct drm_vma_offset_manager { rwlock_t vm_lock; - struct rb_root vm_addr_space_rb; struct drm_mm vm_addr_space_mm; }; @@ -62,10 +61,11 @@ int drm_vma_offset_add(struct drm_vma_offset_manager *mgr, void drm_vma_offset_remove(struct drm_vma_offset_manager *mgr, struct drm_vma_offset_node *node); -int drm_vma_node_allow(struct drm_vma_offset_node *node, struct file *filp); -void drm_vma_node_revoke(struct drm_vma_offset_node *node, struct file *filp); +int drm_vma_node_allow(struct drm_vma_offset_node *node, struct drm_file *tag); +void drm_vma_node_revoke(struct drm_vma_offset_node *node, + struct drm_file *tag); bool drm_vma_node_is_allowed(struct drm_vma_offset_node *node, - struct file *filp); + struct drm_file *tag); /** * drm_vma_offset_exact_lookup_locked() - Look up node by exact address @@ -216,9 +216,9 @@ static inline void drm_vma_node_unmap(struct drm_vma_offset_node *node, /** * drm_vma_node_verify_access() - Access verification helper for TTM * @node: Offset node - * @filp: Open-file + * @tag: Tag of file to check * - * This checks whether @filp is granted access to @node. It is the same as + * This checks whether @tag is granted access to @node. It is the same as * drm_vma_node_is_allowed() but suitable as drop-in helper for TTM * verify_access() callbacks. * @@ -226,9 +226,9 @@ static inline void drm_vma_node_unmap(struct drm_vma_offset_node *node, * 0 if access is granted, -EACCES otherwise. */ static inline int drm_vma_node_verify_access(struct drm_vma_offset_node *node, - struct file *filp) + struct drm_file *tag) { - return drm_vma_node_is_allowed(node, filp) ? 0 : -EACCES; + return drm_vma_node_is_allowed(node, tag) ? 0 : -EACCES; } #endif /* __DRM_VMA_MANAGER_H__ */ diff --git a/include/drm/i2c/tda998x.h b/include/drm/i2c/tda998x.h index 3e419d92cf5a..a25483090cd5 100644 --- a/include/drm/i2c/tda998x.h +++ b/include/drm/i2c/tda998x.h @@ -1,6 +1,24 @@ #ifndef __DRM_I2C_TDA998X_H__ #define __DRM_I2C_TDA998X_H__ +#include <linux/hdmi.h> +#include <dt-bindings/display/tda998x.h> + +enum { + AFMT_UNUSED = 0, + AFMT_SPDIF = TDA998x_SPDIF, + AFMT_I2S = TDA998x_I2S, +}; + +struct tda998x_audio_params { + u8 config; + u8 format; + unsigned sample_width; + unsigned sample_rate; + struct hdmi_audio_infoframe cea; + u8 status[5]; +}; + struct tda998x_encoder_params { u8 swap_b:3; u8 mirr_b:1; @@ -15,16 +33,7 @@ struct tda998x_encoder_params { u8 swap_e:3; u8 mirr_e:1; - u8 audio_cfg; - u8 audio_clk_cfg; - u8 audio_frame[6]; - - enum { - AFMT_SPDIF, - AFMT_I2S - } audio_format; - - unsigned audio_sample_rate; + struct tda998x_audio_params audio_params; }; #endif diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index b1755f8db36b..4e1b274e1164 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -93,6 +93,6 @@ extern bool i915_gpu_turbo_disable(void); #define I845_TSEG_SIZE_1M (3 << 1) #define INTEL_BSM 0x5c -#define INTEL_BSM_MASK (0xFFFF << 20) +#define INTEL_BSM_MASK (-(1u << 20)) #endif /* _I915_DRM_H_ */ diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 33466bfc6440..0d5f4268d75f 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -134,7 +134,7 @@ #define INTEL_IVB_Q_IDS(info) \ INTEL_QUANTA_VGA_DEVICE(info) /* Quanta transcode */ -#define INTEL_HSW_D_IDS(info) \ +#define INTEL_HSW_IDS(info) \ INTEL_VGA_DEVICE(0x0402, info), /* GT1 desktop */ \ INTEL_VGA_DEVICE(0x0412, info), /* GT2 desktop */ \ INTEL_VGA_DEVICE(0x0422, info), /* GT3 desktop */ \ @@ -179,9 +179,7 @@ INTEL_VGA_DEVICE(0x0D2B, info), /* CRW GT3 reserved */ \ INTEL_VGA_DEVICE(0x0D0E, info), /* CRW GT1 reserved */ \ INTEL_VGA_DEVICE(0x0D1E, info), /* CRW GT2 reserved */ \ - INTEL_VGA_DEVICE(0x0D2E, info) /* CRW GT3 reserved */ \ - -#define INTEL_HSW_M_IDS(info) \ + INTEL_VGA_DEVICE(0x0D2E, info), /* CRW GT3 reserved */ \ INTEL_VGA_DEVICE(0x0406, info), /* GT1 mobile */ \ INTEL_VGA_DEVICE(0x0416, info), /* GT2 mobile */ \ INTEL_VGA_DEVICE(0x0426, info), /* GT2 mobile */ \ @@ -198,17 +196,15 @@ INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \ INTEL_VGA_DEVICE(0x0D26, info) /* CRW GT3 mobile */ -#define INTEL_VLV_M_IDS(info) \ +#define INTEL_VLV_IDS(info) \ INTEL_VGA_DEVICE(0x0f30, info), \ INTEL_VGA_DEVICE(0x0f31, info), \ INTEL_VGA_DEVICE(0x0f32, info), \ INTEL_VGA_DEVICE(0x0f33, info), \ - INTEL_VGA_DEVICE(0x0157, info) - -#define INTEL_VLV_D_IDS(info) \ + INTEL_VGA_DEVICE(0x0157, info), \ INTEL_VGA_DEVICE(0x0155, info) -#define INTEL_BDW_GT12M_IDS(info) \ +#define INTEL_BDW_GT12_IDS(info) \ INTEL_VGA_DEVICE(0x1602, info), /* GT1 ULT */ \ INTEL_VGA_DEVICE(0x1606, info), /* GT1 ULT */ \ INTEL_VGA_DEVICE(0x160B, info), /* GT1 Iris */ \ @@ -216,21 +212,17 @@ INTEL_VGA_DEVICE(0x1612, info), /* GT2 Halo */ \ INTEL_VGA_DEVICE(0x1616, info), /* GT2 ULT */ \ INTEL_VGA_DEVICE(0x161B, info), /* GT2 ULT */ \ - INTEL_VGA_DEVICE(0x161E, info) /* GT2 ULX */ - -#define INTEL_BDW_GT12D_IDS(info) \ + INTEL_VGA_DEVICE(0x161E, info), /* GT2 ULX */ \ INTEL_VGA_DEVICE(0x160A, info), /* GT1 Server */ \ INTEL_VGA_DEVICE(0x160D, info), /* GT1 Workstation */ \ INTEL_VGA_DEVICE(0x161A, info), /* GT2 Server */ \ INTEL_VGA_DEVICE(0x161D, info) /* GT2 Workstation */ -#define INTEL_BDW_GT3M_IDS(info) \ +#define INTEL_BDW_GT3_IDS(info) \ INTEL_VGA_DEVICE(0x1622, info), /* ULT */ \ INTEL_VGA_DEVICE(0x1626, info), /* ULT */ \ INTEL_VGA_DEVICE(0x162B, info), /* Iris */ \ - INTEL_VGA_DEVICE(0x162E, info) /* ULX */ - -#define INTEL_BDW_GT3D_IDS(info) \ + INTEL_VGA_DEVICE(0x162E, info), /* ULX */\ INTEL_VGA_DEVICE(0x162A, info), /* Server */ \ INTEL_VGA_DEVICE(0x162D, info) /* Workstation */ @@ -244,14 +236,12 @@ INTEL_VGA_DEVICE(0x163A, info), /* Server */ \ INTEL_VGA_DEVICE(0x163D, info) /* Workstation */ -#define INTEL_BDW_M_IDS(info) \ - INTEL_BDW_GT12M_IDS(info), \ - INTEL_BDW_GT3M_IDS(info), \ - INTEL_BDW_RSVDM_IDS(info) - -#define INTEL_BDW_D_IDS(info) \ - INTEL_BDW_GT12D_IDS(info), \ - INTEL_BDW_GT3D_IDS(info), \ +#define INTEL_BDW_IDS(info) \ + INTEL_BDW_GT12_IDS(info), \ + INTEL_BDW_GT3_IDS(info), \ + INTEL_BDW_RSVDM_IDS(info), \ + INTEL_BDW_GT12_IDS(info), \ + INTEL_BDW_GT3_IDS(info), \ INTEL_BDW_RSVDD_IDS(info) #define INTEL_CHV_IDS(info) \ diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 6f2c59887ba6..9eb940d6755f 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -45,37 +45,7 @@ struct ttm_bo_device; struct drm_mm_node; -/** - * struct ttm_place - * - * @fpfn: first valid page frame number to put the object - * @lpfn: last valid page frame number to put the object - * @flags: memory domain and caching flags for the object - * - * Structure indicating a possible place to put an object. - */ -struct ttm_place { - unsigned fpfn; - unsigned lpfn; - uint32_t flags; -}; - -/** - * struct ttm_placement - * - * @num_placement: number of preferred placements - * @placement: preferred placements - * @num_busy_placement: number of preferred placements when need to evict buffer - * @busy_placement: preferred placements when need to evict buffer - * - * Structure indicating the placement you request for an object. - */ -struct ttm_placement { - unsigned num_placement; - const struct ttm_place *placement; - unsigned num_busy_placement; - const struct ttm_place *busy_placement; -}; +struct ttm_placement; /** * struct ttm_bus_placement diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 99c6d01d24f2..4f0a92185995 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -133,7 +133,6 @@ struct ttm_tt { * struct ttm_dma_tt * * @ttm: Base ttm_tt struct. - * @cpu_address: The CPU address of the pages * @dma_address: The DMA (bus) addresses of the pages * @pages_list: used by some page allocation backend * @@ -143,7 +142,6 @@ struct ttm_tt { */ struct ttm_dma_tt { struct ttm_tt ttm; - void **cpu_address; dma_addr_t *dma_address; struct list_head pages_list; }; @@ -961,7 +959,6 @@ void ttm_mem_io_free(struct ttm_bo_device *bdev, * ttm_bo_move_ttm * * @bo: A pointer to a struct ttm_buffer_object. - * @evict: 1: This is an eviction. Don't try to pipeline. * @interruptible: Sleep interruptible if waiting. * @no_wait_gpu: Return immediately if the GPU is busy. * @new_mem: struct ttm_mem_reg indicating where to move. @@ -977,14 +974,13 @@ void ttm_mem_io_free(struct ttm_bo_device *bdev, */ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, - bool evict, bool interruptible, bool no_wait_gpu, + bool interruptible, bool no_wait_gpu, struct ttm_mem_reg *new_mem); /** * ttm_bo_move_memcpy * * @bo: A pointer to a struct ttm_buffer_object. - * @evict: 1: This is an eviction. Don't try to pipeline. * @interruptible: Sleep interruptible if waiting. * @no_wait_gpu: Return immediately if the GPU is busy. * @new_mem: struct ttm_mem_reg indicating where to move. @@ -1000,8 +996,7 @@ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, */ extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, - bool evict, bool interruptible, - bool no_wait_gpu, + bool interruptible, bool no_wait_gpu, struct ttm_mem_reg *new_mem); /** diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h index 72dcbe81dd07..c4520890f267 100644 --- a/include/drm/ttm/ttm_memory.h +++ b/include/drm/ttm/ttm_memory.h @@ -155,4 +155,5 @@ extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, extern void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page); extern size_t ttm_round_pot(size_t size); +extern uint64_t ttm_get_kernel_zone_memory_size(struct ttm_mem_global *glob); #endif diff --git a/include/drm/ttm/ttm_placement.h b/include/drm/ttm/ttm_placement.h index 8ed44f9bbdfb..932be0c8086e 100644 --- a/include/drm/ttm/ttm_placement.h +++ b/include/drm/ttm/ttm_placement.h @@ -30,6 +30,9 @@ #ifndef _TTM_PLACEMENT_H_ #define _TTM_PLACEMENT_H_ + +#include <linux/types.h> + /* * Memory regions for data placement. */ @@ -37,24 +40,12 @@ #define TTM_PL_SYSTEM 0 #define TTM_PL_TT 1 #define TTM_PL_VRAM 2 -#define TTM_PL_PRIV0 3 -#define TTM_PL_PRIV1 4 -#define TTM_PL_PRIV2 5 -#define TTM_PL_PRIV3 6 -#define TTM_PL_PRIV4 7 -#define TTM_PL_PRIV5 8 -#define TTM_PL_SWAPPED 15 +#define TTM_PL_PRIV 3 #define TTM_PL_FLAG_SYSTEM (1 << TTM_PL_SYSTEM) #define TTM_PL_FLAG_TT (1 << TTM_PL_TT) #define TTM_PL_FLAG_VRAM (1 << TTM_PL_VRAM) -#define TTM_PL_FLAG_PRIV0 (1 << TTM_PL_PRIV0) -#define TTM_PL_FLAG_PRIV1 (1 << TTM_PL_PRIV1) -#define TTM_PL_FLAG_PRIV2 (1 << TTM_PL_PRIV2) -#define TTM_PL_FLAG_PRIV3 (1 << TTM_PL_PRIV3) -#define TTM_PL_FLAG_PRIV4 (1 << TTM_PL_PRIV4) -#define TTM_PL_FLAG_PRIV5 (1 << TTM_PL_PRIV5) -#define TTM_PL_FLAG_SWAPPED (1 << TTM_PL_SWAPPED) +#define TTM_PL_FLAG_PRIV (1 << TTM_PL_PRIV) #define TTM_PL_MASK_MEM 0x0000FFFF /* @@ -72,7 +63,6 @@ #define TTM_PL_FLAG_CACHED (1 << 16) #define TTM_PL_FLAG_UNCACHED (1 << 17) #define TTM_PL_FLAG_WC (1 << 18) -#define TTM_PL_FLAG_SHARED (1 << 20) #define TTM_PL_FLAG_NO_EVICT (1 << 21) #define TTM_PL_FLAG_TOPDOWN (1 << 22) @@ -82,14 +72,36 @@ #define TTM_PL_MASK_MEMTYPE (TTM_PL_MASK_MEM | TTM_PL_MASK_CACHING) -/* - * Access flags to be used for CPU- and GPU- mappings. - * The idea is that the TTM synchronization mechanism will - * allow concurrent READ access and exclusive write access. - * Currently GPU- and CPU accesses are exclusive. +/** + * struct ttm_place + * + * @fpfn: first valid page frame number to put the object + * @lpfn: last valid page frame number to put the object + * @flags: memory domain and caching flags for the object + * + * Structure indicating a possible place to put an object. */ +struct ttm_place { + unsigned fpfn; + unsigned lpfn; + uint32_t flags; +}; -#define TTM_ACCESS_READ (1 << 0) -#define TTM_ACCESS_WRITE (1 << 1) +/** + * struct ttm_placement + * + * @num_placement: number of preferred placements + * @placement: preferred placements + * @num_busy_placement: number of preferred placements when need to evict buffer + * @busy_placement: preferred placements when need to evict buffer + * + * Structure indicating the placement you request for an object. + */ +struct ttm_placement { + unsigned num_placement; + const struct ttm_place *placement; + unsigned num_busy_placement; + const struct ttm_place *busy_placement; +}; #endif diff --git a/include/dt-bindings/display/tda998x.h b/include/dt-bindings/display/tda998x.h new file mode 100644 index 000000000000..34757a3847ef --- /dev/null +++ b/include/dt-bindings/display/tda998x.h @@ -0,0 +1,7 @@ +#ifndef _DT_BINDINGS_TDA998X_H +#define _DT_BINDINGS_TDA998X_H + +#define TDA998x_SPDIF 1 +#define TDA998x_I2S 2 + +#endif /*_DT_BINDINGS_TDA998X_H */ diff --git a/include/dt-bindings/memory/mt2701-larb-port.h b/include/dt-bindings/memory/mt2701-larb-port.h index 78f66786da91..6764d7447422 100644 --- a/include/dt-bindings/memory/mt2701-larb-port.h +++ b/include/dt-bindings/memory/mt2701-larb-port.h @@ -26,7 +26,7 @@ #define LARB0_PORT_OFFSET 0 #define LARB1_PORT_OFFSET 11 #define LARB2_PORT_OFFSET 21 -#define LARB3_PORT_OFFSET 43 +#define LARB3_PORT_OFFSET 44 #define MT2701_M4U_ID_LARB0(port) ((port) + LARB0_PORT_OFFSET) #define MT2701_M4U_ID_LARB1(port) ((port) + LARB1_PORT_OFFSET) diff --git a/include/dt-bindings/thermal/tegra124-soctherm.h b/include/dt-bindings/thermal/tegra124-soctherm.h index 729ab9fc325e..2a99f1d52bb5 100644 --- a/include/dt-bindings/thermal/tegra124-soctherm.h +++ b/include/dt-bindings/thermal/tegra124-soctherm.h @@ -11,4 +11,9 @@ #define TEGRA124_SOCTHERM_SENSOR_PLLX 3 #define TEGRA124_SOCTHERM_SENSOR_NUM 4 +#define TEGRA_SOCTHERM_THROT_LEVEL_LOW 0 +#define TEGRA_SOCTHERM_THROT_LEVEL_MED 1 +#define TEGRA_SOCTHERM_THROT_LEVEL_HIGH 2 +#define TEGRA_SOCTHERM_THROT_LEVEL_NONE -1 + #endif diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 94afcb2c384c..ddbeda6dbdc8 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -946,9 +946,17 @@ struct acpi_reference_args { #ifdef CONFIG_ACPI int acpi_dev_get_property(struct acpi_device *adev, const char *name, acpi_object_type type, const union acpi_object **obj); -int acpi_node_get_property_reference(struct fwnode_handle *fwnode, - const char *name, size_t index, - struct acpi_reference_args *args); +int __acpi_node_get_property_reference(struct fwnode_handle *fwnode, + const char *name, size_t index, size_t num_args, + struct acpi_reference_args *args); + +static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, + const char *name, size_t index, + struct acpi_reference_args *args) +{ + return __acpi_node_get_property_reference(fwnode, name, index, + MAX_ACPI_REFERENCE_ARGS, args); +} int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, void **valptr); @@ -1024,6 +1032,14 @@ static inline int acpi_dev_get_property(struct acpi_device *adev, return -ENXIO; } +static inline int +__acpi_node_get_property_reference(struct fwnode_handle *fwnode, + const char *name, size_t index, size_t num_args, + struct acpi_reference_args *args) +{ + return -ENXIO; +} + static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, const char *name, size_t index, struct acpi_reference_args *args) diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h index e82e3ee2c54a..1035879b322c 100644 --- a/include/linux/amba/clcd.h +++ b/include/linux/amba/clcd.h @@ -67,6 +67,17 @@ #define CNTL_LDMAFIFOTIME (1 << 15) #define CNTL_WATERMARK (1 << 16) +/* ST Microelectronics variant bits */ +#define CNTL_ST_1XBPP_444 0x0 +#define CNTL_ST_1XBPP_5551 (1 << 17) +#define CNTL_ST_1XBPP_565 (1 << 18) +#define CNTL_ST_CDWID_12 0x0 +#define CNTL_ST_CDWID_16 (1 << 19) +#define CNTL_ST_CDWID_18 (1 << 20) +#define CNTL_ST_CDWID_24 ((1 << 19)|(1 << 20)) +#define CNTL_ST_CEAEN (1 << 21) +#define CNTL_ST_LCDBPP24_PACKED (6 << 1) + enum { /* individual formats */ CLCD_CAP_RGB444 = (1 << 0), @@ -93,6 +104,8 @@ enum { CLCD_CAP_ALL = CLCD_CAP_BGR | CLCD_CAP_RGB, }; +struct backlight_device; + struct clcd_panel { struct fb_videomode mode; signed short width; /* width in mm */ @@ -105,6 +118,13 @@ struct clcd_panel { fixedtimings:1, grayscale:1; unsigned int connector; + struct backlight_device *backlight; + /* + * If the B/R lines are switched between the CLCD + * and the panel we need to know this and not try to + * compensate with the BGR bit in the control register. + */ + bool bgr_connection; }; struct clcd_regs { @@ -170,11 +190,38 @@ struct clcd_board { struct amba_device; struct clk; +/** + * struct clcd_vendor_data - holds hardware (IP-block) vendor-specific + * variant information + * + * @clock_timregs: the CLCD needs to be clocked when accessing the + * timer registers, or the hardware will hang. + * @packed_24_bit_pixels: this variant supports 24bit packed pixel data, + * so that RGB accesses 3 bytes at a time, not just on even 32bit + * boundaries, packing the pixel data in memory. ST Microelectronics + * have this. + * @st_bitmux_control: ST Microelectronics have implemented output + * bit line multiplexing into the CLCD control register. This indicates + * that we need to use this. + * @init_board: custom board init function for this variant + * @init_panel: custom panel init function for this variant + */ +struct clcd_vendor_data { + bool clock_timregs; + bool packed_24_bit_pixels; + bool st_bitmux_control; + int (*init_board)(struct amba_device *adev, + struct clcd_board *board); + int (*init_panel)(struct clcd_fb *fb, + struct device_node *panel); +}; + /* this data structure describes each frame buffer device we find */ struct clcd_fb { struct fb_info fb; struct amba_device *dev; struct clk *clk; + struct clcd_vendor_data *vendor; struct clcd_panel *panel; struct clcd_board *board; void *board_data; @@ -231,16 +278,22 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) if (var->grayscale) val |= CNTL_LCDBW; - if (fb->panel->caps && fb->board->caps && - var->bits_per_pixel >= 16) { + if (fb->panel->caps && fb->board->caps && var->bits_per_pixel >= 16) { /* * if board and panel supply capabilities, we can support - * changing BGR/RGB depending on supplied parameters + * changing BGR/RGB depending on supplied parameters. Here + * we switch to what the framebuffer is providing if need + * be, so if the framebuffer is BGR but the display connection + * is RGB (first case) we switch it around. Vice versa mutatis + * mutandis if the framebuffer is RGB but the display connection + * is BGR, we flip it around. */ if (var->red.offset == 0) val &= ~CNTL_BGR; else val |= CNTL_BGR; + if (fb->panel->bgr_connection) + val ^= CNTL_BGR; } switch (var->bits_per_pixel) { @@ -270,6 +323,10 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) else val |= CNTL_LCDBPP16_444; break; + case 24: + /* Modified variant supporting 24 bit packed pixels */ + val |= CNTL_ST_LCDBPP24_PACKED; + break; case 32: val |= CNTL_LCDBPP24; break; diff --git a/include/linux/ata.h b/include/linux/ata.h index adbc812c009b..fdb180367ba1 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -105,6 +105,7 @@ enum { ATA_ID_CFA_KEY_MGMT = 162, ATA_ID_CFA_MODES = 163, ATA_ID_DATA_SET_MGMT = 169, + ATA_ID_SCT_CMD_XPORT = 206, ATA_ID_ROT_SPEED = 217, ATA_ID_PIO4 = (1 << 1), @@ -789,6 +790,48 @@ static inline bool ata_id_sense_reporting_enabled(const u16 *id) } /** + * + * Word: 206 - SCT Command Transport + * 15:12 - Vendor Specific + * 11:6 - Reserved + * 5 - SCT Command Transport Data Tables supported + * 4 - SCT Command Transport Features Control supported + * 3 - SCT Command Transport Error Recovery Control supported + * 2 - SCT Command Transport Write Same supported + * 1 - SCT Command Transport Long Sector Access supported + * 0 - SCT Command Transport supported + */ +static inline bool ata_id_sct_data_tables(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 5) ? true : false; +} + +static inline bool ata_id_sct_features_ctrl(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 4) ? true : false; +} + +static inline bool ata_id_sct_error_recovery_ctrl(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 3) ? true : false; +} + +static inline bool ata_id_sct_write_same(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 2) ? true : false; +} + +static inline bool ata_id_sct_long_sector_access(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 1) ? true : false; +} + +static inline bool ata_id_sct_supported(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 0) ? true : false; +} + +/** * ata_id_major_version - get ATA level of drive * @id: Identify data * @@ -1071,32 +1114,6 @@ static inline void ata_id_to_hd_driveid(u16 *id) #endif } -/* - * Write LBA Range Entries to the buffer that will cover the extent from - * sector to sector + count. This is used for TRIM and for ADD LBA(S) - * TO NV CACHE PINNED SET. - */ -static inline unsigned ata_set_lba_range_entries(void *_buffer, - unsigned num, u64 sector, unsigned long count) -{ - __le64 *buffer = _buffer; - unsigned i = 0, used_bytes; - - while (i < num) { - u64 entry = sector | - ((u64)(count > 0xffff ? 0xffff : count) << 48); - buffer[i++] = __cpu_to_le64(entry); - if (count <= 0xffff) - break; - count -= 0xffff; - sector += 0xffff; - } - - used_bytes = ALIGN(i * 8, 512); - memset(buffer + i, 0, used_bytes - i * 8); - return used_bytes; -} - static inline bool ata_ok(u8 status) { return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR)) diff --git a/include/linux/auto_dev-ioctl.h b/include/linux/auto_dev-ioctl.h index 7caaf298f539..28c15050ebe6 100644 --- a/include/linux/auto_dev-ioctl.h +++ b/include/linux/auto_dev-ioctl.h @@ -10,214 +10,5 @@ #ifndef _LINUX_AUTO_DEV_IOCTL_H #define _LINUX_AUTO_DEV_IOCTL_H -#include <linux/auto_fs.h> -#include <linux/string.h> - -#define AUTOFS_DEVICE_NAME "autofs" - -#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1 -#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0 - -#define AUTOFS_DEVID_LEN 16 - -#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl) - -/* - * An ioctl interface for autofs mount point control. - */ - -struct args_protover { - __u32 version; -}; - -struct args_protosubver { - __u32 sub_version; -}; - -struct args_openmount { - __u32 devid; -}; - -struct args_ready { - __u32 token; -}; - -struct args_fail { - __u32 token; - __s32 status; -}; - -struct args_setpipefd { - __s32 pipefd; -}; - -struct args_timeout { - __u64 timeout; -}; - -struct args_requester { - __u32 uid; - __u32 gid; -}; - -struct args_expire { - __u32 how; -}; - -struct args_askumount { - __u32 may_umount; -}; - -struct args_ismountpoint { - union { - struct args_in { - __u32 type; - } in; - struct args_out { - __u32 devid; - __u32 magic; - } out; - }; -}; - -/* - * All the ioctls use this structure. - * When sending a path size must account for the total length - * of the chunk of memory otherwise is is the size of the - * structure. - */ - -struct autofs_dev_ioctl { - __u32 ver_major; - __u32 ver_minor; - __u32 size; /* total size of data passed in - * including this struct */ - __s32 ioctlfd; /* automount command fd */ - - /* Command parameters */ - - union { - struct args_protover protover; - struct args_protosubver protosubver; - struct args_openmount openmount; - struct args_ready ready; - struct args_fail fail; - struct args_setpipefd setpipefd; - struct args_timeout timeout; - struct args_requester requester; - struct args_expire expire; - struct args_askumount askumount; - struct args_ismountpoint ismountpoint; - }; - - char path[0]; -}; - -static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) -{ - memset(in, 0, sizeof(struct autofs_dev_ioctl)); - in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; - in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; - in->size = sizeof(struct autofs_dev_ioctl); - in->ioctlfd = -1; -} - -/* - * If you change this make sure you make the corresponding change - * to autofs-dev-ioctl.c:lookup_ioctl() - */ -enum { - /* Get various version info */ - AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71, - AUTOFS_DEV_IOCTL_PROTOVER_CMD, - AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, - - /* Open mount ioctl fd */ - AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, - - /* Close mount ioctl fd */ - AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, - - /* Mount/expire status returns */ - AUTOFS_DEV_IOCTL_READY_CMD, - AUTOFS_DEV_IOCTL_FAIL_CMD, - - /* Activate/deactivate autofs mount */ - AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, - AUTOFS_DEV_IOCTL_CATATONIC_CMD, - - /* Expiry timeout */ - AUTOFS_DEV_IOCTL_TIMEOUT_CMD, - - /* Get mount last requesting uid and gid */ - AUTOFS_DEV_IOCTL_REQUESTER_CMD, - - /* Check for eligible expire candidates */ - AUTOFS_DEV_IOCTL_EXPIRE_CMD, - - /* Request busy status */ - AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, - - /* Check if path is a mountpoint */ - AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, -}; - -#define AUTOFS_IOCTL 0x93 - -#define AUTOFS_DEV_IOCTL_VERSION \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_PROTOVER \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_PROTOSUBVER \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_OPENMOUNT \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_READY \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_FAIL \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_SETPIPEFD \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_CATATONIC \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_TIMEOUT \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_REQUESTER \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_EXPIRE \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_ASKUMOUNT \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl) - -#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \ - _IOWR(AUTOFS_IOCTL, \ - AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl) - +#include <uapi/linux/auto_dev-ioctl.h> #endif /* _LINUX_AUTO_DEV_IOCTL_H */ diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h index b4066bb89083..b8f814c95cf5 100644 --- a/include/linux/auto_fs.h +++ b/include/linux/auto_fs.h @@ -10,7 +10,6 @@ #define _LINUX_AUTO_FS_H #include <linux/fs.h> -#include <linux/limits.h> #include <linux/ioctl.h> #include <uapi/linux/auto_fs.h> #endif /* _LINUX_AUTO_FS_H */ diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h index cbdbf34de5b6..3bf5d33800ab 100644 --- a/include/linux/blk-cgroup.h +++ b/include/linux/blk-cgroup.h @@ -343,16 +343,7 @@ static inline struct blkcg *cpd_to_blkcg(struct blkcg_policy_data *cpd) */ static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen) { - char *p; - - p = cgroup_path(blkg->blkcg->css.cgroup, buf, buflen); - if (!p) { - strncpy(buf, "<unavailable>", buflen); - return -ENAMETOOLONG; - } - - memmove(buf, p, buf + buflen - p); - return 0; + return cgroup_path(blkg->blkcg->css.cgroup, buf, buflen); } /** diff --git a/include/linux/ccp.h b/include/linux/ccp.h index 7c2bb27c067c..a7653339fedb 100644 --- a/include/linux/ccp.h +++ b/include/linux/ccp.h @@ -238,9 +238,6 @@ struct ccp_xts_aes_engine { }; /***** SHA engine *****/ -#define CCP_SHA_BLOCKSIZE SHA256_BLOCK_SIZE -#define CCP_SHA_CTXSIZE SHA256_DIGEST_SIZE - /** * ccp_sha_type - type of SHA operation * diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h index 1563265d2097..374bb1c4ef52 100644 --- a/include/linux/ceph/auth.h +++ b/include/linux/ceph/auth.h @@ -104,7 +104,7 @@ extern int ceph_auth_build_hello(struct ceph_auth_client *ac, extern int ceph_handle_auth_reply(struct ceph_auth_client *ac, void *buf, size_t len, void *reply_buf, size_t reply_len); -extern int ceph_entity_name_encode(const char *name, void **p, void *end); +int ceph_auth_entity_name_encode(const char *name, void **p, void *end); extern int ceph_build_auth(struct ceph_auth_client *ac, void *msg_buf, size_t msg_len); diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h index 7868d602c0a0..f96de8de4fa7 100644 --- a/include/linux/ceph/ceph_fs.h +++ b/include/linux/ceph/ceph_fs.h @@ -138,6 +138,9 @@ struct ceph_dir_layout { #define CEPH_MSG_POOLOP_REPLY 48 #define CEPH_MSG_POOLOP 49 +/* mon commands */ +#define CEPH_MSG_MON_COMMAND 50 +#define CEPH_MSG_MON_COMMAND_ACK 51 /* osd */ #define CEPH_MSG_OSD_MAP 41 @@ -176,6 +179,14 @@ struct ceph_mon_statfs_reply { struct ceph_statfs st; } __attribute__ ((packed)); +struct ceph_mon_command { + struct ceph_mon_request_header monhdr; + struct ceph_fsid fsid; + __le32 num_strs; /* always 1 */ + __le32 str_len; + char str[]; +} __attribute__ ((packed)); + struct ceph_osd_getmap { struct ceph_mon_request_header monhdr; struct ceph_fsid fsid; @@ -270,6 +281,7 @@ enum { CEPH_SESSION_FLUSHMSG, CEPH_SESSION_FLUSHMSG_ACK, CEPH_SESSION_FORCE_RO, + CEPH_SESSION_REJECT, }; extern const char *ceph_session_op_name(int op); diff --git a/include/linux/ceph/cls_lock_client.h b/include/linux/ceph/cls_lock_client.h new file mode 100644 index 000000000000..84884d8d4710 --- /dev/null +++ b/include/linux/ceph/cls_lock_client.h @@ -0,0 +1,49 @@ +#ifndef _LINUX_CEPH_CLS_LOCK_CLIENT_H +#define _LINUX_CEPH_CLS_LOCK_CLIENT_H + +#include <linux/ceph/osd_client.h> + +enum ceph_cls_lock_type { + CEPH_CLS_LOCK_NONE = 0, + CEPH_CLS_LOCK_EXCLUSIVE = 1, + CEPH_CLS_LOCK_SHARED = 2, +}; + +struct ceph_locker_id { + struct ceph_entity_name name; /* locker's client name */ + char *cookie; /* locker's cookie */ +}; + +struct ceph_locker_info { + struct ceph_entity_addr addr; /* locker's address */ +}; + +struct ceph_locker { + struct ceph_locker_id id; + struct ceph_locker_info info; +}; + +int ceph_cls_lock(struct ceph_osd_client *osdc, + struct ceph_object_id *oid, + struct ceph_object_locator *oloc, + char *lock_name, u8 type, char *cookie, + char *tag, char *desc, u8 flags); +int ceph_cls_unlock(struct ceph_osd_client *osdc, + struct ceph_object_id *oid, + struct ceph_object_locator *oloc, + char *lock_name, char *cookie); +int ceph_cls_break_lock(struct ceph_osd_client *osdc, + struct ceph_object_id *oid, + struct ceph_object_locator *oloc, + char *lock_name, char *cookie, + struct ceph_entity_name *locker); + +void ceph_free_lockers(struct ceph_locker *lockers, u32 num_lockers); + +int ceph_cls_lock_info(struct ceph_osd_client *osdc, + struct ceph_object_id *oid, + struct ceph_object_locator *oloc, + char *lock_name, u8 *type, char **tag, + struct ceph_locker **lockers, u32 *num_lockers); + +#endif diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 83fc1fff7061..1816c5e26581 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -264,7 +264,8 @@ extern struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private, u64 supported_features, u64 required_features); -extern u64 ceph_client_id(struct ceph_client *client); +struct ceph_entity_addr *ceph_client_addr(struct ceph_client *client); +u64 ceph_client_gid(struct ceph_client *client); extern void ceph_destroy_client(struct ceph_client *client); extern int __ceph_open_session(struct ceph_client *client, unsigned long started); diff --git a/include/linux/ceph/mon_client.h b/include/linux/ceph/mon_client.h index 24d704d1ea5c..d5a3ecea578d 100644 --- a/include/linux/ceph/mon_client.h +++ b/include/linux/ceph/mon_client.h @@ -141,6 +141,9 @@ int ceph_monc_get_version(struct ceph_mon_client *monc, const char *what, int ceph_monc_get_version_async(struct ceph_mon_client *monc, const char *what, ceph_monc_callback_t cb, u64 private_data); +int ceph_monc_blacklist_add(struct ceph_mon_client *monc, + struct ceph_entity_addr *client_addr); + extern int ceph_monc_open_session(struct ceph_mon_client *monc); extern int ceph_monc_validate_auth(struct ceph_mon_client *monc); diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index 858932304260..96337b15a60d 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h @@ -121,6 +121,9 @@ struct ceph_osd_req_op { struct ceph_osd_data response_data; } notify; struct { + struct ceph_osd_data response_data; + } list_watchers; + struct { u64 expected_object_size; u64 expected_write_size; } alloc_hint; @@ -249,6 +252,12 @@ struct ceph_osd_linger_request { size_t *preply_len; }; +struct ceph_watch_item { + struct ceph_entity_name name; + u64 cookie; + struct ceph_entity_addr addr; +}; + struct ceph_osd_client { struct ceph_client *client; @@ -346,7 +355,6 @@ extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *, struct page **pages, u64 length, u32 alignment, bool pages_from_pool, bool own_pages); - extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, u16 opcode, const char *class, const char *method); @@ -389,6 +397,14 @@ extern void ceph_osdc_sync(struct ceph_osd_client *osdc); extern void ceph_osdc_flush_notifies(struct ceph_osd_client *osdc); void ceph_osdc_maybe_request_map(struct ceph_osd_client *osdc); +int ceph_osdc_call(struct ceph_osd_client *osdc, + struct ceph_object_id *oid, + struct ceph_object_locator *oloc, + const char *class, const char *method, + unsigned int flags, + struct page *req_page, size_t req_len, + struct page *resp_page, size_t *resp_len); + extern int ceph_osdc_readpages(struct ceph_osd_client *osdc, struct ceph_vino vino, struct ceph_file_layout *layout, @@ -434,5 +450,10 @@ int ceph_osdc_notify(struct ceph_osd_client *osdc, size_t *preply_len); int ceph_osdc_watch_check(struct ceph_osd_client *osdc, struct ceph_osd_linger_request *lreq); +int ceph_osdc_list_watchers(struct ceph_osd_client *osdc, + struct ceph_object_id *oid, + struct ceph_object_locator *oloc, + struct ceph_watch_item **watchers, + u32 *num_watchers); #endif diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 440a72164a11..c83c23f0577b 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -97,7 +97,7 @@ int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); int cgroup_rm_cftypes(struct cftype *cfts); void cgroup_file_notify(struct cgroup_file *cfile); -char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen); +int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen); int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry); int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *tsk); @@ -555,8 +555,7 @@ static inline int cgroup_name(struct cgroup *cgrp, char *buf, size_t buflen) return kernfs_name(cgrp->kn, buf, buflen); } -static inline char * __must_check cgroup_path(struct cgroup *cgrp, char *buf, - size_t buflen) +static inline int cgroup_path(struct cgroup *cgrp, char *buf, size_t buflen) { return kernfs_path(cgrp->kn, buf, buflen); } @@ -658,8 +657,8 @@ struct cgroup_namespace *copy_cgroup_ns(unsigned long flags, struct user_namespace *user_ns, struct cgroup_namespace *old_ns); -char *cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen, - struct cgroup_namespace *ns); +int cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen, + struct cgroup_namespace *ns); #else /* !CONFIG_CGROUPS */ diff --git a/include/linux/compat.h b/include/linux/compat.h index f964ef79e0ad..63609398ef9f 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -432,7 +432,6 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); -extern __printf(1, 2) int compat_printk(const char *fmt, ...); extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat); extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set); diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 573c5a18908f..432f5c97e18f 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -188,6 +188,13 @@ #endif /* GCC_VERSION >= 40300 */ #if GCC_VERSION >= 40500 + +#ifndef __CHECKER__ +#ifdef LATENT_ENTROPY_PLUGIN +#define __latent_entropy __attribute__((latent_entropy)) +#endif +#endif + /* * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 668569844d37..cf0fa5d86059 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -182,6 +182,29 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); # define unreachable() do { } while (1) #endif +/* + * KENTRY - kernel entry point + * This can be used to annotate symbols (functions or data) that are used + * without their linker symbol being referenced explicitly. For example, + * interrupt vector handlers, or functions in the kernel image that are found + * programatically. + * + * Not required for symbols exported with EXPORT_SYMBOL, or initcalls. Those + * are handled in their own way (with KEEP() in linker scripts). + * + * KENTRY can be avoided if the symbols in question are marked as KEEP() in the + * linker script. For example an architecture could KEEP() its entire + * boot/exception vector code rather than annotate each function and data. + */ +#ifndef KENTRY +# define KENTRY(sym) \ + extern typeof(sym) sym; \ + static const unsigned long __kentry_##sym \ + __used \ + __attribute__((section("___kentry" "+" #sym ), used)) \ + = (unsigned long)&sym; +#endif + #ifndef RELOC_HIDE # define RELOC_HIDE(ptr, off) \ ({ unsigned long __ptr; \ @@ -406,6 +429,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s # define __attribute_const__ /* unimplemented */ #endif +#ifndef __latent_entropy +# define __latent_entropy +#endif + /* * Tell gcc if a function is cold. The compiler will assume any path * directly leading to the call is unlikely. diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 631ba33bbe9f..32dc0cbd51ca 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -639,19 +639,19 @@ static inline int cpufreq_table_find_index_al(struct cpufreq_policy *policy, unsigned int target_freq) { struct cpufreq_frequency_table *table = policy->freq_table; + struct cpufreq_frequency_table *pos, *best = table - 1; unsigned int freq; - int i, best = -1; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - freq = table[i].frequency; + cpufreq_for_each_valid_entry(pos, table) { + freq = pos->frequency; if (freq >= target_freq) - return i; + return pos - table; - best = i; + best = pos; } - return best; + return best - table; } /* Find lowest freq at or above target in a table in descending order */ @@ -659,28 +659,28 @@ static inline int cpufreq_table_find_index_dl(struct cpufreq_policy *policy, unsigned int target_freq) { struct cpufreq_frequency_table *table = policy->freq_table; + struct cpufreq_frequency_table *pos, *best = table - 1; unsigned int freq; - int i, best = -1; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - freq = table[i].frequency; + cpufreq_for_each_valid_entry(pos, table) { + freq = pos->frequency; if (freq == target_freq) - return i; + return pos - table; if (freq > target_freq) { - best = i; + best = pos; continue; } /* No freq found above target_freq */ - if (best == -1) - return i; + if (best == table - 1) + return pos - table; - return best; + return best - table; } - return best; + return best - table; } /* Works only on sorted freq-tables */ @@ -700,28 +700,28 @@ static inline int cpufreq_table_find_index_ah(struct cpufreq_policy *policy, unsigned int target_freq) { struct cpufreq_frequency_table *table = policy->freq_table; + struct cpufreq_frequency_table *pos, *best = table - 1; unsigned int freq; - int i, best = -1; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - freq = table[i].frequency; + cpufreq_for_each_valid_entry(pos, table) { + freq = pos->frequency; if (freq == target_freq) - return i; + return pos - table; if (freq < target_freq) { - best = i; + best = pos; continue; } /* No freq found below target_freq */ - if (best == -1) - return i; + if (best == table - 1) + return pos - table; - return best; + return best - table; } - return best; + return best - table; } /* Find highest freq at or below target in a table in descending order */ @@ -729,19 +729,19 @@ static inline int cpufreq_table_find_index_dh(struct cpufreq_policy *policy, unsigned int target_freq) { struct cpufreq_frequency_table *table = policy->freq_table; + struct cpufreq_frequency_table *pos, *best = table - 1; unsigned int freq; - int i, best = -1; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - freq = table[i].frequency; + cpufreq_for_each_valid_entry(pos, table) { + freq = pos->frequency; if (freq <= target_freq) - return i; + return pos - table; - best = i; + best = pos; } - return best; + return best - table; } /* Works only on sorted freq-tables */ @@ -761,32 +761,32 @@ static inline int cpufreq_table_find_index_ac(struct cpufreq_policy *policy, unsigned int target_freq) { struct cpufreq_frequency_table *table = policy->freq_table; + struct cpufreq_frequency_table *pos, *best = table - 1; unsigned int freq; - int i, best = -1; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - freq = table[i].frequency; + cpufreq_for_each_valid_entry(pos, table) { + freq = pos->frequency; if (freq == target_freq) - return i; + return pos - table; if (freq < target_freq) { - best = i; + best = pos; continue; } /* No freq found below target_freq */ - if (best == -1) - return i; + if (best == table - 1) + return pos - table; /* Choose the closest freq */ - if (target_freq - table[best].frequency > freq - target_freq) - return i; + if (target_freq - best->frequency > freq - target_freq) + return pos - table; - return best; + return best - table; } - return best; + return best - table; } /* Find closest freq to target in a table in descending order */ @@ -794,32 +794,32 @@ static inline int cpufreq_table_find_index_dc(struct cpufreq_policy *policy, unsigned int target_freq) { struct cpufreq_frequency_table *table = policy->freq_table; + struct cpufreq_frequency_table *pos, *best = table - 1; unsigned int freq; - int i, best = -1; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - freq = table[i].frequency; + cpufreq_for_each_valid_entry(pos, table) { + freq = pos->frequency; if (freq == target_freq) - return i; + return pos - table; if (freq > target_freq) { - best = i; + best = pos; continue; } /* No freq found above target_freq */ - if (best == -1) - return i; + if (best == table - 1) + return pos - table; /* Choose the closest freq */ - if (table[best].frequency - target_freq > target_freq - freq) - return i; + if (best->frequency - target_freq > target_freq - freq) + return pos - table; - return best; + return best - table; } - return best; + return best - table; } /* Works only on sorted freq-tables */ diff --git a/include/linux/ctype.h b/include/linux/ctype.h index 653589e3e30e..f13e4ff6835a 100644 --- a/include/linux/ctype.h +++ b/include/linux/ctype.h @@ -22,7 +22,10 @@ extern const unsigned char _ctype[]; #define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) #define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) #define iscntrl(c) ((__ismask(c)&(_C)) != 0) -#define isdigit(c) ((__ismask(c)&(_D)) != 0) +static inline int isdigit(int c) +{ + return '0' <= c && c <= '9'; +} #define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) #define islower(c) ((__ismask(c)&(_L)) != 0) #define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 5ff3e9a4fe5f..5beed7b30561 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -584,9 +584,10 @@ static inline struct dentry *d_real(struct dentry *dentry, * If dentry is on an union/overlay, then return the underlying, real inode. * Otherwise return d_inode(). */ -static inline struct inode *d_real_inode(struct dentry *dentry) +static inline struct inode *d_real_inode(const struct dentry *dentry) { - return d_backing_inode(d_real(dentry, NULL, 0)); + /* This usage of d_real() results in const dentry */ + return d_backing_inode(d_real((struct dentry *) dentry, NULL, 0)); } diff --git a/include/linux/device.h b/include/linux/device.h index 38f02814d53a..bc41e87a969b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -41,6 +41,7 @@ struct device_node; struct fwnode_handle; struct iommu_ops; struct iommu_group; +struct iommu_fwspec; struct bus_attribute { struct attribute attr; @@ -765,6 +766,7 @@ struct device_dma_parameters { * gone away. This should be set by the allocator of the * device (i.e. the bus driver that discovered the device). * @iommu_group: IOMMU group the device belongs to. + * @iommu_fwspec: IOMMU-specific properties supplied by firmware. * * @offline_disabled: If set, the device is permanently online. * @offline: Set after successful invocation of bus type's .offline(). @@ -849,6 +851,7 @@ struct device { void (*release)(struct device *dev); struct iommu_group *iommu_group; + struct iommu_fwspec *iommu_fwspec; bool offline_disabled:1; bool offline:1; diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h index 81c5c8d167ad..32c589062bd9 100644 --- a/include/linux/dma-iommu.h +++ b/include/linux/dma-iommu.h @@ -21,6 +21,7 @@ #ifdef CONFIG_IOMMU_DMA #include <linux/iommu.h> +#include <linux/msi.h> int iommu_dma_init(void); @@ -29,7 +30,8 @@ int iommu_get_dma_cookie(struct iommu_domain *domain); void iommu_put_dma_cookie(struct iommu_domain *domain); /* Setup call for arch DMA mapping code */ -int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, u64 size); +int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, + u64 size, struct device *dev); /* General helpers for DMA-API <-> IOMMU-API interaction */ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent); @@ -62,9 +64,13 @@ void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int iommu_dma_supported(struct device *dev, u64 mask); int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr); +/* The DMA API isn't _quite_ the whole story, though... */ +void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg); + #else struct iommu_domain; +struct msi_msg; static inline int iommu_dma_init(void) { @@ -80,6 +86,10 @@ static inline void iommu_put_dma_cookie(struct iommu_domain *domain) { } +static inline void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) +{ +} + #endif /* CONFIG_IOMMU_DMA */ #endif /* __KERNEL__ */ #endif /* __DMA_IOMMU_H */ diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 0f90eb5e3c6b..08528afdf58b 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -56,6 +56,11 @@ * that gives better TLB efficiency. */ #define DMA_ATTR_ALLOC_SINGLE_PAGES (1UL << 7) +/* + * DMA_ATTR_NO_WARN: This tells the DMA-mapping subsystem to suppress + * allocation failure reports (similarly to __GFP_NOWARN). + */ +#define DMA_ATTR_NO_WARN (1UL << 8) /* * A dma_addr_t can hold any valid DMA or bus address for the platform. diff --git a/include/linux/export.h b/include/linux/export.h index c565f87f005e..2a0f61fbc731 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -1,5 +1,6 @@ #ifndef _LINUX_EXPORT_H #define _LINUX_EXPORT_H + /* * Export symbols from the kernel to modules. Forked from module.h * to reduce the amount of pointless cruft we feed to gcc when only @@ -42,27 +43,26 @@ extern struct module __this_module; #ifdef CONFIG_MODVERSIONS /* Mark the CRC weak since genksyms apparently decides not to * generate a checksums for some symbols */ -#define __CRC_SYMBOL(sym, sec) \ - extern __visible void *__crc_##sym __attribute__((weak)); \ - static const unsigned long __kcrctab_##sym \ - __used \ - __attribute__((section("___kcrctab" sec "+" #sym), unused)) \ +#define __CRC_SYMBOL(sym, sec) \ + extern __visible void *__crc_##sym __attribute__((weak)); \ + static const unsigned long __kcrctab_##sym \ + __used \ + __attribute__((section("___kcrctab" sec "+" #sym), used)) \ = (unsigned long) &__crc_##sym; #else #define __CRC_SYMBOL(sym, sec) #endif /* For every exported symbol, place a struct in the __ksymtab section */ -#define ___EXPORT_SYMBOL(sym, sec) \ - extern typeof(sym) sym; \ - __CRC_SYMBOL(sym, sec) \ - static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"), aligned(1))) \ - = VMLINUX_SYMBOL_STR(sym); \ - extern const struct kernel_symbol __ksymtab_##sym; \ - __visible const struct kernel_symbol __ksymtab_##sym \ - __used \ - __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ +#define ___EXPORT_SYMBOL(sym, sec) \ + extern typeof(sym) sym; \ + __CRC_SYMBOL(sym, sec) \ + static const char __kstrtab_##sym[] \ + __attribute__((section("__ksymtab_strings"), aligned(1))) \ + = VMLINUX_SYMBOL_STR(sym); \ + static const struct kernel_symbol __ksymtab_##sym \ + __used \ + __attribute__((section("___ksymtab" sec "+" #sym), used)) \ = { (unsigned long)&sym, __kstrtab_##sym } #if defined(__KSYM_DEPS__) @@ -78,7 +78,6 @@ extern struct module __this_module; #elif defined(CONFIG_TRIM_UNUSED_KSYMS) -#include <linux/kconfig.h> #include <generated/autoksyms.h> #define __EXPORT_SYMBOL(sym, sec) \ diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index b03c0625fa6e..5ab958cdc50b 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -157,12 +157,13 @@ struct fid { * @fh_to_dentry is given a &struct super_block (@sb) and a file handle * fragment (@fh, @fh_len). It should return a &struct dentry which refers * to the same file that the file handle fragment refers to. If it cannot, - * it should return a %NULL pointer if the file was found but no acceptable - * &dentries were available, or an %ERR_PTR error code indicating why it - * couldn't be found (e.g. %ENOENT or %ENOMEM). Any suitable dentry can be - * returned including, if necessary, a new dentry created with d_alloc_root. - * The caller can then find any other extant dentries by following the - * d_alias links. + * it should return a %NULL pointer if the file cannot be found, or an + * %ERR_PTR error code of %ENOMEM if a memory allocation failure occurred. + * Any other error code is treated like %NULL, and will cause an %ESTALE error + * for callers of exportfs_decode_fh(). + * Any suitable dentry can be returned including, if necessary, a new dentry + * created with d_alloc_root. The caller can then find any other extant + * dentries by following the d_alias links. * * fh_to_parent: * Same as @fh_to_dentry, except that it returns a pointer to the parent diff --git a/include/linux/falloc.h b/include/linux/falloc.h index 996111000a8c..7494dc67c66f 100644 --- a/include/linux/falloc.h +++ b/include/linux/falloc.h @@ -25,6 +25,7 @@ struct space_resv { FALLOC_FL_PUNCH_HOLE | \ FALLOC_FL_COLLAPSE_RANGE | \ FALLOC_FL_ZERO_RANGE | \ - FALLOC_FL_INSERT_RANGE) + FALLOC_FL_INSERT_RANGE | \ + FALLOC_FL_UNSHARE_RANGE) #endif /* _FALLOC_H_ */ diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 5295535b60c6..6e84b2cae6ad 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -30,12 +30,12 @@ struct fdtable { struct rcu_head rcu; }; -static inline bool close_on_exec(int fd, const struct fdtable *fdt) +static inline bool close_on_exec(unsigned int fd, const struct fdtable *fdt) { return test_bit(fd, fdt->close_on_exec); } -static inline bool fd_is_open(int fd, const struct fdtable *fdt) +static inline bool fd_is_open(unsigned int fd, const struct fdtable *fdt) { return test_bit(fd, fdt->open_fds); } @@ -57,7 +57,7 @@ struct files_struct { * written part on a separate cache line in SMP */ spinlock_t file_lock ____cacheline_aligned_in_smp; - int next_fd; + unsigned int next_fd; unsigned long close_on_exec_init[1]; unsigned long open_fds_init[1]; unsigned long full_fds_bits_init[1]; @@ -105,7 +105,7 @@ struct files_struct *get_files_struct(struct task_struct *); void put_files_struct(struct files_struct *fs); void reset_files_struct(struct files_struct *); int unshare_files(struct files_struct **); -struct files_struct *dup_fd(struct files_struct *, int *); +struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy; void do_close_on_exec(struct files_struct *); int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), diff --git a/include/linux/fence-array.h b/include/linux/fence-array.h index 86baaa45567c..a44794e508df 100644 --- a/include/linux/fence-array.h +++ b/include/linux/fence-array.h @@ -52,6 +52,16 @@ struct fence_array { extern const struct fence_ops fence_array_ops; /** + * fence_is_array - check if a fence is from the array subsclass + * + * Return true if it is a fence_array and false otherwise. + */ +static inline bool fence_is_array(struct fence *fence) +{ + return fence->ops == &fence_array_ops; +} + +/** * to_fence_array - cast a fence to a fence_array * @fence: fence to cast to a fence_array * diff --git a/include/linux/fence.h b/include/linux/fence.h index 2ac6fa5f4712..0d763053f97a 100644 --- a/include/linux/fence.h +++ b/include/linux/fence.h @@ -60,7 +60,7 @@ struct fence_cb; * implementer of the fence for its own purposes. Can be used in different * ways by different fence implementers, so do not rely on this. * - * *) Since atomic bitops are used, this is not guaranteed to be the case. + * Since atomic bitops are used, this is not guaranteed to be the case. * Particularly, if the bit was set, but fence_signal was called right * before this bit was set, it would have been able to set the * FENCE_FLAG_SIGNALED_BIT, before enable_signaling was called. diff --git a/include/linux/fs.h b/include/linux/fs.h index b04883e74579..16d2b6e874d6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -63,7 +63,7 @@ extern void __init files_maxfiles_init(void); extern struct files_stat_struct files_stat; extern unsigned long get_max_files(void); -extern int sysctl_nr_open; +extern unsigned int sysctl_nr_open; extern struct inodes_stat_t inodes_stat; extern int leases_enable, lease_break_time; extern int sysctl_protected_symlinks; @@ -224,6 +224,7 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, #define ATTR_KILL_PRIV (1 << 14) #define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */ #define ATTR_TIMES_SET (1 << 16) +#define ATTR_TOUCH (1 << 17) /* * Whiteout is represented by a char device. The following constants define the @@ -439,8 +440,9 @@ struct address_space { unsigned long nrexceptional; pgoff_t writeback_index;/* writeback starts here */ const struct address_space_operations *a_ops; /* methods */ - unsigned long flags; /* error bits/gfp mask */ + unsigned long flags; /* error bits */ spinlock_t private_lock; /* for use by the address_space */ + gfp_t gfp_mask; /* implicit gfp mask for allocations */ struct list_head private_list; /* ditto */ void *private_data; /* ditto */ } __attribute__((aligned(sizeof(long)))); @@ -591,6 +593,7 @@ is_uncached_acl(struct posix_acl *acl) #define IOP_FASTPERM 0x0001 #define IOP_LOOKUP 0x0002 #define IOP_NOFOLLOW 0x0004 +#define IOP_XATTR 0x0008 /* * Keep mostly read-only and often accessed (especially for @@ -1064,6 +1067,18 @@ struct file_lock_context { extern void send_sigio(struct fown_struct *fown, int fd, int band); +/* + * Return the inode to use for locking + * + * For overlayfs this should be the overlay inode, not the real inode returned + * by file_inode(). For any other fs file_inode(filp) and locks_inode(filp) are + * equal. + */ +static inline struct inode *locks_inode(const struct file *f) +{ + return f->f_path.dentry->d_inode; +} + #ifdef CONFIG_FILE_LOCKING extern int fcntl_getlk(struct file *, unsigned int, struct flock __user *); extern int fcntl_setlk(unsigned int, struct file *, unsigned int, @@ -1251,7 +1266,7 @@ static inline struct dentry *file_dentry(const struct file *file) static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl) { - return locks_lock_inode_wait(file_inode(filp), fl); + return locks_lock_inode_wait(locks_inode(filp), fl); } struct fasync_struct { @@ -1459,6 +1474,7 @@ static inline void i_gid_write(struct inode *inode, gid_t gid) } extern struct timespec current_fs_time(struct super_block *sb); +extern struct timespec current_time(struct inode *inode); /* * Snapshotting support. @@ -1733,17 +1749,10 @@ struct inode_operations { int (*rmdir) (struct inode *,struct dentry *); int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t); int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); - int (*rename2) (struct inode *, struct dentry *, struct inode *, struct dentry *, unsigned int); int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); - int (*setxattr) (struct dentry *, struct inode *, - const char *, const void *, size_t, int); - ssize_t (*getxattr) (struct dentry *, struct inode *, - const char *, void *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t); - int (*removexattr) (struct dentry *, const char *); int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); int (*update_time)(struct inode *, struct timespec *, int); @@ -2006,7 +2015,6 @@ enum file_time_flags { S_VERSION = 8, }; -extern bool atime_needs_update(const struct path *, struct inode *); extern void touch_atime(const struct path *); static inline void file_accessed(struct file *file) { @@ -2075,10 +2083,19 @@ struct super_block *sget(struct file_system_type *type, int (*test)(struct super_block *,void *), int (*set)(struct super_block *,void *), int flags, void *data); -extern struct dentry *mount_pseudo(struct file_system_type *, char *, - const struct super_operations *ops, - const struct dentry_operations *dops, - unsigned long); +extern struct dentry *mount_pseudo_xattr(struct file_system_type *, char *, + const struct super_operations *ops, + const struct xattr_handler **xattr, + const struct dentry_operations *dops, + unsigned long); + +static inline struct dentry * +mount_pseudo(struct file_system_type *fs_type, char *name, + const struct super_operations *ops, + const struct dentry_operations *dops, unsigned long magic) +{ + return mount_pseudo_xattr(fs_type, name, ops, NULL, dops, magic); +} /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \ @@ -2155,7 +2172,7 @@ static inline int mandatory_lock(struct inode *ino) static inline int locks_verify_locked(struct file *file) { - if (mandatory_lock(file_inode(file))) + if (mandatory_lock(locks_inode(file))) return locks_mandatory_locked(file); return 0; } @@ -2917,6 +2934,7 @@ extern int vfs_stat(const char __user *, struct kstat *); extern int vfs_lstat(const char __user *, struct kstat *); extern int vfs_fstat(unsigned int, struct kstat *); extern int vfs_fstatat(int , const char __user *, struct kstat *, int); +extern const char *vfs_get_link(struct dentry *, struct delayed_call *); extern int __generic_block_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, @@ -2948,7 +2966,8 @@ extern int simple_open(struct inode *inode, struct file *file); extern int simple_link(struct dentry *, struct inode *, struct dentry *); extern int simple_unlink(struct inode *, struct dentry *); extern int simple_rmdir(struct inode *, struct dentry *); -extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); +extern int simple_rename(struct inode *, struct dentry *, + struct inode *, struct dentry *, unsigned int); extern int noop_fsync(struct file *, loff_t, loff_t, int); extern int simple_empty(struct dentry *); extern int simple_readpage(struct file *file, struct page *page); @@ -2993,7 +3012,7 @@ extern int buffer_migrate_page(struct address_space *, #define buffer_migrate_page NULL #endif -extern int inode_change_ok(const struct inode *, struct iattr *); +extern int setattr_prepare(struct dentry *, struct iattr *); extern int inode_newsize_ok(const struct inode *, loff_t offset); extern void setattr_copy(struct inode *inode, const struct iattr *attr); diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index eed9e853a06f..b8bcc058e031 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -29,7 +29,11 @@ static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u3 static inline int fsnotify_perm(struct file *file, int mask) { struct path *path = &file->f_path; - struct inode *inode = file_inode(file); + /* + * Do not use file_inode() here or anywhere in this file to get the + * inode. That would break *notity on overlayfs. + */ + struct inode *inode = path->dentry->d_inode; __u32 fsnotify_mask = 0; int ret; @@ -173,7 +177,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) static inline void fsnotify_access(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = file_inode(file); + struct inode *inode = path->dentry->d_inode; __u32 mask = FS_ACCESS; if (S_ISDIR(inode->i_mode)) @@ -191,7 +195,7 @@ static inline void fsnotify_access(struct file *file) static inline void fsnotify_modify(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = file_inode(file); + struct inode *inode = path->dentry->d_inode; __u32 mask = FS_MODIFY; if (S_ISDIR(inode->i_mode)) @@ -209,7 +213,7 @@ static inline void fsnotify_modify(struct file *file) static inline void fsnotify_open(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = file_inode(file); + struct inode *inode = path->dentry->d_inode; __u32 mask = FS_OPEN; if (S_ISDIR(inode->i_mode)) @@ -225,7 +229,7 @@ static inline void fsnotify_open(struct file *file) static inline void fsnotify_close(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = file_inode(file); + struct inode *inode = path->dentry->d_inode; fmode_t mode = file->f_mode; __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE; diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 1dbf52f9c24b..e0341af6950e 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -437,7 +437,7 @@ extern void disk_flush_events(struct gendisk *disk, unsigned int mask); extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask); /* drivers/char/random.c */ -extern void add_disk_randomness(struct gendisk *disk); +extern void add_disk_randomness(struct gendisk *disk) __latent_entropy; extern void rand_initialize_disk(struct gendisk *disk); static inline sector_t get_start_sect(struct block_device *bdev) diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 1f0be7213e6d..24e2cc56beb1 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -8,7 +8,6 @@ #include <linux/irqdomain.h> #include <linux/lockdep.h> #include <linux/pinctrl/pinctrl.h> -#include <linux/kconfig.h> struct gpio_desc; struct of_phandle_args; diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h index 4f7d8f4b1e9a..34a0dc18f327 100644 --- a/include/linux/hw_random.h +++ b/include/linux/hw_random.h @@ -29,7 +29,9 @@ * Returns the number of lower random bytes in "data". * Must not be NULL. *OBSOLETE* * @read: New API. drivers can fill up to max bytes of data - * into the buffer. The buffer is aligned for any type. + * into the buffer. The buffer is aligned for any type + * and max is guaranteed to be >= to that alignment + * (either 4 or 8 depending on architecture). * @priv: Private data, for use by the RNG driver. * @quality: Estimation of true entropy in RNG's bitstream * (per mill). diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 174f43f43aff..c05216a8fbac 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -245,7 +245,7 @@ static inline struct team_port *team_get_port_by_index(struct team *team, return NULL; } -static inline int team_num_to_port_index(struct team *team, int num) +static inline int team_num_to_port_index(struct team *team, unsigned int num) { int en_port_count = ACCESS_ONCE(team->en_port_count); diff --git a/include/linux/init.h b/include/linux/init.h index 5a3321a7909b..e30104ceb86d 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -39,7 +39,7 @@ /* These are for everybody (although not all archs will actually discard it in modules) */ -#define __init __section(.init.text) __cold notrace +#define __init __section(.init.text) __cold notrace __latent_entropy #define __initdata __section(.init.data) #define __initconst __section(.init.rodata) #define __exitdata __section(.exit.data) @@ -75,7 +75,8 @@ #define __exit __section(.exit.text) __exitused __cold notrace /* Used for MEMORY_HOTPLUG */ -#define __meminit __section(.meminit.text) __cold notrace +#define __meminit __section(.meminit.text) __cold notrace \ + __latent_entropy #define __meminitdata __section(.meminit.data) #define __meminitconst __section(.meminit.rodata) #define __memexit __section(.memexit.text) __exitused __cold notrace @@ -139,24 +140,8 @@ extern bool initcall_debug; #ifndef __ASSEMBLY__ -#ifdef CONFIG_LTO -/* Work around a LTO gcc problem: when there is no reference to a variable - * in a module it will be moved to the end of the program. This causes - * reordering of initcalls which the kernel does not like. - * Add a dummy reference function to avoid this. The function is - * deleted by the linker. - */ -#define LTO_REFERENCE_INITCALL(x) \ - ; /* yes this is needed */ \ - static __used __exit void *reference_##x(void) \ - { \ - return &x; \ - } -#else -#define LTO_REFERENCE_INITCALL(x) -#endif - -/* initcalls are now grouped by functionality into separate +/* + * initcalls are now grouped by functionality into separate * subsections. Ordering inside the subsections is determined * by link order. * For backwards compatibility, initcall() puts the call in @@ -164,12 +149,16 @@ extern bool initcall_debug; * * The `id' arg to __define_initcall() is needed so that multiple initcalls * can point at the same handler without causing duplicate-symbol build errors. + * + * Initcalls are run by placing pointers in initcall sections that the + * kernel iterates at runtime. The linker can do dead code / data elimination + * and remove that completely, so the initcall sections have to be marked + * as KEEP() in the linker script. */ #define __define_initcall(fn, id) \ static initcall_t __initcall_##fn##id __used \ - __attribute__((__section__(".initcall" #id ".init"))) = fn; \ - LTO_REFERENCE_INITCALL(__initcall_##fn##id) + __attribute__((__section__(".initcall" #id ".init"))) = fn; /* * Early initcalls run before initializing SMP. @@ -205,15 +194,15 @@ extern bool initcall_debug; #define __initcall(fn) device_initcall(fn) -#define __exitcall(fn) \ +#define __exitcall(fn) \ static exitcall_t __exitcall_##fn __exit_call = fn -#define console_initcall(fn) \ - static initcall_t __initcall_##fn \ +#define console_initcall(fn) \ + static initcall_t __initcall_##fn \ __used __section(.con_initcall.init) = fn -#define security_initcall(fn) \ - static initcall_t __initcall_##fn \ +#define security_initcall(fn) \ + static initcall_t __initcall_##fn \ __used __section(.security_initcall.init) = fn struct obs_kernel_param { diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index 645ad06b5d52..58df02bd93c9 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -31,16 +31,16 @@ * See Documentation/io-mapping.txt */ -#ifdef CONFIG_HAVE_ATOMIC_IOMAP - -#include <asm/iomap.h> - struct io_mapping { resource_size_t base; unsigned long size; pgprot_t prot; + void __iomem *iomem; }; +#ifdef CONFIG_HAVE_ATOMIC_IOMAP + +#include <asm/iomap.h> /* * For small address space machines, mapping large objects * into the kernel virtual space isn't practical. Where @@ -49,34 +49,25 @@ struct io_mapping { */ static inline struct io_mapping * -io_mapping_create_wc(resource_size_t base, unsigned long size) +io_mapping_init_wc(struct io_mapping *iomap, + resource_size_t base, + unsigned long size) { - struct io_mapping *iomap; pgprot_t prot; - iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); - if (!iomap) - goto out_err; - if (iomap_create_wc(base, size, &prot)) - goto out_free; + return NULL; iomap->base = base; iomap->size = size; iomap->prot = prot; return iomap; - -out_free: - kfree(iomap); -out_err: - return NULL; } static inline void -io_mapping_free(struct io_mapping *mapping) +io_mapping_fini(struct io_mapping *mapping) { iomap_free(mapping->base, mapping->size); - kfree(mapping); } /* Atomic map/unmap */ @@ -121,21 +112,46 @@ io_mapping_unmap(void __iomem *vaddr) #else #include <linux/uaccess.h> - -/* this struct isn't actually defined anywhere */ -struct io_mapping; +#include <asm/pgtable.h> /* Create the io_mapping object*/ static inline struct io_mapping * -io_mapping_create_wc(resource_size_t base, unsigned long size) +io_mapping_init_wc(struct io_mapping *iomap, + resource_size_t base, + unsigned long size) { - return (struct io_mapping __force *) ioremap_wc(base, size); + iomap->base = base; + iomap->size = size; + iomap->iomem = ioremap_wc(base, size); +#if defined(pgprot_noncached_wc) /* archs can't agree on a name ... */ + iomap->prot = pgprot_noncached_wc(PAGE_KERNEL); +#elif defined(pgprot_writecombine) + iomap->prot = pgprot_writecombine(PAGE_KERNEL); +#else + iomap->prot = pgprot_noncached(PAGE_KERNEL); +#endif + + return iomap; } static inline void -io_mapping_free(struct io_mapping *mapping) +io_mapping_fini(struct io_mapping *mapping) +{ + iounmap(mapping->iomem); +} + +/* Non-atomic map/unmap */ +static inline void __iomem * +io_mapping_map_wc(struct io_mapping *mapping, + unsigned long offset, + unsigned long size) +{ + return mapping->iomem + offset; +} + +static inline void +io_mapping_unmap(void __iomem *vaddr) { - iounmap((void __force __iomem *) mapping); } /* Atomic map/unmap */ @@ -145,30 +161,42 @@ io_mapping_map_atomic_wc(struct io_mapping *mapping, { preempt_disable(); pagefault_disable(); - return ((char __force __iomem *) mapping) + offset; + return io_mapping_map_wc(mapping, offset, PAGE_SIZE); } static inline void io_mapping_unmap_atomic(void __iomem *vaddr) { + io_mapping_unmap(vaddr); pagefault_enable(); preempt_enable(); } -/* Non-atomic map/unmap */ -static inline void __iomem * -io_mapping_map_wc(struct io_mapping *mapping, - unsigned long offset, - unsigned long size) +#endif /* HAVE_ATOMIC_IOMAP */ + +static inline struct io_mapping * +io_mapping_create_wc(resource_size_t base, + unsigned long size) { - return ((char __force __iomem *) mapping) + offset; + struct io_mapping *iomap; + + iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); + if (!iomap) + return NULL; + + if (!io_mapping_init_wc(iomap, base, size)) { + kfree(iomap); + return NULL; + } + + return iomap; } static inline void -io_mapping_unmap(void __iomem *vaddr) +io_mapping_free(struct io_mapping *iomap) { + io_mapping_fini(iomap); + kfree(iomap); } -#endif /* HAVE_ATOMIC_IOMAP */ - #endif /* _LINUX_IO_MAPPING_H */ diff --git a/include/linux/iommu.h b/include/linux/iommu.h index a35fb8b42e1a..436dc21318af 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -331,10 +331,32 @@ extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +/** + * struct iommu_fwspec - per-device IOMMU instance data + * @ops: ops for this device's IOMMU + * @iommu_fwnode: firmware handle for this device's IOMMU + * @iommu_priv: IOMMU driver private data for this device + * @num_ids: number of associated device IDs + * @ids: IDs which this device may present to the IOMMU + */ +struct iommu_fwspec { + const struct iommu_ops *ops; + struct fwnode_handle *iommu_fwnode; + void *iommu_priv; + unsigned int num_ids; + u32 ids[1]; +}; + +int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode, + const struct iommu_ops *ops); +void iommu_fwspec_free(struct device *dev); +int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids); + #else /* CONFIG_IOMMU_API */ struct iommu_ops {}; struct iommu_group {}; +struct iommu_fwspec {}; static inline bool iommu_present(struct bus_type *bus) { @@ -541,6 +563,23 @@ static inline void iommu_device_unlink(struct device *dev, struct device *link) { } +static inline int iommu_fwspec_init(struct device *dev, + struct fwnode_handle *iommu_fwnode, + const struct iommu_ops *ops) +{ + return -ENODEV; +} + +static inline void iommu_fwspec_free(struct device *dev) +{ +} + +static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids, + int num_ids) +{ + return -ENODEV; +} + #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */ diff --git a/include/linux/kasan.h b/include/linux/kasan.h index d600303306eb..820c0ad54a01 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -44,6 +44,7 @@ static inline void kasan_disable_current(void) void kasan_unpoison_shadow(const void *address, size_t size); void kasan_unpoison_task_stack(struct task_struct *task); +void kasan_unpoison_stack_above_sp_to(const void *watermark); void kasan_alloc_pages(struct page *page, unsigned int order); void kasan_free_pages(struct page *page, unsigned int order); @@ -85,6 +86,7 @@ size_t kasan_metadata_size(struct kmem_cache *cache); static inline void kasan_unpoison_shadow(const void *address, size_t size) {} static inline void kasan_unpoison_task_stack(struct task_struct *task) {} +static inline void kasan_unpoison_stack_above_sp_to(const void *watermark) {} static inline void kasan_enable_current(void) {} static inline void kasan_disable_current(void) {} diff --git a/include/linux/kern_levels.h b/include/linux/kern_levels.h index c2ce155d83cc..f282d4e87258 100644 --- a/include/linux/kern_levels.h +++ b/include/linux/kern_levels.h @@ -20,7 +20,7 @@ * line that had no enclosing \n). Only to be used by core/arch code * during early bootup (a continued line is not SMP-safe otherwise). */ -#define KERN_CONT "" +#define KERN_CONT KERN_SOH "c" /* integer equivalents of KERN_<LEVEL> */ #define LOGLEVEL_SCHED -2 /* Deferred messages from sched code diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 96356ef012de..7056238fd9f5 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -269,10 +269,8 @@ static inline bool kernfs_ns_enabled(struct kernfs_node *kn) } int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen); -size_t kernfs_path_len(struct kernfs_node *kn); int kernfs_path_from_node(struct kernfs_node *root_kn, struct kernfs_node *kn, char *buf, size_t buflen); -char *kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen); void pr_cont_kernfs_name(struct kernfs_node *kn); void pr_cont_kernfs_path(struct kernfs_node *kn); struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn); @@ -341,12 +339,10 @@ static inline bool kernfs_ns_enabled(struct kernfs_node *kn) static inline int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen) { return -ENOSYS; } -static inline size_t kernfs_path_len(struct kernfs_node *kn) -{ return 0; } - -static inline char *kernfs_path(struct kernfs_node *kn, char *buf, - size_t buflen) -{ return NULL; } +static inline int kernfs_path_from_node(struct kernfs_node *root_kn, + struct kernfs_node *kn, + char *buf, size_t buflen) +{ return -ENOSYS; } static inline void pr_cont_kernfs_name(struct kernfs_node *kn) { } static inline void pr_cont_kernfs_path(struct kernfs_node *kn) { } @@ -436,6 +432,22 @@ static inline void kernfs_init(void) { } #endif /* CONFIG_KERNFS */ +/** + * kernfs_path - build full path of a given node + * @kn: kernfs_node of interest + * @buf: buffer to copy @kn's name into + * @buflen: size of @buf + * + * Builds and returns the full path of @kn in @buf of @buflen bytes. The + * path is built from the end of @buf so the returned pointer usually + * doesn't match @buf. If @buf isn't long enough, @buf is nul terminated + * and %NULL is returned. + */ +static inline int kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen) +{ + return kernfs_path_from_node(kn, NULL, buf, buflen); +} + static inline struct kernfs_node * kernfs_find_and_get(struct kernfs_node *kn, const char *name) { diff --git a/include/linux/kexec.h b/include/linux/kexec.h index d7437777baaa..406c33dcae13 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -259,6 +259,12 @@ phys_addr_t paddr_vmcoreinfo_note(void); vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name) #define VMCOREINFO_CONFIG(name) \ vmcoreinfo_append_str("CONFIG_%s=y\n", #name) +#define VMCOREINFO_PAGE_OFFSET(value) \ + vmcoreinfo_append_str("PAGE_OFFSET=%lx\n", (unsigned long)value) +#define VMCOREINFO_VMALLOC_START(value) \ + vmcoreinfo_append_str("VMALLOC_START=%lx\n", (unsigned long)value) +#define VMCOREINFO_VMEMMAP_START(value) \ + vmcoreinfo_append_str("VMEMMAP_START=%lx\n", (unsigned long)value) extern struct kimage *kexec_image; extern struct kimage *kexec_crash_image; diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h index 4894c6888bc6..1c2a32829620 100644 --- a/include/linux/kmemleak.h +++ b/include/linux/kmemleak.h @@ -38,6 +38,11 @@ extern void kmemleak_not_leak(const void *ptr) __ref; extern void kmemleak_ignore(const void *ptr) __ref; extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref; extern void kmemleak_no_scan(const void *ptr) __ref; +extern void kmemleak_alloc_phys(phys_addr_t phys, size_t size, int min_count, + gfp_t gfp) __ref; +extern void kmemleak_free_part_phys(phys_addr_t phys, size_t size) __ref; +extern void kmemleak_not_leak_phys(phys_addr_t phys) __ref; +extern void kmemleak_ignore_phys(phys_addr_t phys) __ref; static inline void kmemleak_alloc_recursive(const void *ptr, size_t size, int min_count, unsigned long flags, @@ -106,6 +111,19 @@ static inline void kmemleak_erase(void **ptr) static inline void kmemleak_no_scan(const void *ptr) { } +static inline void kmemleak_alloc_phys(phys_addr_t phys, size_t size, + int min_count, gfp_t gfp) +{ +} +static inline void kmemleak_free_part_phys(phys_addr_t phys, size_t size) +{ +} +static inline void kmemleak_not_leak_phys(phys_addr_t phys) +{ +} +static inline void kmemleak_ignore_phys(phys_addr_t phys) +{ +} #endif /* CONFIG_DEBUG_KMEMLEAK */ diff --git a/include/linux/kthread.h b/include/linux/kthread.h index e691b6a23f72..a6e82a69c363 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -10,6 +10,17 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), int node, const char namefmt[], ...); +/** + * kthread_create - create a kthread on the current node + * @threadfn: the function to run in the thread + * @data: data pointer for @threadfn() + * @namefmt: printf-style format string for the thread name + * @...: arguments for @namefmt. + * + * This macro will create a kthread on the current node, leaving it in + * the stopped state. This is just a helper for kthread_create_on_node(); + * see the documentation there for more details. + */ #define kthread_create(threadfn, data, namefmt, arg...) \ kthread_create_on_node(threadfn, data, NUMA_NO_NODE, namefmt, ##arg) @@ -44,7 +55,7 @@ bool kthread_should_stop(void); bool kthread_should_park(void); bool kthread_freezable_should_stop(bool *was_frozen); void *kthread_data(struct task_struct *k); -void *probe_kthread_data(struct task_struct *k); +void *kthread_probe_data(struct task_struct *k); int kthread_park(struct task_struct *k); void kthread_unpark(struct task_struct *k); void kthread_parkme(void); @@ -57,16 +68,23 @@ extern int tsk_fork_get_node(struct task_struct *tsk); * Simple work processor based on kthread. * * This provides easier way to make use of kthreads. A kthread_work - * can be queued and flushed using queue/flush_kthread_work() + * can be queued and flushed using queue/kthread_flush_work() * respectively. Queued kthread_works are processed by a kthread * running kthread_worker_fn(). */ struct kthread_work; typedef void (*kthread_work_func_t)(struct kthread_work *work); +void kthread_delayed_work_timer_fn(unsigned long __data); + +enum { + KTW_FREEZABLE = 1 << 0, /* freeze during suspend */ +}; struct kthread_worker { + unsigned int flags; spinlock_t lock; struct list_head work_list; + struct list_head delayed_work_list; struct task_struct *task; struct kthread_work *current_work; }; @@ -75,11 +93,19 @@ struct kthread_work { struct list_head node; kthread_work_func_t func; struct kthread_worker *worker; + /* Number of canceling calls that are running at the moment. */ + int canceling; +}; + +struct kthread_delayed_work { + struct kthread_work work; + struct timer_list timer; }; #define KTHREAD_WORKER_INIT(worker) { \ .lock = __SPIN_LOCK_UNLOCKED((worker).lock), \ .work_list = LIST_HEAD_INIT((worker).work_list), \ + .delayed_work_list = LIST_HEAD_INIT((worker).delayed_work_list),\ } #define KTHREAD_WORK_INIT(work, fn) { \ @@ -87,46 +113,88 @@ struct kthread_work { .func = (fn), \ } +#define KTHREAD_DELAYED_WORK_INIT(dwork, fn) { \ + .work = KTHREAD_WORK_INIT((dwork).work, (fn)), \ + .timer = __TIMER_INITIALIZER(kthread_delayed_work_timer_fn, \ + 0, (unsigned long)&(dwork), \ + TIMER_IRQSAFE), \ + } + #define DEFINE_KTHREAD_WORKER(worker) \ struct kthread_worker worker = KTHREAD_WORKER_INIT(worker) #define DEFINE_KTHREAD_WORK(work, fn) \ struct kthread_work work = KTHREAD_WORK_INIT(work, fn) +#define DEFINE_KTHREAD_DELAYED_WORK(dwork, fn) \ + struct kthread_delayed_work dwork = \ + KTHREAD_DELAYED_WORK_INIT(dwork, fn) + /* * kthread_worker.lock needs its own lockdep class key when defined on * stack with lockdep enabled. Use the following macros in such cases. */ #ifdef CONFIG_LOCKDEP # define KTHREAD_WORKER_INIT_ONSTACK(worker) \ - ({ init_kthread_worker(&worker); worker; }) + ({ kthread_init_worker(&worker); worker; }) # define DEFINE_KTHREAD_WORKER_ONSTACK(worker) \ struct kthread_worker worker = KTHREAD_WORKER_INIT_ONSTACK(worker) #else # define DEFINE_KTHREAD_WORKER_ONSTACK(worker) DEFINE_KTHREAD_WORKER(worker) #endif -extern void __init_kthread_worker(struct kthread_worker *worker, +extern void __kthread_init_worker(struct kthread_worker *worker, const char *name, struct lock_class_key *key); -#define init_kthread_worker(worker) \ +#define kthread_init_worker(worker) \ do { \ static struct lock_class_key __key; \ - __init_kthread_worker((worker), "("#worker")->lock", &__key); \ + __kthread_init_worker((worker), "("#worker")->lock", &__key); \ } while (0) -#define init_kthread_work(work, fn) \ +#define kthread_init_work(work, fn) \ do { \ memset((work), 0, sizeof(struct kthread_work)); \ INIT_LIST_HEAD(&(work)->node); \ (work)->func = (fn); \ } while (0) +#define kthread_init_delayed_work(dwork, fn) \ + do { \ + kthread_init_work(&(dwork)->work, (fn)); \ + __setup_timer(&(dwork)->timer, \ + kthread_delayed_work_timer_fn, \ + (unsigned long)(dwork), \ + TIMER_IRQSAFE); \ + } while (0) + int kthread_worker_fn(void *worker_ptr); -bool queue_kthread_work(struct kthread_worker *worker, +__printf(2, 3) +struct kthread_worker * +kthread_create_worker(unsigned int flags, const char namefmt[], ...); + +struct kthread_worker * +kthread_create_worker_on_cpu(int cpu, unsigned int flags, + const char namefmt[], ...); + +bool kthread_queue_work(struct kthread_worker *worker, struct kthread_work *work); -void flush_kthread_work(struct kthread_work *work); -void flush_kthread_worker(struct kthread_worker *worker); + +bool kthread_queue_delayed_work(struct kthread_worker *worker, + struct kthread_delayed_work *dwork, + unsigned long delay); + +bool kthread_mod_delayed_work(struct kthread_worker *worker, + struct kthread_delayed_work *dwork, + unsigned long delay); + +void kthread_flush_work(struct kthread_work *work); +void kthread_flush_worker(struct kthread_worker *worker); + +bool kthread_cancel_work_sync(struct kthread_work *work); +bool kthread_cancel_delayed_work_sync(struct kthread_delayed_work *work); + +void kthread_destroy_worker(struct kthread_worker *worker); #endif /* _LINUX_KTHREAD_H */ diff --git a/include/linux/libata.h b/include/linux/libata.h index e37d4f99f510..616eef4d81ea 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -46,7 +46,8 @@ #ifdef CONFIG_ATA_NONSTANDARD #include <asm/libata-portmap.h> #else -#include <asm-generic/libata-portmap.h> +#define ATA_PRIMARY_IRQ(dev) 14 +#define ATA_SECONDARY_IRQ(dev) 15 #endif /* diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index b519e137b9b7..f4947fda11e7 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -50,23 +50,6 @@ typedef int (*ndctl_fn)(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc); -struct nd_namespace_label; -struct nvdimm_drvdata; - -struct nd_mapping { - struct nvdimm *nvdimm; - struct nd_namespace_label **labels; - u64 start; - u64 size; - /* - * @ndd is for private use at region enable / disable time for - * get_ndd() + put_ndd(), all other nd_mapping to ndd - * conversions use to_ndd() which respects enabled state of the - * nvdimm. - */ - struct nvdimm_drvdata *ndd; -}; - struct nvdimm_bus_descriptor { const struct attribute_group **attr_groups; unsigned long cmd_mask; @@ -89,9 +72,15 @@ struct nd_interleave_set { u64 cookie; }; +struct nd_mapping_desc { + struct nvdimm *nvdimm; + u64 start; + u64 size; +}; + struct nd_region_desc { struct resource *res; - struct nd_mapping *nd_mapping; + struct nd_mapping_desc *mapping; u16 num_mappings; const struct attribute_group **attr_groups; struct nd_interleave_set *nd_set; @@ -129,6 +118,8 @@ static inline struct nd_blk_region_desc *to_blk_region_desc( } int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length); +void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus, + phys_addr_t start, unsigned int len); struct nvdimm_bus *nvdimm_bus_register(struct device *parent, struct nvdimm_bus_descriptor *nfit_desc); void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus); @@ -139,6 +130,7 @@ struct nd_blk_region *to_nd_blk_region(struct device *dev); struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus); struct device *to_nvdimm_bus_dev(struct nvdimm_bus *nvdimm_bus); const char *nvdimm_name(struct nvdimm *nvdimm); +struct kobject *nvdimm_kobj(struct nvdimm *nvdimm); unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm); void *nvdimm_provider_data(struct nvdimm *nvdimm); struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index 77c141797152..58276144ba81 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h @@ -92,12 +92,21 @@ __mlx5_mask(typ, fld)) ___t; \ }) -#define MLX5_SET64(typ, p, fld, v) do { \ +#define __MLX5_SET64(typ, p, fld, v) do { \ BUILD_BUG_ON(__mlx5_bit_sz(typ, fld) != 64); \ - BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \ *((__be64 *)(p) + __mlx5_64_off(typ, fld)) = cpu_to_be64(v); \ } while (0) +#define MLX5_SET64(typ, p, fld, v) do { \ + BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \ + __MLX5_SET64(typ, p, fld, v); \ +} while (0) + +#define MLX5_ARRAY_SET64(typ, p, fld, idx, v) do { \ + BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \ + __MLX5_SET64(typ, p, fld[idx], v); \ +} while (0) + #define MLX5_GET64(typ, p, fld) be64_to_cpu(*((__be64 *)(p) + __mlx5_64_off(typ, fld))) #define MLX5_GET64_PR(typ, p, fld) ({ \ diff --git a/include/linux/mm.h b/include/linux/mm.h index e9caec6a51e9..ffbd72979ee7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1266,9 +1266,10 @@ static inline int fixup_user_fault(struct task_struct *tsk, } #endif -extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); +extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, + unsigned int gup_flags); extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, - void *buf, int len, int write); + void *buf, int len, unsigned int gup_flags); long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, @@ -1276,19 +1277,18 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, struct vm_area_struct **vmas, int *nonblocking); long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, + unsigned int gup_flags, struct page **pages, struct vm_area_struct **vmas); long get_user_pages(unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, + unsigned int gup_flags, struct page **pages, struct vm_area_struct **vmas); long get_user_pages_locked(unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, int *locked); + unsigned int gup_flags, struct page **pages, int *locked); long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, - unsigned int gup_flags); + struct page **pages, unsigned int gup_flags); long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages); + struct page **pages, unsigned int gup_flags); int get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **pages); @@ -1306,7 +1306,7 @@ struct frame_vector { struct frame_vector *frame_vector_create(unsigned int nr_frames); void frame_vector_destroy(struct frame_vector *vec); int get_vaddr_frames(unsigned long start, unsigned int nr_pfns, - bool write, bool force, struct frame_vector *vec); + unsigned int gup_flags, struct frame_vector *vec); void put_vaddr_frames(struct frame_vector *vec); int frame_vector_to_pages(struct frame_vector *vec); void frame_vector_to_pfns(struct frame_vector *vec); @@ -2232,6 +2232,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma, #define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */ #define FOLL_MLOCK 0x1000 /* lock present pages */ #define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */ +#define FOLL_COW 0x4000 /* internal GUP flag */ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, void *data); diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 29a170612203..13f8052b9ff9 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -127,6 +127,82 @@ struct mtd_ooblayout_ops { struct mtd_oob_region *oobfree); }; +/** + * struct mtd_pairing_info - page pairing information + * + * @pair: pair id + * @group: group id + * + * The term "pair" is used here, even though TLC NANDs might group pages by 3 + * (3 bits in a single cell). A pair should regroup all pages that are sharing + * the same cell. Pairs are then indexed in ascending order. + * + * @group is defining the position of a page in a given pair. It can also be + * seen as the bit position in the cell: page attached to bit 0 belongs to + * group 0, page attached to bit 1 belongs to group 1, etc. + * + * Example: + * The H27UCG8T2BTR-BC datasheet describes the following pairing scheme: + * + * group-0 group-1 + * + * pair-0 page-0 page-4 + * pair-1 page-1 page-5 + * pair-2 page-2 page-8 + * ... + * pair-127 page-251 page-255 + * + * + * Note that the "group" and "pair" terms were extracted from Samsung and + * Hynix datasheets, and might be referenced under other names in other + * datasheets (Micron is describing this concept as "shared pages"). + */ +struct mtd_pairing_info { + int pair; + int group; +}; + +/** + * struct mtd_pairing_scheme - page pairing scheme description + * + * @ngroups: number of groups. Should be related to the number of bits + * per cell. + * @get_info: converts a write-unit (page number within an erase block) into + * mtd_pairing information (pair + group). This function should + * fill the info parameter based on the wunit index or return + * -EINVAL if the wunit parameter is invalid. + * @get_wunit: converts pairing information into a write-unit (page) number. + * This function should return the wunit index pointed by the + * pairing information described in the info argument. It should + * return -EINVAL, if there's no wunit corresponding to the + * passed pairing information. + * + * See mtd_pairing_info documentation for a detailed explanation of the + * pair and group concepts. + * + * The mtd_pairing_scheme structure provides a generic solution to represent + * NAND page pairing scheme. Instead of exposing two big tables to do the + * write-unit <-> (pair + group) conversions, we ask the MTD drivers to + * implement the ->get_info() and ->get_wunit() functions. + * + * MTD users will then be able to query these information by using the + * mtd_pairing_info_to_wunit() and mtd_wunit_to_pairing_info() helpers. + * + * @ngroups is here to help MTD users iterating over all the pages in a + * given pair. This value can be retrieved by MTD users using the + * mtd_pairing_groups() helper. + * + * Examples are given in the mtd_pairing_info_to_wunit() and + * mtd_wunit_to_pairing_info() documentation. + */ +struct mtd_pairing_scheme { + int ngroups; + int (*get_info)(struct mtd_info *mtd, int wunit, + struct mtd_pairing_info *info); + int (*get_wunit)(struct mtd_info *mtd, + const struct mtd_pairing_info *info); +}; + struct module; /* only needed for owner field in mtd_info */ struct mtd_info { @@ -188,6 +264,9 @@ struct mtd_info { /* OOB layout description */ const struct mtd_ooblayout_ops *ooblayout; + /* NAND pairing scheme, only provided for MLC/TLC NANDs */ + const struct mtd_pairing_scheme *pairing; + /* the ecc step size. */ unsigned int ecc_step_size; @@ -296,6 +375,12 @@ static inline void mtd_set_ooblayout(struct mtd_info *mtd, mtd->ooblayout = ooblayout; } +static inline void mtd_set_pairing_scheme(struct mtd_info *mtd, + const struct mtd_pairing_scheme *pairing) +{ + mtd->pairing = pairing; +} + static inline void mtd_set_of_node(struct mtd_info *mtd, struct device_node *np) { @@ -312,6 +397,11 @@ static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops) return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize; } +int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit, + struct mtd_pairing_info *info); +int mtd_pairing_info_to_wunit(struct mtd_info *mtd, + const struct mtd_pairing_info *info); +int mtd_pairing_groups(struct mtd_info *mtd); int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys); @@ -397,6 +487,23 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) return do_div(sz, mtd->writesize); } +static inline int mtd_wunit_per_eb(struct mtd_info *mtd) +{ + return mtd->erasesize / mtd->writesize; +} + +static inline int mtd_offset_to_wunit(struct mtd_info *mtd, loff_t offs) +{ + return mtd_div_by_ws(mtd_mod_by_eb(offs, mtd), mtd); +} + +static inline loff_t mtd_wunit_to_offset(struct mtd_info *mtd, loff_t base, + int wunit) +{ + return base + (wunit * mtd->writesize); +} + + static inline int mtd_has_oob(const struct mtd_info *mtd) { return mtd->_read_oob && mtd->_write_oob; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 8dd6e01f45c0..c5d3d5024fc8 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -29,26 +29,26 @@ struct nand_flash_dev; struct device_node; /* Scan and identify a NAND device */ -extern int nand_scan(struct mtd_info *mtd, int max_chips); +int nand_scan(struct mtd_info *mtd, int max_chips); /* * Separate phases of nand_scan(), allowing board driver to intervene * and override command or ECC setup according to flash type. */ -extern int nand_scan_ident(struct mtd_info *mtd, int max_chips, +int nand_scan_ident(struct mtd_info *mtd, int max_chips, struct nand_flash_dev *table); -extern int nand_scan_tail(struct mtd_info *mtd); +int nand_scan_tail(struct mtd_info *mtd); -/* Free resources held by the NAND device */ -extern void nand_release(struct mtd_info *mtd); +/* Unregister the MTD device and free resources held by the NAND device */ +void nand_release(struct mtd_info *mtd); /* Internal helper for board drivers which need to override command function */ -extern void nand_wait_ready(struct mtd_info *mtd); +void nand_wait_ready(struct mtd_info *mtd); /* locks all blocks present in the device */ -extern int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); +int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); /* unlocks specified locked blocks */ -extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); +int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); /* The maximum number of NAND chips in an array */ #define NAND_MAX_CHIPS 8 @@ -141,6 +141,7 @@ enum nand_ecc_algo { * pages and you want to rely on the default implementation. */ #define NAND_ECC_GENERIC_ERASED_CHECK BIT(0) +#define NAND_ECC_MAXIMIZE BIT(1) /* Bit mask for flags passed to do_nand_read_ecc */ #define NAND_GET_DEVICE 0x80 @@ -460,6 +461,13 @@ struct nand_hw_control { wait_queue_head_t wq; }; +static inline void nand_hw_control_init(struct nand_hw_control *nfc) +{ + nfc->active = NULL; + spin_lock_init(&nfc->lock); + init_waitqueue_head(&nfc->wq); +} + /** * struct nand_ecc_ctrl - Control structure for ECC * @mode: ECC mode @@ -566,6 +574,123 @@ struct nand_buffers { }; /** + * struct nand_sdr_timings - SDR NAND chip timings + * + * This struct defines the timing requirements of a SDR NAND chip. + * These information can be found in every NAND datasheets and the timings + * meaning are described in the ONFI specifications: + * www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing + * Parameters) + * + * All these timings are expressed in picoseconds. + * + * @tALH_min: ALE hold time + * @tADL_min: ALE to data loading time + * @tALS_min: ALE setup time + * @tAR_min: ALE to RE# delay + * @tCEA_max: CE# access time + * @tCEH_min: + * @tCH_min: CE# hold time + * @tCHZ_max: CE# high to output hi-Z + * @tCLH_min: CLE hold time + * @tCLR_min: CLE to RE# delay + * @tCLS_min: CLE setup time + * @tCOH_min: CE# high to output hold + * @tCS_min: CE# setup time + * @tDH_min: Data hold time + * @tDS_min: Data setup time + * @tFEAT_max: Busy time for Set Features and Get Features + * @tIR_min: Output hi-Z to RE# low + * @tITC_max: Interface and Timing Mode Change time + * @tRC_min: RE# cycle time + * @tREA_max: RE# access time + * @tREH_min: RE# high hold time + * @tRHOH_min: RE# high to output hold + * @tRHW_min: RE# high to WE# low + * @tRHZ_max: RE# high to output hi-Z + * @tRLOH_min: RE# low to output hold + * @tRP_min: RE# pulse width + * @tRR_min: Ready to RE# low (data only) + * @tRST_max: Device reset time, measured from the falling edge of R/B# to the + * rising edge of R/B#. + * @tWB_max: WE# high to SR[6] low + * @tWC_min: WE# cycle time + * @tWH_min: WE# high hold time + * @tWHR_min: WE# high to RE# low + * @tWP_min: WE# pulse width + * @tWW_min: WP# transition to WE# low + */ +struct nand_sdr_timings { + u32 tALH_min; + u32 tADL_min; + u32 tALS_min; + u32 tAR_min; + u32 tCEA_max; + u32 tCEH_min; + u32 tCH_min; + u32 tCHZ_max; + u32 tCLH_min; + u32 tCLR_min; + u32 tCLS_min; + u32 tCOH_min; + u32 tCS_min; + u32 tDH_min; + u32 tDS_min; + u32 tFEAT_max; + u32 tIR_min; + u32 tITC_max; + u32 tRC_min; + u32 tREA_max; + u32 tREH_min; + u32 tRHOH_min; + u32 tRHW_min; + u32 tRHZ_max; + u32 tRLOH_min; + u32 tRP_min; + u32 tRR_min; + u64 tRST_max; + u32 tWB_max; + u32 tWC_min; + u32 tWH_min; + u32 tWHR_min; + u32 tWP_min; + u32 tWW_min; +}; + +/** + * enum nand_data_interface_type - NAND interface timing type + * @NAND_SDR_IFACE: Single Data Rate interface + */ +enum nand_data_interface_type { + NAND_SDR_IFACE, +}; + +/** + * struct nand_data_interface - NAND interface timing + * @type: type of the timing + * @timings: The timing, type according to @type + */ +struct nand_data_interface { + enum nand_data_interface_type type; + union { + struct nand_sdr_timings sdr; + } timings; +}; + +/** + * nand_get_sdr_timings - get SDR timing from data interface + * @conf: The data interface + */ +static inline const struct nand_sdr_timings * +nand_get_sdr_timings(const struct nand_data_interface *conf) +{ + if (conf->type != NAND_SDR_IFACE) + return ERR_PTR(-EINVAL); + + return &conf->timings.sdr; +} + +/** * struct nand_chip - NAND Private Flash Chip Data * @mtd: MTD device registered to the MTD framework * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the @@ -627,10 +752,9 @@ struct nand_buffers { * also from the datasheet. It is the recommended ECC step * size, if known; if unknown, set to zero. * @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is - * either deduced from the datasheet if the NAND - * chip is not ONFI compliant or set to 0 if it is - * (an ONFI chip is always configured in mode 0 - * after a NAND reset) + * set to the actually used ONFI mode if the chip is + * ONFI compliant or deduced from the datasheet if + * the NAND chip is not ONFI compliant. * @numchips: [INTERN] number of physical chips * @chipsize: [INTERN] the size of one chip for multichip arrays * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 @@ -650,6 +774,7 @@ struct nand_buffers { * @read_retries: [INTERN] the number of read retry modes supported * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand + * @setup_data_interface: [OPTIONAL] setup the data interface and timing * @bbt: [INTERN] bad block table pointer * @bbt_td: [REPLACEABLE] bad block table descriptor for flash * lookup. @@ -696,6 +821,10 @@ struct nand_chip { int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip, int feature_addr, uint8_t *subfeature_para); int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode); + int (*setup_data_interface)(struct mtd_info *mtd, + const struct nand_data_interface *conf, + bool check_only); + int chip_delay; unsigned int options; @@ -725,6 +854,8 @@ struct nand_chip { struct nand_jedec_params jedec_params; }; + struct nand_data_interface *data_interface; + int read_retries; flstate_t state; @@ -893,14 +1024,14 @@ struct nand_manufacturers { extern struct nand_flash_dev nand_flash_ids[]; extern struct nand_manufacturers nand_manuf_ids[]; -extern int nand_default_bbt(struct mtd_info *mtd); -extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs); -extern int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs); -extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt); -extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, - int allowbbt); -extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, uint8_t *buf); +int nand_default_bbt(struct mtd_info *mtd); +int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs); +int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs); +int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt); +int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, + int allowbbt); +int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, uint8_t *buf); /** * struct platform_nand_chip - chip level device structure @@ -988,6 +1119,11 @@ static inline int onfi_get_sync_timing_mode(struct nand_chip *chip) return le16_to_cpu(chip->onfi_params.src_sync_timing_mode); } +int onfi_init_data_interface(struct nand_chip *chip, + struct nand_data_interface *iface, + enum nand_data_interface_type type, + int timing_mode); + /* * Check if it is a SLC nand. * The !nand_is_slc() can be used to check the MLC/TLC nand chips. @@ -1023,57 +1159,10 @@ static inline int jedec_feature(struct nand_chip *chip) : 0; } -/* - * struct nand_sdr_timings - SDR NAND chip timings - * - * This struct defines the timing requirements of a SDR NAND chip. - * These informations can be found in every NAND datasheets and the timings - * meaning are described in the ONFI specifications: - * www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing - * Parameters) - * - * All these timings are expressed in picoseconds. - */ - -struct nand_sdr_timings { - u32 tALH_min; - u32 tADL_min; - u32 tALS_min; - u32 tAR_min; - u32 tCEA_max; - u32 tCEH_min; - u32 tCH_min; - u32 tCHZ_max; - u32 tCLH_min; - u32 tCLR_min; - u32 tCLS_min; - u32 tCOH_min; - u32 tCS_min; - u32 tDH_min; - u32 tDS_min; - u32 tFEAT_max; - u32 tIR_min; - u32 tITC_max; - u32 tRC_min; - u32 tREA_max; - u32 tREH_min; - u32 tRHOH_min; - u32 tRHW_min; - u32 tRHZ_max; - u32 tRLOH_min; - u32 tRP_min; - u32 tRR_min; - u64 tRST_max; - u32 tWB_max; - u32 tWC_min; - u32 tWH_min; - u32 tWHR_min; - u32 tWP_min; - u32 tWW_min; -}; - /* get timing characteristics from ONFI timing mode. */ const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode); +/* get data interface from ONFI timing mode 0, used after reset. */ +const struct nand_data_interface *nand_get_default_data_interface(void); int nand_check_erased_ecc_chunk(void *data, int datalen, void *ecc, int ecclen, @@ -1093,4 +1182,11 @@ int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page); /* Default read_oob syndrome implementation */ int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip, int page); + +/* Reset and initialize a NAND device */ +int nand_reset(struct nand_chip *chip); + +/* Free resources held by the NAND device */ +void nand_cleanup(struct nand_chip *chip); + #endif /* __LINUX_MTD_NAND_H */ diff --git a/include/linux/nd.h b/include/linux/nd.h index f1ea426d6a5e..fa66aeed441a 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -77,11 +77,13 @@ struct nd_namespace_io { * @nsio: device and system physical address range to drive * @alt_name: namespace name supplied in the dimm label * @uuid: namespace name supplied in the dimm label + * @id: ida allocated id */ struct nd_namespace_pmem { struct nd_namespace_io nsio; char *alt_name; u8 *uuid; + int id; }; /** @@ -105,19 +107,19 @@ struct nd_namespace_blk { struct resource **res; }; -static inline struct nd_namespace_io *to_nd_namespace_io(struct device *dev) +static inline struct nd_namespace_io *to_nd_namespace_io(const struct device *dev) { return container_of(dev, struct nd_namespace_io, common.dev); } -static inline struct nd_namespace_pmem *to_nd_namespace_pmem(struct device *dev) +static inline struct nd_namespace_pmem *to_nd_namespace_pmem(const struct device *dev) { struct nd_namespace_io *nsio = to_nd_namespace_io(dev); return container_of(nsio, struct nd_namespace_pmem, nsio); } -static inline struct nd_namespace_blk *to_nd_namespace_blk(struct device *dev) +static inline struct nd_namespace_blk *to_nd_namespace_blk(const struct device *dev) { return container_of(dev, struct nd_namespace_blk, common.dev); } diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index c6564ada9beb..9094faf0699d 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -67,6 +67,7 @@ struct nfs4_stateid_struct { NFS4_DELEGATION_STATEID_TYPE, NFS4_LAYOUT_STATEID_TYPE, NFS4_PNFS_DS_STATEID_TYPE, + NFS4_REVOKED_STATEID_TYPE, } type; }; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 14a762d2734d..b34097c67848 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -103,6 +103,9 @@ struct nfs_client { #define NFS_SP4_MACH_CRED_WRITE 5 /* WRITE */ #define NFS_SP4_MACH_CRED_COMMIT 6 /* COMMIT */ #define NFS_SP4_MACH_CRED_PNFS_CLEANUP 7 /* LAYOUTRETURN */ +#if IS_ENABLED(CONFIG_NFS_V4_1) + wait_queue_head_t cl_lock_waitq; +#endif /* CONFIG_NFS_V4_1 */ #endif /* CONFIG_NFS_V4 */ /* Our own IP address, as a null-terminated string. diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 7cc0deee5bde..beb1e10f446e 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -125,6 +125,11 @@ struct nfs_fattr { | NFS_ATTR_FATTR_V4_SECURITY_LABEL) /* + * Maximal number of supported layout drivers. + */ +#define NFS_MAX_LAYOUT_TYPES 8 + +/* * Info on the file system */ struct nfs_fsinfo { @@ -139,7 +144,8 @@ struct nfs_fsinfo { __u64 maxfilesize; struct timespec time_delta; /* server time granularity */ __u32 lease_time; /* in seconds */ - __u32 layouttype; /* supported pnfs layout driver */ + __u32 nlayouttypes; /* number of layouttypes */ + __u32 layouttype[NFS_MAX_LAYOUT_TYPES]; /* supported pnfs layout driver */ __u32 blksize; /* preferred pnfs io block size */ __u32 clone_blksize; /* granularity of a CLONE operation */ }; diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index b969e9443962..7fd5cfce9140 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h @@ -17,6 +17,9 @@ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); int of_pci_parse_bus_range(struct device_node *node, struct resource *res); int of_get_pci_domain_nr(struct device_node *node); void of_pci_check_probe_only(void); +int of_pci_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out); #else static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) { @@ -52,6 +55,13 @@ of_get_pci_domain_nr(struct device_node *node) return -1; } +static inline int of_pci_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out) +{ + return -EINVAL; +} + static inline void of_pci_check_probe_only(void) { } #endif diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 794dbcb91084..dd15d39e1985 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -16,17 +16,16 @@ #include <linux/hugetlb_inline.h> /* - * Bits in mapping->flags. The lower __GFP_BITS_SHIFT bits are the page - * allocation mode flags. + * Bits in mapping->flags. */ enum mapping_flags { - AS_EIO = __GFP_BITS_SHIFT + 0, /* IO error on async write */ - AS_ENOSPC = __GFP_BITS_SHIFT + 1, /* ENOSPC on async write */ - AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT + 2, /* under mm_take_all_locks() */ - AS_UNEVICTABLE = __GFP_BITS_SHIFT + 3, /* e.g., ramdisk, SHM_LOCK */ - AS_EXITING = __GFP_BITS_SHIFT + 4, /* final truncate in progress */ + AS_EIO = 0, /* IO error on async write */ + AS_ENOSPC = 1, /* ENOSPC on async write */ + AS_MM_ALL_LOCKS = 2, /* under mm_take_all_locks() */ + AS_UNEVICTABLE = 3, /* e.g., ramdisk, SHM_LOCK */ + AS_EXITING = 4, /* final truncate in progress */ /* writeback related tags are not used */ - AS_NO_WRITEBACK_TAGS = __GFP_BITS_SHIFT + 5, + AS_NO_WRITEBACK_TAGS = 5, }; static inline void mapping_set_error(struct address_space *mapping, int error) @@ -78,7 +77,7 @@ static inline int mapping_use_writeback_tags(struct address_space *mapping) static inline gfp_t mapping_gfp_mask(struct address_space * mapping) { - return (__force gfp_t)mapping->flags & __GFP_BITS_MASK; + return mapping->gfp_mask; } /* Restricts the given gfp_mask to what the mapping allows. */ @@ -94,8 +93,7 @@ static inline gfp_t mapping_gfp_constraint(struct address_space *mapping, */ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask) { - m->flags = (m->flags & ~(__force unsigned long)__GFP_BITS_MASK) | - (__force unsigned long)mask; + m->gfp_mask = mask; } void release_pages(struct page **pages, int nr, bool cold); @@ -530,59 +528,10 @@ void page_endio(struct page *page, bool is_write, int err); extern void add_page_wait_queue(struct page *page, wait_queue_t *waiter); /* - * Fault one or two userspace pages into pagetables. - * Return -EINVAL if more than two pages would be needed. - * Return non-zero on a fault. + * Fault everything in given userspace address range in. */ static inline int fault_in_pages_writeable(char __user *uaddr, int size) { - int span, ret; - - if (unlikely(size == 0)) - return 0; - - span = offset_in_page(uaddr) + size; - if (span > 2 * PAGE_SIZE) - return -EINVAL; - /* - * Writing zeroes into userspace here is OK, because we know that if - * the zero gets there, we'll be overwriting it. - */ - ret = __put_user(0, uaddr); - if (ret == 0 && span > PAGE_SIZE) - ret = __put_user(0, uaddr + size - 1); - return ret; -} - -static inline int fault_in_pages_readable(const char __user *uaddr, int size) -{ - volatile char c; - int ret; - - if (unlikely(size == 0)) - return 0; - - ret = __get_user(c, uaddr); - if (ret == 0) { - const char __user *end = uaddr + size - 1; - - if (((unsigned long)uaddr & PAGE_MASK) != - ((unsigned long)end & PAGE_MASK)) { - ret = __get_user(c, end); - (void)c; - } - } - return ret; -} - -/* - * Multipage variants of the above prefault helpers, useful if more than - * PAGE_SIZE of data needs to be prefaulted. These are separate from the above - * functions (which only handle up to PAGE_SIZE) to avoid clobbering the - * filemap.c hotpaths. - */ -static inline int fault_in_multipages_writeable(char __user *uaddr, int size) -{ char __user *end = uaddr + size - 1; if (unlikely(size == 0)) @@ -608,8 +557,7 @@ static inline int fault_in_multipages_writeable(char __user *uaddr, int size) return 0; } -static inline int fault_in_multipages_readable(const char __user *uaddr, - int size) +static inline int fault_in_pages_readable(const char __user *uaddr, int size) { volatile char c; const char __user *end = uaddr + size - 1; diff --git a/include/linux/pkeys.h b/include/linux/pkeys.h index 1d405a2b7272..a1bacf1150b2 100644 --- a/include/linux/pkeys.h +++ b/include/linux/pkeys.h @@ -4,11 +4,6 @@ #include <linux/mm_types.h> #include <asm/mmu_context.h> -#define PKEY_DISABLE_ACCESS 0x1 -#define PKEY_DISABLE_WRITE 0x2 -#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ - PKEY_DISABLE_WRITE) - #ifdef CONFIG_ARCH_HAS_PKEYS #include <asm/pkeys.h> #else /* ! CONFIG_ARCH_HAS_PKEYS */ @@ -16,18 +11,33 @@ #define execute_only_pkey(mm) (0) #define arch_override_mprotect_pkey(vma, prot, pkey) (0) #define PKEY_DEDICATED_EXECUTE_ONLY 0 -#endif /* ! CONFIG_ARCH_HAS_PKEYS */ +#define ARCH_VM_PKEY_FLAGS 0 + +static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) +{ + return (pkey == 0); +} + +static inline int mm_pkey_alloc(struct mm_struct *mm) +{ + return -1; +} -/* - * This is called from mprotect_pkey(). - * - * Returns true if the protection keys is valid. - */ -static inline bool validate_pkey(int pkey) +static inline int mm_pkey_free(struct mm_struct *mm, int pkey) { - if (pkey < 0) - return false; - return (pkey < arch_max_pkey()); + return -EINVAL; } +static inline int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, + unsigned long init_val) +{ + return 0; +} + +static inline void copy_init_pkru_to_fpregs(void) +{ +} + +#endif /* ! CONFIG_ARCH_HAS_PKEYS */ + #endif /* _LINUX_PKEYS_H */ diff --git a/include/linux/platform_data/media/camera-pxa.h b/include/linux/platform_data/media/camera-pxa.h index 6709b1cd7c77..ce5d90e1a6e4 100644 --- a/include/linux/platform_data/media/camera-pxa.h +++ b/include/linux/platform_data/media/camera-pxa.h @@ -37,6 +37,8 @@ struct pxacamera_platform_data { unsigned long flags; unsigned long mclk_10khz; + int sensor_i2c_adapter_id; + int sensor_i2c_address; }; extern void pxa_set_camera_info(struct pxacamera_platform_data *); diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index d5d3d741f028..5a9a739acdd5 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -11,27 +11,7 @@ #include <linux/bug.h> #include <linux/slab.h> #include <linux/rcupdate.h> - -#define ACL_UNDEFINED_ID (-1) - -/* a_type field in acl_user_posix_entry_t */ -#define ACL_TYPE_ACCESS (0x8000) -#define ACL_TYPE_DEFAULT (0x4000) - -/* e_tag entry in struct posix_acl_entry */ -#define ACL_USER_OBJ (0x01) -#define ACL_USER (0x02) -#define ACL_GROUP_OBJ (0x04) -#define ACL_GROUP (0x08) -#define ACL_MASK (0x10) -#define ACL_OTHER (0x20) - -/* permissions in the e_perm field */ -#define ACL_READ (0x04) -#define ACL_WRITE (0x02) -#define ACL_EXECUTE (0x01) -//#define ACL_ADD (0x08) -//#define ACL_DELETE (0x10) +#include <uapi/linux/posix_acl.h> struct posix_acl_entry { short e_tag; @@ -93,6 +73,7 @@ extern int set_posix_acl(struct inode *, int, struct posix_acl *); extern int posix_acl_chmod(struct inode *, umode_t); extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, struct posix_acl **); +extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **); extern int simple_set_acl(struct inode *, struct posix_acl *, int); extern int simple_acl_create(struct inode *, struct inode *); diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h index e5e8ec40278d..8b867e3bf3aa 100644 --- a/include/linux/posix_acl_xattr.h +++ b/include/linux/posix_acl_xattr.h @@ -10,42 +10,25 @@ #define _POSIX_ACL_XATTR_H #include <uapi/linux/xattr.h> +#include <uapi/linux/posix_acl_xattr.h> #include <linux/posix_acl.h> -/* Supported ACL a_version fields */ -#define POSIX_ACL_XATTR_VERSION 0x0002 - -/* An undefined entry e_id value */ -#define ACL_UNDEFINED_ID (-1) - -typedef struct { - __le16 e_tag; - __le16 e_perm; - __le32 e_id; -} posix_acl_xattr_entry; - -typedef struct { - __le32 a_version; - posix_acl_xattr_entry a_entries[0]; -} posix_acl_xattr_header; - - static inline size_t posix_acl_xattr_size(int count) { - return (sizeof(posix_acl_xattr_header) + - (count * sizeof(posix_acl_xattr_entry))); + return (sizeof(struct posix_acl_xattr_header) + + (count * sizeof(struct posix_acl_xattr_entry))); } static inline int posix_acl_xattr_count(size_t size) { - if (size < sizeof(posix_acl_xattr_header)) + if (size < sizeof(struct posix_acl_xattr_header)) return -1; - size -= sizeof(posix_acl_xattr_header); - if (size % sizeof(posix_acl_xattr_entry)) + size -= sizeof(struct posix_acl_xattr_header); + if (size % sizeof(struct posix_acl_xattr_entry)) return -1; - return size / sizeof(posix_acl_xattr_entry); + return size / sizeof(struct posix_acl_xattr_entry); } #ifdef CONFIG_FS_POSIX_ACL diff --git a/include/linux/printk.h b/include/linux/printk.h index 696a56be7d3e..eac1af8502bb 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -16,6 +16,7 @@ static inline int printk_get_level(const char *buffer) switch (buffer[1]) { case '0' ... '7': case 'd': /* KERN_DEFAULT */ + case 'c': /* KERN_CONT */ return buffer[1]; } } diff --git a/include/linux/pwm.h b/include/linux/pwm.h index f1bbae014889..2c6c5114c089 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -641,6 +641,7 @@ static inline void pwm_remove_table(struct pwm_lookup *table, size_t num) #ifdef CONFIG_PWM_SYSFS void pwmchip_sysfs_export(struct pwm_chip *chip); void pwmchip_sysfs_unexport(struct pwm_chip *chip); +void pwmchip_sysfs_unexport_children(struct pwm_chip *chip); #else static inline void pwmchip_sysfs_export(struct pwm_chip *chip) { @@ -649,6 +650,10 @@ static inline void pwmchip_sysfs_export(struct pwm_chip *chip) static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip) { } + +static inline void pwmchip_sysfs_unexport_children(struct pwm_chip *chip) +{ +} #endif /* CONFIG_PWM_SYSFS */ #endif /* __LINUX_PWM_H */ diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 52b97db93830..af3581b8a451 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -461,6 +461,14 @@ static inline struct radix_tree_node *entry_to_node(void *ptr) * * This function updates @iter->index in the case of a successful lookup. * For tagged lookup it also eats @iter->tags. + * + * There are several cases where 'slot' can be passed in as NULL to this + * function. These cases result from the use of radix_tree_iter_next() or + * radix_tree_iter_retry(). In these cases we don't end up dereferencing + * 'slot' because either: + * a) we are doing tagged iteration and iter->tags has been set to 0, or + * b) we are doing non-tagged iteration, and iter->index and iter->next_index + * have been set up so that radix_tree_chunk_size() returns 1 or 0. */ static __always_inline void ** radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags) diff --git a/include/linux/random.h b/include/linux/random.h index 3d6e9815cd85..7bd2403e4fef 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -18,9 +18,20 @@ struct random_ready_callback { }; extern void add_device_randomness(const void *, unsigned int); + +#if defined(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) && !defined(__CHECKER__) +static inline void add_latent_entropy(void) +{ + add_device_randomness((const void *)&latent_entropy, + sizeof(latent_entropy)); +} +#else +static inline void add_latent_entropy(void) {} +#endif + extern void add_input_randomness(unsigned int type, unsigned int code, - unsigned int value); -extern void add_interrupt_randomness(int irq, int irq_flags); + unsigned int value) __latent_entropy; +extern void add_interrupt_randomness(int irq, int irq_flags) __latent_entropy; extern void get_random_bytes(void *buf, int nbytes); extern int add_random_ready_callback(struct random_ready_callback *rdy); @@ -34,7 +45,7 @@ extern const struct file_operations random_fops, urandom_fops; unsigned int get_random_int(void); unsigned long get_random_long(void); -unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len); +unsigned long randomize_page(unsigned long start, unsigned long range); u32 prandom_u32(void); void prandom_bytes(void *buf, size_t nbytes); diff --git a/include/linux/relay.h b/include/linux/relay.h index ecbb34a382b8..68c1448e56bb 100644 --- a/include/linux/relay.h +++ b/include/linux/relay.h @@ -15,6 +15,7 @@ #include <linux/timer.h> #include <linux/wait.h> #include <linux/list.h> +#include <linux/irq_work.h> #include <linux/bug.h> #include <linux/fs.h> #include <linux/poll.h> @@ -38,7 +39,7 @@ struct rchan_buf size_t subbufs_consumed; /* count of sub-buffers consumed */ struct rchan *chan; /* associated channel */ wait_queue_head_t read_wait; /* reader wait queue */ - struct timer_list timer; /* reader wake-up timer */ + struct irq_work wakeup_work; /* reader wakeup */ struct dentry *dentry; /* channel file dentry */ struct kref kref; /* channel buffer refcount */ struct page **page_array; /* array of current buffer pages */ diff --git a/include/linux/sem.h b/include/linux/sem.h index 976ce3a19f1b..d0efd6e6c20a 100644 --- a/include/linux/sem.h +++ b/include/linux/sem.h @@ -21,6 +21,7 @@ struct sem_array { struct list_head list_id; /* undo requests on this array */ int sem_nsems; /* no. of semaphores in array */ int complex_count; /* pending complex operations */ + bool complex_mode; /* no parallel simple ops */ }; #ifdef CONFIG_SYSVIPC diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 4ccf184e971f..b1bc62ba20a2 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -131,6 +131,7 @@ struct rpc_authops { struct rpc_auth * (*create)(struct rpc_auth_create_args *, struct rpc_clnt *); void (*destroy)(struct rpc_auth *); + int (*hash_cred)(struct auth_cred *, unsigned int); struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int); struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int, gfp_t); int (*list_pseudoflavors)(rpc_authflavor_t *, int); diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 5c02b0691587..85cc819676e8 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -125,6 +125,13 @@ struct rpc_create_args { struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ }; +struct rpc_add_xprt_test { + int (*add_xprt_test)(struct rpc_clnt *, + struct rpc_xprt *, + void *calldata); + void *data; +}; + /* Values for "flags" field */ #define RPC_CLNT_CREATE_HARDRTRY (1UL << 0) #define RPC_CLNT_CREATE_AUTOBIND (1UL << 2) @@ -198,6 +205,16 @@ int rpc_clnt_add_xprt(struct rpc_clnt *, struct xprt_create *, void rpc_cap_max_reconnect_timeout(struct rpc_clnt *clnt, unsigned long timeo); +int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *, + struct rpc_xprt_switch *, + struct rpc_xprt *, + void *); + const char *rpc_proc_name(const struct rpc_task *task); + +void rpc_clnt_xprt_switch_put(struct rpc_clnt *); +void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *, struct rpc_xprt *); +bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt, + const struct sockaddr *sap); #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_CLNT_H */ diff --git a/include/linux/sunrpc/rpc_rdma.h b/include/linux/sunrpc/rpc_rdma.h index 3b1ff38f0c37..cfda6adcf33c 100644 --- a/include/linux/sunrpc/rpc_rdma.h +++ b/include/linux/sunrpc/rpc_rdma.h @@ -41,10 +41,15 @@ #define _LINUX_SUNRPC_RPC_RDMA_H #include <linux/types.h> +#include <linux/bitops.h> #define RPCRDMA_VERSION 1 #define rpcrdma_version cpu_to_be32(RPCRDMA_VERSION) +enum { + RPCRDMA_V1_DEF_INLINE_SIZE = 1024, +}; + struct rpcrdma_segment { __be32 rs_handle; /* Registered memory handle */ __be32 rs_length; /* Length of the chunk in bytes */ @@ -129,4 +134,38 @@ enum rpcrdma_proc { #define rdma_done cpu_to_be32(RDMA_DONE) #define rdma_error cpu_to_be32(RDMA_ERROR) +/* + * Private extension to RPC-over-RDMA Version One. + * Message passed during RDMA-CM connection set-up. + * + * Add new fields at the end, and don't permute existing + * fields. + */ +struct rpcrdma_connect_private { + __be32 cp_magic; + u8 cp_version; + u8 cp_flags; + u8 cp_send_size; + u8 cp_recv_size; +} __packed; + +#define rpcrdma_cmp_magic __cpu_to_be32(0xf6ab0e18) + +enum { + RPCRDMA_CMP_VERSION = 1, + RPCRDMA_CMP_F_SND_W_INV_OK = BIT(0), +}; + +static inline u8 +rpcrdma_encode_buffer_size(unsigned int size) +{ + return (size >> 10) - 1; +} + +static inline unsigned int +rpcrdma_decode_buffer_size(u8 val) +{ + return ((unsigned int)val + 1) << 10; +} + #endif /* _LINUX_SUNRPC_RPC_RDMA_H */ diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 817af0b4385e..7ba040c797ec 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -239,8 +239,8 @@ struct rpc_task *rpc_wake_up_first(struct rpc_wait_queue *, void *); void rpc_wake_up_status(struct rpc_wait_queue *, int); void rpc_delay(struct rpc_task *, unsigned long); -void * rpc_malloc(struct rpc_task *, size_t); -void rpc_free(void *); +int rpc_malloc(struct rpc_task *); +void rpc_free(struct rpc_task *); int rpciod_up(void); void rpciod_down(void); int __rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *); diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index d6917b896d3a..cc3ae16eac68 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -86,6 +86,7 @@ struct svc_rdma_op_ctxt { unsigned long flags; enum dma_data_direction direction; int count; + unsigned int mapped_sges; struct ib_sge sge[RPCSVC_MAXPAGES]; struct page *pages[RPCSVC_MAXPAGES]; }; @@ -136,6 +137,7 @@ struct svcxprt_rdma { int sc_ord; /* RDMA read limit */ int sc_max_sge; int sc_max_sge_rd; /* max sge for read target */ + bool sc_snd_w_inv; /* OK to use Send With Invalidate */ atomic_t sc_sq_count; /* Number of SQ WR on queue */ unsigned int sc_sq_depth; /* Depth of SQ */ @@ -193,6 +195,14 @@ struct svcxprt_rdma { #define RPCSVC_MAXPAYLOAD_RDMA RPCSVC_MAXPAYLOAD +/* Track DMA maps for this transport and context */ +static inline void svc_rdma_count_mappings(struct svcxprt_rdma *rdma, + struct svc_rdma_op_ctxt *ctxt) +{ + ctxt->mapped_sges++; + atomic_inc(&rdma->sc_dma_used); +} + /* svc_rdma_backchannel.c */ extern int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, struct rpcrdma_msg *rmsgp, diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 70c6b92e15a7..56c48c884a24 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -67,6 +67,18 @@ struct xdr_buf { len; /* Length of XDR encoded message */ }; +static inline void +xdr_buf_init(struct xdr_buf *buf, void *start, size_t len) +{ + buf->head[0].iov_base = start; + buf->head[0].iov_len = len; + buf->tail[0].iov_len = 0; + buf->page_len = 0; + buf->flags = 0; + buf->len = 0; + buf->buflen = len; +} + /* * pre-xdr'ed macros. */ diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index a16070dd03ee..a5da60b24d83 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -83,9 +83,11 @@ struct rpc_rqst { void (*rq_release_snd_buf)(struct rpc_rqst *); /* release rq_enc_pages */ struct list_head rq_list; - __u32 * rq_buffer; /* XDR encode buffer */ - size_t rq_callsize, - rq_rcvsize; + void *rq_xprtdata; /* Per-xprt private data */ + void *rq_buffer; /* Call XDR encode buffer */ + size_t rq_callsize; + void *rq_rbuffer; /* Reply XDR decode buffer */ + size_t rq_rcvsize; size_t rq_xmit_bytes_sent; /* total bytes sent */ size_t rq_reply_bytes_recvd; /* total reply bytes */ /* received */ @@ -127,8 +129,8 @@ struct rpc_xprt_ops { void (*rpcbind)(struct rpc_task *task); void (*set_port)(struct rpc_xprt *xprt, unsigned short port); void (*connect)(struct rpc_xprt *xprt, struct rpc_task *task); - void * (*buf_alloc)(struct rpc_task *task, size_t size); - void (*buf_free)(void *buffer); + int (*buf_alloc)(struct rpc_task *task); + void (*buf_free)(struct rpc_task *task); int (*send_request)(struct rpc_task *task); void (*set_retrans_timeout)(struct rpc_task *task); void (*timer)(struct rpc_xprt *xprt, struct rpc_task *task); diff --git a/include/linux/sunrpc/xprtmultipath.h b/include/linux/sunrpc/xprtmultipath.h index 5a9acffa41be..507418c1c69e 100644 --- a/include/linux/sunrpc/xprtmultipath.h +++ b/include/linux/sunrpc/xprtmultipath.h @@ -66,4 +66,6 @@ extern struct rpc_xprt *xprt_iter_xprt(struct rpc_xprt_iter *xpi); extern struct rpc_xprt *xprt_iter_get_xprt(struct rpc_xprt_iter *xpi); extern struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi); +extern bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, + const struct sockaddr *sap); #endif diff --git a/include/linux/sunrpc/xprtrdma.h b/include/linux/sunrpc/xprtrdma.h index 39267dc3486a..221b7a2e5406 100644 --- a/include/linux/sunrpc/xprtrdma.h +++ b/include/linux/sunrpc/xprtrdma.h @@ -53,8 +53,8 @@ #define RPCRDMA_MAX_SLOT_TABLE (256U) #define RPCRDMA_MIN_INLINE (1024) /* min inline thresh */ -#define RPCRDMA_DEF_INLINE (1024) /* default inline thresh */ -#define RPCRDMA_MAX_INLINE (3068) /* max inline thresh */ +#define RPCRDMA_DEF_INLINE (4096) /* default inline thresh */ +#define RPCRDMA_MAX_INLINE (65536) /* max inline thresh */ /* Memory registration strategies, by number. * This is part of a kernel / user space API. Do not remove. */ diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h index c6ffe8b0725c..aa17ccfc2f57 100644 --- a/include/linux/sync_file.h +++ b/include/linux/sync_file.h @@ -19,12 +19,7 @@ #include <linux/list.h> #include <linux/spinlock.h> #include <linux/fence.h> - -struct sync_file_cb { - struct fence_cb cb; - struct fence *fence; - struct sync_file *sync_file; -}; +#include <linux/fence-array.h> /** * struct sync_file - sync file to export to the userspace @@ -32,10 +27,9 @@ struct sync_file_cb { * @kref: reference count on fence. * @name: name of sync_file. Useful for debugging * @sync_file_list: membership in global file list - * @num_fences: number of sync_pts in the fence * @wq: wait queue for fence signaling - * @status: 0: signaled, >0:active, <0: error - * @cbs: sync_pts callback information + * @fence: fence with the fences in the sync_file + * @cb: fence callback information */ struct sync_file { struct file *file; @@ -44,14 +38,16 @@ struct sync_file { #ifdef CONFIG_DEBUG_FS struct list_head sync_file_list; #endif - int num_fences; wait_queue_head_t wq; - atomic_t status; - struct sync_file_cb cbs[]; + struct fence *fence; + struct fence_cb cb; }; +#define POLL_ENABLED FENCE_FLAG_USER_BITS + struct sync_file *sync_file_create(struct fence *fence); +struct fence *sync_file_get_fence(int fd); #endif /* _LINUX_SYNC_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index d02239022bd0..91a740f6b884 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -898,4 +898,9 @@ asmlinkage long sys_copy_file_range(int fd_in, loff_t __user *off_in, asmlinkage long sys_mlock2(unsigned long start, size_t len, int flags); +asmlinkage long sys_pkey_mprotect(unsigned long start, size_t len, + unsigned long prot, int pkey); +asmlinkage long sys_pkey_alloc(unsigned long flags, unsigned long init_val); +asmlinkage long sys_pkey_free(int pkey); + #endif diff --git a/include/linux/thermal.h b/include/linux/thermal.h index ee517bef0db0..511182a88e76 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -92,12 +92,24 @@ enum thermal_trend { THERMAL_TREND_DROP_FULL, /* apply lowest cooling action */ }; +/* Thermal notification reason */ +enum thermal_notify_event { + THERMAL_EVENT_UNSPECIFIED, /* Unspecified event */ + THERMAL_EVENT_TEMP_SAMPLE, /* New Temperature sample */ + THERMAL_TRIP_VIOLATED, /* TRIP Point violation */ + THERMAL_TRIP_CHANGED, /* TRIP Point temperature changed */ + THERMAL_DEVICE_DOWN, /* Thermal device is down */ + THERMAL_DEVICE_UP, /* Thermal device is up after a down event */ + THERMAL_DEVICE_POWER_CAPABILITY_CHANGED, /* power capability changed */ +}; + struct thermal_zone_device_ops { int (*bind) (struct thermal_zone_device *, struct thermal_cooling_device *); int (*unbind) (struct thermal_zone_device *, struct thermal_cooling_device *); int (*get_temp) (struct thermal_zone_device *, int *); + int (*set_trips) (struct thermal_zone_device *, int, int); int (*get_mode) (struct thermal_zone_device *, enum thermal_device_mode *); int (*set_mode) (struct thermal_zone_device *, @@ -168,6 +180,10 @@ struct thermal_attr { * @last_temperature: previous temperature read * @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION * @passive: 1 if you've crossed a passive trip point, 0 otherwise. + * @prev_low_trip: the low current temperature if you've crossed a passive + trip point. + * @prev_high_trip: the above current temperature if you've crossed a + passive trip point. * @forced_passive: If > 0, temperature at which to switch on all ACPI * processor cooling devices. Currently only used by the * step-wise governor. @@ -182,6 +198,7 @@ struct thermal_attr { * @lock: lock to protect thermal_instances list * @node: node in thermal_tz_list (in thermal_core.c) * @poll_queue: delayed work for polling + * @notify_event: Last notification event */ struct thermal_zone_device { int id; @@ -199,6 +216,8 @@ struct thermal_zone_device { int last_temperature; int emul_temperature; int passive; + int prev_low_trip; + int prev_high_trip; unsigned int forced_passive; atomic_t need_update; struct thermal_zone_device_ops *ops; @@ -210,6 +229,7 @@ struct thermal_zone_device { struct mutex lock; struct list_head node; struct delayed_work poll_queue; + enum thermal_notify_event notify_event; }; /** @@ -333,6 +353,9 @@ struct thermal_genl_event { * * Optional: * @get_trend: a pointer to a function that reads the sensor temperature trend. + * @set_trips: a pointer to a function that sets a temperature window. When + * this window is left the driver must inform the thermal core via + * thermal_zone_device_update. * @set_emul_temp: a pointer to a function that sets sensor emulated * temperature. * @set_trip_temp: a pointer to a function that sets the trip temperature on @@ -340,7 +363,8 @@ struct thermal_genl_event { */ struct thermal_zone_of_device_ops { int (*get_temp)(void *, int *); - int (*get_trend)(void *, long *); + int (*get_trend)(void *, int, enum thermal_trend *); + int (*set_trips)(void *, int, int); int (*set_emul_temp)(void *, int); int (*set_trip_temp)(void *, int, int); }; @@ -425,7 +449,9 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, unsigned int); int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, struct thermal_cooling_device *); -void thermal_zone_device_update(struct thermal_zone_device *); +void thermal_zone_device_update(struct thermal_zone_device *, + enum thermal_notify_event); +void thermal_zone_set_trips(struct thermal_zone_device *); struct thermal_cooling_device *thermal_cooling_device_register(char *, void *, const struct thermal_cooling_device_ops *); @@ -435,6 +461,8 @@ thermal_of_cooling_device_register(struct device_node *np, char *, void *, void thermal_cooling_device_unregister(struct thermal_cooling_device *); struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name); int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); +int thermal_zone_get_slope(struct thermal_zone_device *tz); +int thermal_zone_get_offset(struct thermal_zone_device *tz); int get_tz_trend(struct thermal_zone_device *, int); struct thermal_instance *get_thermal_instance(struct thermal_zone_device *, @@ -473,7 +501,10 @@ static inline int thermal_zone_unbind_cooling_device( struct thermal_zone_device *tz, int trip, struct thermal_cooling_device *cdev) { return -ENODEV; } -static inline void thermal_zone_device_update(struct thermal_zone_device *tz) +static inline void thermal_zone_device_update(struct thermal_zone_device *tz, + enum thermal_notify_event event) +{ } +static inline void thermal_zone_set_trips(struct thermal_zone_device *tz) { } static inline struct thermal_cooling_device * thermal_cooling_device_register(char *type, void *devdata, @@ -492,6 +523,12 @@ static inline struct thermal_zone_device *thermal_zone_get_zone_by_name( static inline int thermal_zone_get_temp( struct thermal_zone_device *tz, int *temp) { return -ENODEV; } +static inline int thermal_zone_get_slope( + struct thermal_zone_device *tz) +{ return -ENODEV; } +static inline int thermal_zone_get_offset( + struct thermal_zone_device *tz) +{ return -ENODEV; } static inline int get_tz_trend(struct thermal_zone_device *tz, int trip) { return -ENODEV; } static inline struct thermal_instance * diff --git a/include/linux/uio.h b/include/linux/uio.h index b5ebe6dca404..6e22b544d039 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -82,7 +82,6 @@ size_t iov_iter_copy_from_user_atomic(struct page *page, struct iov_iter *i, unsigned long offset, size_t bytes); void iov_iter_advance(struct iov_iter *i, size_t bytes); int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); -#define iov_iter_fault_in_multipages_readable iov_iter_fault_in_readable size_t iov_iter_single_seg_count(const struct iov_iter *i); size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, struct iov_iter *i); @@ -110,12 +109,12 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages); const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags); -static inline size_t iov_iter_count(struct iov_iter *i) +static inline size_t iov_iter_count(const struct iov_iter *i) { return i->count; } -static inline bool iter_is_iovec(struct iov_iter *i) +static inline bool iter_is_iovec(const struct iov_iter *i) { return !(i->type & (ITER_BVEC | ITER_KVEC | ITER_PIPE)); } diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h index 8c3b412d84df..ee162e3e879b 100644 --- a/include/linux/vgaarb.h +++ b/include/linux/vgaarb.h @@ -73,34 +73,6 @@ static inline void vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes) { }; #endif -/** - * vga_get - acquire & locks VGA resources - * - * @pdev: pci device of the VGA card or NULL for the system default - * @rsrc: bit mask of resources to acquire and lock - * @interruptible: blocking should be interruptible by signals ? - * - * This function acquires VGA resources for the given - * card and mark those resources locked. If the resource requested - * are "normal" (and not legacy) resources, the arbiter will first check - * whether the card is doing legacy decoding for that type of resource. If - * yes, the lock is "converted" into a legacy resource lock. - * The arbiter will first look for all VGA cards that might conflict - * and disable their IOs and/or Memory access, including VGA forwarding - * on P2P bridges if necessary, so that the requested resources can - * be used. Then, the card is marked as locking these resources and - * the IO and/or Memory accesse are enabled on the card (including - * VGA forwarding on parent P2P bridges if any). - * This function will block if some conflicting card is already locking - * one of the required resources (or any resource on a different bus - * segment, since P2P bridges don't differenciate VGA memory and IO - * afaik). You can indicate whether this blocking should be interruptible - * by a signal (for userland interface) or not. - * Must not be called at interrupt time or in atomic context. - * If the card already owns the resources, the function succeeds. - * Nested calls are supported (a per-resource counter is maintained) - */ - #if defined(CONFIG_VGA_ARB) extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible); #else @@ -108,11 +80,14 @@ static inline int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interrupt #endif /** - * vga_get_interruptible + * vga_get_interruptible + * @pdev: pci device of the VGA card or NULL for the system default + * @rsrc: bit mask of resources to acquire and lock * - * Shortcut to vga_get + * Shortcut to vga_get with interruptible set to true. + * + * On success, release the VGA resource again with vga_put(). */ - static inline int vga_get_interruptible(struct pci_dev *pdev, unsigned int rsrc) { @@ -120,47 +95,26 @@ static inline int vga_get_interruptible(struct pci_dev *pdev, } /** - * vga_get_uninterruptible + * vga_get_uninterruptible - shortcut to vga_get() + * @pdev: pci device of the VGA card or NULL for the system default + * @rsrc: bit mask of resources to acquire and lock * - * Shortcut to vga_get + * Shortcut to vga_get with interruptible set to false. + * + * On success, release the VGA resource again with vga_put(). */ - static inline int vga_get_uninterruptible(struct pci_dev *pdev, unsigned int rsrc) { return vga_get(pdev, rsrc, 0); } -/** - * vga_tryget - try to acquire & lock legacy VGA resources - * - * @pdev: pci devivce of VGA card or NULL for system default - * @rsrc: bit mask of resources to acquire and lock - * - * This function performs the same operation as vga_get(), but - * will return an error (-EBUSY) instead of blocking if the resources - * are already locked by another card. It can be called in any context - */ - #if defined(CONFIG_VGA_ARB) extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); #else static inline int vga_tryget(struct pci_dev *pdev, unsigned int rsrc) { return 0; } #endif -/** - * vga_put - release lock on legacy VGA resources - * - * @pdev: pci device of VGA card or NULL for system default - * @rsrc: but mask of resource to release - * - * This function releases resources previously locked by vga_get() - * or vga_tryget(). The resources aren't disabled right away, so - * that a subsequence vga_get() on the same card will succeed - * immediately. Resources have a counter, so locks are only - * released if the counter reaches 0. - */ - #if defined(CONFIG_VGA_ARB) extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); #else @@ -168,25 +122,6 @@ extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); #endif -/** - * vga_default_device - * - * This can be defined by the platform. The default implementation - * is rather dumb and will probably only work properly on single - * vga card setups and/or x86 platforms. - * - * If your VGA default device is not PCI, you'll have to return - * NULL here. In this case, I assume it will not conflict with - * any PCI card. If this is not true, I'll have to define two archs - * hooks for enabling/disabling the VGA default device if that is - * possible. This may be a problem with real _ISA_ VGA cards, in - * addition to a PCI one. I don't know at this point how to deal - * with that card. Can theirs IOs be disabled at all ? If not, then - * I suppose it's a matter of having the proper arch hook telling - * us about it, so we basically never allow anybody to succeed a - * vga_get()... - */ - #ifdef CONFIG_VGA_ARB extern struct pci_dev *vga_default_device(void); extern void vga_set_default_device(struct pci_dev *pdev); @@ -195,14 +130,11 @@ static inline struct pci_dev *vga_default_device(void) { return NULL; }; static inline void vga_set_default_device(struct pci_dev *pdev) { }; #endif -/** - * vga_conflicts - * - * Architectures should define this if they have several - * independent PCI domains that can afford concurrent VGA - * decoding +/* + * Architectures should define this if they have several + * independent PCI domains that can afford concurrent VGA + * decoding */ - #ifndef __ARCH_HAS_VGA_CONFLICT static inline int vga_conflicts(struct pci_dev *p1, struct pci_dev *p2) { @@ -210,34 +142,6 @@ static inline int vga_conflicts(struct pci_dev *p1, struct pci_dev *p2) } #endif -/** - * vga_client_register - * - * @pdev: pci device of the VGA client - * @cookie: client cookie to be used in callbacks - * @irq_set_state: irq state change callback - * @set_vga_decode: vga decode change callback - * - * return value: 0 on success, -1 on failure - * Register a client with the VGA arbitration logic - * - * Clients have two callback mechanisms they can use. - * irq enable/disable callback - - * If a client can't disable its GPUs VGA resources, then we - * need to be able to ask it to turn off its irqs when we - * turn off its mem and io decoding. - * set_vga_decode - * If a client can disable its GPU VGA resource, it will - * get a callback from this to set the encode/decode state - * - * Rationale: we cannot disable VGA decode resources unconditionally - * some single GPU laptops seem to require ACPI or BIOS access to the - * VGA registers to control things like backlights etc. - * Hopefully newer multi-GPU laptops do something saner, and desktops - * won't have any special ACPI for this. - * They driver will get a callback when VGA arbitration is first used - * by userspace since we some older X servers have issues. - */ #if defined(CONFIG_VGA_ARB) int vga_client_register(struct pci_dev *pdev, void *cookie, void (*irq_set_state)(void *cookie, bool state), diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h index 7047bc7f8106..35a4d8185b51 100644 --- a/include/linux/watchdog.h +++ b/include/linux/watchdog.h @@ -19,6 +19,7 @@ struct watchdog_ops; struct watchdog_device; struct watchdog_core_data; +struct watchdog_governor; /** struct watchdog_ops - The watchdog-devices operations * @@ -28,6 +29,7 @@ struct watchdog_core_data; * @ping: The routine that sends a keepalive ping to the watchdog device. * @status: The routine that shows the status of the watchdog device. * @set_timeout:The routine for setting the watchdog devices timeout value (in seconds). + * @set_pretimeout:The routine for setting the watchdog devices pretimeout. * @get_timeleft:The routine that gets the time left before a reset (in seconds). * @restart: The routine for restarting the machine. * @ioctl: The routines that handles extra ioctl calls. @@ -46,6 +48,7 @@ struct watchdog_ops { int (*ping)(struct watchdog_device *); unsigned int (*status)(struct watchdog_device *); int (*set_timeout)(struct watchdog_device *, unsigned int); + int (*set_pretimeout)(struct watchdog_device *, unsigned int); unsigned int (*get_timeleft)(struct watchdog_device *); int (*restart)(struct watchdog_device *, unsigned long, void *); long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); @@ -59,8 +62,10 @@ struct watchdog_ops { * watchdog device. * @info: Pointer to a watchdog_info structure. * @ops: Pointer to the list of watchdog operations. + * @gov: Pointer to watchdog pretimeout governor. * @bootstatus: Status of the watchdog device at boot. * @timeout: The watchdog devices timeout value (in seconds). + * @pretimeout: The watchdog devices pre_timeout value. * @min_timeout:The watchdog devices minimum timeout value (in seconds). * @max_timeout:The watchdog devices maximum timeout value (in seconds) * as configurable from user space. Only relevant if @@ -94,8 +99,10 @@ struct watchdog_device { const struct attribute_group **groups; const struct watchdog_info *info; const struct watchdog_ops *ops; + const struct watchdog_governor *gov; unsigned int bootstatus; unsigned int timeout; + unsigned int pretimeout; unsigned int min_timeout; unsigned int max_timeout; unsigned int min_hw_heartbeat_ms; @@ -163,6 +170,13 @@ static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne t > wdd->max_timeout); } +/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid(struct watchdog_device *wdd, + unsigned int t) +{ + return t && wdd->timeout && t >= wdd->timeout; +} + /* Use the following functions to manipulate watchdog driver specific data */ static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data) { @@ -174,6 +188,16 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd) return wdd->driver_data; } +/* Use the following functions to report watchdog pretimeout event */ +#if IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_GOV) +void watchdog_notify_pretimeout(struct watchdog_device *wdd); +#else +static inline void watchdog_notify_pretimeout(struct watchdog_device *wdd) +{ + pr_alert("watchdog%d: pretimeout event\n", wdd->id); +} +#endif + /* drivers/watchdog/watchdog_core.c */ void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority); extern int watchdog_init_timeout(struct watchdog_device *wdd, diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 94079bab9243..e77605a0c8da 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -46,17 +46,16 @@ struct xattr { }; ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); +ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); +int __vfs_setxattr(struct dentry *, struct inode *, const char *, const void *, size_t, int); int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int); int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int); +int __vfs_removexattr(struct dentry *, const char *); int vfs_removexattr(struct dentry *, const char *); -ssize_t generic_getxattr(struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size); ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); -int generic_setxattr(struct dentry *dentry, struct inode *inode, - const char *name, const void *value, size_t size, int flags); -int generic_removexattr(struct dentry *dentry, const char *name); ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, size_t size, gfp_t flags); diff --git a/include/media/drv-intf/sh_mobile_ceu.h b/include/media/drv-intf/sh_mobile_ceu.h index 7f57056c22ba..2f43f7d9e28d 100644 --- a/include/media/drv-intf/sh_mobile_ceu.h +++ b/include/media/drv-intf/sh_mobile_ceu.h @@ -21,7 +21,6 @@ struct sh_mobile_ceu_info { unsigned long flags; int max_width; int max_height; - struct sh_mobile_ceu_companion *csi2; struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ unsigned int *asd_sizes; /* 0-terminated array pf asd group sizes */ }; diff --git a/include/media/drv-intf/sh_mobile_csi2.h b/include/media/drv-intf/sh_mobile_csi2.h deleted file mode 100644 index 14030db51f13..000000000000 --- a/include/media/drv-intf/sh_mobile_csi2.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Driver header for the SH-Mobile MIPI CSI-2 unit - * - * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef SH_MIPI_CSI -#define SH_MIPI_CSI - -#include <linux/list.h> - -enum sh_csi2_phy { - SH_CSI2_PHY_MAIN, - SH_CSI2_PHY_SUB, -}; - -enum sh_csi2_type { - SH_CSI2C, - SH_CSI2I, -}; - -#define SH_CSI2_CRC (1 << 0) -#define SH_CSI2_ECC (1 << 1) - -struct platform_device; - -struct sh_csi2_client_config { - enum sh_csi2_phy phy; - unsigned char lanes; /* bitmask[3:0] */ - unsigned char channel; /* 0..3 */ - struct platform_device *pdev; /* client platform device */ - const char *name; /* async matching: client name */ -}; - -struct v4l2_device; - -struct sh_csi2_pdata { - enum sh_csi2_type type; - unsigned int flags; - struct sh_csi2_client_config *clients; - int num_clients; -}; - -#endif diff --git a/include/media/i2c/smiapp.h b/include/media/i2c/smiapp.h index 029142ddb95c..635007e7441a 100644 --- a/include/media/i2c/smiapp.h +++ b/include/media/i2c/smiapp.h @@ -36,8 +36,6 @@ #define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE 1 #define SMIAPP_CSI_SIGNALLING_MODE_CSI2 2 -#define SMIAPP_NO_XSHUTDOWN -1 - /* * Sometimes due to board layout considerations the camera module can be * mounted rotated. The typical rotation used is 180 degrees which can be @@ -57,7 +55,7 @@ struct smiapp_flash_strobe_parms { u8 trigger; }; -struct smiapp_platform_data { +struct smiapp_hwconfig { /* * Change the cci address if i2c_addr_alt is set. * Both default and alternate cci addr need to be present @@ -75,9 +73,6 @@ struct smiapp_platform_data { enum smiapp_module_board_orient module_board_orient; struct smiapp_flash_strobe_parms *strobe_setup; - - int (*set_xclk)(struct v4l2_subdev *sd, int hz); - int32_t xshutdown; /* gpio or SMIAPP_NO_XSHUTDOWN */ }; #endif /* __SMIAPP_H_ */ diff --git a/include/media/media-device.h b/include/media/media-device.h index 28195242386c..ef93e21335df 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -49,11 +49,21 @@ struct media_entity_notify { }; /** + * struct media_device_ops - Media device operations + * @link_notify: Link state change notification callback. This callback is + * called with the graph_mutex held. + */ +struct media_device_ops { + int (*link_notify)(struct media_link *link, u32 flags, + unsigned int notification); +}; + +/** * struct media_device - Media device * @dev: Parent device * @devnode: Media device node * @driver_name: Optional device driver name. If not set, calls to - * %MEDIA_IOC_DEVICE_INFO will return dev->driver->name. + * %MEDIA_IOC_DEVICE_INFO will return ``dev->driver->name``. * This is needed for USB drivers for example, as otherwise * they'll all appear as if the driver name was "usb". * @model: Device model name @@ -80,8 +90,7 @@ struct media_entity_notify { * @enable_source: Enable Source Handler function pointer * @disable_source: Disable Source Handler function pointer * - * @link_notify: Link state change notification callback. This callback is - * called with the graph_mutex held. + * @ops: Operation handler callbacks * * This structure represents an abstract high-level media device. It allows easy * access to entities and provides basic media device-level support. The @@ -102,16 +111,18 @@ struct media_entity_notify { * sink entity and deactivate the link between them. Drivers * should call this handler to release the source. * - * Note: Bridge driver is expected to implement and set the - * handler when media_device is registered or when - * bridge driver finds the media_device during probe. - * Bridge driver sets source_priv with information - * necessary to run enable/disable source handlers. - * * Use-case: find tuner entity connected to the decoder * entity and check if it is available, and activate the - * the link between them from enable_source and deactivate - * from disable_source. + * the link between them from @enable_source and deactivate + * from @disable_source. + * + * .. note:: + * + * Bridge driver is expected to implement and set the + * handler when &media_device is registered or when + * bridge driver finds the media_device during probe. + * Bridge driver sets source_priv with information + * necessary to run @enable_source and @disable_source handlers. */ struct media_device { /* dev->driver_data points to this struct. */ @@ -148,8 +159,7 @@ struct media_device { struct media_pipeline *pipe); void (*disable_source)(struct media_entity *entity); - int (*link_notify)(struct media_link *link, u32 flags, - unsigned int notification); + const struct media_device_ops *ops; }; /* We don't need to include pci.h or usb.h here */ @@ -168,7 +178,7 @@ struct usb_device; * @ent_enum: Entity enumeration to be initialised * @mdev: The related media device * - * Returns zero on success or a negative error code. + * Return: zero on success or a negative error code. */ static inline __must_check int media_entity_enum_init( struct media_entity_enum *ent_enum, struct media_device *mdev) @@ -211,36 +221,38 @@ void media_device_cleanup(struct media_device *mdev); * * Users, should, instead, call the media_device_register() macro. * - * The caller is responsible for initializing the media_device structure before - * registration. The following fields must be set: + * The caller is responsible for initializing the &media_device structure + * before registration. The following fields of &media_device must be set: * - * - dev must point to the parent device (usually a &pci_dev, &usb_interface or - * &platform_device instance). + * - &media_entity.dev must point to the parent device (usually a &pci_dev, + * &usb_interface or &platform_device instance). * - * - model must be filled with the device model name as a NUL-terminated UTF-8 - * string. The device/model revision must not be stored in this field. + * - &media_entity.model must be filled with the device model name as a + * NUL-terminated UTF-8 string. The device/model revision must not be + * stored in this field. * * The following fields are optional: * - * - serial is a unique serial number stored as a NUL-terminated ASCII string. - * The field is big enough to store a GUID in text form. If the hardware - * doesn't provide a unique serial number this field must be left empty. + * - &media_entity.serial is a unique serial number stored as a + * NUL-terminated ASCII string. The field is big enough to store a GUID + * in text form. If the hardware doesn't provide a unique serial number + * this field must be left empty. * - * - bus_info represents the location of the device in the system as a - * NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to - * "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, - * the usb_make_path() function must be used. This field is used by - * applications to distinguish between otherwise identical devices that don't - * provide a serial number. + * - &media_entity.bus_info represents the location of the device in the + * system as a NUL-terminated ASCII string. For PCI/PCIe devices + * &media_entity.bus_info must be set to "PCI:" (or "PCIe:") followed by + * the value of pci_name(). For USB devices,the usb_make_path() function + * must be used. This field is used by applications to distinguish between + * otherwise identical devices that don't provide a serial number. * - * - hw_revision is the hardware device revision in a driver-specific format. - * When possible the revision should be formatted with the KERNEL_VERSION - * macro. + * - &media_entity.hw_revision is the hardware device revision in a + * driver-specific format. When possible the revision should be formatted + * with the KERNEL_VERSION() macro. * - * - driver_version is formatted with the KERNEL_VERSION macro. The version - * minor must be incremented when new features are added to the userspace API - * without breaking binary compatibility. The version major must be - * incremented when binary compatibility is broken. + * - &media_entity.driver_version is formatted with the KERNEL_VERSION() + * macro. The version minor must be incremented when new features are added + * to the userspace API without breaking binary compatibility. The version + * major must be incremented when binary compatibility is broken. * * .. note:: * @@ -252,6 +264,16 @@ void media_device_cleanup(struct media_device *mdev); */ int __must_check __media_device_register(struct media_device *mdev, struct module *owner); + + +/** + * media_device_register() - Registers a media device element + * + * @mdev: pointer to struct &media_device + * + * This macro calls __media_device_register() passing %THIS_MODULE as + * the __media_device_register() second argument (**owner**). + */ #define media_device_register(mdev) __media_device_register(mdev, THIS_MODULE) /** @@ -259,7 +281,6 @@ int __must_check __media_device_register(struct media_device *mdev, * * @mdev: pointer to struct &media_device * - * * It is safe to call this function on an unregistered (but initialised) * media device. */ @@ -285,14 +306,15 @@ void media_device_unregister(struct media_device *mdev); * framework. * * If the device has pads, media_entity_pads_init() should be called before - * this function. Otherwise, the &media_entity.@pad and &media_entity.@num_pads + * this function. Otherwise, the &media_entity.pad and &media_entity.num_pads * should be zeroed before calling this function. * * Entities have flags that describe the entity capabilities and state: * - * %MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. - * This can be used to report the default audio and video devices or the - * default camera sensor. + * %MEDIA_ENT_FL_DEFAULT + * indicates the default entity for a given type. + * This can be used to report the default audio and video devices or the + * default camera sensor. * * .. note:: * @@ -331,8 +353,10 @@ void media_device_unregister_entity(struct media_entity *entity); * @mdev: The media device * @nptr: The media_entity_notify * - * Note: When a new entity is registered, all the registered - * media_entity_notify callbacks are invoked. + * .. note:: + * + * When a new entity is registered, all the registered + * media_entity_notify callbacks are invoked. */ int __must_check media_device_register_entity_notify(struct media_device *mdev, @@ -410,11 +434,13 @@ void media_device_pci_init(struct media_device *mdev, * @board_name: media device name. If %NULL, the routine will use the usb * product name, if available. * @driver_name: name of the driver. if %NULL, the routine will use the name - * given by udev->dev->driver->name, with is usually the wrong + * given by ``udev->dev->driver->name``, with is usually the wrong * thing to do. * - * NOTE: It is better to call media_device_usb_init() instead, as - * such macro fills driver_name with %KBUILD_MODNAME. + * .. note:: + * + * It is better to call media_device_usb_init() instead, as + * such macro fills driver_name with %KBUILD_MODNAME. */ void __media_device_usb_init(struct media_device *mdev, struct usb_device *udev, @@ -472,6 +498,19 @@ static inline void __media_device_usb_init(struct media_device *mdev, #endif /* CONFIG_MEDIA_CONTROLLER */ +/** + * media_device_usb_init() - create and initialize a + * struct &media_device from a PCI device. + * + * @mdev: pointer to struct &media_device + * @udev: pointer to struct usb_device + * @name: media device name. If %NULL, the routine will use the usb + * product name, if available. + * + * This macro calls media_device_usb_init() passing the + * media_device_usb_init() **driver_name** parameter filled with + * %KBUILD_MODNAME. + */ #define media_device_usb_init(mdev, udev, name) \ __media_device_usb_init(mdev, udev, name, KBUILD_MODNAME) diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 37d494805944..cd23e915764c 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -75,8 +75,9 @@ struct media_file_operations { * @cdev: struct cdev pointer character device * @parent: parent device * @minor: device node minor number - * @flags: flags, combination of the MEDIA_FLAG_* constants - * @release: release callback called at the end of media_devnode_release() + * @flags: flags, combination of the ``MEDIA_FLAG_*`` constants + * @release: release callback called at the end of ``media_devnode_release()`` + * routine at media-device.c. * * This structure represents a media-related device node. * diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 09b03c17784d..b2203ee7a4c1 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -56,7 +56,7 @@ enum media_gobj_type { /** * struct media_gobj - Define a graph object. * - * @mdev: Pointer to the struct media_device that owns the object + * @mdev: Pointer to the struct &media_device that owns the object * @id: Non-zero object ID identifier. The ID should be unique * inside a media_device, as it is composed by * %MEDIA_BITS_PER_TYPE to store the type plus @@ -129,7 +129,7 @@ struct media_pipeline { * an interface. * @gobj1: Part of a union. Used to get the pointer for the second * graph_object of the link. - * @source: Part of a union. Used only if the second object (gobj1) is + * @sink: Part of a union. Used only if the second object (gobj1) is * a pad. In that case, it represents the sink pad. * @entity: Part of a union. Used only if the second object (gobj1) is * an entity. @@ -162,7 +162,9 @@ struct media_link { * @graph_obj: Embedded structure containing the media object common data * @entity: Entity this pad belongs to * @index: Pad index in the entity pads array, numbered from 0 to n - * @flags: Pad flags, as defined in uapi/media.h (MEDIA_PAD_FL_*) + * @flags: Pad flags, as defined in + * :ref:`include/uapi/linux/media.h <media_header>` + * (seek for ``MEDIA_PAD_FL_*``) */ struct media_pad { struct media_gobj graph_obj; /* must be first field in struct */ @@ -182,7 +184,7 @@ struct media_pad { * * .. note:: * - * Those these callbacks are called with struct media_device.@graph_mutex + * Those these callbacks are called with struct &media_device.graph_mutex * mutex held. */ struct media_entity_operations { @@ -210,7 +212,7 @@ struct media_entity_operations { * This allows runtime type identification of media entities and safe casting to * the correct object type. For instance, a media entity structure instance * embedded in a v4l2_subdev structure instance will have the type - * MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast to a v4l2_subdev + * %MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast to a &v4l2_subdev * structure using the container_of() macro. */ enum media_entity_type { @@ -225,9 +227,12 @@ enum media_entity_type { * @graph_obj: Embedded structure containing the media object common data. * @name: Entity name. * @obj_type: Type of the object that implements the media_entity. - * @function: Entity main function, as defined in uapi/media.h - * (MEDIA_ENT_F_*) - * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) + * @function: Entity main function, as defined in + * :ref:`include/uapi/linux/media.h <media_header>` + * (seek for ``MEDIA_ENT_F_*``) + * @flags: Entity flags, as defined in + * :ref:`include/uapi/linux/media.h <media_header>` + * (seek for ``MEDIA_ENT_FL_*``) * @num_pads: Number of sink and source pads. * @num_links: Total number of links, forward and back, enabled and disabled. * @num_backlinks: Number of backlinks @@ -246,9 +251,12 @@ enum media_entity_type { * @minor: Devnode minor number (zero if not applicable). Kept just * for backward compatibility. * - * NOTE: @stream_count and @use_count reference counts must never be - * negative, but are signed integers on purpose: a simple WARN_ON(<0) check - * can be used to detect reference count bugs that would make them negative. + * .. note:: + * + * @stream_count and @use_count reference counts must never be + * negative, but are signed integers on purpose: a simple ``WARN_ON(<0)`` + * check can be used to detect reference count bugs that would make them + * negative. */ struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ @@ -267,10 +275,6 @@ struct media_entity { const struct media_entity_operations *ops; - /* Reference counts must never be negative, but are signed integers on - * purpose: a simple WARN_ON(<0) check can be used to detect reference - * count bugs that would make them negative. - */ int stream_count; int use_count; @@ -289,10 +293,16 @@ struct media_entity { * * @graph_obj: embedded graph object * @links: List of links pointing to graph entities - * @type: Type of the interface as defined in the - * uapi/media/media.h header, e. g. - * MEDIA_INTF_T_* - * @flags: Interface flags as defined in uapi/media/media.h + * @type: Type of the interface as defined in + * :ref:`include/uapi/linux/media.h <media_header>` + * (seek for ``MEDIA_INTF_T_*``) + * @flags: Interface flags as defined in + * :ref:`include/uapi/linux/media.h <media_header>` + * (seek for ``MEDIA_INTF_FL_*``) + * + * .. note:: + * + * Currently, no flags for &media_interface is defined. */ struct media_interface { struct media_gobj graph_obj; @@ -319,7 +329,7 @@ struct media_intf_devnode { /** * media_entity_id() - return the media entity graph object id * - * @entity: pointer to entity + * @entity: pointer to &media_entity */ static inline u32 media_entity_id(struct media_entity *entity) { @@ -329,7 +339,7 @@ static inline u32 media_entity_id(struct media_entity *entity) /** * media_type() - return the media object type * - * @gobj: pointer to the media graph object + * @gobj: Pointer to the struct &media_gobj graph object */ static inline enum media_gobj_type media_type(struct media_gobj *gobj) { @@ -339,7 +349,7 @@ static inline enum media_gobj_type media_type(struct media_gobj *gobj) /** * media_id() - return the media object ID * - * @gobj: pointer to the media graph object + * @gobj: Pointer to the struct &media_gobj graph object */ static inline u32 media_id(struct media_gobj *gobj) { @@ -350,7 +360,7 @@ static inline u32 media_id(struct media_gobj *gobj) * media_gobj_gen_id() - encapsulates type and ID on at the object ID * * @type: object type as define at enum &media_gobj_type. - * @local_id: next ID, from struct &media_device.@id. + * @local_id: next ID, from struct &media_device.id. */ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) { @@ -366,9 +376,9 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) * is_media_entity_v4l2_video_device() - Check if the entity is a video_device * @entity: pointer to entity * - * Return: true if the entity is an instance of a video_device object and can + * Return: %true if the entity is an instance of a video_device object and can * safely be cast to a struct video_device using the container_of() macro, or - * false otherwise. + * %false otherwise. */ static inline bool is_media_entity_v4l2_video_device(struct media_entity *entity) { @@ -379,9 +389,9 @@ static inline bool is_media_entity_v4l2_video_device(struct media_entity *entity * is_media_entity_v4l2_subdev() - Check if the entity is a v4l2_subdev * @entity: pointer to entity * - * Return: true if the entity is an instance of a v4l2_subdev object and can - * safely be cast to a struct v4l2_subdev using the container_of() macro, or - * false otherwise. + * Return: %true if the entity is an instance of a &v4l2_subdev object and can + * safely be cast to a struct &v4l2_subdev using the container_of() macro, or + * %false otherwise. */ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) { @@ -452,7 +462,7 @@ static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum, * @ent_enum: Entity enumeration * @entity: Entity to be tested * - * Returns true if the entity was marked. + * Returns %true if the entity was marked. */ static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, struct media_entity *entity) @@ -464,12 +474,13 @@ static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, } /** - * media_entity_enum_test - Test whether the entity is marked, and mark it + * media_entity_enum_test_and_set - Test whether the entity is marked, + * and mark it * * @ent_enum: Entity enumeration * @entity: Entity to be tested * - * Returns true if the entity was marked, and mark it before doing so. + * Returns %true if the entity was marked, and mark it before doing so. */ static inline bool media_entity_enum_test_and_set(struct media_entity_enum *ent_enum, @@ -486,7 +497,7 @@ media_entity_enum_test_and_set(struct media_entity_enum *ent_enum, * * @ent_enum: Entity enumeration * - * Returns true if the entity was marked. + * Return: %true if the entity was empty. */ static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) { @@ -499,7 +510,8 @@ static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) * @ent_enum1: First entity enumeration * @ent_enum2: Second entity enumeration * - * Returns true if entity enumerations e and f intersect, otherwise false. + * Return: %true if entity enumerations @ent_enum1 and @ent_enum2 intersect, + * otherwise %false. */ static inline bool media_entity_enum_intersects( struct media_entity_enum *ent_enum1, @@ -511,39 +523,63 @@ static inline bool media_entity_enum_intersects( min(ent_enum1->idx_max, ent_enum2->idx_max)); } +/** + * gobj_to_entity - returns the struct &media_entity pointer from the + * @gobj contained on it. + * + * @gobj: Pointer to the struct &media_gobj graph object + */ #define gobj_to_entity(gobj) \ container_of(gobj, struct media_entity, graph_obj) +/** + * gobj_to_pad - returns the struct &media_pad pointer from the + * @gobj contained on it. + * + * @gobj: Pointer to the struct &media_gobj graph object + */ #define gobj_to_pad(gobj) \ container_of(gobj, struct media_pad, graph_obj) +/** + * gobj_to_link - returns the struct &media_link pointer from the + * @gobj contained on it. + * + * @gobj: Pointer to the struct &media_gobj graph object + */ #define gobj_to_link(gobj) \ container_of(gobj, struct media_link, graph_obj) -#define gobj_to_link(gobj) \ - container_of(gobj, struct media_link, graph_obj) - -#define gobj_to_pad(gobj) \ - container_of(gobj, struct media_pad, graph_obj) - +/** + * gobj_to_intf - returns the struct &media_interface pointer from the + * @gobj contained on it. + * + * @gobj: Pointer to the struct &media_gobj graph object + */ #define gobj_to_intf(gobj) \ container_of(gobj, struct media_interface, graph_obj) +/** + * intf_to_devnode - returns the struct media_intf_devnode pointer from the + * @intf contained on it. + * + * @intf: Pointer to struct &media_intf_devnode + */ #define intf_to_devnode(intf) \ container_of(intf, struct media_intf_devnode, intf) /** * media_gobj_create - Initialize a graph object * - * @mdev: Pointer to the media_device that contains the object + * @mdev: Pointer to the &media_device that contains the object * @type: Type of the object - * @gobj: Pointer to the graph object + * @gobj: Pointer to the struct &media_gobj graph object * - * This routine initializes the embedded struct media_gobj inside a - * media graph object. It is called automatically if media_*_create\(\) - * calls are used. However, if the object (entity, link, pad, interface) - * is embedded on some other object, this function should be called before - * registering the object at the media controller. + * This routine initializes the embedded struct &media_gobj inside a + * media graph object. It is called automatically if ``media_*_create`` + * function calls are used. However, if the object (entity, link, pad, + * interface) is embedded on some other object, this function should be + * called before registering the object at the media controller. */ void media_gobj_create(struct media_device *mdev, enum media_gobj_type type, @@ -552,7 +588,7 @@ void media_gobj_create(struct media_device *mdev, /** * media_gobj_destroy - Stop using a graph object on a media device * - * @gobj: Pointer to the graph object + * @gobj: Pointer to the struct &media_gobj graph object * * This should be called by all routines like media_device_unregister() * that remove/destroy media graph objects. @@ -567,11 +603,11 @@ void media_gobj_destroy(struct media_gobj *gobj); * @pads: Array of @num_pads pads. * * The pads array is managed by the entity driver and passed to - * media_entity_pads_init() where its pointer will be stored in the entity - * structure. + * media_entity_pads_init() where its pointer will be stored in the + * &media_entity structure. * * If no pads are needed, drivers could either directly fill - * &media_entity->@num_pads with 0 and &media_entity->@pads with NULL or call + * &media_entity->num_pads with 0 and &media_entity->pads with %NULL or call * this function that will do the same. * * As the number of pads is known in advance, the pads array is not allocated @@ -601,18 +637,21 @@ static inline void media_entity_cleanup(struct media_entity *entity) {}; * @source_pad: number of the source pad in the pads array * @sink: pointer to &media_entity of the sink pad. * @sink_pad: number of the sink pad in the pads array. - * @flags: Link flags, as defined in include/uapi/linux/media.h. + * @flags: Link flags, as defined in + * :ref:`include/uapi/linux/media.h <media_header>` + * ( seek for ``MEDIA_LNK_FL_*``) * * Valid values for flags: * - * - A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can - * be used to transfer media data. When two or more links target a sink pad, - * only one of them can be enabled at a time. + * %MEDIA_LNK_FL_ENABLED + * Indicates that the link is enabled and can be used to transfer media data. + * When two or more links target a sink pad, only one of them can be + * enabled at a time. * - * - A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't - * be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then - * %MEDIA_LNK_FL_ENABLED must also be set since an immutable link is - * always enabled. + * %MEDIA_LNK_FL_IMMUTABLE + * Indicates that the link enabled state can't be modified at runtime. If + * %MEDIA_LNK_FL_IMMUTABLE is set, then %MEDIA_LNK_FL_ENABLED must also be + * set, since an immutable link is always enabled. * * .. note:: * @@ -630,17 +669,17 @@ __must_check int media_create_pad_link(struct media_entity *source, * @source_function: Function of the source entities. Used only if @source is * NULL. * @source: pointer to &media_entity of the source pad. If NULL, it will use - * all entities that matches the @sink_function. + * all entities that matches the @sink_function. * @source_pad: number of the source pad in the pads array * @sink_function: Function of the sink entities. Used only if @sink is NULL. * @sink: pointer to &media_entity of the sink pad. If NULL, it will use - * all entities that matches the @sink_function. + * all entities that matches the @sink_function. * @sink_pad: number of the sink pad in the pads array. * @flags: Link flags, as defined in include/uapi/linux/media.h. - * @allow_both_undefined: if true, then both @source and @sink can be NULL. + * @allow_both_undefined: if %true, then both @source and @sink can be NULL. * In such case, it will create a crossbar between all entities that * matches @source_function to all entities that matches @sink_function. - * If false, it will return 0 and won't create any link if both @source + * If %false, it will return 0 and won't create any link if both @source * and @sink are NULL. * * Valid values for flags: @@ -660,9 +699,11 @@ __must_check int media_create_pad_link(struct media_entity *source, * creates link by link, this function is meant to allow 1:n, n:1 and even * cross-bar (n:n) links. * - * NOTE: Before calling this function, media_entity_pads_init() and - * media_device_register_entity() should be called previously for the entities - * to be linked. + * .. note:: + * + * Before calling this function, media_entity_pads_init() and + * media_device_register_entity() should be called previously for the + * entities to be linked. */ int media_create_pad_links(const struct media_device *mdev, const u32 source_function, @@ -721,7 +762,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags); * flags. * * Media device drivers can be notified of link setup operations by setting the - * media_device::link_notify pointer to a callback function. If provided, the + * &media_device.link_notify pointer to a callback function. If provided, the * notification callback will be called before enabling and after disabling * links. * @@ -731,7 +772,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags); * * Link configuration must not have any side effect on other links. If an * enabled link at a sink pad prevents another link at the same pad from - * being enabled, the link_setup operation must return -EBUSY and can't + * being enabled, the link_setup operation must return %-EBUSY and can't * implicitly disable the first enabled link. * * .. note:: @@ -747,8 +788,8 @@ int media_entity_setup_link(struct media_link *link, u32 flags); * @source: Source pad * @sink: Sink pad * - * Return a pointer to the link between the two entities. If no such link - * exists, return NULL. + * Return: returns a pointer to the link between the two entities. If no + * such link exists, return %NULL. */ struct media_link *media_entity_find_link(struct media_pad *source, struct media_pad *sink); @@ -760,8 +801,8 @@ struct media_link *media_entity_find_link(struct media_pad *source, * Search for a remote pad connected to the given pad by iterating over all * links originating or terminating at that pad until an enabled link is found. * - * Return a pointer to the pad at the remote end of the first found enabled - * link, or NULL if no enabled link has been found. + * Return: returns a pointer to the pad at the remote end of the first found + * enabled link, or %NULL if no enabled link has been found. */ struct media_pad *media_entity_remote_pad(struct media_pad *pad); @@ -772,12 +813,18 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad); * * Get a reference to the parent media device module. * - * The function will return immediately if @entity is NULL. + * The function will return immediately if @entity is %NULL. * - * Return a pointer to the entity on success or NULL on failure. + * Return: returns a pointer to the entity on success or %NULL on failure. */ struct media_entity *media_entity_get(struct media_entity *entity); +/** + * media_entity_graph_walk_init - Allocate resources used by graph walk. + * + * @graph: Media graph structure that will be used to walk the graph + * @mdev: Pointer to the &media_device that contains the object + */ __must_check int media_entity_graph_walk_init( struct media_entity_graph *graph, struct media_device *mdev); @@ -795,12 +842,14 @@ void media_entity_graph_walk_cleanup(struct media_entity_graph *graph); * * Release the reference count acquired by media_entity_get(). * - * The function will return immediately if @entity is NULL. + * The function will return immediately if @entity is %NULL. */ void media_entity_put(struct media_entity *entity); /** - * media_entity_graph_walk_start - Start walking the media graph at a given entity + * media_entity_graph_walk_start - Start walking the media graph at a + * given entity + * * @graph: Media graph structure that will be used to walk the graph * @entity: Starting entity * @@ -824,8 +873,8 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, * The graph structure must have been previously initialized with a call to * media_entity_graph_walk_start(). * - * Return the next entity in the graph or NULL if the whole graph have been - * traversed. + * Return: returns the next entity in the graph or %NULL if the whole graph + * have been traversed. */ struct media_entity * media_entity_graph_walk_next(struct media_entity_graph *graph); @@ -836,8 +885,8 @@ media_entity_graph_walk_next(struct media_entity_graph *graph); * @pipe: Media pipeline to be assigned to all entities in the pipeline. * * Mark all entities connected to a given entity through enabled links, either - * directly or indirectly, as streaming. The given pipeline object is assigned to - * every entity in the pipeline and stored in the media_entity pipe field. + * directly or indirectly, as streaming. The given pipeline object is assigned + * to every entity in the pipeline and stored in the media_entity pipe field. * * Calls to this function can be nested, in which case the same number of * media_entity_pipeline_stop() calls will be required to stop streaming. The @@ -863,7 +912,7 @@ __must_check int __media_entity_pipeline_start(struct media_entity *entity, * * Mark all entities connected to a given entity through enabled links, either * directly or indirectly, as not streaming. The media_entity pipe field is - * reset to NULL. + * reset to %NULL. * * If multiple calls to media_entity_pipeline_start() have been made, the same * number of calls to this function are required to mark the pipeline as not @@ -884,14 +933,21 @@ void __media_entity_pipeline_stop(struct media_entity *entity); * media_devnode_create() - creates and initializes a device node interface * * @mdev: pointer to struct &media_device - * @type: type of the interface, as given by MEDIA_INTF_T_* macros - * as defined in the uapi/media/media.h header. - * @flags: Interface flags as defined in uapi/media/media.h. + * @type: type of the interface, as given by + * :ref:`include/uapi/linux/media.h <media_header>` + * ( seek for ``MEDIA_INTF_T_*``) macros. + * @flags: Interface flags, as defined in + * :ref:`include/uapi/linux/media.h <media_header>` + * ( seek for ``MEDIA_INTF_FL_*``) * @major: Device node major number. * @minor: Device node minor number. * * Return: if succeeded, returns a pointer to the newly allocated * &media_intf_devnode pointer. + * + * .. note:: + * + * Currently, no flags for &media_interface is defined. */ struct media_intf_devnode * __must_check media_devnode_create(struct media_device *mdev, @@ -913,15 +969,19 @@ struct media_link * * * @entity: pointer to %media_entity * @intf: pointer to %media_interface - * @flags: Link flags, as defined in include/uapi/linux/media.h. + * @flags: Link flags, as defined in + * :ref:`include/uapi/linux/media.h <media_header>` + * ( seek for ``MEDIA_LNK_FL_*``) * * * Valid values for flags: * - * - The %MEDIA_LNK_FL_ENABLED flag indicates that the interface is connected to - * the entity hardware. That's the default value for interfaces. An - * interface may be disabled if the hardware is busy due to the usage - * of some other interface that it is currently controlling the hardware. + * %MEDIA_LNK_FL_ENABLED + * Indicates that the interface is connected to the entity hardware. + * That's the default value for interfaces. An interface may be disabled if + * the hardware is busy due to the usage of some other interface that it is + * currently controlling the hardware. + * * A typical example is an hybrid TV device that handle only one type of * stream on a given time. So, when the digital TV is streaming, * the V4L2 interfaces won't be enabled, as such device is not able to @@ -977,6 +1037,18 @@ void __media_remove_intf_links(struct media_interface *intf); */ void media_remove_intf_links(struct media_interface *intf); +/** + * media_entity_call - Calls a struct media_entity_operations operation on + * an entity + * + * @entity: entity where the @operation will be called + * @operation: type of the operation. Should be the name of a member of + * struct &media_entity_operations. + * + * This helper function will check if @operation is not %NULL. On such case, + * it will issue a call to @operation\(@entity, @args\). + */ + #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 10908e356b23..40188d362486 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -231,7 +231,7 @@ void rc_unregister_device(struct rc_dev *dev); int rc_open(struct rc_dev *rdev); /** - * rc_open - Closes a RC device + * rc_close - Closes a RC device * * @rdev: pointer to struct rc_dev. */ diff --git a/include/media/rc-map.h b/include/media/rc-map.h index daa75fcc1ff1..e1cc14cba391 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -11,27 +11,55 @@ #include <linux/input.h> +/** + * enum rc_type - type of the Remote Controller protocol + * + * @RC_TYPE_UNKNOWN: Protocol not known + * @RC_TYPE_OTHER: Protocol known but proprietary + * @RC_TYPE_RC5: Philips RC5 protocol + * @RC_TYPE_RC5X: Philips RC5x protocol + * @RC_TYPE_RC5_SZ: StreamZap variant of RC5 + * @RC_TYPE_JVC: JVC protocol + * @RC_TYPE_SONY12: Sony 12 bit protocol + * @RC_TYPE_SONY15: Sony 15 bit protocol + * @RC_TYPE_SONY20: Sony 20 bit protocol + * @RC_TYPE_NEC: NEC protocol + * @RC_TYPE_NECX: Extended NEC protocol + * @RC_TYPE_NEC32: NEC 32 bit protocol + * @RC_TYPE_SANYO: Sanyo protocol + * @RC_TYPE_MCE_KBD: RC6-ish MCE keyboard/mouse + * @RC_TYPE_RC6_0: Philips RC6-0-16 protocol + * @RC_TYPE_RC6_6A_20: Philips RC6-6A-20 protocol + * @RC_TYPE_RC6_6A_24: Philips RC6-6A-24 protocol + * @RC_TYPE_RC6_6A_32: Philips RC6-6A-32 protocol + * @RC_TYPE_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol + * @RC_TYPE_SHARP: Sharp protocol + * @RC_TYPE_XMP: XMP protocol + * @RC_TYPE_CEC: CEC protocol + */ enum rc_type { - RC_TYPE_UNKNOWN = 0, /* Protocol not known */ - RC_TYPE_OTHER = 1, /* Protocol known but proprietary */ - RC_TYPE_RC5 = 2, /* Philips RC5 protocol */ - RC_TYPE_RC5X = 3, /* Philips RC5x protocol */ - RC_TYPE_RC5_SZ = 4, /* StreamZap variant of RC5 */ - RC_TYPE_JVC = 5, /* JVC protocol */ - RC_TYPE_SONY12 = 6, /* Sony 12 bit protocol */ - RC_TYPE_SONY15 = 7, /* Sony 15 bit protocol */ - RC_TYPE_SONY20 = 8, /* Sony 20 bit protocol */ - RC_TYPE_NEC = 9, /* NEC protocol */ - RC_TYPE_SANYO = 10, /* Sanyo protocol */ - RC_TYPE_MCE_KBD = 11, /* RC6-ish MCE keyboard/mouse */ - RC_TYPE_RC6_0 = 12, /* Philips RC6-0-16 protocol */ - RC_TYPE_RC6_6A_20 = 13, /* Philips RC6-6A-20 protocol */ - RC_TYPE_RC6_6A_24 = 14, /* Philips RC6-6A-24 protocol */ - RC_TYPE_RC6_6A_32 = 15, /* Philips RC6-6A-32 protocol */ - RC_TYPE_RC6_MCE = 16, /* MCE (Philips RC6-6A-32 subtype) protocol */ - RC_TYPE_SHARP = 17, /* Sharp protocol */ - RC_TYPE_XMP = 18, /* XMP protocol */ - RC_TYPE_CEC = 19, /* CEC protocol */ + RC_TYPE_UNKNOWN = 0, + RC_TYPE_OTHER = 1, + RC_TYPE_RC5 = 2, + RC_TYPE_RC5X = 3, + RC_TYPE_RC5_SZ = 4, + RC_TYPE_JVC = 5, + RC_TYPE_SONY12 = 6, + RC_TYPE_SONY15 = 7, + RC_TYPE_SONY20 = 8, + RC_TYPE_NEC = 9, + RC_TYPE_NECX = 10, + RC_TYPE_NEC32 = 11, + RC_TYPE_SANYO = 12, + RC_TYPE_MCE_KBD = 13, + RC_TYPE_RC6_0 = 14, + RC_TYPE_RC6_6A_20 = 15, + RC_TYPE_RC6_6A_24 = 16, + RC_TYPE_RC6_6A_32 = 17, + RC_TYPE_RC6_MCE = 18, + RC_TYPE_SHARP = 19, + RC_TYPE_XMP = 20, + RC_TYPE_CEC = 21, }; #define RC_BIT_NONE 0ULL @@ -45,6 +73,8 @@ enum rc_type { #define RC_BIT_SONY15 (1ULL << RC_TYPE_SONY15) #define RC_BIT_SONY20 (1ULL << RC_TYPE_SONY20) #define RC_BIT_NEC (1ULL << RC_TYPE_NEC) +#define RC_BIT_NECX (1ULL << RC_TYPE_NECX) +#define RC_BIT_NEC32 (1ULL << RC_TYPE_NEC32) #define RC_BIT_SANYO (1ULL << RC_TYPE_SANYO) #define RC_BIT_MCE_KBD (1ULL << RC_TYPE_MCE_KBD) #define RC_BIT_RC6_0 (1ULL << RC_TYPE_RC6_0) @@ -60,8 +90,9 @@ enum rc_type { RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ | \ RC_BIT_JVC | \ RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \ - RC_BIT_NEC | RC_BIT_SANYO | RC_BIT_MCE_KBD | \ - RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ + RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \ + RC_BIT_SANYO | RC_BIT_MCE_KBD | RC_BIT_RC6_0 | \ + RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \ RC_BIT_XMP | RC_BIT_CEC) @@ -76,21 +107,45 @@ enum rc_type { #define RC_SCANCODE_RC6_0(sys, cmd) (((sys) << 8) | (cmd)) #define RC_SCANCODE_RC6_6A(vendor, sys, cmd) (((vendor) << 16) | ((sys) << 8) | (cmd)) +/** + * struct rc_map_table - represents a scancode/keycode pair + * + * @scancode: scan code (u32) + * @keycode: Linux input keycode + */ struct rc_map_table { u32 scancode; u32 keycode; }; +/** + * struct rc_map - represents a keycode map table + * + * @scan: pointer to struct &rc_map_table + * @size: Max number of entries + * @len: Number of entries that are in use + * @alloc: size of \*scan, in bytes + * @rc_type: type of the remote controller protocol, as defined at + * enum &rc_type + * @name: name of the key map table + * @lock: lock to protect access to this structure + */ struct rc_map { struct rc_map_table *scan; - unsigned int size; /* Max number of entries */ - unsigned int len; /* Used number of entries */ - unsigned int alloc; /* Size of *scan in bytes */ + unsigned int size; + unsigned int len; + unsigned int alloc; enum rc_type rc_type; const char *name; spinlock_t lock; }; +/** + * struct rc_map_list - list of the registered &rc_map maps + * + * @list: pointer to struct &list_head + * @map: pointer to struct &rc_map + */ struct rc_map_list { struct list_head list; struct rc_map map; diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h index 4c7fc77eaf29..8723f05c6321 100644 --- a/include/media/rcar-fcp.h +++ b/include/media/rcar-fcp.h @@ -29,7 +29,7 @@ static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np) static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { } static inline int rcar_fcp_enable(struct rcar_fcp_device *fcp) { - return -ENOSYS; + return 0; } static inline void rcar_fcp_disable(struct rcar_fcp_device *fcp) { } #endif diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 97aa13314bfd..1a15c3e4efd3 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -105,16 +105,13 @@ struct soc_camera_host_ops { int (*get_formats)(struct soc_camera_device *, unsigned int, struct soc_camera_format_xlate *); void (*put_formats)(struct soc_camera_device *); - int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *); - int (*get_crop)(struct soc_camera_device *, struct v4l2_crop *); - int (*set_crop)(struct soc_camera_device *, const struct v4l2_crop *); int (*get_selection)(struct soc_camera_device *, struct v4l2_selection *); int (*set_selection)(struct soc_camera_device *, struct v4l2_selection *); /* - * The difference to .set_crop() is, that .set_livecrop is not allowed + * The difference to .set_selection() is, that .set_liveselection is not allowed * to change the output sizes */ - int (*set_livecrop)(struct soc_camera_device *, const struct v4l2_crop *); + int (*set_liveselection)(struct soc_camera_device *, struct v4l2_selection *); int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *); int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); void (*init_videobuf)(struct videobuf_queue *, diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 178a88d45aea..e1006b391cdc 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -93,6 +93,16 @@ struct v4l2_ctrl_type_ops { union v4l2_ctrl_ptr ptr); }; +/** + * typedef v4l2_ctrl_notify_fnc - typedef for a notify argument with a function + * that should be called when a control value has changed. + * + * @ctrl: pointer to struct &v4l2_ctrl + * @priv: control private data + * + * This typedef definition is used as an argument to v4l2_ctrl_notify() + * and as an argument at struct &v4l2_ctrl_handler. + */ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv); /** @@ -229,7 +239,7 @@ struct v4l2_ctrl { * @next: Single-link list node for the hash. * @ctrl: The actual control information. * @helper: Pointer to helper struct. Used internally in - * prepare_ext_ctrls(). + * ``prepare_ext_ctrls`` function at ``v4l2-ctrl.c``. * * Each control handler has a list of these refs. The list_head is used to * keep a sorted-by-control-ID list of all controls, while the next pointer @@ -369,17 +379,39 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, * @key: Used by the lock validator if CONFIG_LOCKDEP is set. * @name: Used by the lock validator if CONFIG_LOCKDEP is set. * - * Returns an error if the buckets could not be allocated. This error will - * also be stored in @hdl->error. + * .. attention:: + * + * Never use this call directly, always use the v4l2_ctrl_handler_init() + * macro that hides the @key and @name arguments. * - * Never use this call directly, always use the v4l2_ctrl_handler_init - * macro that hides the @key and @name arguments. + * Return: returns an error if the buckets could not be allocated. This + * error will also be stored in @hdl->error. */ int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, unsigned int nr_of_controls_hint, struct lock_class_key *key, const char *name); #ifdef CONFIG_LOCKDEP + +/** + * v4l2_ctrl_handler_init - helper function to create a static struct + * &lock_class_key and calls v4l2_ctrl_handler_init_class() + * + * @hdl: The control handler. + * @nr_of_controls_hint: A hint of how many controls this handler is + * expected to refer to. This is the total number, so including + * any inherited controls. It doesn't have to be precise, but if + * it is way off, then you either waste memory (too many buckets + * are allocated) or the control lookup becomes slower (not enough + * buckets are allocated, so there are more slow list lookups). + * It will always work, though. + * + * This helper function creates a static struct &lock_class_key and + * calls v4l2_ctrl_handler_init_class(), providing a proper name for the lock + * validador. + * + * Use this helper function to initialize a control handler. + */ #define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint) \ ( \ ({ \ @@ -564,6 +596,13 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, u32 id, u8 max, u8 def, const s64 *qmenu_int); +/** + * typedef v4l2_ctrl_filter - Typedef to define the filter function to be + * used when adding a control handler. + * + * @ctrl: pointer to struct &v4l2_ctrl. + */ + typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl); /** @@ -635,8 +674,8 @@ void v4l2_ctrl_cluster(unsigned int ncontrols, struct v4l2_ctrl **controls); * be marked active, and any reads will just return the current value without * going through g_volatile_ctrl. * - * In addition, this function will set the V4L2_CTRL_FLAG_UPDATE flag - * on the autofoo control and V4L2_CTRL_FLAG_INACTIVE on the foo control(s) + * In addition, this function will set the %V4L2_CTRL_FLAG_UPDATE flag + * on the autofoo control and %V4L2_CTRL_FLAG_INACTIVE on the foo control(s) * if autofoo is in auto mode. */ void v4l2_ctrl_auto_cluster(unsigned int ncontrols, @@ -686,7 +725,6 @@ void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active); */ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed); - /** *__v4l2_ctrl_modify_range() - Unlocked variant of v4l2_ctrl_modify_range() * @@ -936,9 +974,9 @@ extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops; * v4l2_ctrl_replace - Function to be used as a callback to * &struct v4l2_subscribed_event_ops replace\(\) * - * @old: pointer to :ref:`struct v4l2_event <v4l2-event>` with the reported + * @old: pointer to struct &v4l2_event with the reported * event; - * @new: pointer to :ref:`struct v4l2_event <v4l2-event>` with the modified + * @new: pointer to struct &v4l2_event with the modified * event; */ void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new); @@ -947,9 +985,9 @@ void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new); * v4l2_ctrl_merge - Function to be used as a callback to * &struct v4l2_subscribed_event_ops merge(\) * - * @old: pointer to :ref:`struct v4l2_event <v4l2-event>` with the reported + * @old: pointer to struct &v4l2_event with the reported * event; - * @new: pointer to :ref:`struct v4l2_event <v4l2-event>` with the merged + * @new: pointer to struct &v4l2_event with the merged * event; */ void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new); diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index a122b1bd40f9..e657614521e3 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -25,7 +25,8 @@ #define VFL_TYPE_RADIO 2 #define VFL_TYPE_SUBDEV 3 #define VFL_TYPE_SDR 4 -#define VFL_TYPE_MAX 5 +#define VFL_TYPE_TOUCH 5 +#define VFL_TYPE_MAX 6 /* Is this a receiver, transmitter or mem-to-mem? */ /* Ignored for VFL_TYPE_SUBDEV. */ @@ -55,7 +56,7 @@ struct v4l2_ctrl_handler; * * .. note:: * The size of @prios array matches the number of priority types defined - * by :ref:`enum v4l2_priority <v4l2-priority>`. + * by enum &v4l2_priority. */ struct v4l2_prio_state { atomic_t prios[4]; @@ -72,8 +73,8 @@ void v4l2_prio_init(struct v4l2_prio_state *global); * v4l2_prio_change - changes the v4l2 file handler priority * * @global: pointer to the &struct v4l2_prio_state of the device node. - * @local: pointer to the desired priority, as defined by :ref:`enum v4l2_priority <v4l2-priority>` - * @new: Priority type requested, as defined by :ref:`enum v4l2_priority <v4l2-priority>`. + * @local: pointer to the desired priority, as defined by enum &v4l2_priority + * @new: Priority type requested, as defined by enum &v4l2_priority. * * .. note:: * This function should be used only by the V4L2 core. @@ -85,7 +86,7 @@ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, * v4l2_prio_open - Implements the priority logic for a file handler open * * @global: pointer to the &struct v4l2_prio_state of the device node. - * @local: pointer to the desired priority, as defined by :ref:`enum v4l2_priority <v4l2-priority>` + * @local: pointer to the desired priority, as defined by enum &v4l2_priority * * .. note:: * This function should be used only by the V4L2 core. @@ -96,7 +97,7 @@ void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local); * v4l2_prio_close - Implements the priority logic for a file handler close * * @global: pointer to the &struct v4l2_prio_state of the device node. - * @local: priority to be released, as defined by :ref:`enum v4l2_priority <v4l2-priority>` + * @local: priority to be released, as defined by enum &v4l2_priority * * .. note:: * This function should be used only by the V4L2 core. @@ -114,10 +115,10 @@ void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local); enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global); /** - * v4l2_prio_close - Implements the priority logic for a file handler close + * v4l2_prio_check - Implements the priority logic for a file handler close * * @global: pointer to the &struct v4l2_prio_state of the device node. - * @local: desired priority, as defined by :ref:`enum v4l2_priority <v4l2-priority>` local + * @local: desired priority, as defined by enum &v4l2_priority local * * .. note:: * This function should be used only by the V4L2 core. @@ -294,6 +295,7 @@ struct video_device * - %VFL_TYPE_RADIO - A radio card * - %VFL_TYPE_SUBDEV - A subdevice * - %VFL_TYPE_SDR - Software Defined Radio + * - %VFL_TYPE_TOUCH - A touch sensor * * .. note:: * diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index a9d6aa41790e..8ffa94009d1a 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h @@ -39,7 +39,7 @@ struct v4l2_ctrl_handler; * if this struct is embedded into a larger struct. * @name: unique device name, by default the driver name + bus ID * @notify: notify callback called by some sub-devices. - * @ctrl_handler: The control handler. May be NULL. + * @ctrl_handler: The control handler. May be %NULL. * @prio: Device's priority state * @ref: Keep track of the references to this struct. * @release: Release function that is called when the ref count @@ -53,8 +53,8 @@ struct v4l2_ctrl_handler; * * .. note:: * - * #) dev->driver_data points to this struct. - * #) dev might be NULL if there is no parent device + * #) @dev->driver_data points to this struct. + * #) @dev might be %NULL if there is no parent device */ struct v4l2_device { @@ -76,10 +76,10 @@ struct v4l2_device { /** * v4l2_device_get - gets a V4L2 device reference * - * @v4l2_dev: pointer to struct v4l2_device + * @v4l2_dev: pointer to struct &v4l2_device * * This is an ancillary routine meant to increment the usage for the - * struct v4l2_device pointed by @v4l2_dev. + * struct &v4l2_device pointed by @v4l2_dev. */ static inline void v4l2_device_get(struct v4l2_device *v4l2_dev) { @@ -89,23 +89,23 @@ static inline void v4l2_device_get(struct v4l2_device *v4l2_dev) /** * v4l2_device_put - putss a V4L2 device reference * - * @v4l2_dev: pointer to struct v4l2_device + * @v4l2_dev: pointer to struct &v4l2_device * * This is an ancillary routine meant to decrement the usage for the - * struct v4l2_device pointed by @v4l2_dev. + * struct &v4l2_device pointed by @v4l2_dev. */ int v4l2_device_put(struct v4l2_device *v4l2_dev); /** - * v4l2_device_register -Initialize v4l2_dev and make dev->driver_data - * point to v4l2_dev. + * v4l2_device_register - Initialize v4l2_dev and make @dev->driver_data + * point to @v4l2_dev. * - * @dev: pointer to struct device - * @v4l2_dev: pointer to struct v4l2_device + * @dev: pointer to struct &device + * @v4l2_dev: pointer to struct &v4l2_device * * .. note:: - * dev may be NULL in rare cases (ISA devices). - * In such case the caller must fill in the v4l2_dev->name field + * @dev may be %NULL in rare cases (ISA devices). + * In such case the caller must fill in the @v4l2_dev->name field * before calling this function. */ int __must_check v4l2_device_register(struct device *dev, @@ -113,14 +113,14 @@ int __must_check v4l2_device_register(struct device *dev, /** * v4l2_device_set_name - Optional function to initialize the - * name field of struct v4l2_device + * name field of struct &v4l2_device * - * @v4l2_dev: pointer to struct v4l2_device + * @v4l2_dev: pointer to struct &v4l2_device * @basename: base name for the device name * @instance: pointer to a static atomic_t var with the instance usage for - * the device driver. + * the device driver. * - * v4l2_device_set_name() initializes the name field of struct v4l2_device + * v4l2_device_set_name() initializes the name field of struct &v4l2_device * using the driver name and a driver-global atomic_t instance. * * This function will increment the instance counter and returns the @@ -132,7 +132,7 @@ int __must_check v4l2_device_register(struct device *dev, * * ... * - * instance = v4l2_device_set_name(&v4l2_dev, "foo", &drv_instance); + * instance = v4l2_device_set_name(&\ v4l2_dev, "foo", &\ drv_instance); * * The first time this is called the name field will be set to foo0 and * this function returns 0. If the name ends with a digit (e.g. cx18), @@ -147,16 +147,16 @@ int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, * @v4l2_dev: pointer to struct v4l2_device * * Should be called when the USB parent disconnects. - * Since the parent disappears, this ensures that v4l2_dev doesn't have + * Since the parent disappears, this ensures that @v4l2_dev doesn't have * an invalid parent pointer. * - * .. note:: This function sets v4l2_dev->dev to NULL. + * .. note:: This function sets @v4l2_dev->dev to NULL. */ void v4l2_device_disconnect(struct v4l2_device *v4l2_dev); /** * v4l2_device_unregister - Unregister all sub-devices and any other - * resources related to v4l2_dev. + * resources related to @v4l2_dev. * * @v4l2_dev: pointer to struct v4l2_device */ @@ -165,8 +165,8 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev); /** * v4l2_device_register_subdev - Registers a subdev with a v4l2 device. * - * @v4l2_dev: pointer to struct v4l2_device - * @sd: pointer to struct v4l2_subdev + * @v4l2_dev: pointer to struct &v4l2_device + * @sd: pointer to struct &v4l2_subdev * * While registered, the subdev module is marked as in-use. * @@ -179,7 +179,7 @@ int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, /** * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device. * - * @sd: pointer to struct v4l2_subdev + * @sd: pointer to struct &v4l2_subdev * * .. note :: * @@ -191,7 +191,7 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); /** * v4l2_device_register_subdev_nodes - Registers device nodes for all subdevs * of the v4l2 device that are marked with - * the V4L2_SUBDEV_FL_HAS_DEVNODE flag. + * the %V4L2_SUBDEV_FL_HAS_DEVNODE flag. * * @v4l2_dev: pointer to struct v4l2_device */ @@ -201,9 +201,9 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev); /** * v4l2_subdev_notify - Sends a notification to v4l2_device. * - * @sd: pointer to struct v4l2_subdev + * @sd: pointer to struct &v4l2_subdev * @notification: type of notification. Please notice that the notification - * type is driver-specific. + * type is driver-specific. * @arg: arguments for the notification. Those are specific to each * notification type. */ @@ -222,7 +222,7 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, Ignore any errors. Note that you cannot add or delete a subdev while walking the subdevs list. */ #define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...) \ - do { \ + do { \ list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) \ if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ (sd)->ops->o->f((sd) , ##args); \ @@ -241,15 +241,15 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, return with that error code. Note that you cannot add or delete a subdev while walking the subdevs list. */ #define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \ -({ \ +({ \ long __err = 0; \ \ list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) { \ if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ __err = (sd)->ops->o->f((sd) , ##args); \ if (__err && __err != -ENOIOCTLCMD) \ - break; \ - } \ + break; \ + } \ (__err == -ENOIOCTLCMD) ? 0 : __err; \ }) @@ -276,7 +276,7 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, match them all). If the callback returns an error other than 0 or -ENOIOCTLCMD, then return with that error code. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ +#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ ({ \ struct v4l2_subdev *__sd; \ __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \ @@ -300,8 +300,8 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, /* * Call the specified callback for all subdevs where grp_id & grpmsk != 0 - * (if grpmsk == `0, then match them all). If the callback returns an error - * other than 0 or -ENOIOCTLCMD, then return with that error code. Note that + * (if grpmsk == 0, then match them all). If the callback returns an error + * other than 0 or %-ENOIOCTLCMD, then return with that error code. Note that * you cannot add or delete a subdev while walking the subdevs list. */ #define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \ diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h index 65caadf13eec..0a7d9e1fc8c8 100644 --- a/include/media/v4l2-dv-timings.h +++ b/include/media/v4l2-dv-timings.h @@ -28,8 +28,8 @@ */ extern const struct v4l2_dv_timings v4l2_dv_timings_presets[]; -/* - * v4l2_check_dv_timings_fnc - timings check callback +/** + * typedef v4l2_check_dv_timings_fnc - timings check callback * * @t: the v4l2_dv_timings struct. * @handle: a handle from the driver. diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h index ca854203b8b9..a700285c64a9 100644 --- a/include/media/v4l2-event.h +++ b/include/media/v4l2-event.h @@ -222,7 +222,8 @@ int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub); /** - * v4l2_src_change_event_subscribe - + * v4l2_src_change_event_subscribe - helper function that calls + * v4l2_event_subscribe() if the event is %V4L2_EVENT_SOURCE_CHANGE. * * @fh: pointer to struct v4l2_fh * @sub: pointer to &struct v4l2_event_subscription diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h index 3d184ab52274..b0fe4d6f4a5f 100644 --- a/include/media/v4l2-flash-led-class.h +++ b/include/media/v4l2-flash-led-class.h @@ -20,7 +20,7 @@ struct led_classdev; struct v4l2_flash; enum led_brightness; -/* +/** * struct v4l2_flash_ctrl_data - flash control initialization data, filled * basing on the features declared by the LED flash * class driver in the v4l2_flash_config @@ -33,14 +33,21 @@ struct v4l2_flash_ctrl_data { u32 cid; }; +/** + * struct v4l2_flash_ops - V4L2 flash operations + * + * @external_strobe_set: Setup strobing the flash by hardware pin state + * assertion. + * @intensity_to_led_brightness: Convert intensity to brightness in a device + * specific manner + * @led_brightness_to_intensity: convert brightness to intensity in a device + * specific manner. + */ struct v4l2_flash_ops { - /* setup strobing the flash by hardware pin state assertion */ int (*external_strobe_set)(struct v4l2_flash *v4l2_flash, bool enable); - /* convert intensity to brightness in a device specific manner */ enum led_brightness (*intensity_to_led_brightness) (struct v4l2_flash *v4l2_flash, s32 intensity); - /* convert brightness to intensity in a device specific manner */ s32 (*led_brightness_to_intensity) (struct v4l2_flash *v4l2_flash, enum led_brightness); }; diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 8b1d19bc9b0e..574ff2ae94be 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -287,273 +287,286 @@ struct v4l2_ioctl_ops { /* ioctl callbacks */ /* VIDIOC_QUERYCAP handler */ - int (*vidioc_querycap)(struct file *file, void *fh, struct v4l2_capability *cap); + int (*vidioc_querycap)(struct file *file, void *fh, + struct v4l2_capability *cap); /* VIDIOC_ENUM_FMT handlers */ - int (*vidioc_enum_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_vid_overlay) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_cap)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_overlay)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_out)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); int (*vidioc_enum_fmt_vid_cap_mplane)(struct file *file, void *fh, struct v4l2_fmtdesc *f); int (*vidioc_enum_fmt_vid_out_mplane)(struct file *file, void *fh, struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_sdr_cap) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_sdr_out) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_sdr_cap)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_sdr_out)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); /* VIDIOC_G_FMT handlers */ - int (*vidioc_g_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_g_fmt_vid_cap)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_g_fmt_vid_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_g_fmt_vid_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_g_fmt_vid_out_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_vbi_out) (struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); + int (*vidioc_g_fmt_vbi_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vbi_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_g_fmt_sliced_vbi_cap)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_g_fmt_vid_cap_mplane)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_g_fmt_vid_out_mplane)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_sdr_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_sdr_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_g_fmt_sdr_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_sdr_out)(struct file *file, void *fh, + struct v4l2_format *f); /* VIDIOC_S_FMT handlers */ - int (*vidioc_s_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_s_fmt_vid_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_s_fmt_vid_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_s_fmt_vid_out_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_vbi_out) (struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); + int (*vidioc_s_fmt_vbi_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vbi_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_s_fmt_sliced_vbi_cap)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_s_fmt_vid_cap_mplane)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_s_fmt_vid_out_mplane)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_sdr_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_sdr_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_s_fmt_sdr_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_sdr_out)(struct file *file, void *fh, + struct v4l2_format *f); /* VIDIOC_TRY_FMT handlers */ - int (*vidioc_try_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_try_fmt_vid_cap)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_try_fmt_vid_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_try_fmt_vid_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_try_fmt_vid_out_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_vbi_out) (struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); + int (*vidioc_try_fmt_vbi_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vbi_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_try_fmt_sliced_vbi_cap)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_try_fmt_vid_cap_mplane)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_try_fmt_vid_out_mplane)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_sdr_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_sdr_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_try_fmt_sdr_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_sdr_out)(struct file *file, void *fh, + struct v4l2_format *f); /* Buffer handlers */ - int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b); - int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer *b); - int (*vidioc_qbuf) (struct file *file, void *fh, struct v4l2_buffer *b); - int (*vidioc_expbuf) (struct file *file, void *fh, - struct v4l2_exportbuffer *e); - int (*vidioc_dqbuf) (struct file *file, void *fh, struct v4l2_buffer *b); - - int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b); - int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b); - - int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i); - int (*vidioc_g_fbuf) (struct file *file, void *fh, - struct v4l2_framebuffer *a); - int (*vidioc_s_fbuf) (struct file *file, void *fh, - const struct v4l2_framebuffer *a); + int (*vidioc_reqbufs)(struct file *file, void *fh, + struct v4l2_requestbuffers *b); + int (*vidioc_querybuf)(struct file *file, void *fh, + struct v4l2_buffer *b); + int (*vidioc_qbuf)(struct file *file, void *fh, + struct v4l2_buffer *b); + int (*vidioc_expbuf)(struct file *file, void *fh, + struct v4l2_exportbuffer *e); + int (*vidioc_dqbuf)(struct file *file, void *fh, + struct v4l2_buffer *b); + + int (*vidioc_create_bufs)(struct file *file, void *fh, + struct v4l2_create_buffers *b); + int (*vidioc_prepare_buf)(struct file *file, void *fh, + struct v4l2_buffer *b); + + int (*vidioc_overlay)(struct file *file, void *fh, unsigned int i); + int (*vidioc_g_fbuf)(struct file *file, void *fh, + struct v4l2_framebuffer *a); + int (*vidioc_s_fbuf)(struct file *file, void *fh, + const struct v4l2_framebuffer *a); /* Stream on/off */ - int (*vidioc_streamon) (struct file *file, void *fh, enum v4l2_buf_type i); - int (*vidioc_streamoff)(struct file *file, void *fh, enum v4l2_buf_type i); - - /* Standard handling - ENUMSTD is handled by videodev.c + int (*vidioc_streamon)(struct file *file, void *fh, + enum v4l2_buf_type i); + int (*vidioc_streamoff)(struct file *file, void *fh, + enum v4l2_buf_type i); + + /* + * Standard handling + * + * Note: ENUMSTD is handled by videodev.c */ - int (*vidioc_g_std) (struct file *file, void *fh, v4l2_std_id *norm); - int (*vidioc_s_std) (struct file *file, void *fh, v4l2_std_id norm); - int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a); + int (*vidioc_g_std)(struct file *file, void *fh, v4l2_std_id *norm); + int (*vidioc_s_std)(struct file *file, void *fh, v4l2_std_id norm); + int (*vidioc_querystd)(struct file *file, void *fh, v4l2_std_id *a); /* Input handling */ int (*vidioc_enum_input)(struct file *file, void *fh, struct v4l2_input *inp); - int (*vidioc_g_input) (struct file *file, void *fh, unsigned int *i); - int (*vidioc_s_input) (struct file *file, void *fh, unsigned int i); + int (*vidioc_g_input)(struct file *file, void *fh, unsigned int *i); + int (*vidioc_s_input)(struct file *file, void *fh, unsigned int i); /* Output handling */ - int (*vidioc_enum_output) (struct file *file, void *fh, + int (*vidioc_enum_output)(struct file *file, void *fh, struct v4l2_output *a); - int (*vidioc_g_output) (struct file *file, void *fh, unsigned int *i); - int (*vidioc_s_output) (struct file *file, void *fh, unsigned int i); + int (*vidioc_g_output)(struct file *file, void *fh, unsigned int *i); + int (*vidioc_s_output)(struct file *file, void *fh, unsigned int i); /* Control handling */ - int (*vidioc_queryctrl) (struct file *file, void *fh, - struct v4l2_queryctrl *a); - int (*vidioc_query_ext_ctrl) (struct file *file, void *fh, - struct v4l2_query_ext_ctrl *a); - int (*vidioc_g_ctrl) (struct file *file, void *fh, - struct v4l2_control *a); - int (*vidioc_s_ctrl) (struct file *file, void *fh, - struct v4l2_control *a); - int (*vidioc_g_ext_ctrls) (struct file *file, void *fh, - struct v4l2_ext_controls *a); - int (*vidioc_s_ext_ctrls) (struct file *file, void *fh, - struct v4l2_ext_controls *a); - int (*vidioc_try_ext_ctrls) (struct file *file, void *fh, - struct v4l2_ext_controls *a); - int (*vidioc_querymenu) (struct file *file, void *fh, - struct v4l2_querymenu *a); + int (*vidioc_queryctrl)(struct file *file, void *fh, + struct v4l2_queryctrl *a); + int (*vidioc_query_ext_ctrl)(struct file *file, void *fh, + struct v4l2_query_ext_ctrl *a); + int (*vidioc_g_ctrl)(struct file *file, void *fh, + struct v4l2_control *a); + int (*vidioc_s_ctrl)(struct file *file, void *fh, + struct v4l2_control *a); + int (*vidioc_g_ext_ctrls)(struct file *file, void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_s_ext_ctrls)(struct file *file, void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_try_ext_ctrls)(struct file *file, void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_querymenu)(struct file *file, void *fh, + struct v4l2_querymenu *a); /* Audio ioctls */ - int (*vidioc_enumaudio) (struct file *file, void *fh, - struct v4l2_audio *a); - int (*vidioc_g_audio) (struct file *file, void *fh, - struct v4l2_audio *a); - int (*vidioc_s_audio) (struct file *file, void *fh, - const struct v4l2_audio *a); + int (*vidioc_enumaudio)(struct file *file, void *fh, + struct v4l2_audio *a); + int (*vidioc_g_audio)(struct file *file, void *fh, + struct v4l2_audio *a); + int (*vidioc_s_audio)(struct file *file, void *fh, + const struct v4l2_audio *a); /* Audio out ioctls */ - int (*vidioc_enumaudout) (struct file *file, void *fh, - struct v4l2_audioout *a); - int (*vidioc_g_audout) (struct file *file, void *fh, - struct v4l2_audioout *a); - int (*vidioc_s_audout) (struct file *file, void *fh, - const struct v4l2_audioout *a); - int (*vidioc_g_modulator) (struct file *file, void *fh, - struct v4l2_modulator *a); - int (*vidioc_s_modulator) (struct file *file, void *fh, - const struct v4l2_modulator *a); + int (*vidioc_enumaudout)(struct file *file, void *fh, + struct v4l2_audioout *a); + int (*vidioc_g_audout)(struct file *file, void *fh, + struct v4l2_audioout *a); + int (*vidioc_s_audout)(struct file *file, void *fh, + const struct v4l2_audioout *a); + int (*vidioc_g_modulator)(struct file *file, void *fh, + struct v4l2_modulator *a); + int (*vidioc_s_modulator)(struct file *file, void *fh, + const struct v4l2_modulator *a); /* Crop ioctls */ - int (*vidioc_cropcap) (struct file *file, void *fh, - struct v4l2_cropcap *a); - int (*vidioc_g_crop) (struct file *file, void *fh, - struct v4l2_crop *a); - int (*vidioc_s_crop) (struct file *file, void *fh, - const struct v4l2_crop *a); - int (*vidioc_g_selection) (struct file *file, void *fh, - struct v4l2_selection *s); - int (*vidioc_s_selection) (struct file *file, void *fh, - struct v4l2_selection *s); + int (*vidioc_cropcap)(struct file *file, void *fh, + struct v4l2_cropcap *a); + int (*vidioc_g_crop)(struct file *file, void *fh, + struct v4l2_crop *a); + int (*vidioc_s_crop)(struct file *file, void *fh, + const struct v4l2_crop *a); + int (*vidioc_g_selection)(struct file *file, void *fh, + struct v4l2_selection *s); + int (*vidioc_s_selection)(struct file *file, void *fh, + struct v4l2_selection *s); /* Compression ioctls */ - int (*vidioc_g_jpegcomp) (struct file *file, void *fh, - struct v4l2_jpegcompression *a); - int (*vidioc_s_jpegcomp) (struct file *file, void *fh, - const struct v4l2_jpegcompression *a); - int (*vidioc_g_enc_index) (struct file *file, void *fh, - struct v4l2_enc_idx *a); - int (*vidioc_encoder_cmd) (struct file *file, void *fh, - struct v4l2_encoder_cmd *a); - int (*vidioc_try_encoder_cmd) (struct file *file, void *fh, - struct v4l2_encoder_cmd *a); - int (*vidioc_decoder_cmd) (struct file *file, void *fh, - struct v4l2_decoder_cmd *a); - int (*vidioc_try_decoder_cmd) (struct file *file, void *fh, - struct v4l2_decoder_cmd *a); + int (*vidioc_g_jpegcomp)(struct file *file, void *fh, + struct v4l2_jpegcompression *a); + int (*vidioc_s_jpegcomp)(struct file *file, void *fh, + const struct v4l2_jpegcompression *a); + int (*vidioc_g_enc_index)(struct file *file, void *fh, + struct v4l2_enc_idx *a); + int (*vidioc_encoder_cmd)(struct file *file, void *fh, + struct v4l2_encoder_cmd *a); + int (*vidioc_try_encoder_cmd)(struct file *file, void *fh, + struct v4l2_encoder_cmd *a); + int (*vidioc_decoder_cmd)(struct file *file, void *fh, + struct v4l2_decoder_cmd *a); + int (*vidioc_try_decoder_cmd)(struct file *file, void *fh, + struct v4l2_decoder_cmd *a); /* Stream type-dependent parameter ioctls */ - int (*vidioc_g_parm) (struct file *file, void *fh, - struct v4l2_streamparm *a); - int (*vidioc_s_parm) (struct file *file, void *fh, - struct v4l2_streamparm *a); + int (*vidioc_g_parm)(struct file *file, void *fh, + struct v4l2_streamparm *a); + int (*vidioc_s_parm)(struct file *file, void *fh, + struct v4l2_streamparm *a); /* Tuner ioctls */ - int (*vidioc_g_tuner) (struct file *file, void *fh, - struct v4l2_tuner *a); - int (*vidioc_s_tuner) (struct file *file, void *fh, - const struct v4l2_tuner *a); - int (*vidioc_g_frequency) (struct file *file, void *fh, - struct v4l2_frequency *a); - int (*vidioc_s_frequency) (struct file *file, void *fh, - const struct v4l2_frequency *a); - int (*vidioc_enum_freq_bands) (struct file *file, void *fh, - struct v4l2_frequency_band *band); + int (*vidioc_g_tuner)(struct file *file, void *fh, + struct v4l2_tuner *a); + int (*vidioc_s_tuner)(struct file *file, void *fh, + const struct v4l2_tuner *a); + int (*vidioc_g_frequency)(struct file *file, void *fh, + struct v4l2_frequency *a); + int (*vidioc_s_frequency)(struct file *file, void *fh, + const struct v4l2_frequency *a); + int (*vidioc_enum_freq_bands)(struct file *file, void *fh, + struct v4l2_frequency_band *band); /* Sliced VBI cap */ - int (*vidioc_g_sliced_vbi_cap) (struct file *file, void *fh, - struct v4l2_sliced_vbi_cap *a); + int (*vidioc_g_sliced_vbi_cap)(struct file *file, void *fh, + struct v4l2_sliced_vbi_cap *a); /* Log status ioctl */ - int (*vidioc_log_status) (struct file *file, void *fh); + int (*vidioc_log_status)(struct file *file, void *fh); - int (*vidioc_s_hw_freq_seek) (struct file *file, void *fh, - const struct v4l2_hw_freq_seek *a); + int (*vidioc_s_hw_freq_seek)(struct file *file, void *fh, + const struct v4l2_hw_freq_seek *a); /* Debugging ioctls */ #ifdef CONFIG_VIDEO_ADV_DEBUG - int (*vidioc_g_register) (struct file *file, void *fh, - struct v4l2_dbg_register *reg); - int (*vidioc_s_register) (struct file *file, void *fh, - const struct v4l2_dbg_register *reg); + int (*vidioc_g_register)(struct file *file, void *fh, + struct v4l2_dbg_register *reg); + int (*vidioc_s_register)(struct file *file, void *fh, + const struct v4l2_dbg_register *reg); - int (*vidioc_g_chip_info) (struct file *file, void *fh, - struct v4l2_dbg_chip_info *chip); + int (*vidioc_g_chip_info)(struct file *file, void *fh, + struct v4l2_dbg_chip_info *chip); #endif - int (*vidioc_enum_framesizes) (struct file *file, void *fh, - struct v4l2_frmsizeenum *fsize); + int (*vidioc_enum_framesizes)(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize); - int (*vidioc_enum_frameintervals) (struct file *file, void *fh, - struct v4l2_frmivalenum *fival); + int (*vidioc_enum_frameintervals)(struct file *file, void *fh, + struct v4l2_frmivalenum *fival); /* DV Timings IOCTLs */ - int (*vidioc_s_dv_timings) (struct file *file, void *fh, - struct v4l2_dv_timings *timings); - int (*vidioc_g_dv_timings) (struct file *file, void *fh, - struct v4l2_dv_timings *timings); - int (*vidioc_query_dv_timings) (struct file *file, void *fh, - struct v4l2_dv_timings *timings); - int (*vidioc_enum_dv_timings) (struct file *file, void *fh, - struct v4l2_enum_dv_timings *timings); - int (*vidioc_dv_timings_cap) (struct file *file, void *fh, - struct v4l2_dv_timings_cap *cap); - int (*vidioc_g_edid) (struct file *file, void *fh, struct v4l2_edid *edid); - int (*vidioc_s_edid) (struct file *file, void *fh, struct v4l2_edid *edid); - - int (*vidioc_subscribe_event) (struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub); + int (*vidioc_s_dv_timings)(struct file *file, void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_g_dv_timings)(struct file *file, void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_query_dv_timings)(struct file *file, void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_enum_dv_timings)(struct file *file, void *fh, + struct v4l2_enum_dv_timings *timings); + int (*vidioc_dv_timings_cap)(struct file *file, void *fh, + struct v4l2_dv_timings_cap *cap); + int (*vidioc_g_edid)(struct file *file, void *fh, + struct v4l2_edid *edid); + int (*vidioc_s_edid)(struct file *file, void *fh, + struct v4l2_edid *edid); + + int (*vidioc_subscribe_event)(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub); int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub); /* For other private ioctls */ - long (*vidioc_default) (struct file *file, void *fh, - bool valid_prio, unsigned int cmd, void *arg); + long (*vidioc_default)(struct file *file, void *fh, + bool valid_prio, unsigned int cmd, void *arg); }; @@ -573,38 +586,123 @@ struct v4l2_ioctl_ops { #define V4L2_DEV_DEBUG_POLL 0x10 /* Video standard functions */ -extern const char *v4l2_norm_to_name(v4l2_std_id id); -extern void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod); -extern int v4l2_video_std_construct(struct v4l2_standard *vs, + +/** + * v4l2_norm_to_name - Ancillary routine to analog TV standard name from its ID. + * + * @id: analog TV standard ID. + * + * Return: returns a string with the name of the analog TV standard. + * If the standard is not found or if @id points to multiple standard, + * it returns "Unknown". + */ +const char *v4l2_norm_to_name(v4l2_std_id id); + +/** + * v4l2_video_std_frame_period - Ancillary routine that fills a + * struct &v4l2_fract pointer with the default framerate fraction. + * + * @id: analog TV sdandard ID. + * @frameperiod: struct &v4l2_fract pointer to be filled + * + */ +void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod); + +/** + * v4l2_video_std_construct - Ancillary routine that fills in the fields of + * a &v4l2_standard structure according to the @id parameter. + * + * @vs: struct &v4l2_standard pointer to be filled + * @id: analog TV sdandard ID. + * @name: name of the standard to be used + * + * .. note:: + * + * This ancillary routine is obsolete. Shouldn't be used on newer drivers. + */ +int v4l2_video_std_construct(struct v4l2_standard *vs, int id, const char *name); -/* Prints the ioctl in a human-readable format. If prefix != NULL, - then do printk(KERN_DEBUG "%s: ", prefix) first. */ -extern void v4l_printk_ioctl(const char *prefix, unsigned int cmd); -/* Internal use only: get the mutex (if any) that we need to lock for the - given command. */ +/** + * v4l_printk_ioctl - Ancillary routine that prints the ioctl in a + * human-readable format. + * + * @prefix: prefix to be added at the ioctl prints. + * @cmd: ioctl name + * + * .. note:: + * + * If prefix != %NULL, then it will issue a + * ``printk(KERN_DEBUG "%s: ", prefix)`` first. + */ +void v4l_printk_ioctl(const char *prefix, unsigned int cmd); + struct video_device; -extern struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd); + + +/** + * v4l2_ioctl_get_lock - get the mutex (if any) that it is need to lock for + * a given command. + * + * @vdev: Pointer to struct &video_device. + * @cmd: Ioctl name. + * + * .. note:: Internal use only. Should not be used outside V4L2 core. + */ +struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned int cmd); /* names for fancy debug output */ extern const char *v4l2_field_names[]; extern const char *v4l2_type_names[]; #ifdef CONFIG_COMPAT -/* 32 Bits compatibility layer for 64 bits processors */ -extern long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, - unsigned long arg); +/** + * v4l2_compat_ioctl32 -32 Bits compatibility layer for 64 bits processors + * + * @file: Pointer to struct &file. + * @cmd: Ioctl name. + * @arg: Ioctl argument. + */ +long int v4l2_compat_ioctl32(struct file *file, unsigned int cmd, + unsigned long arg); #endif -typedef long (*v4l2_kioctl)(struct file *file, - unsigned int cmd, void *arg); +/** + * typedef v4l2_kioctl - Typedef used to pass an ioctl handler. + * + * @file: Pointer to struct &file. + * @cmd: Ioctl name. + * @arg: Ioctl argument. + */ +typedef long (*v4l2_kioctl)(struct file *file, unsigned int cmd, void *arg); -/* Include support for obsoleted stuff */ -extern long video_usercopy(struct file *file, unsigned int cmd, - unsigned long arg, v4l2_kioctl func); +/** + * video_usercopy - copies data from/to userspace memory when an ioctl is + * issued. + * + * @file: Pointer to struct &file. + * @cmd: Ioctl name. + * @arg: Ioctl argument. + * @func: function that will handle the ioctl + * + * .. note:: + * + * This routine should be used only inside the V4L2 core. + */ +long int video_usercopy(struct file *file, unsigned int cmd, + unsigned long int arg, v4l2_kioctl func); -/* Standard handlers for V4L ioctl's */ -extern long video_ioctl2(struct file *file, - unsigned int cmd, unsigned long arg); +/** + * video_ioctl2 - Handles a V4L2 ioctl. + * + * @file: Pointer to struct &file. + * @cmd: Ioctl name. + * @arg: Ioctl argument. + * + * Method used to hancle an ioctl. Should be used to fill the + * &v4l2_ioctl_ops.unlocked_ioctl on all V4L2 drivers. + */ +long int video_ioctl2(struct file *file, + unsigned int cmd, unsigned long int arg); #endif /* _V4L2_IOCTL_H */ diff --git a/include/media/v4l2-mc.h b/include/media/v4l2-mc.h index 28c3f9d9c209..2634d9dc9916 100644 --- a/include/media/v4l2-mc.h +++ b/include/media/v4l2-mc.h @@ -53,7 +53,7 @@ enum tuner_pad_index { }; /** - * enum if_vid_dec_index - video IF-PLL pad index for + * enum if_vid_dec_pad_index - video IF-PLL pad index for * MEDIA_ENT_F_IF_VID_DECODER * * @IF_VID_DEC_PAD_IF_INPUT: video Intermediate Frequency (IF) sink pad @@ -68,7 +68,7 @@ enum if_vid_dec_pad_index { }; /** - * enum if_aud_dec_index - audio/sound IF-PLL pad index for + * enum if_aud_dec_pad_index - audio/sound IF-PLL pad index for * MEDIA_ENT_F_IF_AUD_DECODER * * @IF_AUD_DEC_PAD_IF_INPUT: audio Intermediate Frequency (IF) sink pad diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 5a9597dd1ee0..1b355344c804 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -41,9 +41,9 @@ * This function does not have to (and will usually not) wait * until the device enters a state when it can be stopped. * @lock: optional. Define a driver's own lock callback, instead of using - * m2m_ctx->q_lock. + * &v4l2_m2m_ctx->q_lock. * @unlock: optional. Define a driver's own unlock callback, instead of - * using m2m_ctx->q_lock. + * using &v4l2_m2m_ctx->q_lock. */ struct v4l2_m2m_ops { void (*device_run)(void *priv); @@ -55,29 +55,51 @@ struct v4l2_m2m_ops { struct v4l2_m2m_dev; +/** + * struct v4l2_m2m_queue_ctx - represents a queue for buffers ready to be + * processed + * + * @q: pointer to struct &vb2_queue + * @rdy_queue: List of V4L2 mem-to-mem queues + * @rdy_spinlock: spin lock to protect the struct usage + * @num_rdy: number of buffers ready to be processed + * @buffered: is the queue buffered? + * + * Queue for buffers ready to be processed as soon as this + * instance receives access to the device. + */ + struct v4l2_m2m_queue_ctx { -/* private: internal use only */ struct vb2_queue q; - /* Queue for buffers ready to be processed as soon as this - * instance receives access to the device */ struct list_head rdy_queue; spinlock_t rdy_spinlock; u8 num_rdy; bool buffered; }; +/** + * struct v4l2_m2m_ctx - Memory to memory context structure + * + * @q_lock: struct &mutex lock + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * @cap_q_ctx: Capture (output to memory) queue context + * @out_q_ctx: Output (input from memory) queue context + * @queue: List of memory to memory contexts + * @job_flags: Job queue flags, used internally by v4l2-mem2mem.c: + * %TRANS_QUEUED, %TRANS_RUNNING and %TRANS_ABORT. + * @finished: Wait queue used to signalize when a job queue finished. + * @priv: Instance private data + */ struct v4l2_m2m_ctx { /* optional cap/out vb2 queues lock */ struct mutex *q_lock; -/* private: internal use only */ + /* internal use only */ struct v4l2_m2m_dev *m2m_dev; - /* Capture (output to memory) queue context */ struct v4l2_m2m_queue_ctx cap_q_ctx; - /* Output (input from memory) queue context */ struct v4l2_m2m_queue_ctx out_q_ctx; /* For device job queue */ @@ -85,22 +107,75 @@ struct v4l2_m2m_ctx { unsigned long job_flags; wait_queue_head_t finished; - /* Instance private data */ void *priv; }; +/** + * struct v4l2_m2m_buffer - Memory to memory buffer + * + * @vb: pointer to struct &vb2_v4l2_buffer + * @list: list of m2m buffers + */ struct v4l2_m2m_buffer { struct vb2_v4l2_buffer vb; struct list_head list; }; +/** + * v4l2_m2m_get_curr_priv() - return driver private data for the currently + * running instance or NULL if no instance is running + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + */ void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev); +/** + * v4l2_m2m_get_vq() - return vb2_queue for the given type + * + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type + */ struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); +/** + * v4l2_m2m_try_schedule() - check whether an instance is ready to be added to + * the pending job queue and add it if so. + * + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * + * There are three basic requirements an instance has to meet to be able to run: + * 1) at least one source buffer has to be queued, + * 2) at least one destination buffer has to be queued, + * 3) streaming has to be on. + * + * If a queue is buffered (for example a decoder hardware ringbuffer that has + * to be drained before doing streamoff), allow scheduling without v4l2 buffers + * on that queue. + * + * There may also be additional, custom requirements. In such case the driver + * should supply a custom callback (job_ready in v4l2_m2m_ops) that should + * return 1 if the instance is ready. + * An example of the above could be an instance that requires more than one + * src/dst buffer per transaction. + */ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx); +/** + * v4l2_m2m_job_finish() - inform the framework that a job has been finished + * and have it clean up + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * + * Called by a driver to yield back the device after it has finished with it. + * Should be called as soon as possible after reaching a state which allows + * other instances to take control of the device. + * + * This function has to be called only after &v4l2_m2m_ops->device_run + * callback has been called on the driver. To prevent recursion, it should + * not be called directly from the &v4l2_m2m_ops->device_run callback though. + */ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, struct v4l2_m2m_ctx *m2m_ctx); @@ -110,38 +185,165 @@ v4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state) vb2_buffer_done(&buf->vb2_buf, state); } +/** + * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @reqbufs: pointer to struct &v4l2_requestbuffers + */ int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_requestbuffers *reqbufs); +/** + * v4l2_m2m_querybuf() - multi-queue-aware QUERYBUF multiplexer + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @buf: pointer to struct &v4l2_buffer + * + * See v4l2_m2m_mmap() documentation for details. + */ int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); +/** + * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on + * the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @buf: pointer to struct &v4l2_buffer + */ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); + +/** + * v4l2_m2m_dqbuf() - dequeue a source or destination buffer, depending on + * the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @buf: pointer to struct &v4l2_buffer + */ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); + +/** + * v4l2_m2m_prepare_buf() - prepare a source or destination buffer, depending on + * the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @buf: pointer to struct &v4l2_buffer + */ int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); + +/** + * v4l2_m2m_create_bufs() - create a source or destination buffer, depending + * on the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @create: pointer to struct &v4l2_create_buffers + */ int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_create_buffers *create); +/** + * v4l2_m2m_expbuf() - export a source or destination buffer, depending on + * the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @eb: pointer to struct &v4l2_exportbuffer + */ int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_exportbuffer *eb); +/** + * v4l2_m2m_streamon() - turn on streaming for a video queue + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type + */ int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); + +/** + * v4l2_m2m_streamoff() - turn off streaming for a video queue + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type + */ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); +/** + * v4l2_m2m_poll() - poll replacement, for destination buffers only + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @wait: pointer to struct &poll_table_struct + * + * Call from the driver's poll() function. Will poll both queues. If a buffer + * is available to dequeue (with dqbuf) from the source queue, this will + * indicate that a non-blocking write can be performed, while read will be + * returned in case of the destination queue. + */ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct poll_table_struct *wait); +/** + * v4l2_m2m_mmap() - source and destination queues-aware mmap multiplexer + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @vma: pointer to struct &vm_area_struct + * + * Call from driver's mmap() function. Will handle mmap() for both queues + * seamlessly for videobuffer, which will receive normal per-queue offsets and + * proper videobuf queue pointers. The differentiation is made outside videobuf + * by adding a predefined offset to buffers from one of the queues and + * subtracting it before passing it back to videobuf. Only drivers (and + * thus applications) receive modified offsets. + */ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct vm_area_struct *vma); +/** + * v4l2_m2m_init() - initialize per-driver m2m data + * + * @m2m_ops: pointer to struct v4l2_m2m_ops + * + * Usually called from driver's ``probe()`` function. + * + * Return: returns an opaque pointer to the internal data to handle M2M context + */ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops); + +/** + * v4l2_m2m_release() - cleans up and frees a m2m_dev structure + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * + * Usually called from driver's ``remove()`` function. + */ void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); +/** + * v4l2_m2m_ctx_init() - allocate and initialize a m2m context + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * @drv_priv: driver's instance private data + * @queue_init: a callback for queue type-specific initialization function + * to be used for initializing videobuf_queues + * + * Usually called from driver's ``open()`` function. + */ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev, void *drv_priv, int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)); @@ -158,8 +360,23 @@ static inline void v4l2_m2m_set_dst_buffered(struct v4l2_m2m_ctx *m2m_ctx, m2m_ctx->cap_q_ctx.buffered = buffered; } +/** + * v4l2_m2m_ctx_release() - release m2m context + * + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * + * Usually called from driver's release() function. + */ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx); +/** + * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list. + * + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @vbuf: pointer to struct &vb2_v4l2_buffer + * + * Call from videobuf_queue_ops->ops->buf_queue, videobuf_queue_ops callback. + */ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_v4l2_buffer *vbuf); @@ -167,7 +384,7 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for * use * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) @@ -176,10 +393,10 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) } /** - * v4l2_m2m_num_src_bufs_ready() - return the number of destination buffers + * v4l2_m2m_num_dst_bufs_ready() - return the number of destination buffers * ready for use * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) @@ -187,13 +404,18 @@ unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) return m2m_ctx->cap_q_ctx.num_rdy; } +/** + * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers + * + * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx + */ void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx); /** * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready * buffers * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx) { @@ -204,7 +426,7 @@ static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx) * v4l2_m2m_next_dst_buf() - return next destination buffer from the list of * ready buffers * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) { @@ -214,7 +436,7 @@ static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) /** * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx) @@ -225,7 +447,7 @@ struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx) /** * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx) @@ -233,13 +455,19 @@ struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx) return &m2m_ctx->cap_q_ctx.q; } +/** + * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and + * return it + * + * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx + */ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx); /** * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready * buffers and return it * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) { @@ -250,7 +478,7 @@ static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) * v4l2_m2m_dst_buf_remove() - take off a destination buffer from the list of * ready buffers and return it * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) { diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 2a2240c99b30..cf778c5dca18 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -184,8 +184,6 @@ struct v4l2_subdev_io_pin_config { * for it to be warned when the value of a control changes. * * @unsubscribe_event: remove event subscription from the control framework. - * - * @registered_async: the subdevice has been registered async. */ struct v4l2_subdev_core_ops { int (*log_status)(struct v4l2_subdev *sd); @@ -211,11 +209,11 @@ struct v4l2_subdev_core_ops { struct v4l2_event_subscription *sub); int (*unsubscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub); - int (*registered_async)(struct v4l2_subdev *sd); }; /** - * struct s_radio - Callbacks used when v4l device was opened in radio mode. + * struct v4l2_subdev_tuner_ops - Callbacks used when v4l device was opened + * in radio mode. * * @s_radio: callback for %VIDIOC_S_RADIO ioctl handler code. * @@ -229,7 +227,7 @@ struct v4l2_subdev_core_ops { * * @g_tuner: callback for %VIDIOC_G_TUNER ioctl handler code. * - * @s_tuner: callback for %VIDIOC_S_TUNER ioctl handler code. &vt->type must be + * @s_tuner: callback for %VIDIOC_S_TUNER ioctl handler code. @vt->type must be * filled in. Normally done by video_ioctl2 or the * bridge driver. * @@ -358,11 +356,7 @@ struct v4l2_mbus_frame_desc { * @s_stream: used to notify the driver that a video stream will start or has * stopped. * - * @cropcap: callback for %VIDIOC_CROPCAP ioctl handler code. - * - * @g_crop: callback for %VIDIOC_G_CROP ioctl handler code. - * - * @s_crop: callback for %VIDIOC_S_CROP ioctl handler code. + * @g_pixelaspect: callback to return the pixelaspect ratio. * * @g_parm: callback for %VIDIOC_G_PARM ioctl handler code. * @@ -402,9 +396,7 @@ struct v4l2_subdev_video_ops { int (*g_tvnorms_output)(struct v4l2_subdev *sd, v4l2_std_id *std); int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); int (*s_stream)(struct v4l2_subdev *sd, int enable); - int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc); - int (*g_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); - int (*s_crop)(struct v4l2_subdev *sd, const struct v4l2_crop *crop); + int (*g_pixelaspect)(struct v4l2_subdev *sd, struct v4l2_fract *aspect); int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*g_frame_interval)(struct v4l2_subdev *sd, @@ -430,7 +422,7 @@ struct v4l2_subdev_video_ops { * in video mode via the vbi device node. * * @decode_vbi_line: video decoders that support sliced VBI need to implement - * this ioctl. Field p of the &struct v4l2_sliced_vbi_line is set to the + * this ioctl. Field p of the &struct v4l2_decode_vbi_line is set to the * start of the VBI data that was generated by the decoder. The driver * then parses the sliced VBI data and sets the other fields in the * struct accordingly. The pointer p is updated to point to the start of @@ -773,7 +765,7 @@ struct v4l2_subdev_platform_data { * @entity: pointer to &struct media_entity * @list: List of sub-devices * @owner: The owner is the same as the driver's &struct device owner. - * @owner_v4l2_dev: true if the &sd->owner matches the owner of &v4l2_dev->dev + * @owner_v4l2_dev: true if the &sd->owner matches the owner of @v4l2_dev->dev * ownner. Initialized by v4l2_device_register_subdev(). * @flags: subdev flags. Can be: * %V4L2_SUBDEV_FL_IS_I2C - Set this flag if this subdev is a i2c device; @@ -783,9 +775,9 @@ struct v4l2_subdev_platform_data { * %V4L2_SUBDEV_FL_HAS_EVENTS - Set this flag if this subdev generates * events. * - * @v4l2_dev: pointer to &struct v4l2_device - * @ops: pointer to &struct v4l2_subdev_ops - * @internal_ops: pointer to &struct v4l2_subdev_internal_ops. + * @v4l2_dev: pointer to struct &v4l2_device + * @ops: pointer to struct &v4l2_subdev_ops + * @internal_ops: pointer to struct &v4l2_subdev_internal_ops. * Never call these internal ops from within a driver! * @ctrl_handler: The control handler of this subdev. May be NULL. * @name: Name of the sub-device. Please notice that the name must be unique. @@ -896,7 +888,7 @@ static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd) } /** - * v4l2_set_subdevdata - Sets V4L2 dev private host data + * v4l2_set_subdev_hostdata - Sets V4L2 dev private host data * * @sd: pointer to &struct v4l2_subdev * @p: pointer to the private data to be stored. @@ -907,7 +899,7 @@ static inline void v4l2_set_subdev_hostdata(struct v4l2_subdev *sd, void *p) } /** - * v4l2_get_subdevdata - Gets V4L2 dev private data + * v4l2_get_subdev_hostdata - Gets V4L2 dev private data * * @sd: pointer to &struct v4l2_subdev * diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index a4a9a55a0c42..ac5898a55fd9 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -20,6 +20,20 @@ #define VB2_MAX_FRAME (32) #define VB2_MAX_PLANES (8) +/** + * enum vb2_memory - type of memory model used to make the buffers visible + * on userspace. + * + * @VB2_MEMORY_UNKNOWN: Buffer status is unknown or it is not used yet on + * userspace. + * @VB2_MEMORY_MMAP: The buffers are allocated by the Kernel and it is + * memory mapped via mmap() ioctl. This model is + * also used when the user is using the buffers via + * read() or write() system calls. + * @VB2_MEMORY_USERPTR: The buffers was allocated in userspace and it is + * memory mapped via mmap() ioctl. + * @VB2_MEMORY_DMABUF: The buffers are passed to userspace via DMA buffer. + */ enum vb2_memory { VB2_MEMORY_UNKNOWN = 0, VB2_MEMORY_MMAP = 1, @@ -33,15 +47,15 @@ struct vb2_threadio_data; /** * struct vb2_mem_ops - memory handling/memory allocator operations * @alloc: allocate video memory and, optionally, allocator private data, - * return NULL on failure or a pointer to allocator private, + * return ERR_PTR() on failure or a pointer to allocator private, * per-buffer data on success; the returned private structure - * will then be passed as buf_priv argument to other ops in this + * will then be passed as @buf_priv argument to other ops in this * structure. Additional gfp_flags to use when allocating the * are also passed to this operation. These flags are from the * gfp_flags field of vb2_queue. * @put: inform the allocator that the buffer will no longer be used; * usually will result in the allocator freeing the buffer (if - * no other users of this buffer are present); the buf_priv + * no other users of this buffer are present); the @buf_priv * argument is the allocator private per-buffer structure * previously returned from the alloc callback. * @get_dmabuf: acquire userspace memory for a hardware operation; used for @@ -50,18 +64,18 @@ struct vb2_threadio_data; * USERPTR memory types; vaddr is the address passed to the * videobuf layer when queuing a video buffer of USERPTR type; * should return an allocator private per-buffer structure - * associated with the buffer on success, NULL on failure; - * the returned private structure will then be passed as buf_priv + * associated with the buffer on success, ERR_PTR() on failure; + * the returned private structure will then be passed as @buf_priv * argument to other ops in this structure. * @put_userptr: inform the allocator that a USERPTR buffer will no longer * be used. * @attach_dmabuf: attach a shared struct dma_buf for a hardware operation; * used for DMABUF memory types; dev is the alloc device - * dbuf is the shared dma_buf; returns NULL on failure; + * dbuf is the shared dma_buf; returns ERR_PTR() on failure; * allocator private per-buffer structure on success; * this needs to be used for further accesses to the buffer. * @detach_dmabuf: inform the exporter of the buffer that the current DMABUF - * buffer is no longer used; the buf_priv argument is the + * buffer is no longer used; the @buf_priv argument is the * allocator private per-buffer structure previously returned * from the attach_dmabuf callback. * @map_dmabuf: request for access to the dmabuf from allocator; the allocator @@ -95,11 +109,13 @@ struct vb2_threadio_data; * * #) Required ops for read/write access types: alloc, put, num_users, vaddr. * - * #) Required ops for DMABUF types: attach_dmabuf, detach_dmabuf, map_dmabuf, unmap_dmabuf. + * #) Required ops for DMABUF types: attach_dmabuf, detach_dmabuf, + * map_dmabuf, unmap_dmabuf. */ struct vb2_mem_ops { void *(*alloc)(struct device *dev, unsigned long attrs, - unsigned long size, enum dma_data_direction dma_dir, + unsigned long size, + enum dma_data_direction dma_dir, gfp_t gfp_flags); void (*put)(void *buf_priv); struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags); @@ -112,7 +128,8 @@ struct vb2_mem_ops { void (*prepare)(void *buf_priv); void (*finish)(void *buf_priv); - void *(*attach_dmabuf)(struct device *dev, struct dma_buf *dbuf, + void *(*attach_dmabuf)(struct device *dev, + struct dma_buf *dbuf, unsigned long size, enum dma_data_direction dma_dir); void (*detach_dmabuf)(void *buf_priv); @@ -277,7 +294,7 @@ struct vb2_buffer { /** * struct vb2_ops - driver-specific callbacks * - * @queue_setup: called from %VIDIOC_REQBUFS and %VIDIOC_CREATE_BUFS + * @queue_setup: called from VIDIOC_REQBUFS() and VIDIOC_CREATE_BUFS() * handlers before memory allocation. It can be called * twice: if the original number of requested buffers * could not be allocated, then it will be called a @@ -288,11 +305,11 @@ struct vb2_buffer { * buffer in \*num_planes, the size of each plane should be * set in the sizes\[\] array and optional per-plane * allocator specific device in the alloc_devs\[\] array. - * When called from %VIDIOC_REQBUFS, \*num_planes == 0, the - * driver has to use the currently configured format to + * When called from VIDIOC_REQBUFS,() \*num_planes == 0, + * the driver has to use the currently configured format to * determine the plane sizes and \*num_buffers is the total * number of buffers that are being allocated. When called - * from %VIDIOC_CREATE_BUFS, \*num_planes != 0 and it + * from VIDIOC_CREATE_BUFS,() \*num_planes != 0 and it * describes the requested number of planes and sizes\[\] * contains the requested plane sizes. If either * \*num_planes or the requested sizes are invalid callback @@ -311,11 +328,11 @@ struct vb2_buffer { * initialization failure (return != 0) will prevent * queue setup from completing successfully; optional. * @buf_prepare: called every time the buffer is queued from userspace - * and from the %VIDIOC_PREPARE_BUF ioctl; drivers may + * and from the VIDIOC_PREPARE_BUF() ioctl; drivers may * perform any initialization required before each * hardware operation in this callback; drivers can * access/modify the buffer here as it is still synced for - * the CPU; drivers that support %VIDIOC_CREATE_BUFS must + * the CPU; drivers that support VIDIOC_CREATE_BUFS() must * also validate the buffer size; if an error is returned, * the buffer will not be queued in driver; optional. * @buf_finish: called before every dequeue of the buffer back to @@ -339,24 +356,25 @@ struct vb2_buffer { * driver can return an error if hardware fails, in that * case all buffers that have been already given by * the @buf_queue callback are to be returned by the driver - * by calling @vb2_buffer_done\(%VB2_BUF_STATE_QUEUED\). + * by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED. * If you need a minimum number of buffers before you can * start streaming, then set @min_buffers_needed in the * vb2_queue structure. If that is non-zero then - * start_streaming won't be called until at least that + * @start_streaming won't be called until at least that * many buffers have been queued up by userspace. * @stop_streaming: called when 'streaming' state must be disabled; driver * should stop any DMA transactions or wait until they * finish and give back all buffers it got from &buf_queue - * callback by calling @vb2_buffer_done\(\) with either + * callback by calling vb2_buffer_done() with either * %VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use * vb2_wait_for_all_buffers() function * @buf_queue: passes buffer vb to the driver; driver may start * hardware operation on this buffer; driver should give * the buffer back by calling vb2_buffer_done() function; - * it is allways called after calling %VIDIOC_STREAMON ioctl; - * might be called before start_streaming callback if user - * pre-queued buffers before calling %VIDIOC_STREAMON. + * it is allways called after calling VIDIOC_STREAMON() + * ioctl; might be called before @start_streaming callback + * if user pre-queued buffers before calling + * VIDIOC_STREAMON(). */ struct vb2_ops { int (*queue_setup)(struct vb2_queue *q, @@ -378,7 +396,7 @@ struct vb2_ops { }; /** - * struct vb2_ops - driver-specific callbacks + * struct vb2_buf_ops - driver-specific callbacks * * @verify_planes_array: Verify that a given user space structure contains * enough planes for the buffer. This is called @@ -404,7 +422,7 @@ struct vb2_buf_ops { * * @type: private buffer type whose content is defined by the vb2-core * caller. For example, for V4L2, it should match - * the V4L2_BUF_TYPE_* in include/uapi/linux/videodev2.h + * the types defined on enum &v4l2_buf_type * @io_modes: supported io methods (see vb2_io_modes enum) * @dev: device to use for the default allocation context if the driver * doesn't fill in the @alloc_devs array. @@ -439,12 +457,12 @@ struct vb2_buf_ops { * Typically this is 0, but it may be e.g. GFP_DMA or __GFP_DMA32 * to force the buffer allocation to a specific memory zone. * @min_buffers_needed: the minimum number of buffers needed before - * start_streaming() can be called. Used when a DMA engine + * @start_streaming can be called. Used when a DMA engine * cannot be started unless at least this number of buffers * have been queued into the driver. */ /* - * Private elements (won't appear at the DocBook): + * Private elements (won't appear at the uAPI book): * @mmap_lock: private mutex used when buffers are allocated/freed/mmapped * @memory: current memory type used * @bufs: videobuf buffer structures @@ -457,7 +475,7 @@ struct vb2_buf_ops { * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued * @alloc_devs: memory type/allocator-specific per-plane device * @streaming: current streaming state - * @start_streaming_called: start_streaming() was called successfully and we + * @start_streaming_called: @start_streaming was called successfully and we * started streaming. * @error: a fatal error occurred on the queue * @waiting_for_buffers: used in poll() to check if vb2 is still waiting for @@ -536,36 +554,286 @@ struct vb2_queue { #endif }; +/** + * vb2_plane_vaddr() - Return a kernel virtual address of a given plane + * @vb: vb2_buffer to which the plane in question belongs to + * @plane_no: plane number for which the address is to be returned + * + * This function returns a kernel virtual address of a given plane if + * such a mapping exist, NULL otherwise. + */ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no); + +/** + * vb2_plane_cookie() - Return allocator specific cookie for the given plane + * @vb: vb2_buffer to which the plane in question belongs to + * @plane_no: plane number for which the cookie is to be returned + * + * This function returns an allocator specific cookie for a given plane if + * available, NULL otherwise. The allocator should provide some simple static + * inline function, which would convert this cookie to the allocator specific + * type that can be used directly by the driver to access the buffer. This can + * be for example physical address, pointer to scatter list or IOMMU mapping. + */ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no); +/** + * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished + * @vb: vb2_buffer returned from the driver + * @state: either %VB2_BUF_STATE_DONE if the operation finished + * successfully, %VB2_BUF_STATE_ERROR if the operation finished + * with an error or %VB2_BUF_STATE_QUEUED if the driver wants to + * requeue buffers. If start_streaming fails then it should return + * buffers with state %VB2_BUF_STATE_QUEUED to put them back into + * the queue. + * + * This function should be called by the driver after a hardware operation on + * a buffer is finished and the buffer may be returned to userspace. The driver + * cannot use this buffer anymore until it is queued back to it by videobuf + * by the means of &vb2_ops->buf_queue callback. Only buffers previously queued + * to the driver by &vb2_ops->buf_queue can be passed to this function. + * + * While streaming a buffer can only be returned in state DONE or ERROR. + * The start_streaming op can also return them in case the DMA engine cannot + * be started for some reason. In that case the buffers should be returned with + * state QUEUED. + */ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); + +/** + * vb2_discard_done() - discard all buffers marked as DONE + * @q: videobuf2 queue + * + * This function is intended to be used with suspend/resume operations. It + * discards all 'done' buffers as they would be too old to be requested after + * resume. + * + * Drivers must stop the hardware and synchronize with interrupt handlers and/or + * delayed works before calling this function to make sure no buffer will be + * touched by the driver and/or hardware. + */ void vb2_discard_done(struct vb2_queue *q); + +/** + * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2 + * @q: videobuf2 queue + * + * This function will wait until all buffers that have been given to the driver + * by &vb2_ops->buf_queue are given back to vb2 with vb2_buffer_done(). It + * doesn't call wait_prepare()/wait_finish() pair. It is intended to be called + * with all locks taken, for example from &vb2_ops->stop_streaming callback. + */ int vb2_wait_for_all_buffers(struct vb2_queue *q); +/** + * vb2_core_querybuf() - query video buffer information + * @q: videobuf queue + * @index: id number of the buffer + * @pb: buffer struct passed from userspace + * + * Should be called from vidioc_querybuf ioctl handler in driver. + * The passed buffer should have been verified. + * This function fills the relevant information for the userspace. + */ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb); + +/** + * vb2_core_reqbufs() - Initiate streaming + * @q: videobuf2 queue + * @memory: memory type + * @count: requested buffer count + * + * Should be called from vidioc_reqbufs ioctl handler of a driver. + * + * This function: + * + * #) verifies streaming parameters passed from the userspace, + * #) sets up the queue, + * #) negotiates number of buffers and planes per buffer with the driver + * to be used during streaming, + * #) allocates internal buffer structures (struct vb2_buffer), according to + * the agreed parameters, + * #) for MMAP memory type, allocates actual video memory, using the + * memory handling/allocation routines provided during queue initialization + * + * If req->count is 0, all the memory will be freed instead. + * If the queue has been allocated previously (by a previous vb2_reqbufs) call + * and the queue is not busy, memory will be reallocated. + * + * The return values from this function are intended to be directly returned + * from vidioc_reqbufs handler in driver. + */ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, unsigned int *count); + +/** + * vb2_core_create_bufs() - Allocate buffers and any required auxiliary structs + * @q: videobuf2 queue + * @memory: memory type + * @count: requested buffer count + * @requested_planes: number of planes requested + * @requested_sizes: array with the size of the planes + * + * Should be called from VIDIOC_CREATE_BUFS() ioctl handler of a driver. + * This function: + * + * #) verifies parameter sanity + * #) calls the .queue_setup() queue operation + * #) performs any necessary memory allocations + * + * Return: the return values from this function are intended to be directly + * returned from VIDIOC_CREATE_BUFS() handler in driver. + */ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, - unsigned int *count, unsigned requested_planes, - const unsigned int requested_sizes[]); + unsigned int *count, unsigned int requested_planes, + const unsigned int requested_sizes[]); + +/** + * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace + * to the kernel + * @q: videobuf2 queue + * @index: id number of the buffer + * @pb: buffer structure passed from userspace to vidioc_prepare_buf + * handler in driver + * + * Should be called from vidioc_prepare_buf ioctl handler of a driver. + * The passed buffer should have been verified. + * This function calls buf_prepare callback in the driver (if provided), + * in which driver-specific buffer initialization can be performed, + * + * The return values from this function are intended to be directly returned + * from vidioc_prepare_buf handler in driver. + */ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb); + +/** + * vb2_core_qbuf() - Queue a buffer from userspace + * + * @q: videobuf2 queue + * @index: id number of the buffer + * @pb: buffer structure passed from userspace to vidioc_qbuf handler + * in driver + * + * Should be called from vidioc_qbuf ioctl handler of a driver. + * The passed buffer should have been verified. + * + * This function: + * + * #) if necessary, calls buf_prepare callback in the driver (if provided), in + * which driver-specific buffer initialization can be performed, + * #) if streaming is on, queues the buffer in driver by the means of + * &vb2_ops->buf_queue callback for processing. + * + * The return values from this function are intended to be directly returned + * from vidioc_qbuf handler in driver. + */ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb); + +/** + * vb2_core_dqbuf() - Dequeue a buffer to the userspace + * @q: videobuf2 queue + * @pindex: pointer to the buffer index. May be NULL + * @pb: buffer structure passed from userspace to vidioc_dqbuf handler + * in driver + * @nonblocking: if true, this call will not sleep waiting for a buffer if no + * buffers ready for dequeuing are present. Normally the driver + * would be passing (file->f_flags & O_NONBLOCK) here + * + * Should be called from vidioc_dqbuf ioctl handler of a driver. + * The passed buffer should have been verified. + * + * This function: + * + * #) calls buf_finish callback in the driver (if provided), in which + * driver can perform any additional operations that may be required before + * returning the buffer to userspace, such as cache sync, + * #) the buffer struct members are filled with relevant information for + * the userspace. + * + * The return values from this function are intended to be directly returned + * from vidioc_dqbuf handler in driver. + */ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, bool nonblocking); int vb2_core_streamon(struct vb2_queue *q, unsigned int type); int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); +/** + * vb2_core_expbuf() - Export a buffer as a file descriptor + * @q: videobuf2 queue + * @fd: file descriptor associated with DMABUF (set by driver) * + * @type: buffer type + * @index: id number of the buffer + * @plane: index of the plane to be exported, 0 for single plane queues + * @flags: flags for newly created file, currently only O_CLOEXEC is + * supported, refer to manual of open syscall for more details + * + * The return values from this function are intended to be directly returned + * from vidioc_expbuf handler in driver. + */ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, unsigned int index, unsigned int plane, unsigned int flags); +/** + * vb2_core_queue_init() - initialize a videobuf2 queue + * @q: videobuf2 queue; this structure should be allocated in driver + * + * The vb2_queue structure should be allocated by the driver. The driver is + * responsible of clearing it's content and setting initial values for some + * required entries before calling this function. + * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer + * to the struct vb2_queue description in include/media/videobuf2-core.h + * for more information. + */ int vb2_core_queue_init(struct vb2_queue *q); + +/** + * vb2_core_queue_release() - stop streaming, release the queue and free memory + * @q: videobuf2 queue + * + * This function stops streaming and performs necessary clean ups, including + * freeing video buffer memory. The driver is responsible for freeing + * the vb2_queue structure itself. + */ void vb2_core_queue_release(struct vb2_queue *q); +/** + * vb2_queue_error() - signal a fatal error on the queue + * @q: videobuf2 queue + * + * Flag that a fatal unrecoverable error has occurred and wake up all processes + * waiting on the queue. Polling will now set POLLERR and queuing and dequeuing + * buffers will return -EIO. + * + * The error flag will be cleared when cancelling the queue, either from + * vb2_streamoff or vb2_queue_release. Drivers should thus not call this + * function before starting the stream, otherwise the error flag will remain set + * until the queue is released when closing the device node. + */ void vb2_queue_error(struct vb2_queue *q); +/** + * vb2_mmap() - map video buffers into application address space + * @q: videobuf2 queue + * @vma: vma passed to the mmap file operation handler in the driver + * + * Should be called from mmap file operation handler of a driver. + * This function maps one plane of one of the available video buffers to + * userspace. To map whole video memory allocated on reqbufs, this function + * has to be called once per each plane per each buffer previously allocated. + * + * When the userspace application calls mmap, it passes to it an offset returned + * to it earlier by the means of vidioc_querybuf handler. That offset acts as + * a "cookie", which is then used to identify the plane to be mapped. + * This function finds a plane with a matching offset and a mapping is performed + * by the means of a provided memory operation. + * + * The return values from this function are intended to be directly returned + * from the mmap handler in driver. + */ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma); + #ifndef CONFIG_MMU unsigned long vb2_get_unmapped_area(struct vb2_queue *q, unsigned long addr, @@ -573,15 +841,36 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q, unsigned long pgoff, unsigned long flags); #endif + +/** + * vb2_core_poll() - implements poll userspace operation + * @q: videobuf2 queue + * @file: file argument passed to the poll file operation handler + * @wait: wait argument passed to the poll file operation handler + * + * This function implements poll file operation handler for a driver. + * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will + * be informed that the file descriptor of a video device is available for + * reading. + * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor + * will be reported as available for writing. + * + * The return values from this function are intended to be directly returned + * from poll handler in driver. + */ unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file, - poll_table *wait); + poll_table *wait); + size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, loff_t *ppos, int nonblock); size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, loff_t *ppos, int nonblock); -/* - * vb2_thread_fnc - callback function for use with vb2_thread +/** + * typedef vb2_thread_fnc - callback function for use with vb2_thread + * + * @vb: pointer to struct &vb2_buffer + * @priv: pointer to a private pointer * * This is called whenever a buffer is dequeued in the thread. */ @@ -597,9 +886,11 @@ typedef int (*vb2_thread_fnc)(struct vb2_buffer *vb, void *priv); * This starts a thread that will queue and dequeue until an error occurs * or @vb2_thread_stop is called. * - * This function should not be used for anything else but the videobuf2-dvb - * support. If you think you have another good use-case for this, then please - * contact the linux-media mailinglist first. + * .. attention:: + * + * This function should not be used for anything else but the videobuf2-dvb + * support. If you think you have another good use-case for this, then please + * contact the linux-media mailing list first. */ int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv, const char *thread_name); @@ -717,7 +1008,26 @@ static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q) * The following functions are not part of the vb2 core API, but are useful * functions for videobuf2-*. */ + +/** + * vb2_buffer_in_use() - return true if the buffer is in use and + * the queue cannot be freed (by the means of REQBUFS(0)) call + * + * @vb: buffer for which plane size should be returned + * @q: videobuf queue + */ bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb); + +/** + * vb2_verify_memory_type() - Check whether the memory type and buffer type + * passed to a buffer operation are compatible with the queue. + * + * @q: videobuf queue + * @memory: memory model, as defined by enum &vb2_memory. + * @type: private buffer type whose content is defined by the vb2-core + * caller. For example, for V4L2, it should match + * the types defined on enum &v4l2_buf_type + */ int vb2_verify_memory_type(struct vb2_queue *q, enum vb2_memory memory, unsigned int type); #endif /* _MEDIA_VIDEOBUF2_CORE_H */ diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index 3cc836f76675..036127c54bbf 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -25,11 +25,13 @@ /** * struct vb2_v4l2_buffer - video buffer information for v4l2 + * * @vb2_buf: video buffer 2 * @flags: buffer informational flags * @field: enum v4l2_field; field order of the image in the buffer * @timecode: frame timecode * @sequence: sequence count of this frame + * * Should contain enough information to be able to cover all the fields * of struct v4l2_buffer at videodev2.h */ @@ -49,22 +51,183 @@ struct vb2_v4l2_buffer { container_of(vb, struct vb2_v4l2_buffer, vb2_buf) int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b); + +/** + * vb2_reqbufs() - Wrapper for vb2_core_reqbufs() that also verifies + * the memory and type values. + * + * @q: videobuf2 queue + * @req: struct passed from userspace to vidioc_reqbufs handler + * in driver + */ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); +/** + * vb2_create_bufs() - Wrapper for vb2_core_create_bufs() that also verifies + * the memory and type values. + * + * @q: videobuf2 queue + * @create: creation parameters, passed from userspace to vidioc_create_bufs + * handler in driver + */ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create); + +/** + * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel + * + * @q: videobuf2 queue + * @b: buffer structure passed from userspace to vidioc_prepare_buf + * handler in driver + * + * Should be called from vidioc_prepare_buf ioctl handler of a driver. + * This function: + * + * #) verifies the passed buffer, + * #) calls buf_prepare callback in the driver (if provided), in which + * driver-specific buffer initialization can be performed. + * + * The return values from this function are intended to be directly returned + * from vidioc_prepare_buf handler in driver. + */ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b); +/** + * vb2_qbuf() - Queue a buffer from userspace + * @q: videobuf2 queue + * @b: buffer structure passed from userspace to VIDIOC_QBUF() handler + * in driver + * + * Should be called from VIDIOC_QBUF() ioctl handler of a driver. + * + * This function: + * + * #) verifies the passed buffer, + * #) if necessary, calls buf_prepare callback in the driver (if provided), in + * which driver-specific buffer initialization can be performed, + * #) if streaming is on, queues the buffer in driver by the means of buf_queue + * callback for processing. + * + * The return values from this function are intended to be directly returned + * from VIDIOC_QBUF() handler in driver. + */ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b); + +/** + * vb2_expbuf() - Export a buffer as a file descriptor + * @q: videobuf2 queue + * @eb: export buffer structure passed from userspace to VIDIOC_EXPBUF() + * handler in driver + * + * The return values from this function are intended to be directly returned + * from VIDIOC_EXPBUF() handler in driver. + */ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb); + +/** + * vb2_dqbuf() - Dequeue a buffer to the userspace + * @q: videobuf2 queue + * @b: buffer structure passed from userspace to VIDIOC_DQBUF() handler + * in driver + * @nonblocking: if true, this call will not sleep waiting for a buffer if no + * buffers ready for dequeuing are present. Normally the driver + * would be passing (file->f_flags & O_NONBLOCK) here + * + * Should be called from VIDIOC_DQBUF() ioctl handler of a driver. + * + * This function: + * + * #) verifies the passed buffer, + * #) calls buf_finish callback in the driver (if provided), in which + * driver can perform any additional operations that may be required before + * returning the buffer to userspace, such as cache sync, + * #) the buffer struct members are filled with relevant information for + * the userspace. + * + * The return values from this function are intended to be directly returned + * from VIDIOC_DQBUF() handler in driver. + */ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking); +/** + * vb2_streamon - start streaming + * @q: videobuf2 queue + * @type: type argument passed from userspace to vidioc_streamon handler + * + * Should be called from vidioc_streamon handler of a driver. + * + * This function: + * + * 1) verifies current state + * 2) passes any previously queued buffers to the driver and starts streaming + * + * The return values from this function are intended to be directly returned + * from vidioc_streamon handler in the driver. + */ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type); + +/** + * vb2_streamoff - stop streaming + * @q: videobuf2 queue + * @type: type argument passed from userspace to vidioc_streamoff handler + * + * Should be called from vidioc_streamoff handler of a driver. + * + * This function: + * + * #) verifies current state, + * #) stop streaming and dequeues any queued buffers, including those previously + * passed to the driver (after waiting for the driver to finish). + * + * This call can be used for pausing playback. + * The return values from this function are intended to be directly returned + * from vidioc_streamoff handler in the driver + */ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type); +/** + * vb2_queue_init() - initialize a videobuf2 queue + * @q: videobuf2 queue; this structure should be allocated in driver + * + * The vb2_queue structure should be allocated by the driver. The driver is + * responsible of clearing it's content and setting initial values for some + * required entries before calling this function. + * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer + * to the struct vb2_queue description in include/media/videobuf2-core.h + * for more information. + */ int __must_check vb2_queue_init(struct vb2_queue *q); + +/** + * vb2_queue_release() - stop streaming, release the queue and free memory + * @q: videobuf2 queue + * + * This function stops streaming and performs necessary clean ups, including + * freeing video buffer memory. The driver is responsible for freeing + * the vb2_queue structure itself. + */ void vb2_queue_release(struct vb2_queue *q); + +/** + * vb2_poll() - implements poll userspace operation + * @q: videobuf2 queue + * @file: file argument passed to the poll file operation handler + * @wait: wait argument passed to the poll file operation handler + * + * This function implements poll file operation handler for a driver. + * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will + * be informed that the file descriptor of a video device is available for + * reading. + * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor + * will be reported as available for writing. + * + * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any + * pending events. + * + * The return values from this function are intended to be directly returned + * from poll handler in driver. + */ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, - poll_table *wait); + poll_table *wait); /* * The following functions are not part of the vb2 core API, but are simple @@ -105,9 +268,22 @@ unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); #endif -/* struct vb2_ops helpers, only use if vq->lock is non-NULL. */ - +/** + * vb2_ops_wait_prepare - helper function to lock a struct &vb2_queue + * + * @vq: pointer to struct vb2_queue + * + * ..note:: only use if vq->lock is non-NULL. + */ void vb2_ops_wait_prepare(struct vb2_queue *vq); + +/** + * vb2_ops_wait_finish - helper function to unlock a struct &vb2_queue + * + * @vq: pointer to struct vb2_queue + * + * ..note:: only use if vq->lock is non-NULL. + */ void vb2_ops_wait_finish(struct vb2_queue *vq); #endif /* _MEDIA_VIDEOBUF2_V4L2_H */ diff --git a/include/media/vsp1.h b/include/media/vsp1.h index 9322d9775fb7..458b400373d4 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -26,7 +26,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, struct vsp1_du_atomic_config { u32 pixelformat; unsigned int pitch; - dma_addr_t mem[2]; + dma_addr_t mem[3]; struct v4l2_rect src; struct v4l2_rect dst; unsigned int alpha; diff --git a/include/net/bonding.h b/include/net/bonding.h index 6360c259da6d..f32f7ef8a23a 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -37,18 +37,6 @@ #ifndef __long_aligned #define __long_aligned __attribute__((aligned((sizeof(long))))) #endif -/* - * Less bad way to call ioctl from within the kernel; this needs to be - * done some other way to get the call out of interrupt context. - * Needs "ioctl" variable to be supplied by calling context. - */ -#define IOCTL(dev, arg, cmd) ({ \ - int res = 0; \ - mm_segment_t fs = get_fs(); \ - set_fs(get_ds()); \ - res = ioctl(dev, arg, cmd); \ - set_fs(fs); \ - res; }) #define BOND_MODE(bond) ((bond)->params.mode) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index fe78f02a242e..bd19faad0d96 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -796,9 +796,9 @@ enum station_parameters_apply_mask { * (or NULL for no change) * @supported_rates_len: number of supported rates * @sta_flags_mask: station flags that changed - * (bitmask of BIT(NL80211_STA_FLAG_...)) + * (bitmask of BIT(%NL80211_STA_FLAG_...)) * @sta_flags_set: station flags values - * (bitmask of BIT(NL80211_STA_FLAG_...)) + * (bitmask of BIT(%NL80211_STA_FLAG_...)) * @listen_interval: listen interval or -1 for no change * @aid: AID or zero for no change * @peer_aid: mesh peer AID or zero for no change @@ -3088,47 +3088,54 @@ struct ieee80211_iface_limit { * * 1. Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total: * - * struct ieee80211_iface_limit limits1[] = { - * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, - * { .max = 1, .types = BIT(NL80211_IFTYPE_AP}, }, - * }; - * struct ieee80211_iface_combination combination1 = { - * .limits = limits1, - * .n_limits = ARRAY_SIZE(limits1), - * .max_interfaces = 2, - * .beacon_int_infra_match = true, - * }; + * .. code-block:: c + * + * struct ieee80211_iface_limit limits1[] = { + * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, + * { .max = 1, .types = BIT(NL80211_IFTYPE_AP}, }, + * }; + * struct ieee80211_iface_combination combination1 = { + * .limits = limits1, + * .n_limits = ARRAY_SIZE(limits1), + * .max_interfaces = 2, + * .beacon_int_infra_match = true, + * }; * * * 2. Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total: * - * struct ieee80211_iface_limit limits2[] = { - * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) | - * BIT(NL80211_IFTYPE_P2P_GO), }, - * }; - * struct ieee80211_iface_combination combination2 = { - * .limits = limits2, - * .n_limits = ARRAY_SIZE(limits2), - * .max_interfaces = 8, - * .num_different_channels = 1, - * }; + * .. code-block:: c + * + * struct ieee80211_iface_limit limits2[] = { + * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) | + * BIT(NL80211_IFTYPE_P2P_GO), }, + * }; + * struct ieee80211_iface_combination combination2 = { + * .limits = limits2, + * .n_limits = ARRAY_SIZE(limits2), + * .max_interfaces = 8, + * .num_different_channels = 1, + * }; * * * 3. Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total. * - * This allows for an infrastructure connection and three P2P connections. - * - * struct ieee80211_iface_limit limits3[] = { - * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, - * { .max = 3, .types = BIT(NL80211_IFTYPE_P2P_GO) | - * BIT(NL80211_IFTYPE_P2P_CLIENT), }, - * }; - * struct ieee80211_iface_combination combination3 = { - * .limits = limits3, - * .n_limits = ARRAY_SIZE(limits3), - * .max_interfaces = 4, - * .num_different_channels = 2, - * }; + * This allows for an infrastructure connection and three P2P connections. + * + * .. code-block:: c + * + * struct ieee80211_iface_limit limits3[] = { + * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, + * { .max = 3, .types = BIT(NL80211_IFTYPE_P2P_GO) | + * BIT(NL80211_IFTYPE_P2P_CLIENT), }, + * }; + * struct ieee80211_iface_combination combination3 = { + * .limits = limits3, + * .n_limits = ARRAY_SIZE(limits3), + * .max_interfaces = 4, + * .num_different_channels = 2, + * }; + * */ struct ieee80211_iface_combination { const struct ieee80211_iface_limit *limits; diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h index b220dabeab45..3832099289c5 100644 --- a/include/net/l3mdev.h +++ b/include/net/l3mdev.h @@ -114,6 +114,25 @@ static inline u32 l3mdev_fib_table(const struct net_device *dev) return tb_id; } +static inline bool netif_index_is_l3_master(struct net *net, int ifindex) +{ + struct net_device *dev; + bool rc = false; + + if (ifindex == 0) + return false; + + rcu_read_lock(); + + dev = dev_get_by_index_rcu(net, ifindex); + if (dev) + rc = netif_is_l3_master(dev); + + rcu_read_unlock(); + + return rc; +} + struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6); static inline @@ -207,6 +226,11 @@ static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex) return 0; } +static inline bool netif_index_is_l3_master(struct net *net, int ifindex) +{ + return false; +} + static inline struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6) { diff --git a/include/soc/fsl/bman.h b/include/soc/fsl/bman.h new file mode 100644 index 000000000000..eaaf56df4086 --- /dev/null +++ b/include/soc/fsl/bman.h @@ -0,0 +1,129 @@ +/* Copyright 2008 - 2016 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_BMAN_H +#define __FSL_BMAN_H + +/* wrapper for 48-bit buffers */ +struct bm_buffer { + union { + struct { + __be16 bpid; /* hi 8-bits reserved */ + __be16 hi; /* High 16-bits of 48-bit address */ + __be32 lo; /* Low 32-bits of 48-bit address */ + }; + __be64 data; + }; +} __aligned(8); +/* + * Restore the 48 bit address previously stored in BMan + * hardware pools as a dma_addr_t + */ +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf) +{ + return be64_to_cpu(buf->data) & 0xffffffffffffLLU; +} + +static inline u64 bm_buffer_get64(const struct bm_buffer *buf) +{ + return be64_to_cpu(buf->data) & 0xffffffffffffLLU; +} + +static inline void bm_buffer_set64(struct bm_buffer *buf, u64 addr) +{ + buf->hi = cpu_to_be16(upper_32_bits(addr)); + buf->lo = cpu_to_be32(lower_32_bits(addr)); +} + +static inline u8 bm_buffer_get_bpid(const struct bm_buffer *buf) +{ + return be16_to_cpu(buf->bpid) & 0xff; +} + +static inline void bm_buffer_set_bpid(struct bm_buffer *buf, int bpid) +{ + buf->bpid = cpu_to_be16(bpid & 0xff); +} + +/* Managed portal, high-level i/face */ + +/* Portal and Buffer Pools */ +struct bman_portal; +struct bman_pool; + +#define BM_POOL_MAX 64 /* max # of buffer pools */ + +/** + * bman_new_pool - Allocates a Buffer Pool object + * + * Creates a pool object, and returns a reference to it or NULL on error. + */ +struct bman_pool *bman_new_pool(void); + +/** + * bman_free_pool - Deallocates a Buffer Pool object + * @pool: the pool object to release + */ +void bman_free_pool(struct bman_pool *pool); + +/** + * bman_get_bpid - Returns a pool object's BPID. + * @pool: the pool object + * + * The returned value is the index of the encapsulated buffer pool, + * in the range of [0, @BM_POOL_MAX-1]. + */ +int bman_get_bpid(const struct bman_pool *pool); + +/** + * bman_release - Release buffer(s) to the buffer pool + * @pool: the buffer pool object to release to + * @bufs: an array of buffers to release + * @num: the number of buffers in @bufs (1-8) + * + * Adds the given buffers to RCR entries. If the RCR ring is unresponsive, + * the function will return -ETIMEDOUT. Otherwise, it returns zero. + */ +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num); + +/** + * bman_acquire - Acquire buffer(s) from a buffer pool + * @pool: the buffer pool object to acquire from + * @bufs: array for storing the acquired buffers + * @num: the number of buffers desired (@bufs is at least this big) + * + * Issues an "Acquire" command via the portal's management command interface. + * The return value will be the number of buffers obtained from the pool, or a + * negative error code if a h/w error or pool starvation was encountered. In + * the latter case, the content of @bufs is undefined. + */ +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num); + +#endif /* __FSL_BMAN_H */ diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h new file mode 100644 index 000000000000..37f3eb001a16 --- /dev/null +++ b/include/soc/fsl/qman.h @@ -0,0 +1,1074 @@ +/* Copyright 2008 - 2016 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_QMAN_H +#define __FSL_QMAN_H + +#include <linux/bitops.h> + +/* Hardware constants */ +#define QM_CHANNEL_SWPORTAL0 0 +#define QMAN_CHANNEL_POOL1 0x21 +#define QMAN_CHANNEL_POOL1_REV3 0x401 +extern u16 qm_channel_pool1; + +/* Portal processing (interrupt) sources */ +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */ +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */ +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */ +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */ +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */ +/* + * This mask contains all the interrupt sources that need handling except DQRI, + * ie. that if present should trigger slow-path processing. + */ +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \ + QM_PIRQ_MRI) + +/* For qman_static_dequeue_*** APIs */ +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff +/* for n in [1,15] */ +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n)) +/* for conversion from n of qm_channel */ +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel) +{ + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1); +} + +/* --- QMan data structures (and associated constants) --- */ + +/* "Frame Descriptor (FD)" */ +struct qm_fd { + union { + struct { + u8 cfg8b_w1; + u8 bpid; /* Buffer Pool ID */ + u8 cfg8b_w3; + u8 addr_hi; /* high 8-bits of 40-bit address */ + __be32 addr_lo; /* low 32-bits of 40-bit address */ + } __packed; + __be64 data; + }; + __be32 cfg; /* format, offset, length / congestion */ + union { + __be32 cmd; + __be32 status; + }; +} __aligned(8); + +#define QM_FD_FORMAT_SG BIT(31) +#define QM_FD_FORMAT_LONG BIT(30) +#define QM_FD_FORMAT_COMPOUND BIT(29) +#define QM_FD_FORMAT_MASK GENMASK(31, 29) +#define QM_FD_OFF_SHIFT 20 +#define QM_FD_OFF_MASK GENMASK(28, 20) +#define QM_FD_LEN_MASK GENMASK(19, 0) +#define QM_FD_LEN_BIG_MASK GENMASK(28, 0) + +enum qm_fd_format { + /* + * 'contig' implies a contiguous buffer, whereas 'sg' implies a + * scatter-gather table. 'big' implies a 29-bit length with no offset + * field, otherwise length is 20-bit and offset is 9-bit. 'compound' + * implies a s/g-like table, where each entry itself represents a frame + * (contiguous or scatter-gather) and the 29-bit "length" is + * interpreted purely for congestion calculations, ie. a "congestion + * weight". + */ + qm_fd_contig = 0, + qm_fd_contig_big = QM_FD_FORMAT_LONG, + qm_fd_sg = QM_FD_FORMAT_SG, + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG, + qm_fd_compound = QM_FD_FORMAT_COMPOUND +}; + +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd) +{ + return be64_to_cpu(fd->data) & 0xffffffffffLLU; +} + +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd) +{ + return be64_to_cpu(fd->data) & 0xffffffffffLLU; +} + +static inline void qm_fd_addr_set64(struct qm_fd *fd, u64 addr) +{ + fd->addr_hi = upper_32_bits(addr); + fd->addr_lo = cpu_to_be32(lower_32_bits(addr)); +} + +/* + * The 'format' field indicates the interpretation of the remaining + * 29 bits of the 32-bit word. + * If 'format' is _contig or _sg, 20b length and 9b offset. + * If 'format' is _contig_big or _sg_big, 29b length. + * If 'format' is _compound, 29b "congestion weight". + */ +static inline enum qm_fd_format qm_fd_get_format(const struct qm_fd *fd) +{ + return be32_to_cpu(fd->cfg) & QM_FD_FORMAT_MASK; +} + +static inline int qm_fd_get_offset(const struct qm_fd *fd) +{ + return (be32_to_cpu(fd->cfg) & QM_FD_OFF_MASK) >> QM_FD_OFF_SHIFT; +} + +static inline int qm_fd_get_length(const struct qm_fd *fd) +{ + return be32_to_cpu(fd->cfg) & QM_FD_LEN_MASK; +} + +static inline int qm_fd_get_len_big(const struct qm_fd *fd) +{ + return be32_to_cpu(fd->cfg) & QM_FD_LEN_BIG_MASK; +} + +static inline void qm_fd_set_param(struct qm_fd *fd, enum qm_fd_format fmt, + int off, int len) +{ + fd->cfg = cpu_to_be32(fmt | (len & QM_FD_LEN_BIG_MASK) | + ((off << QM_FD_OFF_SHIFT) & QM_FD_OFF_MASK)); +} + +#define qm_fd_set_contig(fd, off, len) \ + qm_fd_set_param(fd, qm_fd_contig, off, len) +#define qm_fd_set_sg(fd, off, len) qm_fd_set_param(fd, qm_fd_sg, off, len) +#define qm_fd_set_contig_big(fd, len) \ + qm_fd_set_param(fd, qm_fd_contig_big, 0, len) +#define qm_fd_set_sg_big(fd, len) qm_fd_set_param(fd, qm_fd_sg_big, 0, len) + +static inline void qm_fd_clear_fd(struct qm_fd *fd) +{ + fd->data = 0; + fd->cfg = 0; + fd->cmd = 0; +} + +/* Scatter/Gather table entry */ +struct qm_sg_entry { + union { + struct { + u8 __reserved1[3]; + u8 addr_hi; /* high 8-bits of 40-bit address */ + __be32 addr_lo; /* low 32-bits of 40-bit address */ + }; + __be64 data; + }; + __be32 cfg; /* E bit, F bit, length */ + u8 __reserved2; + u8 bpid; + __be16 offset; /* 13-bit, _res[13-15]*/ +} __packed; + +#define QM_SG_LEN_MASK GENMASK(29, 0) +#define QM_SG_OFF_MASK GENMASK(12, 0) +#define QM_SG_FIN BIT(30) +#define QM_SG_EXT BIT(31) + +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg) +{ + return be64_to_cpu(sg->data) & 0xffffffffffLLU; +} + +static inline u64 qm_sg_entry_get64(const struct qm_sg_entry *sg) +{ + return be64_to_cpu(sg->data) & 0xffffffffffLLU; +} + +static inline void qm_sg_entry_set64(struct qm_sg_entry *sg, u64 addr) +{ + sg->addr_hi = upper_32_bits(addr); + sg->addr_lo = cpu_to_be32(lower_32_bits(addr)); +} + +static inline bool qm_sg_entry_is_final(const struct qm_sg_entry *sg) +{ + return be32_to_cpu(sg->cfg) & QM_SG_FIN; +} + +static inline bool qm_sg_entry_is_ext(const struct qm_sg_entry *sg) +{ + return be32_to_cpu(sg->cfg) & QM_SG_EXT; +} + +static inline int qm_sg_entry_get_len(const struct qm_sg_entry *sg) +{ + return be32_to_cpu(sg->cfg) & QM_SG_LEN_MASK; +} + +static inline void qm_sg_entry_set_len(struct qm_sg_entry *sg, int len) +{ + sg->cfg = cpu_to_be32(len & QM_SG_LEN_MASK); +} + +static inline void qm_sg_entry_set_f(struct qm_sg_entry *sg, int len) +{ + sg->cfg = cpu_to_be32(QM_SG_FIN | (len & QM_SG_LEN_MASK)); +} + +static inline int qm_sg_entry_get_off(const struct qm_sg_entry *sg) +{ + return be32_to_cpu(sg->offset) & QM_SG_OFF_MASK; +} + +/* "Frame Dequeue Response" */ +struct qm_dqrr_entry { + u8 verb; + u8 stat; + u16 seqnum; /* 15-bit */ + u8 tok; + u8 __reserved2[3]; + u32 fqid; /* 24-bit */ + u32 contextB; + struct qm_fd fd; + u8 __reserved4[32]; +} __packed; +#define QM_DQRR_VERB_VBIT 0x80 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */ +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */ +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */ +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */ +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */ +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */ +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */ +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/ + +/* "ERN Message Response" */ +/* "FQ State Change Notification" */ +union qm_mr_entry { + struct { + u8 verb; + u8 __reserved[63]; + }; + struct { + u8 verb; + u8 dca; + u16 seqnum; + u8 rc; /* Rej Code: 8-bit */ + u8 orp_hi; /* ORP: 24-bit */ + u16 orp_lo; + u32 fqid; /* 24-bit */ + u32 tag; + struct qm_fd fd; + u8 __reserved1[32]; + } __packed ern; + struct { + u8 verb; + u8 fqs; /* Frame Queue Status */ + u8 __reserved1[6]; + u32 fqid; /* 24-bit */ + u32 contextB; + u8 __reserved2[48]; + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */ +}; +#define QM_MR_VERB_VBIT 0x80 +/* + * ERNs originating from direct-connect portals ("dcern") use 0x20 as a verb + * which would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished + * from the other MR types by noting if the 0x20 bit is unset. + */ +#define QM_MR_VERB_TYPE_MASK 0x27 +#define QM_MR_VERB_DC_ERN 0x20 +#define QM_MR_VERB_FQRN 0x21 +#define QM_MR_VERB_FQRNI 0x22 +#define QM_MR_VERB_FQRL 0x23 +#define QM_MR_VERB_FQPN 0x24 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */ +#define QM_MR_RC_CGR_TAILDROP 0x00 +#define QM_MR_RC_WRED 0x10 +#define QM_MR_RC_ERROR 0x20 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30 +#define QM_MR_RC_ORPWINDOW_LATE 0x40 +#define QM_MR_RC_FQ_TAILDROP 0x50 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60 +#define QM_MR_RC_ORP_ZERO 0x70 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */ +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */ + +/* + * An identical structure of FQD fields is present in the "Init FQ" command and + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type. + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the + * latter has two inlines to assist with converting to/from the mant+exp + * representation. + */ +struct qm_fqd_stashing { + /* See QM_STASHING_EXCL_<...> */ + u8 exclusive; + /* Numbers of cachelines */ + u8 cl; /* _res[6-7], as[4-5], ds[2-3], cs[0-1] */ +}; + +struct qm_fqd_oac { + /* "Overhead Accounting Control", see QM_OAC_<...> */ + u8 oac; /* oac[6-7], _res[0-5] */ + /* Two's-complement value (-128 to +127) */ + s8 oal; /* "Overhead Accounting Length" */ +}; + +struct qm_fqd { + /* _res[6-7], orprws[3-5], oa[2], olws[0-1] */ + u8 orpc; + u8 cgid; + __be16 fq_ctrl; /* See QM_FQCTRL_<...> */ + __be16 dest_wq; /* channel[3-15], wq[0-2] */ + __be16 ics_cred; /* 15-bit */ + /* + * For "Initialize Frame Queue" commands, the write-enable mask + * determines whether 'td' or 'oac_init' is observed. For query + * commands, this field is always 'td', and 'oac_query' (below) reflects + * the Overhead ACcounting values. + */ + union { + __be16 td; /* "Taildrop": _res[13-15], mant[5-12], exp[0-4] */ + struct qm_fqd_oac oac_init; + }; + __be32 context_b; + union { + /* Treat it as 64-bit opaque */ + __be64 opaque; + struct { + __be32 hi; + __be32 lo; + }; + /* Treat it as s/w portal stashing config */ + /* see "FQD Context_A field used for [...]" */ + struct { + struct qm_fqd_stashing stashing; + /* + * 48-bit address of FQ context to + * stash, must be cacheline-aligned + */ + __be16 context_hi; + __be32 context_lo; + } __packed; + } context_a; + struct qm_fqd_oac oac_query; +} __packed; + +#define QM_FQD_CHAN_OFF 3 +#define QM_FQD_WQ_MASK GENMASK(2, 0) +#define QM_FQD_TD_EXP_MASK GENMASK(4, 0) +#define QM_FQD_TD_MANT_OFF 5 +#define QM_FQD_TD_MANT_MASK GENMASK(12, 5) +#define QM_FQD_TD_MAX 0xe0000000 +#define QM_FQD_TD_MANT_MAX 0xff +#define QM_FQD_OAC_OFF 6 +#define QM_FQD_AS_OFF 4 +#define QM_FQD_DS_OFF 2 +#define QM_FQD_XS_MASK 0x3 + +/* 64-bit converters for context_hi/lo */ +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd) +{ + return be64_to_cpu(fqd->context_a.opaque) & 0xffffffffffffULL; +} + +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd) +{ + return be64_to_cpu(fqd->context_a.opaque) & 0xffffffffffffULL; +} + +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd) +{ + return qm_fqd_stashing_get64(fqd); +} + +static inline void qm_fqd_stashing_set64(struct qm_fqd *fqd, u64 addr) +{ + fqd->context_a.context_hi = upper_32_bits(addr); + fqd->context_a.context_lo = lower_32_bits(addr); +} + +static inline void qm_fqd_context_a_set64(struct qm_fqd *fqd, u64 addr) +{ + fqd->context_a.hi = cpu_to_be16(upper_32_bits(addr)); + fqd->context_a.lo = cpu_to_be32(lower_32_bits(addr)); +} + +/* convert a threshold value into mant+exp representation */ +static inline int qm_fqd_set_taildrop(struct qm_fqd *fqd, u32 val, + int roundup) +{ + u32 e = 0; + int td, oddbit = 0; + + if (val > QM_FQD_TD_MAX) + return -ERANGE; + + while (val > QM_FQD_TD_MANT_MAX) { + oddbit = val & 1; + val >>= 1; + e++; + if (roundup && oddbit) + val++; + } + + td = (val << QM_FQD_TD_MANT_OFF) & QM_FQD_TD_MANT_MASK; + td |= (e & QM_FQD_TD_EXP_MASK); + fqd->td = cpu_to_be16(td); + return 0; +} +/* and the other direction */ +static inline int qm_fqd_get_taildrop(const struct qm_fqd *fqd) +{ + int td = be16_to_cpu(fqd->td); + + return ((td & QM_FQD_TD_MANT_MASK) >> QM_FQD_TD_MANT_OFF) + << (td & QM_FQD_TD_EXP_MASK); +} + +static inline void qm_fqd_set_stashing(struct qm_fqd *fqd, u8 as, u8 ds, u8 cs) +{ + struct qm_fqd_stashing *st = &fqd->context_a.stashing; + + st->cl = ((as & QM_FQD_XS_MASK) << QM_FQD_AS_OFF) | + ((ds & QM_FQD_XS_MASK) << QM_FQD_DS_OFF) | + (cs & QM_FQD_XS_MASK); +} + +static inline u8 qm_fqd_get_stashing(const struct qm_fqd *fqd) +{ + return fqd->context_a.stashing.cl; +} + +static inline void qm_fqd_set_oac(struct qm_fqd *fqd, u8 val) +{ + fqd->oac_init.oac = val << QM_FQD_OAC_OFF; +} + +static inline void qm_fqd_set_oal(struct qm_fqd *fqd, s8 val) +{ + fqd->oac_init.oal = val; +} + +static inline void qm_fqd_set_destwq(struct qm_fqd *fqd, int ch, int wq) +{ + fqd->dest_wq = cpu_to_be16((ch << QM_FQD_CHAN_OFF) | + (wq & QM_FQD_WQ_MASK)); +} + +static inline int qm_fqd_get_chan(const struct qm_fqd *fqd) +{ + return be16_to_cpu(fqd->dest_wq) >> QM_FQD_CHAN_OFF; +} + +static inline int qm_fqd_get_wq(const struct qm_fqd *fqd) +{ + return be16_to_cpu(fqd->dest_wq) & QM_FQD_WQ_MASK; +} + +/* See "Frame Queue Descriptor (FQD)" */ +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */ +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */ +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */ +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */ +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */ +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */ +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */ +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */ +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */ +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */ +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */ + +/* See "FQD Context_A field used for [...] */ +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */ +#define QM_STASHING_EXCL_ANNOTATION 0x04 +#define QM_STASHING_EXCL_DATA 0x02 +#define QM_STASHING_EXCL_CTX 0x01 + +/* See "Intra Class Scheduling" */ +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */ +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */ +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */ + +/* + * This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields + * and associated commands/responses. The WRED parameters are calculated from + * these fields as follows; + * MaxTH = MA * (2 ^ Mn) + * Slope = SA / (2 ^ Sn) + * MaxP = 4 * (Pn + 1) + */ +struct qm_cgr_wr_parm { + /* MA[24-31], Mn[19-23], SA[12-18], Sn[6-11], Pn[0-5] */ + u32 word; +}; +/* + * This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding + * management commands, this is padded to a 16-bit structure field, so that's + * how we represent it here. The congestion state threshold is calculated from + * these fields as follows; + * CS threshold = TA * (2 ^ Tn) + */ +struct qm_cgr_cs_thres { + /* _res[13-15], TA[5-12], Tn[0-4] */ + u16 word; +}; +/* + * This identical structure of CGR fields is present in the "Init/Modify CGR" + * commands and the "Query CGR" result. It's suctioned out here into its own + * struct. + */ +struct __qm_mc_cgr { + struct qm_cgr_wr_parm wr_parm_g; + struct qm_cgr_wr_parm wr_parm_y; + struct qm_cgr_wr_parm wr_parm_r; + u8 wr_en_g; /* boolean, use QM_CGR_EN */ + u8 wr_en_y; /* boolean, use QM_CGR_EN */ + u8 wr_en_r; /* boolean, use QM_CGR_EN */ + u8 cscn_en; /* boolean, use QM_CGR_EN */ + union { + struct { + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */ + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */ + }; + u32 cscn_targ; /* use QM_CGR_TARG_* */ + }; + u8 cstd_en; /* boolean, use QM_CGR_EN */ + u8 cs; /* boolean, only used in query response */ + struct qm_cgr_cs_thres cs_thres; /* use qm_cgr_cs_thres_set64() */ + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */ +} __packed; +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */ +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/ +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */ +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */ +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */ +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */ +/* Convert CGR thresholds to/from "cs_thres" format */ +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th) +{ + return ((th->word >> 5) & 0xff) << (th->word & 0x1f); +} + +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val, + int roundup) +{ + u32 e = 0; + int oddbit = 0; + + while (val > 0xff) { + oddbit = val & 1; + val >>= 1; + e++; + if (roundup && oddbit) + val++; + } + th->word = ((val & 0xff) << 5) | (e & 0x1f); + return 0; +} + +/* "Initialize FQ" */ +struct qm_mcc_initfq { + u8 __reserved1[2]; + u16 we_mask; /* Write Enable Mask */ + u32 fqid; /* 24-bit */ + u16 count; /* Initialises 'count+1' FQDs */ + struct qm_fqd fqd; /* the FQD fields go here */ + u8 __reserved2[30]; +} __packed; +/* "Initialize/Modify CGR" */ +struct qm_mcc_initcgr { + u8 __reserve1[2]; + u16 we_mask; /* Write Enable Mask */ + struct __qm_mc_cgr cgr; /* CGR fields */ + u8 __reserved2[2]; + u8 cgid; + u8 __reserved3[32]; +} __packed; + +/* INITFQ-specific flags */ +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */ +#define QM_INITFQ_WE_OAC 0x0100 +#define QM_INITFQ_WE_ORPC 0x0080 +#define QM_INITFQ_WE_CGID 0x0040 +#define QM_INITFQ_WE_FQCTRL 0x0020 +#define QM_INITFQ_WE_DESTWQ 0x0010 +#define QM_INITFQ_WE_ICSCRED 0x0008 +#define QM_INITFQ_WE_TDTHRESH 0x0004 +#define QM_INITFQ_WE_CONTEXTB 0x0002 +#define QM_INITFQ_WE_CONTEXTA 0x0001 +/* INITCGR/MODIFYCGR-specific flags */ +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */ +#define QM_CGR_WE_WR_PARM_G 0x0400 +#define QM_CGR_WE_WR_PARM_Y 0x0200 +#define QM_CGR_WE_WR_PARM_R 0x0100 +#define QM_CGR_WE_WR_EN_G 0x0080 +#define QM_CGR_WE_WR_EN_Y 0x0040 +#define QM_CGR_WE_WR_EN_R 0x0020 +#define QM_CGR_WE_CSCN_EN 0x0010 +#define QM_CGR_WE_CSCN_TARG 0x0008 +#define QM_CGR_WE_CSTD_EN 0x0004 +#define QM_CGR_WE_CS_THRES 0x0002 +#define QM_CGR_WE_MODE 0x0001 + +#define QMAN_CGR_FLAG_USE_INIT 0x00000001 + + /* Portal and Frame Queues */ +/* Represents a managed portal */ +struct qman_portal; + +/* + * This object type represents QMan frame queue descriptors (FQD), it is + * cacheline-aligned, and initialised by qman_create_fq(). The structure is + * defined further down. + */ +struct qman_fq; + +/* + * This object type represents a QMan congestion group, it is defined further + * down. + */ +struct qman_cgr; + +/* + * This enum, and the callback type that returns it, are used when handling + * dequeued frames via DQRR. Note that for "null" callbacks registered with the + * portal object (for handling dequeues that do not demux because contextB is + * NULL), the return value *MUST* be qman_cb_dqrr_consume. + */ +enum qman_cb_dqrr_result { + /* DQRR entry can be consumed */ + qman_cb_dqrr_consume, + /* Like _consume, but requests parking - FQ must be held-active */ + qman_cb_dqrr_park, + /* Does not consume, for DCA mode only. */ + qman_cb_dqrr_defer, + /* + * Stop processing without consuming this ring entry. Exits the current + * qman_p_poll_dqrr() or interrupt-handling, as appropriate. If within + * an interrupt handler, the callback would typically call + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value, + * otherwise the interrupt will reassert immediately. + */ + qman_cb_dqrr_stop, + /* Like qman_cb_dqrr_stop, but consumes the current entry. */ + qman_cb_dqrr_consume_stop +}; +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm, + struct qman_fq *fq, + const struct qm_dqrr_entry *dqrr); + +/* + * This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They + * are always consumed after the callback returns. + */ +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq, + const union qm_mr_entry *msg); + +/* + * s/w-visible states. Ie. tentatively scheduled + truly scheduled + active + + * held-active + held-suspended are just "sched". Things like "retired" will not + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until + * then, to indicate it's completing and to gate attempts to retry the retire + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring + * index rather than the FQ that ring entry corresponds to), so repeated park + * commands are allowed (if you're silly enough to try) but won't change FQ + * state, and the resulting park notifications move FQs from "sched" to + * "parked". + */ +enum qman_fq_state { + qman_fq_state_oos, + qman_fq_state_parked, + qman_fq_state_sched, + qman_fq_state_retired +}; + +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */ +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */ +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */ +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */ +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */ +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */ + +/* + * Frame queue objects (struct qman_fq) are stored within memory passed to + * qman_create_fq(), as this allows stashing of caller-provided demux callback + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing, + * they should; + * + * (a) extend the qman_fq structure with their state; eg. + * + * // myfq is allocated and driver_fq callbacks filled in; + * struct my_fq { + * struct qman_fq base; + * int an_extra_field; + * [ ... add other fields to be associated with each FQ ...] + * } *myfq = some_my_fq_allocator(); + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base); + * + * // in a dequeue callback, access extra fields from 'fq' via a cast; + * struct my_fq *myfq = (struct my_fq *)fq; + * do_something_with(myfq->an_extra_field); + * [...] + * + * (b) when and if configuring the FQ for context stashing, specify how ever + * many cachelines are required to stash 'struct my_fq', to accelerate not + * only the QMan driver but the callback as well. + */ + +struct qman_fq_cb { + qman_cb_dqrr dqrr; /* for dequeued frames */ + qman_cb_mr ern; /* for s/w ERNs */ + qman_cb_mr fqs; /* frame-queue state changes*/ +}; + +struct qman_fq { + /* Caller of qman_create_fq() provides these demux callbacks */ + struct qman_fq_cb cb; + /* + * These are internal to the driver, don't touch. In particular, they + * may change, be removed, or extended (so you shouldn't rely on + * sizeof(qman_fq) being a constant). + */ + u32 fqid, idx; + unsigned long flags; + enum qman_fq_state state; + int cgr_groupid; +}; + +/* + * This callback type is used when handling congestion group entry/exit. + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. + */ +typedef void (*qman_cb_cgr)(struct qman_portal *qm, + struct qman_cgr *cgr, int congested); + +struct qman_cgr { + /* Set these prior to qman_create_cgr() */ + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/ + qman_cb_cgr cb; + /* These are private to the driver */ + u16 chan; /* portal channel this object is created on */ + struct list_head node; +}; + +/* Flags to qman_create_fq() */ +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */ +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */ +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */ +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */ + +/* Flags to qman_init_fq() */ +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */ +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */ + + /* Portal Management */ +/** + * qman_p_irqsource_add - add processing sources to be interrupt-driven + * @bits: bitmask of QM_PIRQ_**I processing sources + * + * Adds processing sources that should be interrupt-driven (rather than + * processed via qman_poll_***() functions). + */ +void qman_p_irqsource_add(struct qman_portal *p, u32 bits); + +/** + * qman_p_irqsource_remove - remove processing sources from being int-driven + * @bits: bitmask of QM_PIRQ_**I processing sources + * + * Removes processing sources from being interrupt-driven, so that they will + * instead be processed via qman_poll_***() functions. + */ +void qman_p_irqsource_remove(struct qman_portal *p, u32 bits); + +/** + * qman_affine_cpus - return a mask of cpus that have affine portals + */ +const cpumask_t *qman_affine_cpus(void); + +/** + * qman_affine_channel - return the channel ID of an portal + * @cpu: the cpu whose affine portal is the subject of the query + * + * If @cpu is -1, the affine portal for the current CPU will be used. It is a + * bug to call this function for any value of @cpu (other than -1) that is not a + * member of the mask returned from qman_affine_cpus(). + */ +u16 qman_affine_channel(int cpu); + +/** + * qman_get_affine_portal - return the portal pointer affine to cpu + * @cpu: the cpu whose affine portal is the subject of the query + */ +struct qman_portal *qman_get_affine_portal(int cpu); + +/** + * qman_p_poll_dqrr - process DQRR (fast-path) entries + * @limit: the maximum number of DQRR entries to process + * + * Use of this function requires that DQRR processing not be interrupt-driven. + * The return value represents the number of DQRR entries processed. + */ +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit); + +/** + * qman_p_static_dequeue_add - Add pool channels to the portal SDQCR + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n) + * + * Adds a set of pool channels to the portal's static dequeue command register + * (SDQCR). The requested pools are limited to those the portal has dequeue + * access to. + */ +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools); + + /* FQ management */ +/** + * qman_create_fq - Allocates a FQ + * @fqid: the index of the FQD to encapsulate, must be "Out of Service" + * @flags: bit-mask of QMAN_FQ_FLAG_*** options + * @fq: memory for storing the 'fq', with callbacks filled in + * + * Creates a frame queue object for the given @fqid, unless the + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is + * dynamically allocated (or the function fails if none are available). Once + * created, the caller should not touch the memory at 'fq' except as extended to + * adjacent memory for user-defined fields (see the definition of "struct + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to + * pre-existing frame-queues that aren't to be otherwise interfered with, it + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag + * causes the driver to honour any contextB modifications requested in the + * qm_init_fq() API, as this indicates the frame queue will be consumed by a + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by + * software portals, the contextB field is controlled by the driver and can't be + * modified by the caller. + */ +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq); + +/** + * qman_destroy_fq - Deallocates a FQ + * @fq: the frame queue object to release + * + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is + * not deallocated but the caller regains ownership, to do with as desired. The + * FQ must be in the 'out-of-service' or in the 'parked' state. + */ +void qman_destroy_fq(struct qman_fq *fq); + +/** + * qman_fq_fqid - Queries the frame queue ID of a FQ object + * @fq: the frame queue object to query + */ +u32 qman_fq_fqid(struct qman_fq *fq); + +/** + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled" + * @fq: the frame queue object to modify, must be 'parked' or new. + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options + * @opts: the FQ-modification settings, as defined in the low-level API + * + * The @opts parameter comes from the low-level portal API. Select + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled + * rather than parked. NB, @opts can be NULL. + * + * Note that some fields and options within @opts may be ignored or overwritten + * by the driver; + * 1. the 'count' and 'fqid' fields are always ignored (this operation only + * affects one frame queue: @fq). + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated + * 'fqd' structure's 'context_b' field are sometimes overwritten; + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is + * initialised to a value used by the driver for demux. + * - if context_b is initialised for demux, so is context_a in case stashing + * is requested (see item 4). + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue + * objects.) + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's + * 'dest::channel' field will be overwritten to match the portal used to issue + * the command. If the WE_DESTWQ write-enable bit had already been set by the + * caller, the channel workqueue will be left as-is, otherwise the write-enable + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag + * isn't set, the destination channel/workqueue fields and the write-enable bit + * are left as-is. + * 4. if the driver overwrites context_a/b for demux, then if + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite + * context_a.address fields and will leave the stashing fields provided by the + * user alone, otherwise it will zero out the context_a.stashing fields. + */ +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts); + +/** + * qman_schedule_fq - Schedules a FQ + * @fq: the frame queue object to schedule, must be 'parked' + * + * Schedules the frame queue, which must be Parked, which takes it to + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level. + */ +int qman_schedule_fq(struct qman_fq *fq); + +/** + * qman_retire_fq - Retires a FQ + * @fq: the frame queue object to retire + * @flags: FQ flags (QMAN_FQ_STATE*) if retirement completes immediately + * + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if + * the retirement was started asynchronously, otherwise it returns negative for + * failure. When this function returns zero, @flags is set to indicate whether + * the retired FQ is empty and/or whether it has any ORL fragments (to show up + * as ERNs). Otherwise the corresponding flags will be known when a subsequent + * FQRN message shows up on the portal's message ring. + * + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or + * Active state), the completion will be via the message ring as a FQRN - but + * the corresponding callback may occur before this function returns!! Ie. the + * caller should be prepared to accept the callback as the function is called, + * not only once it has returned. + */ +int qman_retire_fq(struct qman_fq *fq, u32 *flags); + +/** + * qman_oos_fq - Puts a FQ "out of service" + * @fq: the frame queue object to be put out-of-service, must be 'retired' + * + * The frame queue must be retired and empty, and if any order restoration list + * was released as ERNs at the time of retirement, they must all be consumed. + */ +int qman_oos_fq(struct qman_fq *fq); + +/** + * qman_enqueue - Enqueue a frame to a frame queue + * @fq: the frame queue object to enqueue to + * @fd: a descriptor of the frame to be enqueued + * + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid' + * field is ignored. The return value is non-zero on error, such as ring full. + */ +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd); + +/** + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs + * @result: is set by the API to the base FQID of the allocated range + * @count: the number of FQIDs required + * + * Returns 0 on success, or a negative error code. + */ +int qman_alloc_fqid_range(u32 *result, u32 count); +#define qman_alloc_fqid(result) qman_alloc_fqid_range(result, 1) + +/** + * qman_release_fqid - Release the specified frame queue ID + * @fqid: the FQID to be released back to the resource pool + * + * This function can also be used to seed the allocator with + * FQID ranges that it can subsequently allocate from. + * Returns 0 on success, or a negative error code. + */ +int qman_release_fqid(u32 fqid); + + /* Pool-channel management */ +/** + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs + * @result: is set by the API to the base pool-channel ID of the allocated range + * @count: the number of pool-channel IDs required + * + * Returns 0 on success, or a negative error code. + */ +int qman_alloc_pool_range(u32 *result, u32 count); +#define qman_alloc_pool(result) qman_alloc_pool_range(result, 1) + +/** + * qman_release_pool - Release the specified pool-channel ID + * @id: the pool-chan ID to be released back to the resource pool + * + * This function can also be used to seed the allocator with + * pool-channel ID ranges that it can subsequently allocate from. + * Returns 0 on success, or a negative error code. + */ +int qman_release_pool(u32 id); + + /* CGR management */ +/** + * qman_create_cgr - Register a congestion group object + * @cgr: the 'cgr' object, with fields filled in + * @flags: QMAN_CGR_FLAG_* values + * @opts: optional state of CGR settings + * + * Registers this object to receiving congestion entry/exit callbacks on the + * portal affine to the cpu portal on which this API is executed. If opts is + * NULL then only the callback (cgr->cb) function is registered. If @flags + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset + * any unspecified parameters) will be used rather than a modify hw hardware + * (which only modifies the specified parameters). + */ +int qman_create_cgr(struct qman_cgr *cgr, u32 flags, + struct qm_mcc_initcgr *opts); + +/** + * qman_delete_cgr - Deregisters a congestion group object + * @cgr: the 'cgr' object to deregister + * + * "Unplugs" this CGR object from the portal affine to the cpu on which this API + * is executed. This must be excuted on the same affine portal on which it was + * created. + */ +int qman_delete_cgr(struct qman_cgr *cgr); + +/** + * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU + * @cgr: the 'cgr' object to deregister + * + * This will select the proper CPU and run there qman_delete_cgr(). + */ +void qman_delete_cgr_safe(struct qman_cgr *cgr); + +/** + * qman_query_cgr_congested - Queries CGR's congestion status + * @cgr: the 'cgr' object to query + * @result: returns 'cgr's congestion status, 1 (true) if congested + */ +int qman_query_cgr_congested(struct qman_cgr *cgr, bool *result); + +/** + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs + * @result: is set by the API to the base CGR ID of the allocated range + * @count: the number of CGR IDs required + * + * Returns 0 on success, or a negative error code. + */ +int qman_alloc_cgrid_range(u32 *result, u32 count); +#define qman_alloc_cgrid(result) qman_alloc_cgrid_range(result, 1) + +/** + * qman_release_cgrid - Release the specified CGR ID + * @id: the CGR ID to be released back to the resource pool + * + * This function can also be used to seed the allocator with + * CGR ID ranges that it can subsequently allocate from. + * Returns 0 on success, or a negative error code. + */ +int qman_release_cgrid(u32 id); + +#endif /* __FSL_QMAN_H */ diff --git a/include/trace/events/cgroup.h b/include/trace/events/cgroup.h new file mode 100644 index 000000000000..ab68640a18d0 --- /dev/null +++ b/include/trace/events/cgroup.h @@ -0,0 +1,163 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM cgroup + +#if !defined(_TRACE_CGROUP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_CGROUP_H + +#include <linux/cgroup.h> +#include <linux/tracepoint.h> + +DECLARE_EVENT_CLASS(cgroup_root, + + TP_PROTO(struct cgroup_root *root), + + TP_ARGS(root), + + TP_STRUCT__entry( + __field( int, root ) + __field( u16, ss_mask ) + __string( name, root->name ) + ), + + TP_fast_assign( + __entry->root = root->hierarchy_id; + __entry->ss_mask = root->subsys_mask; + __assign_str(name, root->name); + ), + + TP_printk("root=%d ss_mask=%#x name=%s", + __entry->root, __entry->ss_mask, __get_str(name)) +); + +DEFINE_EVENT(cgroup_root, cgroup_setup_root, + + TP_PROTO(struct cgroup_root *root), + + TP_ARGS(root) +); + +DEFINE_EVENT(cgroup_root, cgroup_destroy_root, + + TP_PROTO(struct cgroup_root *root), + + TP_ARGS(root) +); + +DEFINE_EVENT(cgroup_root, cgroup_remount, + + TP_PROTO(struct cgroup_root *root), + + TP_ARGS(root) +); + +DECLARE_EVENT_CLASS(cgroup, + + TP_PROTO(struct cgroup *cgrp), + + TP_ARGS(cgrp), + + TP_STRUCT__entry( + __field( int, root ) + __field( int, id ) + __field( int, level ) + __dynamic_array(char, path, + cgrp->kn ? cgroup_path(cgrp, NULL, 0) + 1 + : strlen("(null)")) + ), + + TP_fast_assign( + __entry->root = cgrp->root->hierarchy_id; + __entry->id = cgrp->id; + __entry->level = cgrp->level; + if (cgrp->kn) + cgroup_path(cgrp, __get_dynamic_array(path), + __get_dynamic_array_len(path)); + else + __assign_str(path, "(null)"); + ), + + TP_printk("root=%d id=%d level=%d path=%s", + __entry->root, __entry->id, __entry->level, __get_str(path)) +); + +DEFINE_EVENT(cgroup, cgroup_mkdir, + + TP_PROTO(struct cgroup *cgroup), + + TP_ARGS(cgroup) +); + +DEFINE_EVENT(cgroup, cgroup_rmdir, + + TP_PROTO(struct cgroup *cgroup), + + TP_ARGS(cgroup) +); + +DEFINE_EVENT(cgroup, cgroup_release, + + TP_PROTO(struct cgroup *cgroup), + + TP_ARGS(cgroup) +); + +DEFINE_EVENT(cgroup, cgroup_rename, + + TP_PROTO(struct cgroup *cgroup), + + TP_ARGS(cgroup) +); + +DECLARE_EVENT_CLASS(cgroup_migrate, + + TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup), + + TP_ARGS(dst_cgrp, task, threadgroup), + + TP_STRUCT__entry( + __field( int, dst_root ) + __field( int, dst_id ) + __field( int, dst_level ) + __dynamic_array(char, dst_path, + dst_cgrp->kn ? cgroup_path(dst_cgrp, NULL, 0) + 1 + : strlen("(null)")) + __field( int, pid ) + __string( comm, task->comm ) + ), + + TP_fast_assign( + __entry->dst_root = dst_cgrp->root->hierarchy_id; + __entry->dst_id = dst_cgrp->id; + __entry->dst_level = dst_cgrp->level; + if (dst_cgrp->kn) + cgroup_path(dst_cgrp, __get_dynamic_array(dst_path), + __get_dynamic_array_len(dst_path)); + else + __assign_str(dst_path, "(null)"); + __entry->pid = task->pid; + __assign_str(comm, task->comm); + ), + + TP_printk("dst_root=%d dst_id=%d dst_level=%d dst_path=%s pid=%d comm=%s", + __entry->dst_root, __entry->dst_id, __entry->dst_level, + __get_str(dst_path), __entry->pid, __get_str(comm)) +); + +DEFINE_EVENT(cgroup_migrate, cgroup_attach_task, + + TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup), + + TP_ARGS(dst_cgrp, task, threadgroup) +); + +DEFINE_EVENT(cgroup_migrate, cgroup_transfer_tasks, + + TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup), + + TP_ARGS(dst_cgrp, task, threadgroup) +); + +#endif /* _TRACE_CGROUP_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/include/uapi/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h index 58274382a616..8c27db0c5c08 100644 --- a/include/uapi/asm-generic/mman-common.h +++ b/include/uapi/asm-generic/mman-common.h @@ -72,4 +72,9 @@ #define MAP_HUGE_SHIFT 26 #define MAP_HUGE_MASK 0x3f +#define PKEY_DISABLE_ACCESS 0x1 +#define PKEY_DISABLE_WRITE 0x2 +#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ + PKEY_DISABLE_WRITE) + #endif /* __ASM_GENERIC_MMAN_COMMON_H */ diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index a26415b5151c..9b1462e38b82 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -724,9 +724,15 @@ __SYSCALL(__NR_copy_file_range, sys_copy_file_range) __SC_COMP(__NR_preadv2, sys_preadv2, compat_sys_preadv2) #define __NR_pwritev2 287 __SC_COMP(__NR_pwritev2, sys_pwritev2, compat_sys_pwritev2) +#define __NR_pkey_mprotect 288 +__SYSCALL(__NR_pkey_mprotect, sys_pkey_mprotect) +#define __NR_pkey_alloc 289 +__SYSCALL(__NR_pkey_alloc, sys_pkey_alloc) +#define __NR_pkey_free 290 +__SYSCALL(__NR_pkey_free, sys_pkey_free) #undef __NR_syscalls -#define __NR_syscalls 288 +#define __NR_syscalls 291 /* * All syscalls below here should go away really, diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 462246aa200e..d6b5a21f3d3c 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -77,6 +77,10 @@ extern "C" { #define AMDGPU_GEM_CREATE_NO_CPU_ACCESS (1 << 1) /* Flag that USWC attributes should be used for GTT */ #define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2) +/* Flag that the memory should be in VRAM and cleared */ +#define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3) +/* Flag that create shadow bo(GTT) while allocating vram bo */ +#define AMDGPU_GEM_CREATE_SHADOW (1 << 4) struct drm_amdgpu_gem_create_in { /** the requested memory size */ @@ -481,6 +485,8 @@ struct drm_amdgpu_cs_chunk_data { #define AMDGPU_INFO_DEV_INFO 0x16 /* visible vram usage */ #define AMDGPU_INFO_VIS_VRAM_USAGE 0x17 +/* number of TTM buffer evictions */ +#define AMDGPU_INFO_NUM_EVICTIONS 0x18 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff @@ -643,6 +649,7 @@ struct drm_amdgpu_info_hw_ip { * Supported GPU families */ #define AMDGPU_FAMILY_UNKNOWN 0 +#define AMDGPU_FAMILY_SI 110 /* Hainan, Oland, Verde, Pitcairn, Tahiti */ #define AMDGPU_FAMILY_CI 120 /* Bonaire, Hawaii */ #define AMDGPU_FAMILY_KV 125 /* Kaveri, Kabini, Mullins */ #define AMDGPU_FAMILY_VI 130 /* Iceland, Tonga */ diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 452675fb55d9..b2c52843bc70 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -646,6 +646,7 @@ struct drm_gem_open { #define DRM_CAP_CURSOR_WIDTH 0x8 #define DRM_CAP_CURSOR_HEIGHT 0x9 #define DRM_CAP_ADDFB2_MODIFIERS 0x10 +#define DRM_CAP_PAGE_FLIP_TARGET 0x11 /** DRM_IOCTL_GET_CAP ioctl argument type */ struct drm_get_cap { diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 49a72659b801..df0e3504c349 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -520,7 +520,13 @@ struct drm_color_lut { #define DRM_MODE_PAGE_FLIP_EVENT 0x01 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02 -#define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT|DRM_MODE_PAGE_FLIP_ASYNC) +#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4 +#define DRM_MODE_PAGE_FLIP_TARGET_RELATIVE 0x8 +#define DRM_MODE_PAGE_FLIP_TARGET (DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE | \ + DRM_MODE_PAGE_FLIP_TARGET_RELATIVE) +#define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | \ + DRM_MODE_PAGE_FLIP_ASYNC | \ + DRM_MODE_PAGE_FLIP_TARGET) /* * Request a page flip on the specified crtc. @@ -543,8 +549,7 @@ struct drm_color_lut { * 'as soon as possible', meaning that it not delay waiting for vblank. * This may cause tearing on the screen. * - * The reserved field must be zero until we figure out something - * clever to use it for. + * The reserved field must be zero. */ struct drm_mode_crtc_page_flip { @@ -555,6 +560,34 @@ struct drm_mode_crtc_page_flip { __u64 user_data; }; +/* + * Request a page flip on the specified crtc. + * + * Same as struct drm_mode_crtc_page_flip, but supports new flags and + * re-purposes the reserved field: + * + * The sequence field must be zero unless either of the + * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is specified. When + * the ABSOLUTE flag is specified, the sequence field denotes the absolute + * vblank sequence when the flip should take effect. When the RELATIVE + * flag is specified, the sequence field denotes the relative (to the + * current one when the ioctl is called) vblank sequence when the flip + * should take effect. NOTE: DRM_IOCTL_WAIT_VBLANK must still be used to + * make sure the vblank sequence before the target one has passed before + * calling this ioctl. The purpose of the + * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is merely to clarify + * the target for when code dealing with a page flip runs during a + * vertical blank period. + */ + +struct drm_mode_crtc_page_flip_target { + __u32 crtc_id; + __u32 fb_id; + __u32 flags; + __u32 sequence; + __u64 user_data; +}; + /* create a dumb scanout buffer */ struct drm_mode_create_dumb { __u32 height; diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index d7e81a3886fd..03725fe89859 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -62,6 +62,30 @@ extern "C" { #define I915_ERROR_UEVENT "ERROR" #define I915_RESET_UEVENT "RESET" +/* + * MOCS indexes used for GPU surfaces, defining the cacheability of the + * surface data and the coherency for this data wrt. CPU vs. GPU accesses. + */ +enum i915_mocs_table_index { + /* + * Not cached anywhere, coherency between CPU and GPU accesses is + * guaranteed. + */ + I915_MOCS_UNCACHED, + /* + * Cacheability and coherency controlled by the kernel automatically + * based on the DRM_I915_GEM_SET_CACHING IOCTL setting and the current + * usage of the surface (used for display scanout or not). + */ + I915_MOCS_PTE, + /* + * Cached in all GPU caches available on the platform. + * Coherency between CPU and GPU accesses to the surface is not + * guaranteed without extra synchronization. + */ + I915_MOCS_CACHED, +}; + /* Each region is a minimum of 16k, and there are at most 255 of them. */ #define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use @@ -363,6 +387,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_EXEC_SOFTPIN 37 #define I915_PARAM_HAS_POOLED_EU 38 #define I915_PARAM_MIN_EU_IN_POOL 39 +#define I915_PARAM_MMAP_GTT_VERSION 40 typedef struct drm_i915_getparam { __s32 param; @@ -698,15 +723,20 @@ struct drm_i915_gem_exec_object2 { */ __u64 offset; -#define EXEC_OBJECT_NEEDS_FENCE (1<<0) -#define EXEC_OBJECT_NEEDS_GTT (1<<1) -#define EXEC_OBJECT_WRITE (1<<2) +#define EXEC_OBJECT_NEEDS_FENCE (1<<0) +#define EXEC_OBJECT_NEEDS_GTT (1<<1) +#define EXEC_OBJECT_WRITE (1<<2) #define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3) -#define EXEC_OBJECT_PINNED (1<<4) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define EXEC_OBJECT_PAD_TO_SIZE (1<<5) +/* All remaining bits are MBZ and RESERVED FOR FUTURE USE */ +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PAD_TO_SIZE<<1) __u64 flags; - __u64 rsvd1; + union { + __u64 rsvd1; + __u64 pad_to_size; + }; __u64 rsvd2; }; @@ -826,7 +856,16 @@ struct drm_i915_gem_busy { * having flushed any pending activity), and a non-zero return that * the object is still in-flight on the GPU. (The GPU has not yet * signaled completion for all pending requests that reference the - * object.) + * object.) An object is guaranteed to become idle eventually (so + * long as no new GPU commands are executed upon it). Due to the + * asynchronous nature of the hardware, an object reported + * as busy may become idle before the ioctl is completed. + * + * Furthermore, if the object is busy, which engine is busy is only + * provided as a guide. There are race conditions which prevent the + * report of which engines are busy from being always accurate. + * However, the converse is not true. If the object is idle, the + * result of the ioctl, that all engines are idle, is accurate. * * The returned dword is split into two fields to indicate both * the engines on which the object is being read, and the @@ -849,6 +888,11 @@ struct drm_i915_gem_busy { * execution engines, e.g. multiple media engines, which are * mapped to the same identifier in the EXECBUFFER2 ioctl and * so are not separately reported for busyness. + * + * Caveat emptor: + * Only the boolean result of this query is reliable; that is whether + * the object is idle or busy. The report of which engines are busy + * should be only used as a heuristic. */ __u32 busy; }; @@ -897,6 +941,7 @@ struct drm_i915_gem_caching { #define I915_TILING_NONE 0 #define I915_TILING_X 1 #define I915_TILING_Y 2 +#define I915_TILING_LAST I915_TILING_Y #define I915_BIT_6_SWIZZLE_NONE 0 #define I915_BIT_6_SWIZZLE_9 1 diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index 49f778de8e06..8c51e8a0df89 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -42,6 +42,15 @@ extern "C" { #define MSM_PIPE_2D1 0x02 #define MSM_PIPE_3D0 0x10 +/* The pipe-id just uses the lower bits, so can be OR'd with flags in + * the upper 16 bits (which could be extended further, if needed, maybe + * we extend/overload the pipe-id some day to deal with multiple rings, + * but even then I don't think we need the full lower 16 bits). + */ +#define MSM_PIPE_ID_MASK 0xffff +#define MSM_PIPE_ID(x) ((x) & MSM_PIPE_ID_MASK) +#define MSM_PIPE_FLAGS(x) ((x) & ~MSM_PIPE_ID_MASK) + /* timeouts are specified in clock-monotonic absolute times (to simplify * restarting interrupted ioctls). The following struct is logically the * same as 'struct timespec' but 32/64b ABI safe. @@ -175,17 +184,28 @@ struct drm_msm_gem_submit_bo { __u64 presumed; /* in/out, presumed buffer address */ }; +/* Valid submit ioctl flags: */ +#define MSM_SUBMIT_NO_IMPLICIT 0x80000000 /* disable implicit sync */ +#define MSM_SUBMIT_FENCE_FD_IN 0x40000000 /* enable input fence_fd */ +#define MSM_SUBMIT_FENCE_FD_OUT 0x20000000 /* enable output fence_fd */ +#define MSM_SUBMIT_FLAGS ( \ + MSM_SUBMIT_NO_IMPLICIT | \ + MSM_SUBMIT_FENCE_FD_IN | \ + MSM_SUBMIT_FENCE_FD_OUT | \ + 0) + /* Each cmdstream submit consists of a table of buffers involved, and * one or more cmdstream buffers. This allows for conditional execution * (context-restore), and IB buffers needed for per tile/bin draw cmds. */ struct drm_msm_gem_submit { - __u32 pipe; /* in, MSM_PIPE_x */ + __u32 flags; /* MSM_PIPE_x | MSM_SUBMIT_x */ __u32 fence; /* out */ __u32 nr_bos; /* in, number of submit_bo's */ __u32 nr_cmds; /* in, number of submit_cmd's */ __u64 __user bos; /* in, ptr to array of submit_bo's */ __u64 __user cmds; /* in, ptr to array of submit_cmd's */ + __s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */ }; /* The normal way to synchronize with the GPU is just to CPU_PREP on diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index d0352a971ebd..6965d0909554 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -336,6 +336,8 @@ header-y += pkt_cls.h header-y += pkt_sched.h header-y += pmu.h header-y += poll.h +header-y += posix_acl.h +header-y += posix_acl_xattr.h header-y += posix_types.h header-y += ppdev.h header-y += ppp-comp.h @@ -397,6 +399,7 @@ header-y += string.h header-y += suspend_ioctls.h header-y += swab.h header-y += synclink.h +header-y += sync_file.h header-y += sysctl.h header-y += sysinfo.h header-y += target_core_user.h diff --git a/include/uapi/linux/auto_dev-ioctl.h b/include/uapi/linux/auto_dev-ioctl.h new file mode 100644 index 000000000000..021ed331dd71 --- /dev/null +++ b/include/uapi/linux/auto_dev-ioctl.h @@ -0,0 +1,221 @@ +/* + * Copyright 2008 Red Hat, Inc. All rights reserved. + * Copyright 2008 Ian Kent <raven@themaw.net> + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + */ + +#ifndef _UAPI_LINUX_AUTO_DEV_IOCTL_H +#define _UAPI_LINUX_AUTO_DEV_IOCTL_H + +#include <linux/auto_fs.h> +#include <linux/string.h> + +#define AUTOFS_DEVICE_NAME "autofs" + +#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1 +#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0 + +#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl) + +/* + * An ioctl interface for autofs mount point control. + */ + +struct args_protover { + __u32 version; +}; + +struct args_protosubver { + __u32 sub_version; +}; + +struct args_openmount { + __u32 devid; +}; + +struct args_ready { + __u32 token; +}; + +struct args_fail { + __u32 token; + __s32 status; +}; + +struct args_setpipefd { + __s32 pipefd; +}; + +struct args_timeout { + __u64 timeout; +}; + +struct args_requester { + __u32 uid; + __u32 gid; +}; + +struct args_expire { + __u32 how; +}; + +struct args_askumount { + __u32 may_umount; +}; + +struct args_ismountpoint { + union { + struct args_in { + __u32 type; + } in; + struct args_out { + __u32 devid; + __u32 magic; + } out; + }; +}; + +/* + * All the ioctls use this structure. + * When sending a path size must account for the total length + * of the chunk of memory otherwise is is the size of the + * structure. + */ + +struct autofs_dev_ioctl { + __u32 ver_major; + __u32 ver_minor; + __u32 size; /* total size of data passed in + * including this struct */ + __s32 ioctlfd; /* automount command fd */ + + /* Command parameters */ + + union { + struct args_protover protover; + struct args_protosubver protosubver; + struct args_openmount openmount; + struct args_ready ready; + struct args_fail fail; + struct args_setpipefd setpipefd; + struct args_timeout timeout; + struct args_requester requester; + struct args_expire expire; + struct args_askumount askumount; + struct args_ismountpoint ismountpoint; + }; + + char path[0]; +}; + +static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) +{ + memset(in, 0, sizeof(struct autofs_dev_ioctl)); + in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; + in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; + in->size = sizeof(struct autofs_dev_ioctl); + in->ioctlfd = -1; +} + +/* + * If you change this make sure you make the corresponding change + * to autofs-dev-ioctl.c:lookup_ioctl() + */ +enum { + /* Get various version info */ + AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71, + AUTOFS_DEV_IOCTL_PROTOVER_CMD, + AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, + + /* Open mount ioctl fd */ + AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, + + /* Close mount ioctl fd */ + AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, + + /* Mount/expire status returns */ + AUTOFS_DEV_IOCTL_READY_CMD, + AUTOFS_DEV_IOCTL_FAIL_CMD, + + /* Activate/deactivate autofs mount */ + AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, + AUTOFS_DEV_IOCTL_CATATONIC_CMD, + + /* Expiry timeout */ + AUTOFS_DEV_IOCTL_TIMEOUT_CMD, + + /* Get mount last requesting uid and gid */ + AUTOFS_DEV_IOCTL_REQUESTER_CMD, + + /* Check for eligible expire candidates */ + AUTOFS_DEV_IOCTL_EXPIRE_CMD, + + /* Request busy status */ + AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, + + /* Check if path is a mountpoint */ + AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, +}; + +#define AUTOFS_IOCTL 0x93 + +#define AUTOFS_DEV_IOCTL_VERSION \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_PROTOVER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_PROTOSUBVER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_OPENMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_READY \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_FAIL \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_SETPIPEFD \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_CATATONIC \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_TIMEOUT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_REQUESTER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_EXPIRE \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_ASKUMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl) + +#endif /* _UAPI_LINUX_AUTO_DEV_IOCTL_H */ diff --git a/include/uapi/linux/auto_fs.h b/include/uapi/linux/auto_fs.h index 9175a1b4dc69..1bfc3ed8b284 100644 --- a/include/uapi/linux/auto_fs.h +++ b/include/uapi/linux/auto_fs.h @@ -12,6 +12,7 @@ #define _UAPI_LINUX_AUTO_FS_H #include <linux/types.h> +#include <linux/limits.h> #ifndef __KERNEL__ #include <sys/ioctl.h> #endif /* __KERNEL__ */ diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index ac5eacd3055b..db4c253f8011 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -239,7 +239,17 @@ struct btrfs_ioctl_fs_info_args { * Used by: * struct btrfs_ioctl_feature_flags */ -#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0) +#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0) +/* + * Older kernels (< 4.9) on big-endian systems produced broken free space tree + * bitmaps, and btrfs-progs also used to corrupt the free space tree (versions + * < 4.7.3). If this bit is clear, then the free space tree cannot be trusted. + * btrfs-progs can also intentionally clear this bit to ask the kernel to + * rebuild the free space tree, however this might not work on older kernels + * that do not know about this bit. If not sure, clear the cache manually on + * first mount when booting older kernel versions. + */ +#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID (1ULL << 1) #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) diff --git a/include/uapi/linux/dvb/video.h b/include/uapi/linux/dvb/video.h index 49392564f9d6..260f033a5b54 100644 --- a/include/uapi/linux/dvb/video.h +++ b/include/uapi/linux/dvb/video.h @@ -206,7 +206,8 @@ typedef __u16 video_attributes_t; /* 6 line 21-2 data present in GOP (1=yes, 0=no) */ /* 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */ /* 2 source letterboxed (1=yes, 0=no) */ -/* 0 film/camera mode (0=camera, 1=film (625/50 only)) */ +/* 0 film/camera mode (0= + *camera, 1=film (625/50 only)) */ /* bit definitions for capabilities: */ diff --git a/include/uapi/linux/falloc.h b/include/uapi/linux/falloc.h index 3e445a760f14..b075f601919b 100644 --- a/include/uapi/linux/falloc.h +++ b/include/uapi/linux/falloc.h @@ -58,4 +58,22 @@ */ #define FALLOC_FL_INSERT_RANGE 0x20 +/* + * FALLOC_FL_UNSHARE_RANGE is used to unshare shared blocks within the + * file size without overwriting any existing data. The purpose of this + * call is to preemptively reallocate any blocks that are subject to + * copy-on-write. + * + * Different filesystems may implement different limitations on the + * granularity of the operation. Most will limit operations to filesystem + * block size boundaries, but this boundary may be larger or smaller + * depending on the filesystem and/or the configuration of the filesystem + * or file. + * + * This flag can only be used with allocate-mode fallocate, which is + * to say that it cannot be used with the punch, zero, collapse, or + * insert range modes. + */ +#define FALLOC_FL_UNSHARE_RANGE 0x40 + #endif /* _UAPI_FALLOC_H_ */ diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 3b00f7c8943f..acb2b6152ba0 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -132,6 +132,7 @@ struct inodes_stat_t { #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ /* These sb flags are internal to the kernel */ +#define MS_NOREMOTELOCK (1<<27) #define MS_NOSEC (1<<28) #define MS_BORN (1<<29) #define MS_ACTIVE (1<<30) @@ -157,7 +158,8 @@ struct fsxattr { __u32 fsx_extsize; /* extsize field value (get/set)*/ __u32 fsx_nextents; /* nextents field value (get) */ __u32 fsx_projid; /* project identifier (get/set) */ - unsigned char fsx_pad[12]; + __u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/ + unsigned char fsx_pad[8]; }; /* @@ -178,6 +180,7 @@ struct fsxattr { #define FS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ #define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ #define FS_XFLAG_DAX 0x00008000 /* use DAX for IO */ +#define FS_XFLAG_COWEXTSIZE 0x00010000 /* CoW extent size allocator hint */ #define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* the read-only stuff doesn't really belong here, but any other place is diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index e398beac67b8..9bd559472c92 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h @@ -65,6 +65,7 @@ #define V9FS_MAGIC 0x01021997 #define BDEVFS_MAGIC 0x62646576 +#define DAXFS_MAGIC 0x64646178 #define BINFMTFS_MAGIC 0x42494e4d #define DEVPTS_SUPER_MAGIC 0x1cd1 #define FUTEXFS_SUPER_MAGIC 0xBAD1DEA diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index 190d491d5b13..2168759c1287 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -97,7 +97,7 @@ #define MEDIA_BUS_FMT_YUV10_1X30 0x2016 #define MEDIA_BUS_FMT_AYUV8_1X32 0x2017 -/* Bayer - next is 0x3019 */ +/* Bayer - next is 0x3021 */ #define MEDIA_BUS_FMT_SBGGR8_1X8 0x3001 #define MEDIA_BUS_FMT_SGBRG8_1X8 0x3013 #define MEDIA_BUS_FMT_SGRBG8_1X8 0x3002 @@ -122,6 +122,14 @@ #define MEDIA_BUS_FMT_SGBRG12_1X12 0x3010 #define MEDIA_BUS_FMT_SGRBG12_1X12 0x3011 #define MEDIA_BUS_FMT_SRGGB12_1X12 0x3012 +#define MEDIA_BUS_FMT_SBGGR14_1X14 0x3019 +#define MEDIA_BUS_FMT_SGBRG14_1X14 0x301a +#define MEDIA_BUS_FMT_SGRBG14_1X14 0x301b +#define MEDIA_BUS_FMT_SRGGB14_1X14 0x301c +#define MEDIA_BUS_FMT_SBGGR16_1X16 0x301d +#define MEDIA_BUS_FMT_SGBRG16_1X16 0x301e +#define MEDIA_BUS_FMT_SGRBG16_1X16 0x301f +#define MEDIA_BUS_FMT_SRGGB16_1X16 0x3020 /* JPEG compressed formats - next is 0x4002 */ #define MEDIA_BUS_FMT_JPEG_1X8 0x4001 diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 7acf0f634f70..4890787731b8 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -307,6 +307,7 @@ struct media_links_enum { #define MEDIA_INTF_T_V4L_RADIO (MEDIA_INTF_T_V4L_BASE + 2) #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) +#define MEDIA_INTF_T_V4L_TOUCH (MEDIA_INTF_T_V4L_BASE + 5) #define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) #define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1) diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h index ba5a8c79652a..ede5c6a62164 100644 --- a/include/uapi/linux/ndctl.h +++ b/include/uapi/linux/ndctl.h @@ -21,14 +21,16 @@ struct nd_cmd_smart { } __packed; #define ND_SMART_HEALTH_VALID (1 << 0) -#define ND_SMART_TEMP_VALID (1 << 1) -#define ND_SMART_SPARES_VALID (1 << 2) -#define ND_SMART_ALARM_VALID (1 << 3) -#define ND_SMART_USED_VALID (1 << 4) -#define ND_SMART_SHUTDOWN_VALID (1 << 5) -#define ND_SMART_VENDOR_VALID (1 << 6) -#define ND_SMART_TEMP_TRIP (1 << 0) -#define ND_SMART_SPARE_TRIP (1 << 1) +#define ND_SMART_SPARES_VALID (1 << 1) +#define ND_SMART_USED_VALID (1 << 2) +#define ND_SMART_TEMP_VALID (1 << 3) +#define ND_SMART_CTEMP_VALID (1 << 4) +#define ND_SMART_ALARM_VALID (1 << 9) +#define ND_SMART_SHUTDOWN_VALID (1 << 10) +#define ND_SMART_VENDOR_VALID (1 << 11) +#define ND_SMART_SPARE_TRIP (1 << 0) +#define ND_SMART_TEMP_TRIP (1 << 1) +#define ND_SMART_CTEMP_TRIP (1 << 2) #define ND_SMART_NON_CRITICAL_HEALTH (1 << 0) #define ND_SMART_CRITICAL_HEALTH (1 << 1) #define ND_SMART_FATAL_HEALTH (1 << 2) @@ -37,14 +39,15 @@ struct nd_smart_payload { __u32 flags; __u8 reserved0[4]; __u8 health; - __u16 temperature; __u8 spares; - __u8 alarm_flags; __u8 life_used; + __u8 alarm_flags; + __u16 temperature; + __u16 ctrl_temperature; + __u8 reserved1[15]; __u8 shutdown_state; - __u8 reserved1; __u32 vendor_size; - __u8 vendor_data[108]; + __u8 vendor_data[92]; } __packed; struct nd_cmd_smart_threshold { @@ -53,7 +56,8 @@ struct nd_cmd_smart_threshold { } __packed; struct nd_smart_threshold_payload { - __u16 alarm_control; + __u8 alarm_control; + __u8 reserved0; __u16 temperature; __u8 spares; __u8 reserved[3]; diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 2b871e0858d9..4ae62796bfde 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -39,8 +39,9 @@ #define NFS4_FH_VOL_MIGRATION 0x0004 #define NFS4_FH_VOL_RENAME 0x0008 -#define NFS4_OPEN_RESULT_CONFIRM 0x0002 -#define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004 +#define NFS4_OPEN_RESULT_CONFIRM 0x0002 +#define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004 +#define NFS4_OPEN_RESULT_MAY_NOTIFY_LOCK 0x0020 #define NFS4_SHARE_ACCESS_MASK 0x000F #define NFS4_SHARE_ACCESS_READ 0x0001 diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index d812172d1d7b..e5a2e68b2236 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -612,6 +612,8 @@ */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ #define PCI_EXP_DEVCAP2_ARI 0x00000020 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCAP2_ATOMIC_ROUTE 0x00000040 /* Atomic Op routing */ +#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* Atomic 64-bit compare */ #define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */ #define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */ #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */ @@ -619,6 +621,7 @@ #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ #define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f /* Completion Timeout Value */ #define PCI_EXP_DEVCTL2_ARI 0x0020 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCTL2_ATOMIC_REQ 0x0040 /* Set Atomic requests */ #define PCI_EXP_DEVCTL2_IDO_REQ_EN 0x0100 /* Allow IDO for requests */ #define PCI_EXP_DEVCTL2_IDO_CMP_EN 0x0200 /* Allow IDO for completions */ #define PCI_EXP_DEVCTL2_LTR_EN 0x0400 /* Enable LTR mechanism */ diff --git a/include/uapi/linux/posix_acl.h b/include/uapi/linux/posix_acl.h new file mode 100644 index 000000000000..1037cb19aa17 --- /dev/null +++ b/include/uapi/linux/posix_acl.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2002 Andreas Gruenbacher <a.gruenbacher@computer.org> + * Copyright (C) 2016 Red Hat, Inc. + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#ifndef __UAPI_POSIX_ACL_H +#define __UAPI_POSIX_ACL_H + +#define ACL_UNDEFINED_ID (-1) + +/* a_type field in acl_user_posix_entry_t */ +#define ACL_TYPE_ACCESS (0x8000) +#define ACL_TYPE_DEFAULT (0x4000) + +/* e_tag entry in struct posix_acl_entry */ +#define ACL_USER_OBJ (0x01) +#define ACL_USER (0x02) +#define ACL_GROUP_OBJ (0x04) +#define ACL_GROUP (0x08) +#define ACL_MASK (0x10) +#define ACL_OTHER (0x20) + +/* permissions in the e_perm field */ +#define ACL_READ (0x04) +#define ACL_WRITE (0x02) +#define ACL_EXECUTE (0x01) + +#endif /* __UAPI_POSIX_ACL_H */ diff --git a/include/uapi/linux/posix_acl_xattr.h b/include/uapi/linux/posix_acl_xattr.h new file mode 100644 index 000000000000..8b579844109b --- /dev/null +++ b/include/uapi/linux/posix_acl_xattr.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2002 Andreas Gruenbacher <a.gruenbacher@computer.org> + * Copyright (C) 2016 Red Hat, Inc. + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#ifndef __UAPI_POSIX_ACL_XATTR_H +#define __UAPI_POSIX_ACL_XATTR_H + +#include <linux/types.h> + +/* Supported ACL a_version fields */ +#define POSIX_ACL_XATTR_VERSION 0x0002 + +/* An undefined entry e_id value */ +#define ACL_UNDEFINED_ID (-1) + +struct posix_acl_xattr_entry { + __le16 e_tag; + __le16 e_perm; + __le32 e_id; +}; + +struct posix_acl_xattr_header { + __le32 a_version; +}; + +#endif /* __UAPI_POSIX_ACL_XATTR_H */ diff --git a/include/uapi/linux/sync_file.h b/include/uapi/linux/sync_file.h index 413303d37b56..5b287d6970b3 100644 --- a/include/uapi/linux/sync_file.h +++ b/include/uapi/linux/sync_file.h @@ -85,15 +85,12 @@ struct sync_file_info { #define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data) /** - * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence + * DOC: SYNC_IOC_FILE_INFO - get detailed information on a sync_file * - * Takes a struct sync_file_info_data with extra space allocated for pt_info. - * Caller should write the size of the buffer into len. On return, len is - * updated to reflect the total size of the sync_file_info_data including - * pt_info. - * - * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. - * To iterate over the sync_pt_infos, use the sync_pt_info.len field. + * Takes a struct sync_file_info. If num_fences is 0, the field is updated + * with the actual number of fences. If num_fences is > 0, the system will + * use the pointer provided on sync_fence_info to return up to num_fences of + * struct sync_fence_info, with detailed fence information. */ #define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info) diff --git a/include/uapi/linux/v4l2-dv-timings.h b/include/uapi/linux/v4l2-dv-timings.h index 086168e18ca8..f31957166337 100644 --- a/include/uapi/linux/v4l2-dv-timings.h +++ b/include/uapi/linux/v4l2-dv-timings.h @@ -934,4 +934,16 @@ V4L2_DV_FL_REDUCED_BLANKING) \ } +/* SDI timings definitions */ + +/* SMPTE-125M */ +#define V4L2_DV_BT_SDI_720X487I60 { \ + .type = V4L2_DV_BT_656_1120, \ + V4L2_INIT_BT_TIMINGS(720, 487, 1, \ + V4L2_DV_HSYNC_POS_POL, \ + 13500000, 16, 121, 0, 0, 19, 0, 0, 19, 0, \ + V4L2_DV_BT_STD_SDI, \ + V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE) \ +} + #endif diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 724f43e69d03..94f123f3e04e 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -292,13 +292,11 @@ enum v4l2_ycbcr_encoding { * various colorspaces: * * V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_470_SYSTEM_M, - * V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_ADOBERGB and - * V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601 + * V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_SRGB, + * V4L2_COLORSPACE_ADOBERGB and V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601 * * V4L2_COLORSPACE_REC709 and V4L2_COLORSPACE_DCI_P3: V4L2_YCBCR_ENC_709 * - * V4L2_COLORSPACE_SRGB: V4L2_YCBCR_ENC_SYCC - * * V4L2_COLORSPACE_BT2020: V4L2_YCBCR_ENC_BT2020 * * V4L2_COLORSPACE_SMPTE240M: V4L2_YCBCR_ENC_SMPTE240M @@ -317,8 +315,14 @@ enum v4l2_ycbcr_encoding { /* Rec. 709/EN 61966-2-4 Extended Gamut -- HDTV */ V4L2_YCBCR_ENC_XV709 = 4, - /* sYCC (Y'CbCr encoding of sRGB) */ +#ifndef __KERNEL__ + /* + * sYCC (Y'CbCr encoding of sRGB), identical to ENC_601. It was added + * originally due to a misunderstanding of the sYCC standard. It should + * not be used, instead use V4L2_YCBCR_ENC_601. + */ V4L2_YCBCR_ENC_SYCC = 5, +#endif /* BT.2020 Non-constant Luminance Y'CbCr */ V4L2_YCBCR_ENC_BT2020 = 6, @@ -345,8 +349,8 @@ enum v4l2_quantization { /* * The default for R'G'B' quantization is always full range, except * for the BT2020 colorspace. For Y'CbCr the quantization is always - * limited range, except for COLORSPACE_JPEG, SYCC, XV601 or XV709: - * those are full range. + * limited range, except for COLORSPACE_JPEG, SRGB, ADOBERGB, + * XV601 or XV709: those are full range. */ V4L2_QUANTIZATION_DEFAULT = 0, V4L2_QUANTIZATION_FULL_RANGE = 1, @@ -361,7 +365,8 @@ enum v4l2_quantization { #define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb, colsp, ycbcr_enc) \ (((is_rgb) && (colsp) == V4L2_COLORSPACE_BT2020) ? V4L2_QUANTIZATION_LIM_RANGE : \ (((is_rgb) || (ycbcr_enc) == V4L2_YCBCR_ENC_XV601 || \ - (ycbcr_enc) == V4L2_YCBCR_ENC_XV709 || (colsp) == V4L2_COLORSPACE_JPEG) ? \ + (ycbcr_enc) == V4L2_YCBCR_ENC_XV709 || (colsp) == V4L2_COLORSPACE_JPEG) || \ + (colsp) == V4L2_COLORSPACE_ADOBERGB || (colsp) == V4L2_COLORSPACE_SRGB ? \ V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE)) enum v4l2_priority { @@ -440,6 +445,8 @@ struct v4l2_capability { #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ +#define V4L2_CAP_TOUCH 0x10000000 /* Is a touch device */ + #define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ /* @@ -635,6 +642,12 @@ struct v4l2_pix_format { #define V4L2_SDR_FMT_CS14LE v4l2_fourcc('C', 'S', '1', '4') /* complex s14le */ #define V4L2_SDR_FMT_RU12LE v4l2_fourcc('R', 'U', '1', '2') /* real u12le */ +/* Touch formats - used for Touch devices */ +#define V4L2_TCH_FMT_DELTA_TD16 v4l2_fourcc('T', 'D', '1', '6') /* 16-bit signed deltas */ +#define V4L2_TCH_FMT_DELTA_TD08 v4l2_fourcc('T', 'D', '0', '8') /* 8-bit signed deltas */ +#define V4L2_TCH_FMT_TU16 v4l2_fourcc('T', 'U', '1', '6') /* 16-bit unsigned touch data */ +#define V4L2_TCH_FMT_TU08 v4l2_fourcc('T', 'U', '0', '8') /* 8-bit unsigned touch data */ + /* priv field value to indicates that subsequent fields are valid. */ #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe @@ -1261,6 +1274,7 @@ struct v4l2_bt_timings { #define V4L2_DV_BT_STD_DMT (1 << 1) /* VESA Discrete Monitor Timings */ #define V4L2_DV_BT_STD_CVT (1 << 2) /* VESA Coordinated Video Timings */ #define V4L2_DV_BT_STD_GTF (1 << 3) /* VESA Generalized Timings Formula */ +#define V4L2_DV_BT_STD_SDI (1 << 4) /* SDI Timings */ /* Flags */ @@ -1292,6 +1306,11 @@ struct v4l2_bt_timings { * use the range 16-235) as opposed to 0-255. All formats defined in CEA-861 * except for the 640x480 format are CE formats. */ #define V4L2_DV_FL_IS_CE_VIDEO (1 << 4) +/* Some formats like SMPTE-125M have an interlaced signal with a odd + * total height. For these formats, if this flag is set, the first + * field has the extra line. If not, it is the second field. + */ +#define V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE (1 << 5) /* A few useful defines to calculate the total blanking and frame sizes */ #define V4L2_DV_BT_BLANKING_WIDTH(bt) \ @@ -1401,6 +1420,7 @@ struct v4l2_input { /* Values for the 'type' field */ #define V4L2_INPUT_TYPE_TUNER 1 #define V4L2_INPUT_TYPE_CAMERA 2 +#define V4L2_INPUT_TYPE_TOUCH 3 /* field 'status' - general */ #define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ @@ -1415,6 +1435,8 @@ struct v4l2_input { /* field 'status' - analog */ #define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ #define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ +#define V4L2_IN_ST_NO_V_LOCK 0x00000400 /* No vertical sync lock */ +#define V4L2_IN_ST_NO_STD_LOCK 0x00000800 /* No standard format lock */ /* field 'status' - digital */ #define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ diff --git a/include/uapi/rdma/qedr-abi.h b/include/uapi/rdma/qedr-abi.h new file mode 100644 index 000000000000..75c270d839c8 --- /dev/null +++ b/include/uapi/rdma/qedr-abi.h @@ -0,0 +1,106 @@ +/* QLogic qedr NIC Driver + * Copyright (c) 2015-2016 QLogic Corporation + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and /or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __QEDR_USER_H__ +#define __QEDR_USER_H__ + +#include <linux/types.h> + +#define QEDR_ABI_VERSION (8) + +/* user kernel communication data structures. */ + +struct qedr_alloc_ucontext_resp { + __u64 db_pa; + __u32 db_size; + + __u32 max_send_wr; + __u32 max_recv_wr; + __u32 max_srq_wr; + __u32 sges_per_send_wr; + __u32 sges_per_recv_wr; + __u32 sges_per_srq_wr; + __u32 max_cqes; +}; + +struct qedr_alloc_pd_ureq { + __u64 rsvd1; +}; + +struct qedr_alloc_pd_uresp { + __u32 pd_id; +}; + +struct qedr_create_cq_ureq { + __u64 addr; + __u64 len; +}; + +struct qedr_create_cq_uresp { + __u32 db_offset; + __u16 icid; +}; + +struct qedr_create_qp_ureq { + __u32 qp_handle_hi; + __u32 qp_handle_lo; + + /* SQ */ + /* user space virtual address of SQ buffer */ + __u64 sq_addr; + + /* length of SQ buffer */ + __u64 sq_len; + + /* RQ */ + /* user space virtual address of RQ buffer */ + __u64 rq_addr; + + /* length of RQ buffer */ + __u64 rq_len; +}; + +struct qedr_create_qp_uresp { + __u32 qp_id; + __u32 atomic_supported; + + /* SQ */ + __u32 sq_db_offset; + __u16 sq_icid; + + /* RQ */ + __u32 rq_db_offset; + __u16 rq_icid; + + __u32 rq_db2_offset; +}; + +#endif /* __QEDR_USER_H__ */ diff --git a/include/video/exynos_mipi_dsim.h b/include/video/exynos_mipi_dsim.h deleted file mode 100644 index 6a578f8a1b3e..000000000000 --- a/include/video/exynos_mipi_dsim.h +++ /dev/null @@ -1,358 +0,0 @@ -/* include/video/exynos_mipi_dsim.h - * - * Platform data header for Samsung SoC MIPI-DSIM. - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd - * - * InKi Dae <inki.dae@samsung.com> - * Donghwa Lee <dh09.lee@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef _EXYNOS_MIPI_DSIM_H -#define _EXYNOS_MIPI_DSIM_H - -#include <linux/device.h> -#include <linux/fb.h> - -#define PANEL_NAME_SIZE (32) - -/* - * Enumerate display interface type. - * - * DSIM_COMMAND means cpu interface and rgb interface for DSIM_VIDEO. - * - * P.S. MIPI DSI Master has two display controller intefaces, RGB Interface - * for main display and CPU Interface(same as I80 Interface) for main - * and sub display. - */ -enum mipi_dsim_interface_type { - DSIM_COMMAND, - DSIM_VIDEO -}; - -enum mipi_dsim_virtual_ch_no { - DSIM_VIRTUAL_CH_0, - DSIM_VIRTUAL_CH_1, - DSIM_VIRTUAL_CH_2, - DSIM_VIRTUAL_CH_3 -}; - -enum mipi_dsim_burst_mode_type { - DSIM_NON_BURST_SYNC_EVENT, - DSIM_BURST_SYNC_EVENT, - DSIM_NON_BURST_SYNC_PULSE, - DSIM_BURST, - DSIM_NON_VIDEO_MODE -}; - -enum mipi_dsim_no_of_data_lane { - DSIM_DATA_LANE_1, - DSIM_DATA_LANE_2, - DSIM_DATA_LANE_3, - DSIM_DATA_LANE_4 -}; - -enum mipi_dsim_byte_clk_src { - DSIM_PLL_OUT_DIV8, - DSIM_EXT_CLK_DIV8, - DSIM_EXT_CLK_BYPASS -}; - -enum mipi_dsim_pixel_format { - DSIM_CMD_3BPP, - DSIM_CMD_8BPP, - DSIM_CMD_12BPP, - DSIM_CMD_16BPP, - DSIM_VID_16BPP_565, - DSIM_VID_18BPP_666PACKED, - DSIM_18BPP_666LOOSELYPACKED, - DSIM_24BPP_888 -}; - -/* - * struct mipi_dsim_config - interface for configuring mipi-dsi controller. - * - * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse. - * @eot_disable: enable or disable EoT packet in HS mode. - * @auto_vertical_cnt: specifies auto vertical count mode. - * in Video mode, the vertical line transition uses line counter - * configured by VSA, VBP, and Vertical resolution. - * If this bit is set to '1', the line counter does not use VSA and VBP - * registers.(in command mode, this variable is ignored) - * @hse: set horizontal sync event mode. - * In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC - * start packet to MIPI DSI slave at MIPI DSI spec1.1r02. - * this bit transfers HSYNC end packet in VSYNC pulse and Vporch area - * (in mommand mode, this variable is ignored) - * @hfp: specifies HFP disable mode. - * if this variable is set, DSI master ignores HFP area in VIDEO mode. - * (in command mode, this variable is ignored) - * @hbp: specifies HBP disable mode. - * if this variable is set, DSI master ignores HBP area in VIDEO mode. - * (in command mode, this variable is ignored) - * @hsa: specifies HSA disable mode. - * if this variable is set, DSI master ignores HSA area in VIDEO mode. - * (in command mode, this variable is ignored) - * @cma_allow: specifies the number of horizontal lines, where command packet - * transmission is allowed after Stable VFP period. - * @e_interface: specifies interface to be used.(CPU or RGB interface) - * @e_virtual_ch: specifies virtual channel number that main or - * sub diaplsy uses. - * @e_pixel_format: specifies pixel stream format for main or sub display. - * @e_burst_mode: selects Burst mode in Video mode. - * in Non-burst mode, RGB data area is filled with RGB data and NULL - * packets, according to input bandwidth of RGB interface. - * In Burst mode, RGB data area is filled with RGB data only. - * @e_no_data_lane: specifies data lane count to be used by Master. - * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8) - * DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported. - * @pll_stable_time: specifies the PLL Timer for stability of the ganerated - * clock(System clock cycle base) - * if the timer value goes to 0x00000000, the clock stable bit of status - * and interrupt register is set. - * @esc_clk: specifies escape clock frequency for getting the escape clock - * prescaler value. - * @stop_holding_cnt: specifies the interval value between transmitting - * read packet(or write "set_tear_on" command) and BTA request. - * after transmitting read packet or write "set_tear_on" command, - * BTA requests to D-PHY automatically. this counter value specifies - * the interval between them. - * @bta_timeout: specifies the timer for BTA. - * this register specifies time out from BTA request to change - * the direction with respect to Tx escape clock. - * @rx_timeout: specifies the timer for LP Rx mode timeout. - * this register specifies time out on how long RxValid deasserts, - * after RxLpdt asserts with respect to Tx escape clock. - * - RxValid specifies Rx data valid indicator. - * - RxLpdt specifies an indicator that D-PHY is under RxLpdt mode. - * - RxValid and RxLpdt specifies signal from D-PHY. - */ -struct mipi_dsim_config { - unsigned char auto_flush; - unsigned char eot_disable; - - unsigned char auto_vertical_cnt; - unsigned char hse; - unsigned char hfp; - unsigned char hbp; - unsigned char hsa; - unsigned char cmd_allow; - - enum mipi_dsim_interface_type e_interface; - enum mipi_dsim_virtual_ch_no e_virtual_ch; - enum mipi_dsim_pixel_format e_pixel_format; - enum mipi_dsim_burst_mode_type e_burst_mode; - enum mipi_dsim_no_of_data_lane e_no_data_lane; - enum mipi_dsim_byte_clk_src e_byte_clk; - - /* - * =========================================== - * | P | M | S | MHz | - * ------------------------------------------- - * | 3 | 100 | 3 | 100 | - * | 3 | 100 | 2 | 200 | - * | 3 | 63 | 1 | 252 | - * | 4 | 100 | 1 | 300 | - * | 4 | 110 | 1 | 330 | - * | 12 | 350 | 1 | 350 | - * | 3 | 100 | 1 | 400 | - * | 4 | 150 | 1 | 450 | - * | 6 | 118 | 1 | 472 | - * | 3 | 120 | 1 | 480 | - * | 12 | 250 | 0 | 500 | - * | 4 | 100 | 0 | 600 | - * | 3 | 81 | 0 | 648 | - * | 3 | 88 | 0 | 704 | - * | 3 | 90 | 0 | 720 | - * | 3 | 100 | 0 | 800 | - * | 12 | 425 | 0 | 850 | - * | 4 | 150 | 0 | 900 | - * | 12 | 475 | 0 | 950 | - * | 6 | 250 | 0 | 1000 | - * ------------------------------------------- - */ - - /* - * pms could be calculated as the following. - * M * 24 / P * 2 ^ S = MHz - */ - unsigned char p; - unsigned short m; - unsigned char s; - - unsigned int pll_stable_time; - unsigned long esc_clk; - - unsigned short stop_holding_cnt; - unsigned char bta_timeout; - unsigned short rx_timeout; -}; - -/* - * struct mipi_dsim_device - global interface for mipi-dsi driver. - * - * @dev: driver model representation of the device. - * @id: unique device id. - * @clock: pointer to MIPI-DSI clock of clock framework. - * @irq: interrupt number to MIPI-DSI controller. - * @reg_base: base address to memory mapped SRF of MIPI-DSI controller. - * (virtual address) - * @lock: the mutex protecting this data structure. - * @dsim_info: infomation for configuring mipi-dsi controller. - * @master_ops: callbacks to mipi-dsi operations. - * @dsim_lcd_dev: pointer to activated ddi device. - * (it would be registered by mipi-dsi driver.) - * @dsim_lcd_drv: pointer to activated_ddi driver. - * (it would be registered by mipi-dsi driver.) - * @lcd_info: pointer to mipi_lcd_info structure. - * @state: specifies status of MIPI-DSI controller. - * the status could be RESET, INIT, STOP, HSCLKEN and ULPS. - * @data_lane: specifiec enabled data lane number. - * this variable would be set by driver according to e_no_data_lane - * automatically. - * @e_clk_src: select byte clock source. - * @pd: pointer to MIPI-DSI driver platform data. - * @phy: pointer to the MIPI-DSI PHY - */ -struct mipi_dsim_device { - struct device *dev; - int id; - struct clk *clock; - unsigned int irq; - void __iomem *reg_base; - struct mutex lock; - - struct mipi_dsim_config *dsim_config; - struct mipi_dsim_master_ops *master_ops; - struct mipi_dsim_lcd_device *dsim_lcd_dev; - struct mipi_dsim_lcd_driver *dsim_lcd_drv; - - unsigned int state; - unsigned int data_lane; - unsigned int e_clk_src; - bool suspended; - - struct mipi_dsim_platform_data *pd; - struct phy *phy; -}; - -/* - * struct mipi_dsim_platform_data - interface to platform data - * for mipi-dsi driver. - * - * @lcd_panel_name: specifies lcd panel name registered to mipi-dsi driver. - * lcd panel driver searched would be actived. - * @dsim_config: pointer of structure for configuring mipi-dsi controller. - * @enabled: indicate whether mipi controller got enabled or not. - * @lcd_panel_info: pointer for lcd panel specific structure. - * this structure specifies width, height, timing and polarity and so on. - */ -struct mipi_dsim_platform_data { - char lcd_panel_name[PANEL_NAME_SIZE]; - - struct mipi_dsim_config *dsim_config; - unsigned int enabled; - void *lcd_panel_info; -}; - -/* - * struct mipi_dsim_master_ops - callbacks to mipi-dsi operations. - * - * @cmd_write: transfer command to lcd panel at LP mode. - * @cmd_read: read command from rx register. - * @get_dsim_frame_done: get the status that all screen data have been - * transferred to mipi-dsi. - * @clear_dsim_frame_done: clear frame done status. - * @get_fb_frame_done: get frame done status of display controller. - * @trigger: trigger display controller. - * - this one would be used only in case of CPU mode. - * @set_early_blank_mode: set framebuffer blank mode. - * - this callback should be called prior to fb_blank() by a client driver - * only if needing. - * @set_blank_mode: set framebuffer blank mode. - * - this callback should be called after fb_blank() by a client driver - * only if needing. - */ - -struct mipi_dsim_master_ops { - int (*cmd_write)(struct mipi_dsim_device *dsim, unsigned int data_id, - const unsigned char *data0, unsigned int data1); - int (*cmd_read)(struct mipi_dsim_device *dsim, unsigned int data_id, - unsigned int data0, unsigned int req_size, u8 *rx_buf); - int (*get_dsim_frame_done)(struct mipi_dsim_device *dsim); - int (*clear_dsim_frame_done)(struct mipi_dsim_device *dsim); - - int (*get_fb_frame_done)(struct fb_info *info); - void (*trigger)(struct fb_info *info); - int (*set_early_blank_mode)(struct mipi_dsim_device *dsim, int power); - int (*set_blank_mode)(struct mipi_dsim_device *dsim, int power); -}; - -/* - * device structure for mipi-dsi based lcd panel. - * - * @name: name of the device to use with this device, or an - * alias for that name. - * @dev: driver model representation of the device. - * @id: id of device to be registered. - * @bus_id: bus id for identifing connected bus - * and this bus id should be same as id of mipi_dsim_device. - * @irq: irq number for signaling when framebuffer transfer of - * lcd panel module is completed. - * this irq would be used only for MIPI-DSI based CPU mode lcd panel. - * @master: pointer to mipi-dsi master device object. - * @platform_data: lcd panel specific platform data. - */ -struct mipi_dsim_lcd_device { - char *name; - struct device dev; - int id; - int bus_id; - int irq; - int panel_reverse; - - struct mipi_dsim_device *master; - void *platform_data; -}; - -/* - * driver structure for mipi-dsi based lcd panel. - * - * this structure should be registered by lcd panel driver. - * mipi-dsi driver seeks lcd panel registered through name field - * and calls these callback functions in appropriate time. - * - * @name: name of the driver to use with this device, or an - * alias for that name. - * @id: id of driver to be registered. - * this id would be used for finding device object registered. - */ -struct mipi_dsim_lcd_driver { - char *name; - int id; - - void (*power_on)(struct mipi_dsim_lcd_device *dsim_dev, int enable); - void (*set_sequence)(struct mipi_dsim_lcd_device *dsim_dev); - int (*probe)(struct mipi_dsim_lcd_device *dsim_dev); - int (*remove)(struct mipi_dsim_lcd_device *dsim_dev); - void (*shutdown)(struct mipi_dsim_lcd_device *dsim_dev); - int (*suspend)(struct mipi_dsim_lcd_device *dsim_dev); - int (*resume)(struct mipi_dsim_lcd_device *dsim_dev); -}; - -/* - * register mipi_dsim_lcd_device to mipi-dsi master. - */ -int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device - *lcd_dev); -/** - * register mipi_dsim_lcd_driver object defined by lcd panel driver - * to mipi-dsi driver. - */ -int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver - *lcd_drv); -#endif /* _EXYNOS_MIPI_DSIM_H */ diff --git a/include/video/imx-ipu-image-convert.h b/include/video/imx-ipu-image-convert.h new file mode 100644 index 000000000000..7b87efc6d77a --- /dev/null +++ b/include/video/imx-ipu-image-convert.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2012-2016 Mentor Graphics Inc. + * + * i.MX Queued image conversion support, with tiling and rotation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#ifndef __IMX_IPU_IMAGE_CONVERT_H__ +#define __IMX_IPU_IMAGE_CONVERT_H__ + +#include <video/imx-ipu-v3.h> + +struct ipu_image_convert_ctx; + +/** + * struct ipu_image_convert_run - image conversion run request struct + * + * @ctx: the conversion context + * @in_phys: dma addr of input image buffer for this run + * @out_phys: dma addr of output image buffer for this run + * @status: completion status of this run + */ +struct ipu_image_convert_run { + struct ipu_image_convert_ctx *ctx; + + dma_addr_t in_phys; + dma_addr_t out_phys; + + int status; + + /* internal to image converter, callers don't touch */ + struct list_head list; +}; + +/** + * ipu_image_convert_cb_t - conversion callback function prototype + * + * @run: the completed conversion run pointer + * @ctx: a private context pointer for the callback + */ +typedef void (*ipu_image_convert_cb_t)(struct ipu_image_convert_run *run, + void *ctx); + +/** + * ipu_image_convert_enum_format() - enumerate the image converter's + * supported input and output pixel formats. + * + * @index: pixel format index + * @fourcc: v4l2 fourcc for this index + * + * Returns 0 with a valid index and fills in v4l2 fourcc, -EINVAL otherwise. + * + * In V4L2, drivers can call ipu_image_enum_format() in .enum_fmt. + */ +int ipu_image_convert_enum_format(int index, u32 *fourcc); + +/** + * ipu_image_convert_adjust() - adjust input/output images to IPU restrictions. + * + * @in: input image format, adjusted on return + * @out: output image format, adjusted on return + * @rot_mode: rotation mode + * + * In V4L2, drivers can call ipu_image_convert_adjust() in .try_fmt. + */ +void ipu_image_convert_adjust(struct ipu_image *in, struct ipu_image *out, + enum ipu_rotate_mode rot_mode); + +/** + * ipu_image_convert_verify() - verify that input/output image formats + * and rotation mode meet IPU restrictions. + * + * @in: input image format + * @out: output image format + * @rot_mode: rotation mode + * + * Returns 0 if the formats and rotation mode meet IPU restrictions, + * -EINVAL otherwise. + */ +int ipu_image_convert_verify(struct ipu_image *in, struct ipu_image *out, + enum ipu_rotate_mode rot_mode); + +/** + * ipu_image_convert_prepare() - prepare a conversion context. + * + * @ipu: the IPU handle to use for the conversions + * @ic_task: the IC task to use for the conversions + * @in: input image format + * @out: output image format + * @rot_mode: rotation mode + * @complete: run completion callback + * @complete_context: a context pointer for the completion callback + * + * Returns an opaque conversion context pointer on success, error pointer + * on failure. The input/output formats and rotation mode must already meet + * IPU retrictions. + * + * In V4L2, drivers should call ipu_image_convert_prepare() at streamon. + */ +struct ipu_image_convert_ctx * +ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task, + struct ipu_image *in, struct ipu_image *out, + enum ipu_rotate_mode rot_mode, + ipu_image_convert_cb_t complete, + void *complete_context); + +/** + * ipu_image_convert_unprepare() - unprepare a conversion context. + * + * @ctx: the conversion context pointer to unprepare + * + * Aborts any active or pending conversions for this context and + * frees the context. Any currently active or pending runs belonging + * to this context are returned via the completion callback with an + * error run status. + * + * In V4L2, drivers should call ipu_image_convert_unprepare() at + * streamoff. + */ +void ipu_image_convert_unprepare(struct ipu_image_convert_ctx *ctx); + +/** + * ipu_image_convert_queue() - queue a conversion run + * + * @run: the run request pointer + * + * ipu_image_convert_run must be dynamically allocated (_not_ as a local + * var) by callers and filled in with a previously prepared conversion + * context handle and the dma addr's of the input and output image buffers + * for this conversion run. + * + * When this conversion completes, the run pointer is returned via the + * completion callback. The caller is responsible for freeing the run + * object after it completes. + * + * In V4L2, drivers should call ipu_image_convert_queue() while + * streaming to queue the conversion of a received input buffer. + * For example mem2mem devices this would be called in .device_run. + */ +int ipu_image_convert_queue(struct ipu_image_convert_run *run); + +/** + * ipu_image_convert_abort() - abort conversions + * + * @ctx: the conversion context pointer + * + * This will abort any active or pending conversions for this context. + * Any currently active or pending runs belonging to this context are + * returned via the completion callback with an error run status. + */ +void ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx); + +/** + * ipu_image_convert() - asynchronous image conversion request + * + * @ipu: the IPU handle to use for the conversion + * @ic_task: the IC task to use for the conversion + * @in: input image format + * @out: output image format + * @rot_mode: rotation mode + * @complete: run completion callback + * @complete_context: a context pointer for the completion callback + * + * Request a single image conversion. Returns the run that has been queued. + * A conversion context is automatically created and is available in run->ctx. + * As with ipu_image_convert_prepare(), the input/output formats and rotation + * mode must already meet IPU retrictions. + * + * On successful return the caller can queue more run requests if needed, using + * the prepared context in run->ctx. The caller is responsible for unpreparing + * the context when no more conversion requests are needed. + */ +struct ipu_image_convert_run * +ipu_image_convert(struct ipu_soc *ipu, enum ipu_ic_task ic_task, + struct ipu_image *in, struct ipu_image *out, + enum ipu_rotate_mode rot_mode, + ipu_image_convert_cb_t complete, + void *complete_context); + +/** + * ipu_image_convert_sync() - synchronous single image conversion request + * + * @ipu: the IPU handle to use for the conversion + * @ic_task: the IC task to use for the conversion + * @in: input image format + * @out: output image format + * @rot_mode: rotation mode + * + * Carry out a single image conversion. Returns when the conversion + * completes. The input/output formats and rotation mode must already + * meet IPU retrictions. The created context is automatically unprepared + * and the run freed on return. + */ +int ipu_image_convert_sync(struct ipu_soc *ipu, enum ipu_ic_task ic_task, + struct ipu_image *in, struct ipu_image *out, + enum ipu_rotate_mode rot_mode); + + +#endif /* __IMX_IPU_IMAGE_CONVERT_H__ */ diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index 7adeaae06961..173073eb6aaf 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h @@ -63,23 +63,41 @@ enum ipu_csi_dest { /* * Enumeration of IPU rotation modes */ +#define IPU_ROT_BIT_VFLIP (1 << 0) +#define IPU_ROT_BIT_HFLIP (1 << 1) +#define IPU_ROT_BIT_90 (1 << 2) + enum ipu_rotate_mode { IPU_ROTATE_NONE = 0, - IPU_ROTATE_VERT_FLIP, - IPU_ROTATE_HORIZ_FLIP, - IPU_ROTATE_180, - IPU_ROTATE_90_RIGHT, - IPU_ROTATE_90_RIGHT_VFLIP, - IPU_ROTATE_90_RIGHT_HFLIP, - IPU_ROTATE_90_LEFT, + IPU_ROTATE_VERT_FLIP = IPU_ROT_BIT_VFLIP, + IPU_ROTATE_HORIZ_FLIP = IPU_ROT_BIT_HFLIP, + IPU_ROTATE_180 = (IPU_ROT_BIT_VFLIP | IPU_ROT_BIT_HFLIP), + IPU_ROTATE_90_RIGHT = IPU_ROT_BIT_90, + IPU_ROTATE_90_RIGHT_VFLIP = (IPU_ROT_BIT_90 | IPU_ROT_BIT_VFLIP), + IPU_ROTATE_90_RIGHT_HFLIP = (IPU_ROT_BIT_90 | IPU_ROT_BIT_HFLIP), + IPU_ROTATE_90_LEFT = (IPU_ROT_BIT_90 | + IPU_ROT_BIT_VFLIP | IPU_ROT_BIT_HFLIP), }; +/* 90-degree rotations require the IRT unit */ +#define ipu_rot_mode_is_irt(m) (((m) & IPU_ROT_BIT_90) != 0) + enum ipu_color_space { IPUV3_COLORSPACE_RGB, IPUV3_COLORSPACE_YUV, IPUV3_COLORSPACE_UNKNOWN, }; +/* + * Enumeration of VDI MOTION select + */ +enum ipu_motion_sel { + MOTION_NONE = 0, + LOW_MOTION, + MED_MOTION, + HIGH_MOTION, +}; + struct ipuv3_channel; enum ipu_channel_irq { @@ -97,20 +115,42 @@ enum ipu_channel_irq { #define IPUV3_CHANNEL_CSI2 2 #define IPUV3_CHANNEL_CSI3 3 #define IPUV3_CHANNEL_VDI_MEM_IC_VF 5 +/* + * NOTE: channels 6,7 are unused in the IPU and are not IDMAC channels, + * but the direct CSI->VDI linking is handled the same way as IDMAC + * channel linking in the FSU via the IPU_FS_PROC_FLOW registers, so + * these channel names are used to support the direct CSI->VDI link. + */ +#define IPUV3_CHANNEL_CSI_DIRECT 6 +#define IPUV3_CHANNEL_CSI_VDI_PREV 7 +#define IPUV3_CHANNEL_MEM_VDI_PREV 8 +#define IPUV3_CHANNEL_MEM_VDI_CUR 9 +#define IPUV3_CHANNEL_MEM_VDI_NEXT 10 #define IPUV3_CHANNEL_MEM_IC_PP 11 #define IPUV3_CHANNEL_MEM_IC_PRP_VF 12 +#define IPUV3_CHANNEL_VDI_MEM_RECENT 13 #define IPUV3_CHANNEL_G_MEM_IC_PRP_VF 14 #define IPUV3_CHANNEL_G_MEM_IC_PP 15 +#define IPUV3_CHANNEL_G_MEM_IC_PRP_VF_ALPHA 17 +#define IPUV3_CHANNEL_G_MEM_IC_PP_ALPHA 18 +#define IPUV3_CHANNEL_MEM_VDI_PLANE1_COMB_ALPHA 19 #define IPUV3_CHANNEL_IC_PRP_ENC_MEM 20 #define IPUV3_CHANNEL_IC_PRP_VF_MEM 21 #define IPUV3_CHANNEL_IC_PP_MEM 22 #define IPUV3_CHANNEL_MEM_BG_SYNC 23 #define IPUV3_CHANNEL_MEM_BG_ASYNC 24 +#define IPUV3_CHANNEL_MEM_VDI_PLANE1_COMB 25 +#define IPUV3_CHANNEL_MEM_VDI_PLANE3_COMB 26 #define IPUV3_CHANNEL_MEM_FG_SYNC 27 #define IPUV3_CHANNEL_MEM_DC_SYNC 28 #define IPUV3_CHANNEL_MEM_FG_ASYNC 29 #define IPUV3_CHANNEL_MEM_FG_SYNC_ALPHA 31 +#define IPUV3_CHANNEL_MEM_FG_ASYNC_ALPHA 33 +#define IPUV3_CHANNEL_DC_MEM_READ 40 #define IPUV3_CHANNEL_MEM_DC_ASYNC 41 +#define IPUV3_CHANNEL_MEM_DC_COMMAND 42 +#define IPUV3_CHANNEL_MEM_DC_COMMAND2 43 +#define IPUV3_CHANNEL_MEM_DC_OUTPUT_MASK 44 #define IPUV3_CHANNEL_MEM_ROT_ENC 45 #define IPUV3_CHANNEL_MEM_ROT_VF 46 #define IPUV3_CHANNEL_MEM_ROT_PP 47 @@ -118,6 +158,8 @@ enum ipu_channel_irq { #define IPUV3_CHANNEL_ROT_VF_MEM 49 #define IPUV3_CHANNEL_ROT_PP_MEM 50 #define IPUV3_CHANNEL_MEM_BG_SYNC_ALPHA 51 +#define IPUV3_CHANNEL_MEM_BG_ASYNC_ALPHA 52 +#define IPUV3_NUM_CHANNELS 64 int ipu_map_irq(struct ipu_soc *ipu, int irq); int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, @@ -138,6 +180,7 @@ int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, /* * IPU Common functions */ +int ipu_get_num(struct ipu_soc *ipu); void ipu_set_csi_src_mux(struct ipu_soc *ipu, int csi_id, bool mipi_csi2); void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi); void ipu_dump(struct ipu_soc *ipu); @@ -160,6 +203,10 @@ int ipu_idmac_get_current_buffer(struct ipuv3_channel *channel); bool ipu_idmac_buffer_is_ready(struct ipuv3_channel *channel, u32 buf_num); void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num); void ipu_idmac_clear_buffer(struct ipuv3_channel *channel, u32 buf_num); +int ipu_fsu_link(struct ipu_soc *ipu, int src_ch, int sink_ch); +int ipu_fsu_unlink(struct ipu_soc *ipu, int src_ch, int sink_ch); +int ipu_idmac_link(struct ipuv3_channel *src, struct ipuv3_channel *sink); +int ipu_idmac_unlink(struct ipuv3_channel *src, struct ipuv3_channel *sink); /* * IPU Channel Parameter Memory (cpmem) functions @@ -184,8 +231,10 @@ void ipu_cpmem_set_resolution(struct ipuv3_channel *ch, int xres, int yres); void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride); void ipu_cpmem_set_high_priority(struct ipuv3_channel *ch); void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf); +void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off); void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride); void ipu_cpmem_set_axi_id(struct ipuv3_channel *ch, u32 id); +int ipu_cpmem_get_burstsize(struct ipuv3_channel *ch); void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize); void ipu_cpmem_set_block_mode(struct ipuv3_channel *ch); void ipu_cpmem_set_rotation(struct ipuv3_channel *ch, @@ -317,6 +366,19 @@ void ipu_ic_put(struct ipu_ic *ic); void ipu_ic_dump(struct ipu_ic *ic); /* + * IPU Video De-Interlacer (vdi) functions + */ +struct ipu_vdi; +void ipu_vdi_set_field_order(struct ipu_vdi *vdi, v4l2_std_id std, u32 field); +void ipu_vdi_set_motion(struct ipu_vdi *vdi, enum ipu_motion_sel motion_sel); +void ipu_vdi_setup(struct ipu_vdi *vdi, u32 code, int xres, int yres); +void ipu_vdi_unsetup(struct ipu_vdi *vdi); +int ipu_vdi_enable(struct ipu_vdi *vdi); +int ipu_vdi_disable(struct ipu_vdi *vdi); +struct ipu_vdi *ipu_vdi_get(struct ipu_soc *ipu); +void ipu_vdi_put(struct ipu_vdi *vdi); + +/* * IPU Sensor Multiple FIFO Controller (SMFC) functions */ struct ipu_smfc *ipu_smfc_get(struct ipu_soc *ipu, unsigned int chno); |