linux/drivers/acpi/acpica/utxface.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/******************************************************************************
   3 *
   4 * Module Name: utxface - External interfaces, miscellaneous utility functions
   5 *
   6 * Copyright (C) 2000 - 2021, Intel Corp.
   7 *
   8 *****************************************************************************/
   9
  10#define EXPORT_ACPI_INTERFACES
  11
  12#include <acpi/acpi.h>
  13#include "accommon.h"
  14#include "acdebug.h"
  15
  16#define _COMPONENT          ACPI_UTILITIES
  17ACPI_MODULE_NAME("utxface")
  18
  19/*******************************************************************************
  20 *
  21 * FUNCTION:    acpi_terminate
  22 *
  23 * PARAMETERS:  None
  24 *
  25 * RETURN:      Status
  26 *
  27 * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources.
  28 *
  29 ******************************************************************************/
  30acpi_status ACPI_INIT_FUNCTION acpi_terminate(void)
  31{
  32        acpi_status status;
  33
  34        ACPI_FUNCTION_TRACE(acpi_terminate);
  35
  36        /* Shutdown and free all resources */
  37
  38        acpi_ut_subsystem_shutdown();
  39
  40        /* Free the mutex objects */
  41
  42        acpi_ut_mutex_terminate();
  43
  44        /* Now we can shutdown the OS-dependent layer */
  45
  46        status = acpi_os_terminate();
  47        return_ACPI_STATUS(status);
  48}
  49
  50ACPI_EXPORT_SYMBOL_INIT(acpi_terminate)
  51
  52#ifndef ACPI_ASL_COMPILER
  53#ifdef ACPI_FUTURE_USAGE
  54/*******************************************************************************
  55 *
  56 * FUNCTION:    acpi_subsystem_status
  57 *
  58 * PARAMETERS:  None
  59 *
  60 * RETURN:      Status of the ACPI subsystem
  61 *
  62 * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
  63 *              before making any other calls, to ensure the subsystem
  64 *              initialized successfully.
  65 *
  66 ******************************************************************************/
  67acpi_status acpi_subsystem_status(void)
  68{
  69
  70        if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) {
  71                return (AE_OK);
  72        } else {
  73                return (AE_ERROR);
  74        }
  75}
  76
  77ACPI_EXPORT_SYMBOL(acpi_subsystem_status)
  78
  79/*******************************************************************************
  80 *
  81 * FUNCTION:    acpi_get_system_info
  82 *
  83 * PARAMETERS:  out_buffer      - A buffer to receive the resources for the
  84 *                                device
  85 *
  86 * RETURN:      status          - the status of the call
  87 *
  88 * DESCRIPTION: This function is called to get information about the current
  89 *              state of the ACPI subsystem. It will return system information
  90 *              in the out_buffer.
  91 *
  92 *              If the function fails an appropriate status will be returned
  93 *              and the value of out_buffer is undefined.
  94 *
  95 ******************************************************************************/
  96acpi_status acpi_get_system_info(struct acpi_buffer *out_buffer)
  97{
  98        struct acpi_system_info *info_ptr;
  99        acpi_status status;
 100
 101        ACPI_FUNCTION_TRACE(acpi_get_system_info);
 102
 103        /* Parameter validation */
 104
 105        status = acpi_ut_validate_buffer(out_buffer);
 106        if (ACPI_FAILURE(status)) {
 107                return_ACPI_STATUS(status);
 108        }
 109
 110        /* Validate/Allocate/Clear caller buffer */
 111
 112        status =
 113            acpi_ut_initialize_buffer(out_buffer,
 114                                      sizeof(struct acpi_system_info));
 115        if (ACPI_FAILURE(status)) {
 116                return_ACPI_STATUS(status);
 117        }
 118
 119        /*
 120         * Populate the return buffer
 121         */
 122        info_ptr = (struct acpi_system_info *)out_buffer->pointer;
 123        info_ptr->acpi_ca_version = ACPI_CA_VERSION;
 124
 125        /* System flags (ACPI capabilities) */
 126
 127        info_ptr->flags = ACPI_SYS_MODE_ACPI;
 128
 129        /* Timer resolution - 24 or 32 bits  */
 130
 131        if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) {
 132                info_ptr->timer_resolution = 24;
 133        } else {
 134                info_ptr->timer_resolution = 32;
 135        }
 136
 137        /* Clear the reserved fields */
 138
 139        info_ptr->reserved1 = 0;
 140        info_ptr->reserved2 = 0;
 141
 142        /* Current debug levels */
 143
 144        info_ptr->debug_layer = acpi_dbg_layer;
 145        info_ptr->debug_level = acpi_dbg_level;
 146
 147        return_ACPI_STATUS(AE_OK);
 148}
 149
 150ACPI_EXPORT_SYMBOL(acpi_get_system_info)
 151
 152/*******************************************************************************
 153 *
 154 * FUNCTION:    acpi_get_statistics
 155 *
 156 * PARAMETERS:  stats           - Where the statistics are returned
 157 *
 158 * RETURN:      status          - the status of the call
 159 *
 160 * DESCRIPTION: Get the contents of the various system counters
 161 *
 162 ******************************************************************************/
 163acpi_status acpi_get_statistics(struct acpi_statistics *stats)
 164{
 165        ACPI_FUNCTION_TRACE(acpi_get_statistics);
 166
 167        /* Parameter validation */
 168
 169        if (!stats) {
 170                return_ACPI_STATUS(AE_BAD_PARAMETER);
 171        }
 172
 173        /* Various interrupt-based event counters */
 174
 175        stats->sci_count = acpi_sci_count;
 176        stats->gpe_count = acpi_gpe_count;
 177
 178        memcpy(stats->fixed_event_count, acpi_fixed_event_count,
 179               sizeof(acpi_fixed_event_count));
 180
 181        /* Other counters */
 182
 183        stats->method_count = acpi_method_count;
 184        return_ACPI_STATUS(AE_OK);
 185}
 186
 187ACPI_EXPORT_SYMBOL(acpi_get_statistics)
 188
 189/*****************************************************************************
 190 *
 191 * FUNCTION:    acpi_install_initialization_handler
 192 *
 193 * PARAMETERS:  handler             - Callback procedure
 194 *              function            - Not (currently) used, see below
 195 *
 196 * RETURN:      Status
 197 *
 198 * DESCRIPTION: Install an initialization handler
 199 *
 200 * TBD: When a second function is added, must save the Function also.
 201 *
 202 ****************************************************************************/
 203acpi_status
 204acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
 205{
 206
 207        if (!handler) {
 208                return (AE_BAD_PARAMETER);
 209        }
 210
 211        if (acpi_gbl_init_handler) {
 212                return (AE_ALREADY_EXISTS);
 213        }
 214
 215        acpi_gbl_init_handler = handler;
 216        return (AE_OK);
 217}
 218
 219ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
 220#endif
 221
 222/*****************************************************************************
 223 *
 224 * FUNCTION:    acpi_purge_cached_objects
 225 *
 226 * PARAMETERS:  None
 227 *
 228 * RETURN:      Status
 229 *
 230 * DESCRIPTION: Empty all caches (delete the cached objects)
 231 *
 232 ****************************************************************************/
 233acpi_status acpi_purge_cached_objects(void)
 234{
 235        ACPI_FUNCTION_TRACE(acpi_purge_cached_objects);
 236
 237        (void)acpi_os_purge_cache(acpi_gbl_state_cache);
 238        (void)acpi_os_purge_cache(acpi_gbl_operand_cache);
 239        (void)acpi_os_purge_cache(acpi_gbl_ps_node_cache);
 240        (void)acpi_os_purge_cache(acpi_gbl_ps_node_ext_cache);
 241
 242        return_ACPI_STATUS(AE_OK);
 243}
 244
 245ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects)
 246
 247/*****************************************************************************
 248 *
 249 * FUNCTION:    acpi_install_interface
 250 *
 251 * PARAMETERS:  interface_name      - The interface to install
 252 *
 253 * RETURN:      Status
 254 *
 255 * DESCRIPTION: Install an _OSI interface to the global list
 256 *
 257 ****************************************************************************/
 258acpi_status acpi_install_interface(acpi_string interface_name)
 259{
 260        acpi_status status;
 261        struct acpi_interface_info *interface_info;
 262
 263        /* Parameter validation */
 264
 265        if (!interface_name || (strlen(interface_name) == 0)) {
 266                return (AE_BAD_PARAMETER);
 267        }
 268
 269        status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
 270        if (ACPI_FAILURE(status)) {
 271                return (status);
 272        }
 273
 274        /* Check if the interface name is already in the global list */
 275
 276        interface_info = acpi_ut_get_interface(interface_name);
 277        if (interface_info) {
 278                /*
 279                 * The interface already exists in the list. This is OK if the
 280                 * interface has been marked invalid -- just clear the bit.
 281                 */
 282                if (interface_info->flags & ACPI_OSI_INVALID) {
 283                        interface_info->flags &= ~ACPI_OSI_INVALID;
 284                        status = AE_OK;
 285                } else {
 286                        status = AE_ALREADY_EXISTS;
 287                }
 288        } else {
 289                /* New interface name, install into the global list */
 290
 291                status = acpi_ut_install_interface(interface_name);
 292        }
 293
 294        acpi_os_release_mutex(acpi_gbl_osi_mutex);
 295        return (status);
 296}
 297
 298ACPI_EXPORT_SYMBOL(acpi_install_interface)
 299
 300/*****************************************************************************
 301 *
 302 * FUNCTION:    acpi_remove_interface
 303 *
 304 * PARAMETERS:  interface_name      - The interface to remove
 305 *
 306 * RETURN:      Status
 307 *
 308 * DESCRIPTION: Remove an _OSI interface from the global list
 309 *
 310 ****************************************************************************/
 311acpi_status acpi_remove_interface(acpi_string interface_name)
 312{
 313        acpi_status status;
 314
 315        /* Parameter validation */
 316
 317        if (!interface_name || (strlen(interface_name) == 0)) {
 318                return (AE_BAD_PARAMETER);
 319        }
 320
 321        status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
 322        if (ACPI_FAILURE(status)) {
 323                return (status);
 324        }
 325
 326        status = acpi_ut_remove_interface(interface_name);
 327
 328        acpi_os_release_mutex(acpi_gbl_osi_mutex);
 329        return (status);
 330}
 331
 332ACPI_EXPORT_SYMBOL(acpi_remove_interface)
 333
 334/*****************************************************************************
 335 *
 336 * FUNCTION:    acpi_install_interface_handler
 337 *
 338 * PARAMETERS:  handler             - The _OSI interface handler to install
 339 *                                    NULL means "remove existing handler"
 340 *
 341 * RETURN:      Status
 342 *
 343 * DESCRIPTION: Install a handler for the predefined _OSI ACPI method.
 344 *              invoked during execution of the internal implementation of
 345 *              _OSI. A NULL handler simply removes any existing handler.
 346 *
 347 ****************************************************************************/
 348acpi_status acpi_install_interface_handler(acpi_interface_handler handler)
 349{
 350        acpi_status status;
 351
 352        status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
 353        if (ACPI_FAILURE(status)) {
 354                return (status);
 355        }
 356
 357        if (handler && acpi_gbl_interface_handler) {
 358                status = AE_ALREADY_EXISTS;
 359        } else {
 360                acpi_gbl_interface_handler = handler;
 361        }
 362
 363        acpi_os_release_mutex(acpi_gbl_osi_mutex);
 364        return (status);
 365}
 366
 367ACPI_EXPORT_SYMBOL(acpi_install_interface_handler)
 368
 369/*****************************************************************************
 370 *
 371 * FUNCTION:    acpi_update_interfaces
 372 *
 373 * PARAMETERS:  action              - Actions to be performed during the
 374 *                                    update
 375 *
 376 * RETURN:      Status
 377 *
 378 * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
 379 *              string or/and feature group strings.
 380 *
 381 ****************************************************************************/
 382acpi_status acpi_update_interfaces(u8 action)
 383{
 384        acpi_status status;
 385
 386        status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
 387        if (ACPI_FAILURE(status)) {
 388                return (status);
 389        }
 390
 391        status = acpi_ut_update_interfaces(action);
 392
 393        acpi_os_release_mutex(acpi_gbl_osi_mutex);
 394        return (status);
 395}
 396
 397/*****************************************************************************
 398 *
 399 * FUNCTION:    acpi_check_address_range
 400 *
 401 * PARAMETERS:  space_id            - Address space ID
 402 *              address             - Start address
 403 *              length              - Length
 404 *              warn                - TRUE if warning on overlap desired
 405 *
 406 * RETURN:      Count of the number of conflicts detected.
 407 *
 408 * DESCRIPTION: Check if the input address range overlaps any of the
 409 *              ASL operation region address ranges.
 410 *
 411 ****************************************************************************/
 412
 413u32
 414acpi_check_address_range(acpi_adr_space_type space_id,
 415                         acpi_physical_address address,
 416                         acpi_size length, u8 warn)
 417{
 418        u32 overlaps;
 419        acpi_status status;
 420
 421        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 422        if (ACPI_FAILURE(status)) {
 423                return (0);
 424        }
 425
 426        overlaps = acpi_ut_check_address_range(space_id, address,
 427                                               (u32)length, warn);
 428
 429        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 430        return (overlaps);
 431}
 432
 433ACPI_EXPORT_SYMBOL(acpi_check_address_range)
 434#endif                          /* !ACPI_ASL_COMPILER */
 435/*******************************************************************************
 436 *
 437 * FUNCTION:    acpi_decode_pld_buffer
 438 *
 439 * PARAMETERS:  in_buffer           - Buffer returned by _PLD method
 440 *              length              - Length of the in_buffer
 441 *              return_buffer       - Where the decode buffer is returned
 442 *
 443 * RETURN:      Status and the decoded _PLD buffer. User must deallocate
 444 *              the buffer via ACPI_FREE.
 445 *
 446 * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
 447 *              a local struct that is much more useful to an ACPI driver.
 448 *
 449 ******************************************************************************/
 450acpi_status
 451acpi_decode_pld_buffer(u8 *in_buffer,
 452                       acpi_size length, struct acpi_pld_info **return_buffer)
 453{
 454        struct acpi_pld_info *pld_info;
 455        u32 *buffer = ACPI_CAST_PTR(u32, in_buffer);
 456        u32 dword;
 457
 458        /* Parameter validation */
 459
 460        if (!in_buffer || !return_buffer
 461            || (length < ACPI_PLD_REV1_BUFFER_SIZE)) {
 462                return (AE_BAD_PARAMETER);
 463        }
 464
 465        pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info));
 466        if (!pld_info) {
 467                return (AE_NO_MEMORY);
 468        }
 469
 470        /* First 32-bit DWord */
 471
 472        ACPI_MOVE_32_TO_32(&dword, &buffer[0]);
 473        pld_info->revision = ACPI_PLD_GET_REVISION(&dword);
 474        pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword);
 475        pld_info->red = ACPI_PLD_GET_RED(&dword);
 476        pld_info->green = ACPI_PLD_GET_GREEN(&dword);
 477        pld_info->blue = ACPI_PLD_GET_BLUE(&dword);
 478
 479        /* Second 32-bit DWord */
 480
 481        ACPI_MOVE_32_TO_32(&dword, &buffer[1]);
 482        pld_info->width = ACPI_PLD_GET_WIDTH(&dword);
 483        pld_info->height = ACPI_PLD_GET_HEIGHT(&dword);
 484
 485        /* Third 32-bit DWord */
 486
 487        ACPI_MOVE_32_TO_32(&dword, &buffer[2]);
 488        pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword);
 489        pld_info->dock = ACPI_PLD_GET_DOCK(&dword);
 490        pld_info->lid = ACPI_PLD_GET_LID(&dword);
 491        pld_info->panel = ACPI_PLD_GET_PANEL(&dword);
 492        pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword);
 493        pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword);
 494        pld_info->shape = ACPI_PLD_GET_SHAPE(&dword);
 495        pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword);
 496        pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword);
 497        pld_info->group_position = ACPI_PLD_GET_POSITION(&dword);
 498        pld_info->bay = ACPI_PLD_GET_BAY(&dword);
 499
 500        /* Fourth 32-bit DWord */
 501
 502        ACPI_MOVE_32_TO_32(&dword, &buffer[3]);
 503        pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword);
 504        pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword);
 505        pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword);
 506        pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword);
 507        pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword);
 508        pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword);
 509        pld_info->order = ACPI_PLD_GET_ORDER(&dword);
 510
 511        if (length >= ACPI_PLD_REV2_BUFFER_SIZE) {
 512
 513                /* Fifth 32-bit DWord (Revision 2 of _PLD) */
 514
 515                ACPI_MOVE_32_TO_32(&dword, &buffer[4]);
 516                pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword);
 517                pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword);
 518        }
 519
 520        *return_buffer = pld_info;
 521        return (AE_OK);
 522}
 523
 524ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer)
 525