Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/dpll/zl3073x/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 5 kB image not shown  

Quelle  devlink.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only

#include <linux/device/devres.h>
#include <linux/netlink.h>
#include <linux/sprintf.h>
#include <linux/types.h>
#include <net/devlink.h>

#include "core.h"
#include "devlink.h"
#include "dpll.h"
#include "regs.h"

/**
 * zl3073x_devlink_info_get - Devlink device info callback
 * @devlink: devlink structure pointer
 * @req: devlink request pointer to store information
 * @extack: netlink extack pointer to report errors
 *
 * Return: 0 on success, <0 on error
 */

static int
zl3073x_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
    struct netlink_ext_ack *extack)
{
 struct zl3073x_dev *zldev = devlink_priv(devlink);
 u16 id, revision, fw_ver;
 char buf[16];
 u32 cfg_ver;
 int rc;

 rc = zl3073x_read_u16(zldev, ZL_REG_ID, &id);
 if (rc)
  return rc;

 snprintf(buf, sizeof(buf), "%X", id);
 rc = devlink_info_version_fixed_put(req,
         DEVLINK_INFO_VERSION_GENERIC_ASIC_ID,
         buf);
 if (rc)
  return rc;

 rc = zl3073x_read_u16(zldev, ZL_REG_REVISION, &revision);
 if (rc)
  return rc;

 snprintf(buf, sizeof(buf), "%X", revision);
 rc = devlink_info_version_fixed_put(req,
         DEVLINK_INFO_VERSION_GENERIC_ASIC_REV,
         buf);
 if (rc)
  return rc;

 rc = zl3073x_read_u16(zldev, ZL_REG_FW_VER, &fw_ver);
 if (rc)
  return rc;

 snprintf(buf, sizeof(buf), "%u", fw_ver);
 rc = devlink_info_version_running_put(req,
           DEVLINK_INFO_VERSION_GENERIC_FW,
           buf);
 if (rc)
  return rc;

 rc = zl3073x_read_u32(zldev, ZL_REG_CUSTOM_CONFIG_VER, &cfg_ver);
 if (rc)
  return rc;

 /* No custom config version */
 if (cfg_ver == U32_MAX)
  return 0;

 snprintf(buf, sizeof(buf), "%lu.%lu.%lu.%lu",
   FIELD_GET(GENMASK(31, 24), cfg_ver),
   FIELD_GET(GENMASK(23, 16), cfg_ver),
   FIELD_GET(GENMASK(15, 8), cfg_ver),
   FIELD_GET(GENMASK(7, 0), cfg_ver));

 return devlink_info_version_running_put(req, "custom_cfg", buf);
}

static int
zl3073x_devlink_reload_down(struct devlink *devlink, bool netns_change,
       enum devlink_reload_action action,
       enum devlink_reload_limit limit,
       struct netlink_ext_ack *extack)
{
 struct zl3073x_dev *zldev = devlink_priv(devlink);

 if (action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT)
  return -EOPNOTSUPP;

 /* Stop normal operation */
 zl3073x_dev_stop(zldev);

 return 0;
}

static int
zl3073x_devlink_reload_up(struct devlink *devlink,
     enum devlink_reload_action action,
     enum devlink_reload_limit limit,
     u32 *actions_performed,
     struct netlink_ext_ack *extack)
{
 struct zl3073x_dev *zldev = devlink_priv(devlink);
 union devlink_param_value val;
 int rc;

 if (action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT)
  return -EOPNOTSUPP;

 rc = devl_param_driverinit_value_get(devlink,
          DEVLINK_PARAM_GENERIC_ID_CLOCK_ID,
          &val);
 if (rc)
  return rc;

 if (zldev->clock_id != val.vu64) {
  dev_dbg(zldev->dev,
   "'clock_id' changed to %016llx\n", val.vu64);
  zldev->clock_id = val.vu64;
 }

 /* Restart normal operation */
 rc = zl3073x_dev_start(zldev, false);
 if (rc)
  dev_warn(zldev->dev, "Failed to re-start normal operation\n");

 *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);

 return 0;
}

static const struct devlink_ops zl3073x_devlink_ops = {
 .info_get = zl3073x_devlink_info_get,
 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
 .reload_down = zl3073x_devlink_reload_down,
 .reload_up = zl3073x_devlink_reload_up,
};

static void
zl3073x_devlink_free(void *ptr)
{
 devlink_free(ptr);
}

/**
 * zl3073x_devm_alloc - allocates zl3073x device structure
 * @dev: pointer to device structure
 *
 * Allocates zl3073x device structure as device resource.
 *
 * Return: pointer to zl3073x device on success, error pointer on error
 */

struct zl3073x_dev *zl3073x_devm_alloc(struct device *dev)
{
 struct zl3073x_dev *zldev;
 struct devlink *devlink;
 int rc;

 devlink = devlink_alloc(&zl3073x_devlink_ops, sizeof(*zldev), dev);
 if (!devlink)
  return ERR_PTR(-ENOMEM);

 /* Add devres action to free devlink device */
 rc = devm_add_action_or_reset(dev, zl3073x_devlink_free, devlink);
 if (rc)
  return ERR_PTR(rc);

 zldev = devlink_priv(devlink);
 zldev->dev = dev;
 dev_set_drvdata(zldev->dev, zldev);

 return zldev;
}
EXPORT_SYMBOL_NS_GPL(zl3073x_devm_alloc, "ZL3073X");

static int
zl3073x_devlink_param_clock_id_validate(struct devlink *devlink, u32 id,
     union devlink_param_value val,
     struct netlink_ext_ack *extack)
{
 if (!val.vu64) {
  NL_SET_ERR_MSG_MOD(extack, "'clock_id' must be non-zero");
  return -EINVAL;
 }

 return 0;
}

static const struct devlink_param zl3073x_devlink_params[] = {
 DEVLINK_PARAM_GENERIC(CLOCK_ID, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
         NULL, NULL,
         zl3073x_devlink_param_clock_id_validate),
};

static void
zl3073x_devlink_unregister(void *ptr)
{
 struct devlink *devlink = priv_to_devlink(ptr);

 devl_lock(devlink);

 /* Unregister devlink params */
 devl_params_unregister(devlink, zl3073x_devlink_params,
          ARRAY_SIZE(zl3073x_devlink_params));

 /* Unregister devlink instance */
 devl_unregister(devlink);

 devl_unlock(devlink);
}

/**
 * zl3073x_devlink_register - register devlink instance and params
 * @zldev: zl3073x device to register the devlink for
 *
 * Register the devlink instance and parameters associated with the device.
 *
 * Return: 0 on success, <0 on error
 */

int zl3073x_devlink_register(struct zl3073x_dev *zldev)
{
 struct devlink *devlink = priv_to_devlink(zldev);
 union devlink_param_value value;
 int rc;

 devl_lock(devlink);

 /* Register devlink params */
 rc = devl_params_register(devlink, zl3073x_devlink_params,
      ARRAY_SIZE(zl3073x_devlink_params));
 if (rc) {
  devl_unlock(devlink);

  return rc;
 }

 value.vu64 = zldev->clock_id;
 devl_param_driverinit_value_set(devlink,
     DEVLINK_PARAM_GENERIC_ID_CLOCK_ID,
     value);

 /* Register devlink instance */
 devl_register(devlink);

 devl_unlock(devlink);

 /* Add devres action to unregister devlink device */
 return devm_add_action_or_reset(zldev->dev, zl3073x_devlink_unregister,
     zldev);
}

Messung V0.5
C=95 H=100 G=97

¤ 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.