diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 4e9a84db479b93..cef19351a411ee 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -453,6 +453,7 @@ static void drm_atomic_crtc_print_state(struct drm_printer *p, drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask); drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask); drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode)); + drm_printf(p, "\tbackground_color=%llx\n", state->background_color); if (crtc->funcs->atomic_print_state) crtc->funcs->atomic_print_state(p, state); diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index a6414a2c488e81..e62cca50875d50 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -75,6 +75,7 @@ __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state, struct drm_crtc *crtc) { crtc_state->crtc = crtc; + crtc_state->background_color = DRM_ARGB64_PREP(0xffff, 0, 0, 0); } EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset); diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index d1556527cca37b..adc75d821d1d36 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -407,6 +407,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, &replaced); state->color_mgmt_changed |= replaced; return ret; + } else if (property == config->background_color_property) { + state->background_color = val; } else if (property == config->prop_out_fence_ptr) { s32 __user *fence_ptr = u64_to_user_ptr(val); @@ -452,6 +454,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, *val = (state->ctm) ? state->ctm->base.id : 0; else if (property == config->gamma_lut_property) *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; + else if (property == config->background_color_property) + *val = state->background_color; else if (property == config->prop_out_fence_ptr) *val = 0; else if (property == crtc->scaling_filter_property) diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index e802c9f0331abf..ad8e52c0793981 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -191,10 +191,6 @@ * plane does not expose the "alpha" property, then this is * assumed to be 1.0 * - * Note that all the property extensions described here apply either to the - * plane or the CRTC (e.g. for the background color, which currently is not - * exposed and assumed to be black). - * * SCALING_FILTER: * Indicates scaling filter to be used for plane scaler * @@ -207,6 +203,25 @@ * * Drivers can set up this property for a plane by calling * drm_plane_create_scaling_filter_property + * + * The property extensions described above all apply to the plane. Drivers + * may also expose the following crtc property extension: + * + * BACKGROUND_COLOR: + * Background color is set up with drm_crtc_attach_background_color_property(), + * and expects a 64-bit ARGB value following DRM_FORMAT_ARGB16161616, as + * generated by the DRM_ARGB64_PREP*() helpers. It controls the color of a + * full-screen layer that exists below all planes. This color will be used + * for pixels not covered by any plane and may also be blended with plane + * contents as allowed by a plane's alpha values. + * The background color defaults to black, and is assumed to be black for + * drivers that do not expose this property. Although background color + * isn't a plane, it is assumed that the color provided here undergoes the + * CRTC degamma/CSC/gamma transformations applied after the planes blending. + * Note that the color value includes an alpha channel, hence non-opaque + * background color values are allowed, but since physically transparent + * monitors do not (yet) exists, the final alpha value may not reach the + * video sink or it may simply ignore it. */ /** @@ -654,3 +669,19 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane, return 0; } EXPORT_SYMBOL(drm_plane_create_blend_mode_property); + +/** + * drm_crtc_attach_background_color_property - attach background color property + * @crtc: drm crtc + * + * Attaches the background color property to @crtc. The property defaults to + * solid black and will accept 64-bit ARGB values in the format generated by + * DRM_ARGB64_PREP*() helpers. + */ +void drm_crtc_attach_background_color_property(struct drm_crtc *crtc) +{ + drm_object_attach_property(&crtc->base, + crtc->dev->mode_config.background_color_property, + DRM_ARGB64_PREP(0xffff, 0, 0, 0)); +} +EXPORT_SYMBOL(drm_crtc_attach_background_color_property); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index cd0a81df3f335a..3e67bc06931d16 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -375,6 +375,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create_range(dev, 0, + "BACKGROUND_COLOR", 0, U64_MAX); + if (!prop) + return -ENOMEM; + dev->mode_config.background_color_property = prop; + prop = drm_property_create(dev, DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, "IN_FORMATS", 0); diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 5ce7ad53e184a3..64265651dbb2e0 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1434,6 +1435,8 @@ int __vc4_crtc_init(struct drm_device *drm, if (ret) return ret; + drm_crtc_attach_background_color_property(crtc); + drm_crtc_helper_add(crtc, crtc_helper_funcs); if (vc4->gen == VC4_GEN_4) { diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 9f7cff04a6ef12..4ae905855bb466 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -1256,6 +1256,7 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); unsigned int channel = vc4_state->assigned_channel; + u64 bgcolor = crtc->state->background_color; struct drm_plane *plane; struct vc4_plane_state *vc4_plane_state; bool debug_dump_regs = false; @@ -1320,16 +1321,46 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm->mm_node.size); if (vc4->gen >= VC4_GEN_6_C) { - /* This sets a black background color fill, as is the case + /* This sets the background color fill, as is the case * with other DRM drivers. */ + if (vc4->gen == VC4_GEN_6_C) { + HVS_WRITE(SCALER6_DISPX_BGND(channel), + VC4_SET_FIELD(DRM_ARGB64_GETR_BPCS(bgcolor, 8), + SCALER6_DISPX_BGND_FILL_RED) | + VC4_SET_FIELD(DRM_ARGB64_GETG_BPCS(bgcolor, 8), + SCALER6_DISPX_BGND_FILL_GREEN) | + VC4_SET_FIELD(DRM_ARGB64_GETB_BPCS(bgcolor, 8), + SCALER6_DISPX_BGND_FILL_BLUE) | + VC4_SET_FIELD(DRM_ARGB64_GETA_BPCS(bgcolor, 8), + SCALER6_DISPX_BGND_FILL_ALPHA)); + } else { + /* GEN_6_D takes a 12bit background colour */ + HVS_WRITE(SCALER6D_DISPX_BGND0(channel), + VC4_SET_FIELD(DRM_ARGB64_GETG_BPCS(bgcolor, 12), + SCALER6D_DISPX_BGND0_FILL_GREEN) | + VC4_SET_FIELD(DRM_ARGB64_GETB_BPCS(bgcolor, 12), + SCALER6D_DISPX_BGND0_FILL_BLUE)); + HVS_WRITE(SCALER6D_DISPX_BGND1(channel), + VC4_SET_FIELD(DRM_ARGB64_GETR_BPCS(bgcolor, 12), + SCALER6D_DISPX_BGND1_FILL_RED) | + VC4_SET_FIELD(DRM_ARGB64_GETA_BPCS(bgcolor, 12), + SCALER6D_DISPX_BGND1_FILL_ALPHA)); + } hvs->bg_fill[channel] = enable_bg_fill; } else { /* we can actually run with a lower core clock when background * fill is enabled on VC4_GEN_5 so leave it enabled always. */ HVS_WRITE(SCALER_DISPBKGNDX(channel), - HVS_READ(SCALER_DISPBKGNDX(channel)) | + (HVS_READ(SCALER_DISPBKGNDX(channel)) & + ~SCALER_DISPBKGND_FILL_MASK) | + VC4_SET_FIELD(DRM_ARGB64_GETR_BPCS(bgcolor, 8), + SCALER_DISPBKGND_FILL_RED) | + VC4_SET_FIELD(DRM_ARGB64_GETG_BPCS(bgcolor, 8), + SCALER_DISPBKGND_FILL_GREEN) | + VC4_SET_FIELD(DRM_ARGB64_GETB_BPCS(bgcolor, 8), + SCALER_DISPBKGND_FILL_BLUE) | SCALER_DISPBKGND_FILL); } diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index 68d83d27c32ad9..c4387459046838 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h @@ -402,6 +402,15 @@ * opaque display planes will cover everything. */ # define SCALER_DISPBKGND_FILL BIT(24) +# define SCALER_DISPBKGND_FILL_RED_MASK VC4_MASK(23, 16) +# define SCALER_DISPBKGND_FILL_RED_SHIFT 16 +# define SCALER_DISPBKGND_FILL_GREEN_MASK VC4_MASK(15, 8) +# define SCALER_DISPBKGND_FILL_GREEN_SHIFT 8 +# define SCALER_DISPBKGND_FILL_BLUE_MASK VC4_MASK(7, 0) +# define SCALER_DISPBKGND_FILL_BLUE_SHIFT 0 +# define SCALER_DISPBKGND_FILL_MASK (SCALER_DISPBKGND_FILL_RED_MASK | \ + SCALER_DISPBKGND_FILL_GREEN_MASK | \ + SCALER_DISPBKGND_FILL_BLUE_MASK) #define SCALER_DISPSTAT0 0x00000048 # define SCALER_DISPSTATX_MODE_MASK VC4_MASK(31, 30) @@ -580,9 +589,16 @@ # define SCALER6_DISPX_CTRL1_INTLACE BIT(0) #define SCALER6_DISP0_BGND 0x00000038 -#define SCALER6_DISPX_BGND(x) ((hvs->vc4->gen == VC4_GEN_6_C) ? \ - (SCALER6_DISP0_BGND + ((x) * (SCALER6_DISP1_BGND - SCALER6_DISP0_BGND))) : \ - (SCALER6D_DISP0_BGND + ((x) * (SCALER6D_DISP1_BGND - SCALER6D_DISP0_BGND)))) +#define SCALER6_DISPX_BGND(x) \ + (SCALER6_DISP0_BGND + ((x) * (SCALER6_DISP1_BGND - SCALER6_DISP0_BGND))) +# define SCALER6_DISPX_BGND_FILL_ALPHA_MASK VC4_MASK(31, 24) +# define SCALER6_DISPX_BGND_FILL_ALPHA_SHIFT 24 +# define SCALER6_DISPX_BGND_FILL_RED_MASK VC4_MASK(23, 16) +# define SCALER6_DISPX_BGND_FILL_RED_SHIFT 16 +# define SCALER6_DISPX_BGND_FILL_GREEN_MASK VC4_MASK(15, 8) +# define SCALER6_DISPX_BGND_FILL_GREEN_SHIFT 8 +# define SCALER6_DISPX_BGND_FILL_BLUE_MASK VC4_MASK(7, 0) +# define SCALER6_DISPX_BGND_FILL_BLUE_SHIFT 0 #define SCALER6_DISP0_LPTRS 0x0000003c #define SCALER6_DISPX_LPTRS(x) ((hvs->vc4->gen == VC4_GEN_6_C) ? \ @@ -698,16 +714,22 @@ #define SCALER6D_HISTBIN7 0x000000f0 #define SCALER6D_HVS_ID 0x000000fc -#define SCALER6D_DISP0_CTRL0 0x00000100 -#define SCALER6D_DISP0_CTRL1 0x00000104 -#define SCALER6D_DISP0_BGND 0x00000108 -#define SCALER6D_DISP0_LPTRS 0x00000110 -#define SCALER6D_DISP0_COB 0x00000114 -#define SCALER6D_DISP0_STATUS 0x00000118 #define SCALER6D_DISP0_CTRL0 0x00000100 #define SCALER6D_DISP0_CTRL1 0x00000104 #define SCALER6D_DISP0_BGND0 0x00000108 +#define SCALER6D_DISPX_BGND0(x) \ + (SCALER6D_DISP0_BGND0 + ((x) * (SCALER6D_DISP1_BGND0 - SCALER6D_DISP0_BGND0))) +# define SCALER6D_DISPX_BGND0_FILL_GREEN_MASK VC4_MASK(31, 20) +# define SCALER6D_DISPX_BGND0_FILL_GREEN_SHIFT 20 +# define SCALER6D_DISPX_BGND0_FILL_BLUE_MASK VC4_MASK(15, 4) +# define SCALER6D_DISPX_BGND0_FILL_BLUE_SHIFT 4 #define SCALER6D_DISP0_BGND1 0x0000010c +#define SCALER6D_DISPX_BGND1(x) \ + (SCALER6D_DISP0_BGND1 + ((x) * (SCALER6D_DISP1_BGND1 - SCALER6D_DISP0_BGND1))) +# define SCALER6D_DISPX_BGND1_FILL_ALPHA_MASK VC4_MASK(31, 20) +# define SCALER6D_DISPX_BGND1_FILL_ALPHA_SHIFT 20 +# define SCALER6D_DISPX_BGND1_FILL_RED_MASK VC4_MASK(15, 4) +# define SCALER6D_DISPX_BGND1_FILL_RED_SHIFT 4 #define SCALER6D_DISP0_LPTRS 0x00000110 #define SCALER6D_DISP0_COB 0x00000114 #define SCALER6D_DISP0_STATUS 0x00000118 diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h index a84c58f3f13cdc..87fbf64e664923 100644 --- a/include/drm/drm_blend.h +++ b/include/drm/drm_blend.h @@ -31,8 +31,9 @@ #define DRM_MODE_BLEND_COVERAGE 1 #define DRM_MODE_BLEND_PIXEL_NONE 2 -struct drm_device; struct drm_atomic_state; +struct drm_crtc; +struct drm_device; struct drm_plane; struct drm_connector; @@ -59,6 +60,7 @@ int drm_atomic_normalize_zpos(struct drm_device *dev, struct drm_atomic_state *state); int drm_plane_create_blend_mode_property(struct drm_plane *plane, unsigned int supported_modes); +void drm_crtc_attach_background_color_property(struct drm_crtc *crtc); int drm_connector_create_rotation_property(struct drm_connector *conn, unsigned int rotation, diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c85b9f6b94f152..ed7b1490a49ff1 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -274,6 +274,18 @@ struct drm_crtc_state { */ struct drm_property_blob *gamma_lut; + /** + * @background_color: + * + * RGB value representing the CRTC's background color. The background + * color (aka "canvas color") of a CRTC is the color that will be used + * for pixels not covered by a plane, or covered by transparent pixels + * of a plane. The value here should be built using DRM_ARGB64_PREP*() + * helpers, while the individual color components can be extracted with + * desired precision via the DRM_ARGB64_GET*() macros. + */ + u64 background_color; + /** * @target_vblank: * diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 2e848b81621858..ea422afec5c410 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -814,6 +814,11 @@ struct drm_mode_config { * gamma LUT as supported by the driver (read-only). */ struct drm_property *gamma_lut_size_property; + /** + * @background_color_property: Optional CRTC property to set the + * background color. + */ + struct drm_property *background_color_property; /** * @suggested_x_property: Optional connector property with a hint for diff --git a/include/linux/math.h b/include/linux/math.h index 0198c92cbe3ef5..24bb868f971cf2 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -89,23 +89,7 @@ } \ ) -/* - * Divide positive or negative dividend by positive or negative divisor - * and round to closest integer. Result is undefined for negative - * divisors if the dividend variable type is unsigned and for negative - * dividends if the divisor variable type is unsigned. - */ -#define DIV_ROUND_CLOSEST(x, divisor)( \ -{ \ - typeof(x) __x = x; \ - typeof(divisor) __d = divisor; \ - (((typeof(x))-1) > 0 || \ - ((typeof(divisor))-1) > 0 || \ - (((__x) > 0) == ((__d) > 0))) ? \ - (((__x) + ((__d) / 2)) / (__d)) : \ - (((__x) - ((__d) / 2)) / (__d)); \ -} \ -) +#define DIV_ROUND_CLOSEST __KERNEL_DIV_ROUND_CLOSEST /* * Same as above but for u64 dividends. divisor must be a 32-bit * number. diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 6a04b6107614fe..dc5a4049df1d06 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -27,6 +27,9 @@ #ifndef _DRM_MODE_H #define _DRM_MODE_H +#include +#include + #include "drm.h" #if defined(__cplusplus) @@ -1364,6 +1367,83 @@ struct drm_mode_closefb { __u32 pad; }; +/* + * Put 16-bit ARGB values into a standard 64-bit representation that can be + * used for ioctl parameters, inter-driver communication, etc. + * + * If the component values being provided contain less than 16 bits of + * precision, use a conversion ratio to get a better color approximation. + * The ratio is computed as (2^16 - 1) / (2^bpc - 1), where bpc and 16 are + * the input and output precision, respectively. + * Also note bpc must be greater than 0. + */ +#define __DRM_ARGB64_PREP(c, shift) \ + (((__u64)(c) & __GENMASK(15, 0)) << (shift)) + +#define __DRM_ARGB64_PREP_BPC(c, shift, bpc) \ +({ \ + __u16 mask = __GENMASK((bpc) - 1, 0); \ + __u16 conv = __KERNEL_DIV_ROUND_CLOSEST((mask & (c)) * \ + __GENMASK(15, 0), mask);\ + __DRM_ARGB64_PREP(conv, shift); \ +}) + +#define DRM_ARGB64_PREP(alpha, red, green, blue) \ +( \ + __DRM_ARGB64_PREP(alpha, 48) | \ + __DRM_ARGB64_PREP(red, 32) | \ + __DRM_ARGB64_PREP(green, 16) | \ + __DRM_ARGB64_PREP(blue, 0) \ +) + +#define DRM_ARGB64_PREP_BPC(alpha, red, green, blue, bpc) \ +({ \ + __typeof__(bpc) __bpc = bpc; \ + __DRM_ARGB64_PREP_BPC(alpha, 48, __bpc) | \ + __DRM_ARGB64_PREP_BPC(red, 32, __bpc) | \ + __DRM_ARGB64_PREP_BPC(green, 16, __bpc) | \ + __DRM_ARGB64_PREP_BPC(blue, 0, __bpc); \ +}) + +/* + * Extract the specified color component from a standard 64-bit ARGB value. + * + * If the requested precision is less than 16 bits, make use of a conversion + * ratio calculated as (2^bpc - 1) / (2^16 - 1), where bpc and 16 are the + * output and input precision, respectively. + * + * If speed is more important than accuracy, use DRM_ARGB64_GET*_BPCS() + * instead of DRM_ARGB64_GET*_BPC() in order to replace the expensive + * division with a simple bit right-shift operation. + */ +#define __DRM_ARGB64_GET(c, shift) \ + ((__u16)(((__u64)(c) >> (shift)) & __GENMASK(15, 0))) + +#define __DRM_ARGB64_GET_BPC(c, shift, bpc) \ +({ \ + __u16 comp = __DRM_ARGB64_GET(c, shift); \ + __KERNEL_DIV_ROUND_CLOSEST(comp * __GENMASK((bpc) - 1, 0), \ + __GENMASK(15, 0)); \ +}) + +#define __DRM_ARGB64_GET_BPCS(c, shift, bpc) \ + (__DRM_ARGB64_GET(c, shift) >> (16 - (bpc))) + +#define DRM_ARGB64_GETA(c) __DRM_ARGB64_GET(c, 48) +#define DRM_ARGB64_GETR(c) __DRM_ARGB64_GET(c, 32) +#define DRM_ARGB64_GETG(c) __DRM_ARGB64_GET(c, 16) +#define DRM_ARGB64_GETB(c) __DRM_ARGB64_GET(c, 0) + +#define DRM_ARGB64_GETA_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 48, bpc) +#define DRM_ARGB64_GETR_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 32, bpc) +#define DRM_ARGB64_GETG_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 16, bpc) +#define DRM_ARGB64_GETB_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 0, bpc) + +#define DRM_ARGB64_GETA_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 48, bpc) +#define DRM_ARGB64_GETR_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 32, bpc) +#define DRM_ARGB64_GETG_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 16, bpc) +#define DRM_ARGB64_GETB_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 0, bpc) + #if defined(__cplusplus) } #endif diff --git a/include/uapi/linux/const.h b/include/uapi/linux/const.h index b8f629ef135f35..565f309b9df8b1 100644 --- a/include/uapi/linux/const.h +++ b/include/uapi/linux/const.h @@ -50,4 +50,22 @@ #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) +/* + * Divide positive or negative dividend by positive or negative divisor + * and round to closest integer. Result is undefined for negative + * divisors if the dividend variable type is unsigned and for negative + * dividends if the divisor variable type is unsigned. + */ +#define __KERNEL_DIV_ROUND_CLOSEST(x, divisor) \ +({ \ + __typeof__(x) __x = x; \ + __typeof__(divisor) __d = divisor; \ + \ + (((__typeof__(x))-1) > 0 || \ + ((__typeof__(divisor))-1) > 0 || \ + (((__x) > 0) == ((__d) > 0))) ? \ + (((__x) + ((__d) / 2)) / (__d)) : \ + (((__x) - ((__d) / 2)) / (__d)); \ +}) + #endif /* _UAPI_LINUX_CONST_H */