2016-11-05 18:08:07 +03:00
/*
* Copyright ( C ) 2016 Red Hat
*
* 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 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 COPYRIGHT HOLDER ( S ) OR AUTHOR ( S ) 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 :
* Rob Clark < robdclark @ gmail . com >
*/
# ifndef DRM_PRINT_H_
# define DRM_PRINT_H_
2017-02-16 02:33:18 +03:00
# include <linux/compiler.h>
# include <linux/printk.h>
2016-11-05 18:08:07 +03:00
# include <linux/seq_file.h>
# include <linux/device.h>
/**
* DOC : print
*
* A simple wrapper for dev_printk ( ) , seq_printf ( ) , etc . Allows same
* debug code to be used for both debugfs and printk logging .
*
* For example : :
*
* void log_some_info ( struct drm_printer * p )
* {
* drm_printf ( p , " foo=%d \n " , foo ) ;
* drm_printf ( p , " bar=%d \n " , bar ) ;
* }
*
* # ifdef CONFIG_DEBUG_FS
* void debugfs_show ( struct seq_file * f )
* {
* struct drm_printer p = drm_seq_file_printer ( f ) ;
* log_some_info ( & p ) ;
* }
* # endif
*
* void some_other_function ( . . . )
* {
* struct drm_printer p = drm_info_printer ( drm - > dev ) ;
* log_some_info ( & p ) ;
* }
*/
/**
* struct drm_printer - drm output " stream "
*
* Do not use struct members directly . Use drm_printer_seq_file ( ) ,
* drm_printer_info ( ) , etc to initialize . And drm_printf ( ) for output .
*/
struct drm_printer {
2016-12-28 19:42:09 +03:00
/* private: */
2016-11-05 18:08:07 +03:00
void ( * printfn ) ( struct drm_printer * p , struct va_format * vaf ) ;
void * arg ;
2016-12-28 19:42:09 +03:00
const char * prefix ;
2016-11-05 18:08:07 +03:00
} ;
void __drm_printfn_seq_file ( struct drm_printer * p , struct va_format * vaf ) ;
void __drm_printfn_info ( struct drm_printer * p , struct va_format * vaf ) ;
2016-12-28 19:42:09 +03:00
void __drm_printfn_debug ( struct drm_printer * p , struct va_format * vaf ) ;
2016-11-05 18:08:07 +03:00
2017-02-16 02:33:18 +03:00
__printf ( 2 , 3 )
2016-11-05 18:08:07 +03:00
void drm_printf ( struct drm_printer * p , const char * f , . . . ) ;
2017-11-07 22:13:39 +03:00
/**
* drm_printf_indent - Print to a & drm_printer stream with indentation
* @ printer : DRM printer
* @ indent : Tab indentation level ( max 5 )
* @ fmt : Format string
*/
# define drm_printf_indent(printer, indent, fmt, ...) \
drm_printf ( ( printer ) , " %.*s " fmt , ( indent ) , " \t \t \t \t \t X " , # # __VA_ARGS__ )
2016-11-05 18:08:07 +03:00
/**
* drm_seq_file_printer - construct a & drm_printer that outputs to & seq_file
2016-12-29 23:48:26 +03:00
* @ f : the & struct seq_file to output to
2016-11-05 18:08:07 +03:00
*
* RETURNS :
* The & drm_printer object
*/
static inline struct drm_printer drm_seq_file_printer ( struct seq_file * f )
{
struct drm_printer p = {
. printfn = __drm_printfn_seq_file ,
. arg = f ,
} ;
return p ;
}
/**
* drm_info_printer - construct a & drm_printer that outputs to dev_printk ( )
2016-12-29 23:48:26 +03:00
* @ dev : the & struct device pointer
2016-11-05 18:08:07 +03:00
*
* RETURNS :
* The & drm_printer object
*/
static inline struct drm_printer drm_info_printer ( struct device * dev )
{
struct drm_printer p = {
. printfn = __drm_printfn_info ,
. arg = dev ,
} ;
return p ;
}
2016-12-28 19:42:09 +03:00
/**
* drm_debug_printer - construct a & drm_printer that outputs to pr_debug ( )
* @ prefix : debug output prefix
*
* RETURNS :
* The & drm_printer object
*/
static inline struct drm_printer drm_debug_printer ( const char * prefix )
{
struct drm_printer p = {
. printfn = __drm_printfn_debug ,
. prefix = prefix
} ;
return p ;
}
2017-10-18 07:30:07 +03:00
/*
* The following categories are defined :
*
* CORE : Used in the generic drm code : drm_ioctl . c , drm_mm . c , drm_memory . c , . . .
* This is the category used by the DRM_DEBUG ( ) macro .
*
* DRIVER : Used in the vendor specific part of the driver : i915 , radeon , . . .
* This is the category used by the DRM_DEBUG_DRIVER ( ) macro .
*
* KMS : used in the modesetting code .
* This is the category used by the DRM_DEBUG_KMS ( ) macro .
*
* PRIME : used in the prime code .
* This is the category used by the DRM_DEBUG_PRIME ( ) macro .
*
* ATOMIC : used in the atomic code .
* This is the category used by the DRM_DEBUG_ATOMIC ( ) macro .
*
* VBL : used for verbose debug message in the vblank code
* This is the category used by the DRM_DEBUG_VBL ( ) macro .
*
* Enabling verbose debug messages is done through the drm . debug parameter ,
* each category being enabled by a bit .
*
* drm . debug = 0x1 will enable CORE messages
* drm . debug = 0x2 will enable DRIVER messages
* drm . debug = 0x3 will enable CORE and DRIVER messages
* . . .
* drm . debug = 0x3f will enable all messages
*
* An interesting feature is that it ' s possible to enable verbose logging at
* 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
# define DRM_UT_PRIME 0x08
# define DRM_UT_ATOMIC 0x10
# define DRM_UT_VBL 0x20
# define DRM_UT_STATE 0x40
2017-11-21 13:33:10 +03:00
# define DRM_UT_LEASE 0x80
2017-10-18 07:30:07 +03:00
__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 , . . . ) ;
__printf ( 3 , 4 )
void drm_printk ( const char * level , unsigned int category ,
const char * format , . . . ) ;
2017-10-18 07:31:22 +03:00
/* Macros to make printk easier */
2017-10-18 07:30:07 +03:00
# 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 .
*
2017-10-18 07:31:22 +03:00
* @ dev : device pointer
* @ fmt : printf ( ) like format string .
2017-10-18 07:30:07 +03:00
*/
# 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 .
*
2017-10-18 07:31:22 +03:00
* @ dev : device pointer
* @ fmt : printf ( ) like format string .
2017-10-18 07:30:07 +03:00
*/
# define DRM_DEV_ERROR_RATELIMITED(dev, fmt, ...) \
( { \
static DEFINE_RATELIMIT_STATE ( _rs , \
DEFAULT_RATELIMIT_INTERVAL , \
DEFAULT_RATELIMIT_BURST ) ; \
\
if ( __ratelimit ( & _rs ) ) \
DRM_DEV_ERROR ( dev , fmt , # # __VA_ARGS__ ) ; \
} )
# define DRM_ERROR_RATELIMITED(fmt, ...) \
DRM_DEV_ERROR_RATELIMITED ( NULL , fmt , # # __VA_ARGS__ )
# define DRM_DEV_INFO(dev, fmt, ...) \
drm_dev_printk ( dev , KERN_INFO , DRM_UT_NONE , __func__ , " " , 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 .
*
2017-10-18 07:31:22 +03:00
* @ dev : device pointer
* @ fmt : printf ( ) like format string .
2017-10-18 07:30:07 +03:00
*/
# 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__ )
2017-11-21 13:33:10 +03:00
# define DRM_DEBUG_LEASE(fmt, ...) \
drm_printk ( KERN_DEBUG , DRM_UT_LEASE , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
# 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 ) ; \
} )
/**
* Rate limited debug output . Like DRM_DEBUG ( ) but won ' t flood the log .
*
2017-10-18 07:31:22 +03:00
* @ dev : device pointer
* @ fmt : printf ( ) like format string .
2017-10-18 07:30:07 +03:00
*/
# 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 )
2016-11-05 18:08:07 +03:00
# endif /* DRM_PRINT_H_ */