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>
2019-02-21 00:03:37 +03:00
# include <linux/debugfs.h>
2016-11-05 18:08:07 +03:00
2019-06-10 01:07:48 +03:00
# include <drm/drm.h>
2016-11-05 18:08:07 +03:00
/**
* 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 ) ;
2018-07-24 19:33:21 +03:00
void ( * puts ) ( struct drm_printer * p , const char * str ) ;
2016-11-05 18:08:07 +03:00
void * arg ;
2016-12-28 19:42:09 +03:00
const char * prefix ;
2016-11-05 18:08:07 +03:00
} ;
2018-07-24 19:33:20 +03:00
void __drm_printfn_coredump ( struct drm_printer * p , struct va_format * vaf ) ;
2018-07-24 19:33:23 +03:00
void __drm_puts_coredump ( struct drm_printer * p , const char * str ) ;
2016-11-05 18:08:07 +03:00
void __drm_printfn_seq_file ( struct drm_printer * p , struct va_format * vaf ) ;
2018-07-24 19:33:22 +03:00
void __drm_puts_seq_file ( struct drm_printer * p , const char * str ) ;
2016-11-05 18:08:07 +03:00
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 , . . . ) ;
2018-07-24 19:33:21 +03:00
void drm_puts ( struct drm_printer * p , const char * str ) ;
2019-02-21 00:03:37 +03:00
void drm_print_regset32 ( struct drm_printer * p , struct debugfs_regset32 * regset ) ;
2016-11-05 18:08:07 +03:00
2017-12-14 23:30:51 +03:00
__printf ( 2 , 0 )
2017-11-23 11:40:46 +03:00
/**
* drm_vprintf - print to a & drm_printer stream
* @ p : the & drm_printer
* @ fmt : format string
* @ va : the va_list
*/
static inline void
drm_vprintf ( struct drm_printer * p , const char * fmt , va_list * va )
{
struct va_format vaf = { . fmt = fmt , . va = va } ;
p - > printfn ( p , & vaf ) ;
}
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
2018-07-24 19:33:20 +03:00
/**
* struct drm_print_iterator - local struct used with drm_printer_coredump
* @ data : Pointer to the devcoredump output buffer
* @ start : The offset within the buffer to start writing
* @ remain : The number of bytes to write for this iteration
*/
struct drm_print_iterator {
void * data ;
ssize_t start ;
ssize_t remain ;
/* private: */
ssize_t offset ;
} ;
/**
* drm_coredump_printer - construct a & drm_printer that can output to a buffer
* from the read function for devcoredump
* @ iter : A pointer to a struct drm_print_iterator for the read instance
*
* This wrapper extends drm_printf ( ) to work with a dev_coredumpm ( ) callback
* function . The passed in drm_print_iterator struct contains the buffer
* pointer , size and offset as passed in from devcoredump .
*
* For example : :
*
* void coredump_read ( char * buffer , loff_t offset , size_t count ,
* void * data , size_t datalen )
* {
* struct drm_print_iterator iter ;
* struct drm_printer p ;
*
* iter . data = buffer ;
* iter . start = offset ;
* iter . remain = count ;
*
* p = drm_coredump_printer ( & iter ) ;
*
* drm_printf ( p , " foo=%d \n " , foo ) ;
* }
*
* void makecoredump ( . . . )
* {
* . . .
* dev_coredumpm ( dev , THIS_MODULE , data , 0 , GFP_KERNEL ,
* coredump_read , . . . )
* }
*
* RETURNS :
* The & drm_printer object
*/
static inline struct drm_printer
drm_coredump_printer ( struct drm_print_iterator * iter )
{
struct drm_printer p = {
. printfn = __drm_printfn_coredump ,
2018-07-24 19:33:23 +03:00
. puts = __drm_puts_coredump ,
2018-07-24 19:33:20 +03:00
. arg = iter ,
} ;
/* Set the internal offset of the iterator to zero */
iter - > offset = 0 ;
return p ;
}
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 ,
2018-07-24 19:33:22 +03:00
. puts = __drm_puts_seq_file ,
2016-11-05 18:08:07 +03:00
. 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
2018-07-16 18:44:32 +03:00
# define DRM_UT_DP 0x100
2017-10-18 07:30:07 +03:00
2018-03-16 23:56:27 +03:00
__printf ( 3 , 4 )
2017-10-18 07:30:07 +03:00
void drm_dev_printk ( const struct device * dev , const char * level ,
2018-03-16 23:56:27 +03:00
const char * format , . . . ) ;
__printf ( 3 , 4 )
void drm_dev_dbg ( const struct device * dev , unsigned int category ,
const char * format , . . . ) ;
2018-03-14 01:02:15 +03:00
__printf ( 2 , 3 )
void drm_dbg ( unsigned int category , const char * format , . . . ) ;
__printf ( 1 , 2 )
void drm_err ( 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, ...) \
2018-03-16 23:56:27 +03:00
printk # # once ( KERN_ # # level " [ " DRM_NAME " ] " fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
# 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, ...) \
2018-03-16 23:56:27 +03:00
drm_dev_printk ( dev , KERN_ERR , " *ERROR* " fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
# define DRM_ERROR(fmt, ...) \
2018-03-14 01:02:15 +03:00
drm_err ( fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
/**
* 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, ...) \
2018-03-16 23:56:27 +03:00
drm_dev_printk ( dev , KERN_INFO , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
# 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
*/
2018-03-16 23:56:27 +03:00
# define DRM_DEV_DEBUG(dev, fmt, ...) \
drm_dev_dbg ( dev , DRM_UT_CORE , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
# define DRM_DEBUG(fmt, ...) \
2018-03-14 01:02:15 +03:00
drm_dbg ( DRM_UT_CORE , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
2018-03-16 23:56:27 +03:00
# define DRM_DEV_DEBUG_DRIVER(dev, fmt, ...) \
drm_dev_dbg ( dev , DRM_UT_DRIVER , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
# define DRM_DEBUG_DRIVER(fmt, ...) \
2018-03-14 01:02:15 +03:00
drm_dbg ( DRM_UT_DRIVER , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
2018-03-16 23:56:27 +03:00
# define DRM_DEV_DEBUG_KMS(dev, fmt, ...) \
drm_dev_dbg ( dev , DRM_UT_KMS , fmt , # # __VA_ARGS__ )
2018-03-14 01:02:15 +03:00
# define DRM_DEBUG_KMS(fmt, ...) \
drm_dbg ( DRM_UT_KMS , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
2018-03-16 23:56:27 +03:00
# define DRM_DEV_DEBUG_PRIME(dev, fmt, ...) \
drm_dev_dbg ( dev , DRM_UT_PRIME , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
# define DRM_DEBUG_PRIME(fmt, ...) \
2018-03-14 01:02:15 +03:00
drm_dbg ( DRM_UT_PRIME , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
2018-03-16 23:56:27 +03:00
# define DRM_DEV_DEBUG_ATOMIC(dev, fmt, ...) \
drm_dev_dbg ( dev , DRM_UT_ATOMIC , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
# define DRM_DEBUG_ATOMIC(fmt, ...) \
2018-03-14 01:02:15 +03:00
drm_dbg ( DRM_UT_ATOMIC , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
2018-03-16 23:56:27 +03:00
# define DRM_DEV_DEBUG_VBL(dev, fmt, ...) \
drm_dev_dbg ( dev , DRM_UT_VBL , fmt , # # __VA_ARGS__ )
2018-03-14 01:02:15 +03:00
# define DRM_DEBUG_VBL(fmt, ...) \
drm_dbg ( DRM_UT_VBL , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
2017-11-21 13:33:10 +03:00
# define DRM_DEBUG_LEASE(fmt, ...) \
2018-03-14 01:02:15 +03:00
drm_dbg ( DRM_UT_LEASE , fmt , # # __VA_ARGS__ )
2017-11-21 13:33:10 +03:00
2018-07-16 18:44:32 +03:00
# define DRM_DEV_DEBUG_DP(dev, fmt, ...) \
drm_dev_dbg ( dev , DRM_UT_DP , fmt , # # __VA_ARGS__ )
2018-07-19 00:57:16 +03:00
# define DRM_DEBUG_DP(fmt, ...) \
2018-07-16 18:44:32 +03:00
drm_dbg ( DRM_UT_DP , fmt , # # __VA_ARGS__ )
2018-03-16 23:56:27 +03:00
# define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, category, fmt, ...) \
2017-10-18 07:30:07 +03:00
( { \
static DEFINE_RATELIMIT_STATE ( _rs , \
DEFAULT_RATELIMIT_INTERVAL , \
DEFAULT_RATELIMIT_BURST ) ; \
if ( __ratelimit ( & _rs ) ) \
2018-03-16 23:56:27 +03:00
drm_dev_dbg ( dev , category , fmt , # # __VA_ARGS__ ) ; \
2017-10-18 07:30:07 +03:00
} )
/**
* 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
*/
2018-03-16 23:56:27 +03:00
# define DRM_DEV_DEBUG_RATELIMITED(dev, fmt, ...) \
_DEV_DRM_DEFINE_DEBUG_RATELIMITED ( dev , DRM_UT_CORE , \
fmt , # # __VA_ARGS__ )
# define DRM_DEBUG_RATELIMITED(fmt, ...) \
DRM_DEV_DEBUG_RATELIMITED ( NULL , fmt , # # __VA_ARGS__ )
# define DRM_DEV_DEBUG_DRIVER_RATELIMITED(dev, fmt, ...) \
_DRM_DEV_DEFINE_DEBUG_RATELIMITED ( dev , DRM_UT_DRIVER , \
fmt , # # __VA_ARGS__ )
# define DRM_DEBUG_DRIVER_RATELIMITED(fmt, ...) \
DRM_DEV_DEBUG_DRIVER_RATELIMITED ( NULL , fmt , # # __VA_ARGS__ )
# define DRM_DEV_DEBUG_KMS_RATELIMITED(dev, fmt, ...) \
_DRM_DEV_DEFINE_DEBUG_RATELIMITED ( dev , DRM_UT_KMS , \
fmt , # # __VA_ARGS__ )
# define DRM_DEBUG_KMS_RATELIMITED(fmt, ...) \
DRM_DEV_DEBUG_KMS_RATELIMITED ( NULL , fmt , # # __VA_ARGS__ )
# define DRM_DEV_DEBUG_PRIME_RATELIMITED(dev, fmt, ...) \
_DRM_DEV_DEFINE_DEBUG_RATELIMITED ( dev , DRM_UT_PRIME , \
fmt , # # __VA_ARGS__ )
# define DRM_DEBUG_PRIME_RATELIMITED(fmt, ...) \
DRM_DEV_DEBUG_PRIME_RATELIMITED ( NULL , fmt , # # __VA_ARGS__ )
2017-10-18 07:30:07 +03:00
2016-11-05 18:08:07 +03:00
# endif /* DRM_PRINT_H_ */