Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/m68k/fpsp040/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 18 kB image not shown  

SSL apmt.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * ARM APMT table support.
 * Design document number: ARM DEN0117.
 *
 * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
 *
 */


#define pr_fmt(fmt) "ACPI: APMT: " fmt

#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include "init.h"

#define DEV_NAME "arm-cs-arch-pmu"

/* There can be up to 3 resources: page 0 and 1 address, and interrupt. */
#define DEV_MAX_RESOURCE_COUNT 3

/* Root pointer to the mapped APMT table */
static struct acpi_table_header *apmt_table;

static int __init apmt_init_resources(struct resource *res,
          struct acpi_apmt_node *node)
{
 int irq, trigger;
 int num_res = 0;

 res[num_res].start = node->base_address0;
 res[num_res].end = node->base_address0 + SZ_4K - 1;
 res[num_res].flags = IORESOURCE_MEM;

 num_res++;

 if (node->flags & ACPI_APMT_FLAGS_DUAL_PAGE) {
  res[num_res].start = node->base_address1;
  res[num_res].end = node->base_address1 + SZ_4K - 1;
  res[num_res].flags = IORESOURCE_MEM;

  num_res++;
 }

 if (node->ovflw_irq != 0) {
  trigger = (node->ovflw_irq_flags & ACPI_APMT_OVFLW_IRQ_FLAGS_MODE);
  trigger = (trigger == ACPI_APMT_OVFLW_IRQ_FLAGS_MODE_LEVEL) ?
   ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
  irq = acpi_register_gsi(NULL, node->ovflw_irq, trigger,
      ACPI_ACTIVE_HIGH);

  if (irq <= 0) {
   pr_warn("APMT could not register gsi hwirq %d\n", irq);
   return num_res;
  }

  res[num_res].start = irq;
  res[num_res].end = irq;
  res[num_res].flags = IORESOURCE_IRQ;

  num_res++;
 }

 return num_res;
}

/**
 * apmt_add_platform_device() - Allocate a platform device for APMT node
 * @node: Pointer to device ACPI APMT node
 * @fwnode: fwnode associated with the APMT node
 *
 * Returns: 0 on success, <0 failure
 */

static int __init apmt_add_platform_device(struct acpi_apmt_node *node,
        struct fwnode_handle *fwnode)
{
 struct platform_device *pdev;
 int ret, count;
 struct resource res[DEV_MAX_RESOURCE_COUNT];

 pdev = platform_device_alloc(DEV_NAME, PLATFORM_DEVID_AUTO);
 if (!pdev)
  return -ENOMEM;

 memset(res, 0, sizeof(res));

 count = apmt_init_resources(res, node);

 ret = platform_device_add_resources(pdev, res, count);
 if (ret)
  goto dev_put;

 /*
 * Add a copy of APMT node pointer to platform_data to be used to
 * retrieve APMT data information.
 */

 ret = platform_device_add_data(pdev, &node, sizeof(node));
 if (ret)
  goto dev_put;

 pdev->dev.fwnode = fwnode;

 ret = platform_device_add(pdev);

 if (ret)
  goto dev_put;

 return 0;

dev_put:
 platform_device_put(pdev);

 return ret;
}

static int __init apmt_init_platform_devices(void)
{
 struct acpi_apmt_node *apmt_node;
 struct acpi_table_apmt *apmt;
 struct fwnode_handle *fwnode;
 u64 offset, end;
 int ret;

 /*
 * apmt_table and apmt both point to the start of APMT table, but
 * have different struct types
 */

 apmt = (struct acpi_table_apmt *)apmt_table;
 offset = sizeof(*apmt);
 end = apmt->header.length;

 while (offset < end) {
  apmt_node = ACPI_ADD_PTR(struct acpi_apmt_node, apmt,
     offset);

  fwnode = acpi_alloc_fwnode_static();
  if (!fwnode)
   return -ENOMEM;

  ret = apmt_add_platform_device(apmt_node, fwnode);
  if (ret) {
   acpi_free_fwnode_static(fwnode);
   return ret;
  }

  offset += apmt_node->length;
 }

 return 0;
}

void __init acpi_apmt_init(void)
{
 acpi_status status;
 int ret;

 /**
 * APMT table nodes will be used at runtime after the apmt init,
 * so we don't need to call acpi_put_table() to release
 * the APMT table mapping.
 */

 status = acpi_get_table(ACPI_SIG_APMT, 0, &apmt_table);

 if (ACPI_FAILURE(status)) {
  if (status != AE_NOT_FOUND) {
   const char *msg = acpi_format_exception(status);

   pr_err("Failed to get APMT table, %s\n", msg);
  }

  return;
 }

 ret = apmt_init_platform_devices();
 if (ret) {
  pr_err("Failed to initialize APMT platform devices, ret: %d\n", ret);
  acpi_put_table(apmt_table);
 }
}

Messung V0.5
C=95 H=89 G=91

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.