linux_dsm_epyc7002/include/linux/fwnode.h

116 lines
3.8 KiB
C
Raw Normal View History

/*
* fwnode.h - Firmware device node object handle type definition.
*
* Copyright (C) 2015, Intel Corporation
* Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _LINUX_FWNODE_H_
#define _LINUX_FWNODE_H_
#include <linux/types.h>
enum fwnode_type {
FWNODE_INVALID = 0,
FWNODE_OF,
FWNODE_ACPI,
ACPI / property: Add support for data-only subnodes In some cases, the information expressed via device properties is hierarchical by nature. For example, the properties of a composite device consisting of multiple semi-dependent components may need to be represented in the form of a tree of property data sets corresponding to specific components of the device. Unfortunately, using ACPI device objects for this purpose turns out to be problematic, mostly due to the assumption made by some operating systems (that platform firmware generally needs to work with) that each device object in the ACPI namespace represents a device requiring a separate driver. That assumption leads to complications which reportedly are impractically difficult to overcome and a different approach is needed for the sake of interoperability. The approach implemented here is based on extending _DSD via pointers (links) to additional ACPI objects returning data packages formatted in accordance with the _DSD formatting rules defined by Section 6.2.5 of ACPI 6. Those additional objects are referred to as data-only subnodes of the device object containing the _DSD pointing to them. The links to them need to be located in a separate section of the _DSD data package following UUID dbb8e3e6-5886-4ba6-8795-1319f52a966b referred to as the Hierarchical Data Extension UUID as defined in [1]. Each of them is represented by a package of two strings. The first string in that package (the key) is regarded as the name of the data-only subnode pointed to by the link. The second string in it (the target) is expected to hold the ACPI namespace path (possibly utilizing the usual ACPI namespace search rules) of an ACPI object evaluating to a data package extending the _DSD. The device properties initialization code follows those links, creates a struct acpi_data_node object for each of them to store the data returned by the ACPI object pointed to by it and processes those data recursively (which may lead to the creation of more struct acpi_data_node objects if the returned data package contains the Hierarchical Data Extension UUID section with more links in it). All of the struct acpi_data_node objects are present until the the ACPI device object containing the _DSD with links to them is deleted and they are deleted along with that object. [1]: http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2015-08-27 09:36:14 +07:00
FWNODE_ACPI_DATA,
ACPI: Add FWNODE_ACPI_STATIC fwnode type On systems booting with a device tree, every struct device is associated with a struct device_node, that provides its DT firmware representation. The device node can be used in generic kernel contexts (eg IRQ translation, IOMMU streamid mapping), to retrieve the properties associated with the device and carry out kernel operations accordingly. Owing to the 1:1 relationship between the device and its device_node, the device_node can also be used as a look-up token for the device (eg looking up a device through its device_node), to retrieve the device in kernel paths where the device_node is available. On systems booting with ACPI, the same abstraction provided by the device_node is required to provide look-up functionality. The struct acpi_device, that represents firmware objects in the ACPI namespace already includes a struct fwnode_handle of type FWNODE_ACPI as their member; the same abstraction is missing though for devices that are instantiated out of static ACPI tables entries (eg ARM SMMU devices). Add a new fwnode_handle type to associate devices created out of static ACPI table entries to the respective firmware components and create a simple ACPI core layer interface to dynamically allocate and free the corresponding firmware nodes so that kernel subsystems can use it to instantiate the nodes and associate them with the respective devices. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org> Reviewed-by: Tomasz Nowicki <tn@semihalf.com> Tested-by: Hanjun Guo <hanjun.guo@linaro.org> Tested-by: Tomasz Nowicki <tn@semihalf.com> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Signed-off-by: Will Deacon <will.deacon@arm.com>
2016-11-21 17:01:33 +07:00
FWNODE_ACPI_STATIC,
FWNODE_PDATA,
ACPI: Add FWNODE_ACPI_STATIC fwnode type On systems booting with a device tree, every struct device is associated with a struct device_node, that provides its DT firmware representation. The device node can be used in generic kernel contexts (eg IRQ translation, IOMMU streamid mapping), to retrieve the properties associated with the device and carry out kernel operations accordingly. Owing to the 1:1 relationship between the device and its device_node, the device_node can also be used as a look-up token for the device (eg looking up a device through its device_node), to retrieve the device in kernel paths where the device_node is available. On systems booting with ACPI, the same abstraction provided by the device_node is required to provide look-up functionality. The struct acpi_device, that represents firmware objects in the ACPI namespace already includes a struct fwnode_handle of type FWNODE_ACPI as their member; the same abstraction is missing though for devices that are instantiated out of static ACPI tables entries (eg ARM SMMU devices). Add a new fwnode_handle type to associate devices created out of static ACPI table entries to the respective firmware components and create a simple ACPI core layer interface to dynamically allocate and free the corresponding firmware nodes so that kernel subsystems can use it to instantiate the nodes and associate them with the respective devices. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org> Reviewed-by: Tomasz Nowicki <tn@semihalf.com> Tested-by: Hanjun Guo <hanjun.guo@linaro.org> Tested-by: Tomasz Nowicki <tn@semihalf.com> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Signed-off-by: Will Deacon <will.deacon@arm.com>
2016-11-21 17:01:33 +07:00
FWNODE_IRQCHIP
};
struct fwnode_operations;
struct fwnode_handle {
enum fwnode_type type;
2015-04-04 04:23:37 +07:00
struct fwnode_handle *secondary;
const struct fwnode_operations *ops;
};
/**
* struct fwnode_endpoint - Fwnode graph endpoint
* @port: Port number
* @id: Endpoint id
* @local_fwnode: reference to the related fwnode
*/
struct fwnode_endpoint {
unsigned int port;
unsigned int id;
const struct fwnode_handle *local_fwnode;
};
/**
* struct fwnode_operations - Operations for fwnode interface
* @get: Get a reference to an fwnode.
* @put: Put a reference to an fwnode.
* @property_present: Return true if a property is present.
* @property_read_integer_array: Read an array of integer properties. Return
* zero on success, a negative error code
* otherwise.
* @property_read_string_array: Read an array of string properties. Return zero
* on success, a negative error code otherwise.
* @get_parent: Return the parent of an fwnode.
* @get_next_child_node: Return the next child node in an iteration.
* @get_named_child_node: Return a child node with a given name.
* @graph_get_next_endpoint: Return an endpoint node in an iteration.
* @graph_get_remote_endpoint: Return the remote endpoint node of a local
* endpoint node.
* @graph_get_port_parent: Return the parent node of a port node.
* @graph_parse_endpoint: Parse endpoint for port and endpoint id.
*/
struct fwnode_operations {
void (*get)(struct fwnode_handle *fwnode);
void (*put)(struct fwnode_handle *fwnode);
bool (*device_is_available)(struct fwnode_handle *fwnode);
bool (*property_present)(struct fwnode_handle *fwnode,
const char *propname);
int (*property_read_int_array)(struct fwnode_handle *fwnode,
const char *propname,
unsigned int elem_size, void *val,
size_t nval);
int (*property_read_string_array)(struct fwnode_handle *fwnode_handle,
const char *propname,
const char **val, size_t nval);
struct fwnode_handle *(*get_parent)(struct fwnode_handle *fwnode);
struct fwnode_handle *
(*get_next_child_node)(struct fwnode_handle *fwnode,
struct fwnode_handle *child);
struct fwnode_handle *
(*get_named_child_node)(struct fwnode_handle *fwnode, const char *name);
struct fwnode_handle *
(*graph_get_next_endpoint)(struct fwnode_handle *fwnode,
struct fwnode_handle *prev);
struct fwnode_handle *
(*graph_get_remote_endpoint)(struct fwnode_handle *fwnode);
struct fwnode_handle *
(*graph_get_port_parent)(struct fwnode_handle *fwnode);
int (*graph_parse_endpoint)(struct fwnode_handle *fwnode,
struct fwnode_endpoint *endpoint);
};
#define fwnode_has_op(fwnode, op) \
((fwnode) && (fwnode)->ops && (fwnode)->ops->op)
#define fwnode_call_int_op(fwnode, op, ...) \
(fwnode ? (fwnode_has_op(fwnode, op) ? \
(fwnode)->ops->op(fwnode, ## __VA_ARGS__) : -ENXIO) : \
-EINVAL)
#define fwnode_call_bool_op(fwnode, op, ...) \
(fwnode ? (fwnode_has_op(fwnode, op) ? \
(fwnode)->ops->op(fwnode, ## __VA_ARGS__) : false) : \
false)
#define fwnode_call_ptr_op(fwnode, op, ...) \
(fwnode_has_op(fwnode, op) ? \
(fwnode)->ops->op(fwnode, ## __VA_ARGS__) : NULL)
#define fwnode_call_void_op(fwnode, op, ...) \
do { \
if (fwnode_has_op(fwnode, op)) \
(fwnode)->ops->op(fwnode, ## __VA_ARGS__); \
} while (false)
#endif