GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2013 Google, Inc
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
* Marek Vasut <marex@denx.de>
|
||||
*/
|
||||
|
||||
#ifndef _DM_DEVICE_INTERNAL_H
|
||||
#define _DM_DEVICE_INTERNAL_H
|
||||
|
||||
#include <dm/ofnode.h>
|
||||
|
||||
struct device_node;
|
||||
struct udevice;
|
||||
|
||||
/**
|
||||
* device_bind() - Create a device and bind it to a driver
|
||||
*
|
||||
* Called to set up a new device attached to a driver. The device will either
|
||||
* have platdata, or a device tree node which can be used to create the
|
||||
* platdata.
|
||||
*
|
||||
* Once bound a device exists but is not yet active until device_probe() is
|
||||
* called.
|
||||
*
|
||||
* @parent: Pointer to device's parent, under which this driver will exist
|
||||
* @drv: Device's driver
|
||||
* @name: Name of device (e.g. device tree node name)
|
||||
* @platdata: Pointer to data for this device - the structure is device-
|
||||
* specific but may include the device's I/O address, etc.. This is NULL for
|
||||
* devices which use device tree.
|
||||
* @of_offset: Offset of device tree node for this device. This is -1 for
|
||||
* devices which don't use device tree.
|
||||
* @devp: if non-NULL, returns a pointer to the bound device
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int device_bind(struct udevice *parent, const struct driver *drv,
|
||||
const char *name, void *platdata, int of_offset,
|
||||
struct udevice **devp);
|
||||
|
||||
int device_bind_ofnode(struct udevice *parent, const struct driver *drv,
|
||||
const char *name, void *platdata, ofnode node,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* device_bind_with_driver_data() - Create a device and bind it to a driver
|
||||
*
|
||||
* Called to set up a new device attached to a driver, in the case where the
|
||||
* driver was matched to the device by means of a match table that provides
|
||||
* driver_data.
|
||||
*
|
||||
* Once bound a device exists but is not yet active until device_probe() is
|
||||
* called.
|
||||
*
|
||||
* @parent: Pointer to device's parent, under which this driver will exist
|
||||
* @drv: Device's driver
|
||||
* @name: Name of device (e.g. device tree node name)
|
||||
* @driver_data: The driver_data field from the driver's match table.
|
||||
* @node: Device tree node for this device. This is invalid for devices which
|
||||
* don't use device tree.
|
||||
* @devp: if non-NULL, returns a pointer to the bound device
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int device_bind_with_driver_data(struct udevice *parent,
|
||||
const struct driver *drv, const char *name,
|
||||
ulong driver_data, ofnode node,
|
||||
struct udevice **devp);
|
||||
/**
|
||||
* device_bind_by_name: Create a device and bind it to a driver
|
||||
*
|
||||
* This is a helper function used to bind devices which do not use device
|
||||
* tree.
|
||||
*
|
||||
* @parent: Pointer to device's parent
|
||||
* @pre_reloc_only: If true, bind the driver only if its DM_FLAG_PRE_RELOC flag
|
||||
* is set. If false bind the driver always.
|
||||
* @info: Name and platdata for this device
|
||||
* @devp: if non-NULL, returns a pointer to the bound device
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
|
||||
const struct driver_info *info, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* device_probe() - Probe a device, activating it
|
||||
*
|
||||
* Activate a device so that it is ready for use. All its parents are probed
|
||||
* first.
|
||||
*
|
||||
* @dev: Pointer to device to probe
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int device_probe(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* device_remove() - Remove a device, de-activating it
|
||||
*
|
||||
* De-activate a device so that it is no longer ready for use. All its
|
||||
* children are deactivated first.
|
||||
*
|
||||
* @dev: Pointer to device to remove
|
||||
* @flags: Flags for selective device removal (DM_REMOVE_...)
|
||||
* @return 0 if OK, -ve on error (an error here is normally a very bad thing)
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||
int device_remove(struct udevice *dev, uint flags);
|
||||
#else
|
||||
static inline int device_remove(struct udevice *dev, uint flags) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* device_unbind() - Unbind a device, destroying it
|
||||
*
|
||||
* Unbind a device and remove all memory used by it
|
||||
*
|
||||
* @dev: Pointer to device to unbind
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||
int device_unbind(struct udevice *dev);
|
||||
#else
|
||||
static inline int device_unbind(struct udevice *dev) { return 0; }
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||
void device_free(struct udevice *dev);
|
||||
#else
|
||||
static inline void device_free(struct udevice *dev) {}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* device_chld_unbind() - Unbind all device's children from the device if bound
|
||||
* to drv
|
||||
*
|
||||
* On error, the function continues to unbind all children, and reports the
|
||||
* first error.
|
||||
*
|
||||
* @dev: The device that is to be stripped of its children
|
||||
* @drv: The targeted driver
|
||||
* @return 0 on success, -ve on error
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||
int device_chld_unbind(struct udevice *dev, struct driver *drv);
|
||||
#else
|
||||
static inline int device_chld_unbind(struct udevice *dev, struct driver *drv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* device_chld_remove() - Stop all device's children
|
||||
* @dev: The device whose children are to be removed
|
||||
* @drv: The targeted driver
|
||||
* @flags: Flag, if this functions is called in the pre-OS stage
|
||||
* @return 0 on success, -ve on error
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||
int device_chld_remove(struct udevice *dev, struct driver *drv,
|
||||
uint flags);
|
||||
#else
|
||||
static inline int device_chld_remove(struct udevice *dev, struct driver *drv,
|
||||
uint flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* simple_bus_translate() - translate a bus address to a system address
|
||||
*
|
||||
* This handles the 'ranges' property in a simple bus. It translates the
|
||||
* device address @addr to a system address using this property.
|
||||
*
|
||||
* @dev: Simple bus device (parent of target device)
|
||||
* @addr: Address to translate
|
||||
* @return new address
|
||||
*/
|
||||
fdt_addr_t simple_bus_translate(struct udevice *dev, fdt_addr_t addr);
|
||||
|
||||
/* Cast away any volatile pointer */
|
||||
#define DM_ROOT_NON_CONST (((gd_t *)gd)->dm_root)
|
||||
#define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root)
|
||||
|
||||
/* device resource management */
|
||||
#ifdef CONFIG_DEVRES
|
||||
|
||||
/**
|
||||
* devres_release_probe - Release managed resources allocated after probing
|
||||
* @dev: Device to release resources for
|
||||
*
|
||||
* Release all resources allocated for @dev when it was probed or later.
|
||||
* This function is called on driver removal.
|
||||
*/
|
||||
void devres_release_probe(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* devres_release_all - Release all managed resources
|
||||
* @dev: Device to release resources for
|
||||
*
|
||||
* Release all resources associated with @dev. This function is
|
||||
* called on driver unbinding.
|
||||
*/
|
||||
void devres_release_all(struct udevice *dev);
|
||||
|
||||
#else /* ! CONFIG_DEVRES */
|
||||
|
||||
static inline void devres_release_probe(struct udevice *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void devres_release_all(struct udevice *dev)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* ! CONFIG_DEVRES */
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,149 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2017 Google, Inc
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
* Marek Vasut <marex@denx.de>
|
||||
*/
|
||||
|
||||
#ifndef _DM_FDTADDR_H
|
||||
#define _DM_FDTADDR_H
|
||||
|
||||
#include <fdtdec.h>
|
||||
|
||||
struct udevice;
|
||||
|
||||
/**
|
||||
* devfdt_get_addr() - Get the reg property of a device
|
||||
*
|
||||
* @dev: Pointer to a device
|
||||
*
|
||||
* @return addr
|
||||
*/
|
||||
fdt_addr_t devfdt_get_addr(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* devfdt_get_addr_ptr() - Return pointer to the address of the reg property
|
||||
* of a device
|
||||
*
|
||||
* @dev: Pointer to a device
|
||||
*
|
||||
* @return Pointer to addr, or NULL if there is no such property
|
||||
*/
|
||||
void *devfdt_get_addr_ptr(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* devfdt_remap_addr() - Return pointer to the memory-mapped I/O address
|
||||
* of the reg property of a device
|
||||
*
|
||||
* @dev: Pointer to a device
|
||||
*
|
||||
* @return Pointer to addr, or NULL if there is no such property
|
||||
*/
|
||||
void *devfdt_remap_addr(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* devfdt_remap_addr_index() - Return indexed pointer to the memory-mapped
|
||||
* I/O address of the reg property of a device
|
||||
* @index: the 'reg' property can hold a list of <addr, size> pairs
|
||||
* and @index is used to select which one is required
|
||||
*
|
||||
* @dev: Pointer to a device
|
||||
*
|
||||
* @return Pointer to addr, or NULL if there is no such property
|
||||
*/
|
||||
void *devfdt_remap_addr_index(struct udevice *dev, int index);
|
||||
|
||||
/**
|
||||
* devfdt_remap_addr_name() - Get the reg property of a device, indexed by
|
||||
* name, as a memory-mapped I/O pointer
|
||||
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
|
||||
* 'reg-names' property providing named-based identification. @index
|
||||
* indicates the value to search for in 'reg-names'.
|
||||
*
|
||||
* @dev: Pointer to a device
|
||||
*
|
||||
* @return Pointer to addr, or NULL if there is no such property
|
||||
*/
|
||||
void *devfdt_remap_addr_name(struct udevice *dev, const char *name);
|
||||
|
||||
/**
|
||||
* devfdt_map_physmem() - Read device address from reg property of the
|
||||
* device node and map the address into CPU address
|
||||
* space.
|
||||
*
|
||||
* @dev: Pointer to device
|
||||
* @size: size of the memory to map
|
||||
*
|
||||
* @return mapped address, or NULL if the device does not have reg
|
||||
* property.
|
||||
*/
|
||||
void *devfdt_map_physmem(struct udevice *dev, unsigned long size);
|
||||
|
||||
/**
|
||||
* devfdt_get_addr_index() - Get the indexed reg property of a device
|
||||
*
|
||||
* @dev: Pointer to a device
|
||||
* @index: the 'reg' property can hold a list of <addr, size> pairs
|
||||
* and @index is used to select which one is required
|
||||
*
|
||||
* @return addr
|
||||
*/
|
||||
fdt_addr_t devfdt_get_addr_index(struct udevice *dev, int index);
|
||||
|
||||
/**
|
||||
* devfdt_get_addr_size_index() - Get the indexed reg property of a device
|
||||
*
|
||||
* Returns the address and size specified in the 'reg' property of a device.
|
||||
*
|
||||
* @dev: Pointer to a device
|
||||
* @index: the 'reg' property can hold a list of <addr, size> pairs
|
||||
* and @index is used to select which one is required
|
||||
* @size: Pointer to size varible - this function returns the size
|
||||
* specified in the 'reg' property here
|
||||
*
|
||||
* @return addr
|
||||
*/
|
||||
fdt_addr_t devfdt_get_addr_size_index(struct udevice *dev, int index,
|
||||
fdt_size_t *size);
|
||||
|
||||
/**
|
||||
* devfdt_get_addr_name() - Get the reg property of a device, indexed by name
|
||||
*
|
||||
* @dev: Pointer to a device
|
||||
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
|
||||
* 'reg-names' property providing named-based identification. @index
|
||||
* indicates the value to search for in 'reg-names'.
|
||||
*
|
||||
* @return addr
|
||||
*/
|
||||
fdt_addr_t devfdt_get_addr_name(struct udevice *dev, const char *name);
|
||||
|
||||
/**
|
||||
* devfdt_get_addr_size_name() - Get the reg property and its size for a device,
|
||||
* indexed by name
|
||||
*
|
||||
* Returns the address and size specified in the 'reg' property of a device.
|
||||
*
|
||||
* @dev: Pointer to a device
|
||||
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
|
||||
* 'reg-names' property providing named-based identification. @index
|
||||
* indicates the value to search for in 'reg-names'.
|
||||
* @size: Pointer to size variable - this function returns the size
|
||||
* specified in the 'reg' property here
|
||||
*
|
||||
* @return addr
|
||||
*/
|
||||
fdt_addr_t devfdt_get_addr_size_name(struct udevice *dev, const char *name,
|
||||
fdt_size_t *size);
|
||||
|
||||
/**
|
||||
* devfdt_get_addr_pci() - Read an address and handle PCI address translation
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @return address or FDT_ADDR_T_NONE if not found
|
||||
*/
|
||||
fdt_addr_t devfdt_get_addr_pci(struct udevice *dev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2013 Google, Inc
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _DM_LISTS_H_
|
||||
#define _DM_LISTS_H_
|
||||
|
||||
#include <dm/ofnode.h>
|
||||
#include <dm/uclass-id.h>
|
||||
|
||||
/**
|
||||
* lists_driver_lookup_name() - Return u_boot_driver corresponding to name
|
||||
*
|
||||
* This function returns a pointer to a driver given its name. This is used
|
||||
* for binding a driver given its name and platdata.
|
||||
*
|
||||
* @name: Name of driver to look up
|
||||
* @return pointer to driver, or NULL if not found
|
||||
*/
|
||||
struct driver *lists_driver_lookup_name(const char *name);
|
||||
|
||||
/**
|
||||
* lists_uclass_lookup() - Return uclass_driver based on ID of the class
|
||||
* id: ID of the class
|
||||
*
|
||||
* This function returns the pointer to uclass_driver, which is the class's
|
||||
* base structure based on the ID of the class. Returns NULL on error.
|
||||
*/
|
||||
struct uclass_driver *lists_uclass_lookup(enum uclass_id id);
|
||||
|
||||
/**
|
||||
* lists_bind_drivers() - search for and bind all drivers to parent
|
||||
*
|
||||
* This searches the U_BOOT_DEVICE() structures and creates new devices for
|
||||
* each one. The devices will have @parent as their parent.
|
||||
*
|
||||
* @parent: parent device (root)
|
||||
* @pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC flag.
|
||||
* If false bind all drivers.
|
||||
*/
|
||||
int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);
|
||||
|
||||
/**
|
||||
* lists_bind_fdt() - bind a device tree node
|
||||
*
|
||||
* This creates a new device bound to the given device tree node, with
|
||||
* @parent as its parent.
|
||||
*
|
||||
* @parent: parent device (root)
|
||||
* @node: device tree node to bind
|
||||
* @devp: if non-NULL, returns a pointer to the bound device
|
||||
* @pre_reloc_only: If true, bind only nodes with special devicetree properties,
|
||||
* or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
|
||||
* @return 0 if device was bound, -EINVAL if the device tree is invalid,
|
||||
* other -ve value on error
|
||||
*/
|
||||
int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
|
||||
bool pre_reloc_only);
|
||||
|
||||
/**
|
||||
* device_bind_driver() - bind a device to a driver
|
||||
*
|
||||
* This binds a new device to a driver.
|
||||
*
|
||||
* @parent: Parent device
|
||||
* @drv_name: Name of driver to attach to this parent
|
||||
* @dev_name: Name of the new device thus created
|
||||
* @devp: If non-NULL, returns the newly bound device
|
||||
*/
|
||||
int device_bind_driver(struct udevice *parent, const char *drv_name,
|
||||
const char *dev_name, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* device_bind_driver_to_node() - bind a device to a driver for a node
|
||||
*
|
||||
* This binds a new device to a driver for a given device tree node. This
|
||||
* should only be needed if the node lacks a compatible strings.
|
||||
*
|
||||
* @parent: Parent device
|
||||
* @drv_name: Name of driver to attach to this parent
|
||||
* @dev_name: Name of the new device thus created
|
||||
* @node: Device tree node
|
||||
* @devp: If non-NULL, returns the newly bound device
|
||||
*/
|
||||
int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
|
||||
const char *dev_name, ofnode node,
|
||||
struct udevice **devp);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,141 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2017 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*/
|
||||
|
||||
#ifndef _DM_OF_H
|
||||
#define _DM_OF_H
|
||||
|
||||
#include <asm/u-boot.h>
|
||||
#include <asm/global_data.h>
|
||||
|
||||
/* integer value within a device tree property which references another node */
|
||||
typedef u32 phandle;
|
||||
|
||||
/**
|
||||
* struct property: Device tree property
|
||||
*
|
||||
* @name: Property name
|
||||
* @length: Length of property in bytes
|
||||
* @value: Pointer to property value
|
||||
* @next: Pointer to next property, or NULL if none
|
||||
*/
|
||||
struct property {
|
||||
char *name;
|
||||
int length;
|
||||
void *value;
|
||||
struct property *next;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct device_node: Device tree node
|
||||
*
|
||||
* @name: Node name
|
||||
* @type: Node type (value of device_type property) or "<NULL>" if none
|
||||
* @phandle: Phandle value of this none, or 0 if none
|
||||
* @full_name: Full path to node, e.g. "/bus@1/spi@1100"
|
||||
* @properties: Pointer to head of list of properties, or NULL if none
|
||||
* @parent: Pointer to parent node, or NULL if this is the root node
|
||||
* @child: Pointer to head of child node list, or NULL if no children
|
||||
* @sibling: Pointer to the next sibling node, or NULL if this is the last
|
||||
*/
|
||||
struct device_node {
|
||||
const char *name;
|
||||
const char *type;
|
||||
phandle phandle;
|
||||
const char *full_name;
|
||||
|
||||
struct property *properties;
|
||||
struct device_node *parent;
|
||||
struct device_node *child;
|
||||
struct device_node *sibling;
|
||||
};
|
||||
|
||||
#define OF_MAX_PHANDLE_ARGS 16
|
||||
|
||||
/**
|
||||
* struct of_phandle_args - structure to hold phandle and arguments
|
||||
*
|
||||
* This is used when decoding a phandle in a device tree property. Typically
|
||||
* these look like this:
|
||||
*
|
||||
* wibble {
|
||||
* phandle = <5>;
|
||||
* };
|
||||
*
|
||||
* ...
|
||||
* some-prop = <&wibble 1 2 3>
|
||||
*
|
||||
* Here &node is the phandle of the node 'wibble', i.e. 5. There are three
|
||||
* arguments: 1, 2, 3.
|
||||
*
|
||||
* So when decoding the phandle in some-prop, np will point to wibble,
|
||||
* args_count will be 3 and the three arguments will be in args.
|
||||
*
|
||||
* @np: Node that the phandle refers to
|
||||
* @args_count: Number of arguments
|
||||
* @args: Argument values
|
||||
*/
|
||||
struct of_phandle_args {
|
||||
struct device_node *np;
|
||||
int args_count;
|
||||
uint32_t args[OF_MAX_PHANDLE_ARGS];
|
||||
};
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/**
|
||||
* of_live_active() - check if livetree is active
|
||||
*
|
||||
* @returns true if livetree is active, false it not
|
||||
*/
|
||||
#ifdef CONFIG_OF_LIVE
|
||||
static inline bool of_live_active(void)
|
||||
{
|
||||
return gd->of_root != NULL;
|
||||
}
|
||||
#else
|
||||
static inline bool of_live_active(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define OF_BAD_ADDR ((u64)-1)
|
||||
|
||||
static inline const char *of_node_full_name(const struct device_node *np)
|
||||
{
|
||||
return np ? np->full_name : "<no-node>";
|
||||
}
|
||||
|
||||
/* Default #address and #size cells */
|
||||
#if !defined(OF_ROOT_NODE_ADDR_CELLS_DEFAULT)
|
||||
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2
|
||||
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
|
||||
#endif
|
||||
|
||||
/* Default string compare functions */
|
||||
#if !defined(of_compat_cmp)
|
||||
#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
|
||||
#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
|
||||
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
|
||||
#endif
|
||||
|
||||
/* Helper to read a big number; size is in cells (not bytes) */
|
||||
static inline u64 of_read_number(const __be32 *cell, int size)
|
||||
{
|
||||
u64 r = 0;
|
||||
while (size--)
|
||||
r = (r << 32) | be32_to_cpu(*(cell++));
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Like of_read_number, but we want an unsigned long result */
|
||||
static inline unsigned long of_read_ulong(const __be32 *cell, int size)
|
||||
{
|
||||
/* toss away upper bits if unsigned long is smaller than u64 */
|
||||
return of_read_number(cell, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,444 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Originally from Linux v4.9
|
||||
* Copyright (C) 1996-2005 Paul Mackerras.
|
||||
*
|
||||
* Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
|
||||
* Updates for SPARC64 by David S. Miller
|
||||
* Derived from PowerPC and Sparc prom.h files by Stephen Rothwell, IBM Corp.
|
||||
*
|
||||
* Copyright (c) 2017 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* Modified for U-Boot
|
||||
* Copyright (c) 2017 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef _DM_OF_ACCESS_H
|
||||
#define _DM_OF_ACCESS_H
|
||||
|
||||
#include <dm/of.h>
|
||||
|
||||
/**
|
||||
* of_find_all_nodes - Get next node in global list
|
||||
* @prev: Previous node or NULL to start iteration
|
||||
* of_node_put() will be called on it
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_all_nodes(struct device_node *prev);
|
||||
|
||||
#define for_each_of_allnodes_from(from, dn) \
|
||||
for (dn = of_find_all_nodes(from); dn; dn = of_find_all_nodes(dn))
|
||||
#define for_each_of_allnodes(dn) for_each_of_allnodes_from(NULL, dn)
|
||||
|
||||
/* Dummy functions to mirror Linux. These are not used in U-Boot */
|
||||
#define of_node_get(x) (x)
|
||||
static inline void of_node_put(const struct device_node *np) { }
|
||||
|
||||
/**
|
||||
* of_n_addr_cells() - Get the number of address cells for a node
|
||||
*
|
||||
* This walks back up the tree to find the closest #address-cells property
|
||||
* which controls the given node.
|
||||
*
|
||||
* @np: Node pointer to check
|
||||
* @return number of address cells this node uses
|
||||
*/
|
||||
int of_n_addr_cells(const struct device_node *np);
|
||||
|
||||
/**
|
||||
* of_n_size_cells() - Get the number of size cells for a node
|
||||
*
|
||||
* This walks back up the tree to find the closest #size-cells property
|
||||
* which controls the given node.
|
||||
*
|
||||
* @np: Node pointer to check
|
||||
* @return number of size cells this node uses
|
||||
*/
|
||||
int of_n_size_cells(const struct device_node *np);
|
||||
|
||||
/**
|
||||
* of_simple_addr_cells() - Get the address cells property in a node
|
||||
*
|
||||
* This function matches fdt_address_cells().
|
||||
*
|
||||
* @np: Node pointer to check
|
||||
* @return value of #address-cells property in this node, or 2 if none
|
||||
*/
|
||||
int of_simple_addr_cells(const struct device_node *np);
|
||||
|
||||
/**
|
||||
* of_simple_size_cells() - Get the size cells property in a node
|
||||
*
|
||||
* This function matches fdt_size_cells().
|
||||
*
|
||||
* @np: Node pointer to check
|
||||
* @return value of #size-cells property in this node, or 2 if none
|
||||
*/
|
||||
int of_simple_size_cells(const struct device_node *np);
|
||||
|
||||
/**
|
||||
* of_find_property() - find a property in a node
|
||||
*
|
||||
* @np: Pointer to device node holding property
|
||||
* @name: Name of property
|
||||
* @lenp: If non-NULL, returns length of property
|
||||
* @return pointer to property, or NULL if not found
|
||||
*/
|
||||
struct property *of_find_property(const struct device_node *np,
|
||||
const char *name, int *lenp);
|
||||
|
||||
/**
|
||||
* of_get_property() - get a property value
|
||||
*
|
||||
* Find a property with a given name for a given node and return the value.
|
||||
*
|
||||
* @np: Pointer to device node holding property
|
||||
* @name: Name of property
|
||||
* @lenp: If non-NULL, returns length of property
|
||||
* @return pointer to property value, or NULL if not found
|
||||
*/
|
||||
const void *of_get_property(const struct device_node *np, const char *name,
|
||||
int *lenp);
|
||||
|
||||
/**
|
||||
* of_device_is_compatible() - Check if the node matches given constraints
|
||||
* @device: pointer to node
|
||||
* @compat: required compatible string, NULL or "" for any match
|
||||
* @type: required device_type value, NULL or "" for any match
|
||||
* @name: required node name, NULL or "" for any match
|
||||
*
|
||||
* Checks if the given @compat, @type and @name strings match the
|
||||
* properties of the given @device. A constraints can be skipped by
|
||||
* passing NULL or an empty string as the constraint.
|
||||
*
|
||||
* @return 0 for no match, and a positive integer on match. The return
|
||||
* value is a relative score with larger values indicating better
|
||||
* matches. The score is weighted for the most specific compatible value
|
||||
* to get the highest score. Matching type is next, followed by matching
|
||||
* name. Practically speaking, this results in the following priority
|
||||
* order for matches:
|
||||
*
|
||||
* 1. specific compatible && type && name
|
||||
* 2. specific compatible && type
|
||||
* 3. specific compatible && name
|
||||
* 4. specific compatible
|
||||
* 5. general compatible && type && name
|
||||
* 6. general compatible && type
|
||||
* 7. general compatible && name
|
||||
* 8. general compatible
|
||||
* 9. type && name
|
||||
* 10. type
|
||||
* 11. name
|
||||
*/
|
||||
int of_device_is_compatible(const struct device_node *np, const char *compat,
|
||||
const char *type, const char *name);
|
||||
|
||||
/**
|
||||
* of_device_is_available() - check if a device is available for use
|
||||
*
|
||||
* @device: Node to check for availability
|
||||
*
|
||||
* @return true if the status property is absent or set to "okay", false
|
||||
* otherwise
|
||||
*/
|
||||
bool of_device_is_available(const struct device_node *np);
|
||||
|
||||
/**
|
||||
* of_get_parent() - Get a node's parent, if any
|
||||
*
|
||||
* @node: Node to check
|
||||
* @eturns a node pointer, or NULL if none
|
||||
*/
|
||||
struct device_node *of_get_parent(const struct device_node *np);
|
||||
|
||||
/**
|
||||
* of_find_node_opts_by_path() - Find a node matching a full OF path
|
||||
*
|
||||
* @path: Either the full path to match, or if the path does not start with
|
||||
* '/', the name of a property of the /aliases node (an alias). In the
|
||||
* case of an alias, the node matching the alias' value will be returned.
|
||||
* @opts: Address of a pointer into which to store the start of an options
|
||||
* string appended to the end of the path with a ':' separator. Can be NULL
|
||||
*
|
||||
* Valid paths:
|
||||
* /foo/bar Full path
|
||||
* foo Valid alias
|
||||
* foo/bar Valid alias + relative path
|
||||
*
|
||||
* @return a node pointer or NULL if not found
|
||||
*/
|
||||
struct device_node *of_find_node_opts_by_path(const char *path,
|
||||
const char **opts);
|
||||
|
||||
static inline struct device_node *of_find_node_by_path(const char *path)
|
||||
{
|
||||
return of_find_node_opts_by_path(path, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* of_find_compatible_node() - find a node based on its compatible string
|
||||
*
|
||||
* Find a node based on type and one of the tokens in its "compatible" property
|
||||
* @from: Node to start searching from or NULL. the node you pass will not be
|
||||
* searched, only the next one will; typically, you pass what the previous
|
||||
* call returned.
|
||||
* @type: The type string to match "device_type" or NULL to ignore
|
||||
* @compatible: The string to match to one of the tokens in the device
|
||||
* "compatible" list.
|
||||
* @return node pointer or NULL if not found
|
||||
*/
|
||||
struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compatible);
|
||||
|
||||
/**
|
||||
* of_find_node_by_prop_value() - find a node with a given property value
|
||||
*
|
||||
* Find a node based on a property value.
|
||||
* @from: Node to start searching from or NULL. the node you pass will not be
|
||||
* searched, only the next one will; typically, you pass what the previous
|
||||
* call returned.
|
||||
* @propname: property name to check
|
||||
* @propval: property value to search for
|
||||
* @proplen: length of the value in propval
|
||||
* @return node pointer or NULL if not found
|
||||
*/
|
||||
struct device_node *of_find_node_by_prop_value(struct device_node *from,
|
||||
const char *propname,
|
||||
const void *propval,
|
||||
int proplen);
|
||||
/**
|
||||
* of_find_node_by_phandle() - Find a node given a phandle
|
||||
*
|
||||
* @handle: phandle of the node to find
|
||||
*
|
||||
* @return node pointer, or NULL if not found
|
||||
*/
|
||||
struct device_node *of_find_node_by_phandle(phandle handle);
|
||||
|
||||
/**
|
||||
* of_read_u32() - Find and read a 32-bit integer from a property
|
||||
*
|
||||
* Search for a property in a device node and read a 32-bit value from
|
||||
* it.
|
||||
*
|
||||
* @np: device node from which the property value is to be read.
|
||||
* @propname: name of the property to be searched.
|
||||
* @outp: pointer to return value, modified only if return value is 0.
|
||||
*
|
||||
* @return 0 on success, -EINVAL if the property does not exist,
|
||||
* -ENODATA if property does not have a value, and -EOVERFLOW if the
|
||||
* property data isn't large enough.
|
||||
*/
|
||||
int of_read_u32(const struct device_node *np, const char *propname, u32 *outp);
|
||||
|
||||
/**
|
||||
* of_read_u64() - Find and read a 64-bit integer from a property
|
||||
*
|
||||
* Search for a property in a device node and read a 64-bit value from
|
||||
* it.
|
||||
*
|
||||
* @np: device node from which the property value is to be read.
|
||||
* @propname: name of the property to be searched.
|
||||
* @outp: pointer to return value, modified only if return value is 0.
|
||||
*
|
||||
* @return 0 on success, -EINVAL if the property does not exist,
|
||||
* -ENODATA if property does not have a value, and -EOVERFLOW if the
|
||||
* property data isn't large enough.
|
||||
*/
|
||||
int of_read_u64(const struct device_node *np, const char *propname, u64 *outp);
|
||||
|
||||
/**
|
||||
* of_read_u32_array() - Find and read an array of 32 bit integers
|
||||
*
|
||||
* Search for a property in a device node and read 32-bit value(s) from
|
||||
* it.
|
||||
*
|
||||
* @np: device node from which the property value is to be read.
|
||||
* @propname: name of the property to be searched.
|
||||
* @out_values: pointer to return value, modified only if return value is 0.
|
||||
* @sz: number of array elements to read
|
||||
* @return 0 on success, -EINVAL if the property does not exist, -ENODATA
|
||||
* if property does not have a value, and -EOVERFLOW is longer than sz.
|
||||
*/
|
||||
int of_read_u32_array(const struct device_node *np, const char *propname,
|
||||
u32 *out_values, size_t sz);
|
||||
|
||||
/**
|
||||
* of_property_match_string() - Find string in a list and return index
|
||||
*
|
||||
* This function searches a string list property and returns the index
|
||||
* of a specific string value.
|
||||
*
|
||||
* @np: pointer to node containing string list property
|
||||
* @propname: string list property name
|
||||
* @string: pointer to string to search for in string list
|
||||
* @return 0 on success, -EINVAL if the property does not exist, -ENODATA
|
||||
* if property does not have a value, and -EOVERFLOW is longer than sz.
|
||||
*/
|
||||
int of_property_match_string(const struct device_node *np, const char *propname,
|
||||
const char *string);
|
||||
|
||||
int of_property_read_string_helper(const struct device_node *np,
|
||||
const char *propname, const char **out_strs,
|
||||
size_t sz, int index);
|
||||
|
||||
/**
|
||||
* of_property_read_string_index() - Find and read a string from a multiple
|
||||
* strings property.
|
||||
* @np: device node from which the property value is to be read.
|
||||
* @propname: name of the property to be searched.
|
||||
* @index: index of the string in the list of strings
|
||||
* @out_string: pointer to null terminated return string, modified only if
|
||||
* return value is 0.
|
||||
*
|
||||
* Search for a property in a device tree node and retrieve a null
|
||||
* terminated string value (pointer to data, not a copy) in the list of strings
|
||||
* contained in that property.
|
||||
* Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
|
||||
* property does not have a value, and -EILSEQ if the string is not
|
||||
* null-terminated within the length of the property data.
|
||||
*
|
||||
* The out_string pointer is modified only if a valid string can be decoded.
|
||||
*/
|
||||
static inline int of_property_read_string_index(const struct device_node *np,
|
||||
const char *propname,
|
||||
int index, const char **output)
|
||||
{
|
||||
int rc = of_property_read_string_helper(np, propname, output, 1, index);
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_property_count_strings() - Find and return the number of strings from a
|
||||
* multiple strings property.
|
||||
* @np: device node from which the property value is to be read.
|
||||
* @propname: name of the property to be searched.
|
||||
*
|
||||
* Search for a property in a device tree node and retrieve the number of null
|
||||
* terminated string contain in it. Returns the number of strings on
|
||||
* success, -EINVAL if the property does not exist, -ENODATA if property
|
||||
* does not have a value, and -EILSEQ if the string is not null-terminated
|
||||
* within the length of the property data.
|
||||
*/
|
||||
static inline int of_property_count_strings(const struct device_node *np,
|
||||
const char *propname)
|
||||
{
|
||||
return of_property_read_string_helper(np, propname, NULL, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* of_parse_phandle - Resolve a phandle property to a device_node pointer
|
||||
* @np: Pointer to device node holding phandle property
|
||||
* @phandle_name: Name of property holding a phandle value
|
||||
* @index: For properties holding a table of phandles, this is the index into
|
||||
* the table
|
||||
*
|
||||
* Returns the device_node pointer with refcount incremented. Use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_parse_phandle(const struct device_node *np,
|
||||
const char *phandle_name, int index);
|
||||
|
||||
/**
|
||||
* of_parse_phandle_with_args() - Find a node pointed by phandle in a list
|
||||
*
|
||||
* @np: pointer to a device tree node containing a list
|
||||
* @list_name: property name that contains a list
|
||||
* @cells_name: property name that specifies phandles' arguments count
|
||||
* @index: index of a phandle to parse out
|
||||
* @out_args: optional pointer to output arguments structure (will be filled)
|
||||
* @return 0 on success (with @out_args filled out if not NULL), -ENOENT if
|
||||
* @list_name does not exist, -EINVAL if a phandle was not found,
|
||||
* @cells_name could not be found, the arguments were truncated or there
|
||||
* were too many arguments.
|
||||
*
|
||||
* This function is useful to parse lists of phandles and their arguments.
|
||||
* Returns 0 on success and fills out_args, on error returns appropriate
|
||||
* errno value.
|
||||
*
|
||||
* Caller is responsible to call of_node_put() on the returned out_args->np
|
||||
* pointer.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* phandle1: node1 {
|
||||
* #list-cells = <2>;
|
||||
* }
|
||||
*
|
||||
* phandle2: node2 {
|
||||
* #list-cells = <1>;
|
||||
* }
|
||||
*
|
||||
* node3 {
|
||||
* list = <&phandle1 1 2 &phandle2 3>;
|
||||
* }
|
||||
*
|
||||
* To get a device_node of the `node2' node you may call this:
|
||||
* of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
|
||||
*/
|
||||
int of_parse_phandle_with_args(const struct device_node *np,
|
||||
const char *list_name, const char *cells_name,
|
||||
int index, struct of_phandle_args *out_args);
|
||||
|
||||
/**
|
||||
* of_count_phandle_with_args() - Count the number of phandle in a list
|
||||
*
|
||||
* @np: pointer to a device tree node containing a list
|
||||
* @list_name: property name that contains a list
|
||||
* @cells_name: property name that specifies phandles' arguments count
|
||||
* @return number of phandle found, -ENOENT if
|
||||
* @list_name does not exist, -EINVAL if a phandle was not found,
|
||||
* @cells_name could not be found, the arguments were truncated or there
|
||||
* were too many arguments.
|
||||
*
|
||||
* Returns number of phandle found on success, on error returns appropriate
|
||||
* errno value.
|
||||
*
|
||||
*/
|
||||
int of_count_phandle_with_args(const struct device_node *np,
|
||||
const char *list_name, const char *cells_name);
|
||||
|
||||
/**
|
||||
* of_alias_scan() - Scan all properties of the 'aliases' node
|
||||
*
|
||||
* The function scans all the properties of the 'aliases' node and populates
|
||||
* the lookup table with the properties. It returns the number of alias
|
||||
* properties found, or an error code in case of failure.
|
||||
*
|
||||
* @return 9 if OK, -ENOMEM if not enough memory
|
||||
*/
|
||||
int of_alias_scan(void);
|
||||
|
||||
/**
|
||||
* of_alias_get_id - Get alias id for the given device_node
|
||||
*
|
||||
* Travels the lookup table to get the alias id for the given device_node and
|
||||
* alias stem.
|
||||
*
|
||||
* @np: Pointer to the given device_node
|
||||
* @stem: Alias stem of the given device_node
|
||||
* @return alias ID, if found, else -ENODEV
|
||||
*/
|
||||
int of_alias_get_id(const struct device_node *np, const char *stem);
|
||||
|
||||
/**
|
||||
* of_alias_get_highest_id - Get highest alias id for the given stem
|
||||
* @stem: Alias stem to be examined
|
||||
*
|
||||
* The function travels the lookup table to get the highest alias id for the
|
||||
* given alias stem.
|
||||
* @return alias ID, if found, else -1
|
||||
*/
|
||||
int of_alias_get_highest_id(const char *stem);
|
||||
|
||||
/**
|
||||
* of_get_stdout() - Get node to use for stdout
|
||||
*
|
||||
* @return node referred to by stdout-path alias, or NULL if none
|
||||
*/
|
||||
struct device_node *of_get_stdout(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Taken from Linux v4.9 drivers/of/address.c
|
||||
*
|
||||
* Modified for U-Boot
|
||||
* Copyright (c) 2017 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef _DM_OF_ADDR_H
|
||||
#define _DM_OF_ADDR_H
|
||||
|
||||
/**
|
||||
* of_translate_address() - translate a device-tree address to a CPU address
|
||||
*
|
||||
* Translate an address from the device-tree into a CPU physical address,
|
||||
* this walks up the tree and applies the various bus mappings on the way.
|
||||
*
|
||||
* Note: We consider that crossing any level with #size-cells == 0 to mean
|
||||
* that translation is impossible (that is we are not dealing with a value
|
||||
* that can be mapped to a cpu physical address). This is not really specified
|
||||
* that way, but this is traditionally the way IBM at least do things
|
||||
*
|
||||
* @np: node to check
|
||||
* @in_addr: pointer to input address
|
||||
* @return translated address or OF_BAD_ADDR on error
|
||||
*/
|
||||
u64 of_translate_address(const struct device_node *no, const __be32 *in_addr);
|
||||
|
||||
/**
|
||||
* of_translate_dma_address() - translate a device-tree DMA address to a CPU
|
||||
* address
|
||||
*
|
||||
* Translate a DMA address from the device-tree into a CPU physical address,
|
||||
* this walks up the tree and applies the various bus mappings on the way.
|
||||
*
|
||||
* Note: We consider that crossing any level with #size-cells == 0 to mean
|
||||
* that translation is impossible (that is we are not dealing with a value
|
||||
* that can be mapped to a cpu physical address). This is not really specified
|
||||
* that way, but this is traditionally the way IBM at least do things
|
||||
*
|
||||
* @np: node to check
|
||||
* @in_addr: pointer to input DMA address
|
||||
* @return translated DMA address or OF_BAD_ADDR on error
|
||||
*/
|
||||
u64 of_translate_dma_address(const struct device_node *no, const __be32 *in_addr);
|
||||
|
||||
/**
|
||||
* of_get_address() - obtain an address from a node
|
||||
*
|
||||
* Extract an address from a node, returns the region size and the address
|
||||
* space flags too. The PCI version uses a BAR number instead of an absolute
|
||||
* index.
|
||||
*
|
||||
* @np: Node to check
|
||||
* @index: Index of address to read (0 = first)
|
||||
* @size: place to put size on success
|
||||
* @flags: place to put flags on success
|
||||
* @return pointer to address which can be read
|
||||
*/
|
||||
const __be32 *of_get_address(const struct device_node *no, int index,
|
||||
u64 *size, unsigned int *flags);
|
||||
|
||||
struct resource;
|
||||
|
||||
/**
|
||||
* of_address_to_resource() - translate device tree address to resource
|
||||
*
|
||||
* Note that if your address is a PIO address, the conversion will fail if
|
||||
* the physical address can't be internally converted to an IO token with
|
||||
* pci_address_to_pio(), that is because it's either called to early or it
|
||||
* can't be matched to any host bridge IO space
|
||||
*
|
||||
* @np: node to check
|
||||
* @index: index of address to read (0 = first)
|
||||
* @r: place to put resource information
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int of_address_to_resource(const struct device_node *no, int index,
|
||||
struct resource *r);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2017 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*/
|
||||
|
||||
#ifndef _DM_OF_EXTRA_H
|
||||
#define _DM_OF_EXTRA_H
|
||||
|
||||
#include <dm/ofnode.h>
|
||||
|
||||
enum fmap_compress_t {
|
||||
FMAP_COMPRESS_NONE,
|
||||
FMAP_COMPRESS_LZ4,
|
||||
};
|
||||
|
||||
enum fmap_hash_t {
|
||||
FMAP_HASH_NONE,
|
||||
FMAP_HASH_SHA1,
|
||||
FMAP_HASH_SHA256,
|
||||
};
|
||||
|
||||
/* A flash map entry, containing an offset and length */
|
||||
struct fmap_entry {
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
uint32_t used; /* Number of bytes used in region */
|
||||
enum fmap_compress_t compress_algo; /* Compression type */
|
||||
uint32_t unc_length; /* Uncompressed length */
|
||||
enum fmap_hash_t hash_algo; /* Hash algorithm */
|
||||
const uint8_t *hash; /* Hash value */
|
||||
int hash_size; /* Hash size */
|
||||
};
|
||||
|
||||
/**
|
||||
* Read a flash entry from the fdt
|
||||
*
|
||||
* @param node Reference to node to read
|
||||
* @param entry Place to put offset and size of this node
|
||||
* @return 0 if ok, -ve on error
|
||||
*/
|
||||
int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry);
|
||||
|
||||
/**
|
||||
* ofnode_decode_region() - Decode a memory region from a node
|
||||
*
|
||||
* Look up a property in a node which contains a memory region address and
|
||||
* size. Then return a pointer to this address.
|
||||
*
|
||||
* The property must hold one address with a length. This is only tested on
|
||||
* 32-bit machines.
|
||||
*
|
||||
* @param node ofnode to examine
|
||||
* @param prop_name name of property to find
|
||||
* @param basep Returns base address of region
|
||||
* @param size Returns size of region
|
||||
* @return 0 if ok, -1 on error (property not found)
|
||||
*/
|
||||
int ofnode_decode_region(ofnode node, const char *prop_name, fdt_addr_t *basep,
|
||||
fdt_size_t *sizep);
|
||||
|
||||
/**
|
||||
* ofnode_decode_memory_region()- Decode a named region within a memory bank
|
||||
*
|
||||
* This function handles selection of a memory region. The region is
|
||||
* specified as an offset/size within a particular type of memory.
|
||||
*
|
||||
* The properties used are:
|
||||
*
|
||||
* <mem_type>-memory<suffix> for the name of the memory bank
|
||||
* <mem_type>-offset<suffix> for the offset in that bank
|
||||
*
|
||||
* The property value must have an offset and a size. The function checks
|
||||
* that the region is entirely within the memory bank.5
|
||||
*
|
||||
* @param node ofnode containing the properties (-1 for /config)
|
||||
* @param mem_type Type of memory to use, which is a name, such as
|
||||
* "u-boot" or "kernel".
|
||||
* @param suffix String to append to the memory/offset
|
||||
* property names
|
||||
* @param basep Returns base of region
|
||||
* @param sizep Returns size of region
|
||||
* @return 0 if OK, -ive on error
|
||||
*/
|
||||
int ofnode_decode_memory_region(ofnode config_node, const char *mem_type,
|
||||
const char *suffix, fdt_addr_t *basep,
|
||||
fdt_size_t *sizep);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,853 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2017 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*/
|
||||
|
||||
#ifndef _DM_OFNODE_H
|
||||
#define _DM_OFNODE_H
|
||||
|
||||
/* TODO(sjg@chromium.org): Drop fdtdec.h include */
|
||||
#include <fdtdec.h>
|
||||
#include <dm/of.h>
|
||||
|
||||
/* Enable checks to protect against invalid calls */
|
||||
#undef OF_CHECKS
|
||||
|
||||
struct resource;
|
||||
|
||||
/**
|
||||
* ofnode - reference to a device tree node
|
||||
*
|
||||
* This union can hold either a straightforward pointer to a struct device_node
|
||||
* in the live device tree, or an offset within the flat device tree. In the
|
||||
* latter case, the pointer value is just the integer offset within the flat DT.
|
||||
*
|
||||
* Thus we can reference nodes in both the live tree (once available) and the
|
||||
* flat tree (until then). Functions are available to translate between an
|
||||
* ofnode and either an offset or a struct device_node *.
|
||||
*
|
||||
* The reference can also hold a null offset, in which case the pointer value
|
||||
* here is NULL. This corresponds to a struct device_node * value of
|
||||
* NULL, or an offset of -1.
|
||||
*
|
||||
* There is no ambiguity as to whether ofnode holds an offset or a node
|
||||
* pointer: when the live tree is active it holds a node pointer, otherwise it
|
||||
* holds an offset. The value itself does not need to be unique and in theory
|
||||
* the same value could point to a valid device node or a valid offset. We
|
||||
* could arrange for a unique value to be used (e.g. by making the pointer
|
||||
* point to an offset within the flat device tree in the case of an offset) but
|
||||
* this increases code size slightly due to the subtraction. Since it offers no
|
||||
* real benefit, the approach described here seems best.
|
||||
*
|
||||
* For now these points use constant types, since we don't allow writing
|
||||
* the DT.
|
||||
*
|
||||
* @np: Pointer to device node, used for live tree
|
||||
* @of_offset: Pointer into flat device tree, used for flat tree. Note that this
|
||||
* is not a really a pointer to a node: it is an offset value. See above.
|
||||
*/
|
||||
typedef union ofnode_union {
|
||||
const struct device_node *np; /* will be used for future live tree */
|
||||
long of_offset;
|
||||
} ofnode;
|
||||
|
||||
struct ofnode_phandle_args {
|
||||
ofnode node;
|
||||
int args_count;
|
||||
uint32_t args[OF_MAX_PHANDLE_ARGS];
|
||||
};
|
||||
|
||||
/**
|
||||
* _ofnode_to_np() - convert an ofnode to a live DT node pointer
|
||||
*
|
||||
* This cannot be called if the reference contains an offset.
|
||||
*
|
||||
* @node: Reference containing struct device_node * (possibly invalid)
|
||||
* @return pointer to device node (can be NULL)
|
||||
*/
|
||||
static inline const struct device_node *ofnode_to_np(ofnode node)
|
||||
{
|
||||
#ifdef OF_CHECKS
|
||||
if (!of_live_active())
|
||||
return NULL;
|
||||
#endif
|
||||
return node.np;
|
||||
}
|
||||
|
||||
/**
|
||||
* ofnode_to_offset() - convert an ofnode to a flat DT offset
|
||||
*
|
||||
* This cannot be called if the reference contains a node pointer.
|
||||
*
|
||||
* @node: Reference containing offset (possibly invalid)
|
||||
* @return DT offset (can be -1)
|
||||
*/
|
||||
static inline int ofnode_to_offset(ofnode node)
|
||||
{
|
||||
#ifdef OF_CHECKS
|
||||
if (of_live_active())
|
||||
return -1;
|
||||
#endif
|
||||
return node.of_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* ofnode_valid() - check if an ofnode is valid
|
||||
*
|
||||
* @return true if the reference contains a valid ofnode, false if it is NULL
|
||||
*/
|
||||
static inline bool ofnode_valid(ofnode node)
|
||||
{
|
||||
if (of_live_active())
|
||||
return node.np != NULL;
|
||||
else
|
||||
return node.of_offset != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* offset_to_ofnode() - convert a DT offset to an ofnode
|
||||
*
|
||||
* @of_offset: DT offset (either valid, or -1)
|
||||
* @return reference to the associated DT offset
|
||||
*/
|
||||
static inline ofnode offset_to_ofnode(int of_offset)
|
||||
{
|
||||
ofnode node;
|
||||
|
||||
if (of_live_active())
|
||||
node.np = NULL;
|
||||
else
|
||||
node.of_offset = of_offset;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* np_to_ofnode() - convert a node pointer to an ofnode
|
||||
*
|
||||
* @np: Live node pointer (can be NULL)
|
||||
* @return reference to the associated node pointer
|
||||
*/
|
||||
static inline ofnode np_to_ofnode(const struct device_node *np)
|
||||
{
|
||||
ofnode node;
|
||||
|
||||
node.np = np;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* ofnode_is_np() - check if a reference is a node pointer
|
||||
*
|
||||
* This function associated that if there is a valid live tree then all
|
||||
* references will use it. This is because using the flat DT when the live tree
|
||||
* is valid is not permitted.
|
||||
*
|
||||
* @node: reference to check (possibly invalid)
|
||||
* @return true if the reference is a live node pointer, false if it is a DT
|
||||
* offset
|
||||
*/
|
||||
static inline bool ofnode_is_np(ofnode node)
|
||||
{
|
||||
#ifdef OF_CHECKS
|
||||
/*
|
||||
* Check our assumption that flat tree offsets are not used when a
|
||||
* live tree is in use.
|
||||
*/
|
||||
assert(!ofnode_valid(node) ||
|
||||
(of_live_active() ? _ofnode_to_np(node)
|
||||
: _ofnode_to_np(node)));
|
||||
#endif
|
||||
return of_live_active() && ofnode_valid(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* ofnode_equal() - check if two references are equal
|
||||
*
|
||||
* @return true if equal, else false
|
||||
*/
|
||||
static inline bool ofnode_equal(ofnode ref1, ofnode ref2)
|
||||
{
|
||||
/* We only need to compare the contents */
|
||||
return ref1.of_offset == ref2.of_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* ofnode_null() - Obtain a null ofnode
|
||||
*
|
||||
* This returns an ofnode which points to no node. It works both with the flat
|
||||
* tree and livetree.
|
||||
*/
|
||||
static inline ofnode ofnode_null(void)
|
||||
{
|
||||
ofnode node;
|
||||
|
||||
if (of_live_active())
|
||||
node.np = NULL;
|
||||
else
|
||||
node.of_offset = -1;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* ofnode_read_u32() - Read a 32-bit integer from a property
|
||||
*
|
||||
* @ref: valid node reference to read property from
|
||||
* @propname: name of the property to read from
|
||||
* @outp: place to put value (if found)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int ofnode_read_u32(ofnode node, const char *propname, u32 *outp);
|
||||
|
||||
/**
|
||||
* ofnode_read_s32() - Read a 32-bit integer from a property
|
||||
*
|
||||
* @ref: valid node reference to read property from
|
||||
* @propname: name of the property to read from
|
||||
* @outp: place to put value (if found)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
static inline int ofnode_read_s32(ofnode node, const char *propname,
|
||||
s32 *out_value)
|
||||
{
|
||||
return ofnode_read_u32(node, propname, (u32 *)out_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* ofnode_read_u32_default() - Read a 32-bit integer from a property
|
||||
*
|
||||
* @ref: valid node reference to read property from
|
||||
* @propname: name of the property to read from
|
||||
* @def: default value to return if the property has no value
|
||||
* @return property value, or @def if not found
|
||||
*/
|
||||
u32 ofnode_read_u32_default(ofnode ref, const char *propname, u32 def);
|
||||
|
||||
/**
|
||||
* ofnode_read_s32_default() - Read a 32-bit integer from a property
|
||||
*
|
||||
* @ref: valid node reference to read property from
|
||||
* @propname: name of the property to read from
|
||||
* @def: default value to return if the property has no value
|
||||
* @return property value, or @def if not found
|
||||
*/
|
||||
int ofnode_read_s32_default(ofnode node, const char *propname, s32 def);
|
||||
|
||||
/**
|
||||
* ofnode_read_u64() - Read a 64-bit integer from a property
|
||||
*
|
||||
* @node: valid node reference to read property from
|
||||
* @propname: name of the property to read from
|
||||
* @outp: place to put value (if found)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int ofnode_read_u64(ofnode node, const char *propname, u64 *outp);
|
||||
|
||||
/**
|
||||
* ofnode_read_u64_default() - Read a 64-bit integer from a property
|
||||
*
|
||||
* @ref: valid node reference to read property from
|
||||
* @propname: name of the property to read from
|
||||
* @def: default value to return if the property has no value
|
||||
* @return property value, or @def if not found
|
||||
*/
|
||||
u64 ofnode_read_u64_default(ofnode node, const char *propname, u64 def);
|
||||
|
||||
/**
|
||||
* ofnode_read_string() - Read a string from a property
|
||||
*
|
||||
* @ref: valid node reference to read property from
|
||||
* @propname: name of the property to read
|
||||
* @return string from property value, or NULL if there is no such property
|
||||
*/
|
||||
const char *ofnode_read_string(ofnode node, const char *propname);
|
||||
|
||||
/**
|
||||
* ofnode_read_u32_array() - Find and read an array of 32 bit integers
|
||||
*
|
||||
* @node: valid node reference to read property from
|
||||
* @propname: name of the property to read
|
||||
* @out_values: pointer to return value, modified only if return value is 0
|
||||
* @sz: number of array elements to read
|
||||
* @return 0 if OK, -ve on error
|
||||
*
|
||||
* Search for a property in a device node and read 32-bit value(s) from
|
||||
* it. Returns 0 on success, -EINVAL if the property does not exist,
|
||||
* -ENODATA if property does not have a value, and -EOVERFLOW if the
|
||||
* property data isn't large enough.
|
||||
*
|
||||
* The out_values is modified only if a valid u32 value can be decoded.
|
||||
*/
|
||||
int ofnode_read_u32_array(ofnode node, const char *propname,
|
||||
u32 *out_values, size_t sz);
|
||||
|
||||
/**
|
||||
* ofnode_read_bool() - read a boolean value from a property
|
||||
*
|
||||
* @node: valid node reference to read property from
|
||||
* @propname: name of property to read
|
||||
* @return true if property is present (meaning true), false if not present
|
||||
*/
|
||||
bool ofnode_read_bool(ofnode node, const char *propname);
|
||||
|
||||
/**
|
||||
* ofnode_find_subnode() - find a named subnode of a parent node
|
||||
*
|
||||
* @node: valid reference to parent node
|
||||
* @subnode_name: name of subnode to find
|
||||
* @return reference to subnode (which can be invalid if there is no such
|
||||
* subnode)
|
||||
*/
|
||||
ofnode ofnode_find_subnode(ofnode node, const char *subnode_name);
|
||||
|
||||
/**
|
||||
* ofnode_first_subnode() - find the first subnode of a parent node
|
||||
*
|
||||
* @node: valid reference to a valid parent node
|
||||
* @return reference to the first subnode (which can be invalid if the parent
|
||||
* node has no subnodes)
|
||||
*/
|
||||
ofnode ofnode_first_subnode(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_next_subnode() - find the next sibling of a subnode
|
||||
*
|
||||
* @node: valid reference to previous node (sibling)
|
||||
* @return reference to the next subnode (which can be invalid if the node
|
||||
* has no more siblings)
|
||||
*/
|
||||
ofnode ofnode_next_subnode(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_get_parent() - get the ofnode's parent (enclosing ofnode)
|
||||
*
|
||||
* @node: valid node to look up
|
||||
* @return ofnode reference of the parent node
|
||||
*/
|
||||
ofnode ofnode_get_parent(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_get_name() - get the name of a node
|
||||
*
|
||||
* @node: valid node to look up
|
||||
* @return name of node
|
||||
*/
|
||||
const char *ofnode_get_name(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_get_by_phandle() - get ofnode from phandle
|
||||
*
|
||||
* @phandle: phandle to look up
|
||||
* @return ofnode reference to the phandle
|
||||
*/
|
||||
ofnode ofnode_get_by_phandle(uint phandle);
|
||||
|
||||
/**
|
||||
* ofnode_read_size() - read the size of a property
|
||||
*
|
||||
* @node: node to check
|
||||
* @propname: property to check
|
||||
* @return size of property if present, or -EINVAL if not
|
||||
*/
|
||||
int ofnode_read_size(ofnode node, const char *propname);
|
||||
|
||||
/**
|
||||
* ofnode_get_addr_size_index() - get an address/size from a node
|
||||
* based on index
|
||||
*
|
||||
* This reads the register address/size from a node based on index
|
||||
*
|
||||
* @node: node to read from
|
||||
* @index: Index of address to read (0 for first)
|
||||
* @size: Pointer to size of the address
|
||||
* @return address, or FDT_ADDR_T_NONE if not present or invalid
|
||||
*/
|
||||
phys_addr_t ofnode_get_addr_size_index(ofnode node, int index,
|
||||
fdt_size_t *size);
|
||||
|
||||
/**
|
||||
* ofnode_get_addr_index() - get an address from a node
|
||||
*
|
||||
* This reads the register address from a node
|
||||
*
|
||||
* @node: node to read from
|
||||
* @index: Index of address to read (0 for first)
|
||||
* @return address, or FDT_ADDR_T_NONE if not present or invalid
|
||||
*/
|
||||
phys_addr_t ofnode_get_addr_index(ofnode node, int index);
|
||||
|
||||
/**
|
||||
* ofnode_get_addr() - get an address from a node
|
||||
*
|
||||
* This reads the register address from a node
|
||||
*
|
||||
* @node: node to read from
|
||||
* @return address, or FDT_ADDR_T_NONE if not present or invalid
|
||||
*/
|
||||
phys_addr_t ofnode_get_addr(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_stringlist_search() - find a string in a string list and return index
|
||||
*
|
||||
* Note that it is possible for this function to succeed on property values
|
||||
* that are not NUL-terminated. That's because the function will stop after
|
||||
* finding the first occurrence of @string. This can for example happen with
|
||||
* small-valued cell properties, such as #address-cells, when searching for
|
||||
* the empty string.
|
||||
*
|
||||
* @node: node to check
|
||||
* @propname: name of the property containing the string list
|
||||
* @string: string to look up in the string list
|
||||
*
|
||||
* @return:
|
||||
* the index of the string in the list of strings
|
||||
* -ENODATA if the property is not found
|
||||
* -EINVAL on some other error
|
||||
*/
|
||||
int ofnode_stringlist_search(ofnode node, const char *propname,
|
||||
const char *string);
|
||||
|
||||
/**
|
||||
* ofnode_read_string_index() - obtain an indexed string from a string list
|
||||
*
|
||||
* Note that this will successfully extract strings from properties with
|
||||
* non-NUL-terminated values. For example on small-valued cell properties
|
||||
* this function will return the empty string.
|
||||
*
|
||||
* If non-NULL, the length of the string (on success) or a negative error-code
|
||||
* (on failure) will be stored in the integer pointer to by lenp.
|
||||
*
|
||||
* @node: node to check
|
||||
* @propname: name of the property containing the string list
|
||||
* @index: index of the string to return
|
||||
* @lenp: return location for the string length or an error code on failure
|
||||
*
|
||||
* @return:
|
||||
* length of string, if found or -ve error value if not found
|
||||
*/
|
||||
int ofnode_read_string_index(ofnode node, const char *propname, int index,
|
||||
const char **outp);
|
||||
|
||||
/**
|
||||
* ofnode_read_string_count() - find the number of strings in a string list
|
||||
*
|
||||
* @node: node to check
|
||||
* @propname: name of the property containing the string list
|
||||
* @return:
|
||||
* number of strings in the list, or -ve error value if not found
|
||||
*/
|
||||
int ofnode_read_string_count(ofnode node, const char *property);
|
||||
|
||||
/**
|
||||
* ofnode_parse_phandle_with_args() - Find a node pointed by phandle in a list
|
||||
*
|
||||
* This function is useful to parse lists of phandles and their arguments.
|
||||
* Returns 0 on success and fills out_args, on error returns appropriate
|
||||
* errno value.
|
||||
*
|
||||
* Caller is responsible to call of_node_put() on the returned out_args->np
|
||||
* pointer.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* phandle1: node1 {
|
||||
* #list-cells = <2>;
|
||||
* }
|
||||
*
|
||||
* phandle2: node2 {
|
||||
* #list-cells = <1>;
|
||||
* }
|
||||
*
|
||||
* node3 {
|
||||
* list = <&phandle1 1 2 &phandle2 3>;
|
||||
* }
|
||||
*
|
||||
* To get a device_node of the `node2' node you may call this:
|
||||
* ofnode_parse_phandle_with_args(node3, "list", "#list-cells", 0, 1, &args);
|
||||
*
|
||||
* @node: device tree node containing a list
|
||||
* @list_name: property name that contains a list
|
||||
* @cells_name: property name that specifies phandles' arguments count
|
||||
* @cells_count: Cell count to use if @cells_name is NULL
|
||||
* @index: index of a phandle to parse out
|
||||
* @out_args: optional pointer to output arguments structure (will be filled)
|
||||
* @return 0 on success (with @out_args filled out if not NULL), -ENOENT if
|
||||
* @list_name does not exist, -EINVAL if a phandle was not found,
|
||||
* @cells_name could not be found, the arguments were truncated or there
|
||||
* were too many arguments.
|
||||
*/
|
||||
int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
|
||||
const char *cells_name, int cell_count,
|
||||
int index,
|
||||
struct ofnode_phandle_args *out_args);
|
||||
|
||||
/**
|
||||
* ofnode_count_phandle_with_args() - Count number of phandle in a list
|
||||
*
|
||||
* This function is useful to count phandles into a list.
|
||||
* Returns number of phandle on success, on error returns appropriate
|
||||
* errno value.
|
||||
*
|
||||
* @node: device tree node containing a list
|
||||
* @list_name: property name that contains a list
|
||||
* @cells_name: property name that specifies phandles' arguments count
|
||||
* @return number of phandle on success, -ENOENT if @list_name does not
|
||||
* exist, -EINVAL if a phandle was not found, @cells_name could not
|
||||
* be found.
|
||||
*/
|
||||
int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
|
||||
const char *cells_name);
|
||||
|
||||
/**
|
||||
* ofnode_path() - find a node by full path
|
||||
*
|
||||
* @path: Full path to node, e.g. "/bus/spi@1"
|
||||
* @return reference to the node found. Use ofnode_valid() to check if it exists
|
||||
*/
|
||||
ofnode ofnode_path(const char *path);
|
||||
|
||||
/**
|
||||
* ofnode_get_chosen_prop() - get the value of a chosen property
|
||||
*
|
||||
* This looks for a property within the /chosen node and returns its value
|
||||
*
|
||||
* @propname: Property name to look for
|
||||
* @return property value if found, else NULL
|
||||
*/
|
||||
const char *ofnode_get_chosen_prop(const char *propname);
|
||||
|
||||
/**
|
||||
* ofnode_get_chosen_node() - get the chosen node
|
||||
*
|
||||
* @return the chosen node if present, else ofnode_null()
|
||||
*/
|
||||
ofnode ofnode_get_chosen_node(const char *name);
|
||||
|
||||
struct display_timing;
|
||||
/**
|
||||
* ofnode_decode_display_timing() - decode display timings
|
||||
*
|
||||
* Decode display timings from the supplied 'display-timings' node.
|
||||
* See doc/device-tree-bindings/video/display-timing.txt for binding
|
||||
* information.
|
||||
*
|
||||
* @node 'display-timing' node containing the timing subnodes
|
||||
* @index Index number to read (0=first timing subnode)
|
||||
* @config Place to put timings
|
||||
* @return 0 if OK, -FDT_ERR_NOTFOUND if not found
|
||||
*/
|
||||
int ofnode_decode_display_timing(ofnode node, int index,
|
||||
struct display_timing *config);
|
||||
|
||||
/**
|
||||
* ofnode_get_property()- - get a pointer to the value of a node property
|
||||
*
|
||||
* @node: node to read
|
||||
* @propname: property to read
|
||||
* @lenp: place to put length on success
|
||||
* @return pointer to property, or NULL if not found
|
||||
*/
|
||||
const void *ofnode_get_property(ofnode node, const char *propname, int *lenp);
|
||||
|
||||
/**
|
||||
* ofnode_is_available() - check if a node is marked available
|
||||
*
|
||||
* @node: node to check
|
||||
* @return true if node's 'status' property is "okay" (or is missing)
|
||||
*/
|
||||
bool ofnode_is_available(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_get_addr_size() - get address and size from a property
|
||||
*
|
||||
* This does no address translation. It simply reads an property that contains
|
||||
* an address and a size value, one after the other.
|
||||
*
|
||||
* @node: node to read from
|
||||
* @propname: property to read
|
||||
* @sizep: place to put size value (on success)
|
||||
* @return address value, or FDT_ADDR_T_NONE on error
|
||||
*/
|
||||
phys_addr_t ofnode_get_addr_size(ofnode node, const char *propname,
|
||||
phys_size_t *sizep);
|
||||
|
||||
/**
|
||||
* ofnode_read_u8_array_ptr() - find an 8-bit array
|
||||
*
|
||||
* Look up a property in a node and return a pointer to its contents as a
|
||||
* byte array of given length. The property must have at least enough data
|
||||
* for the array (count bytes). It may have more, but this will be ignored.
|
||||
* The data is not copied.
|
||||
*
|
||||
* @node node to examine
|
||||
* @propname name of property to find
|
||||
* @sz number of array elements
|
||||
* @return pointer to byte array if found, or NULL if the property is not
|
||||
* found or there is not enough data
|
||||
*/
|
||||
const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname,
|
||||
size_t sz);
|
||||
|
||||
/**
|
||||
* ofnode_read_pci_addr() - look up a PCI address
|
||||
*
|
||||
* Look at an address property in a node and return the PCI address which
|
||||
* corresponds to the given type in the form of fdt_pci_addr.
|
||||
* The property must hold one fdt_pci_addr with a lengh.
|
||||
*
|
||||
* @node node to examine
|
||||
* @type pci address type (FDT_PCI_SPACE_xxx)
|
||||
* @propname name of property to find
|
||||
* @addr returns pci address in the form of fdt_pci_addr
|
||||
* @return 0 if ok, -ENOENT if the property did not exist, -EINVAL if the
|
||||
* format of the property was invalid, -ENXIO if the requested
|
||||
* address type was not found
|
||||
*/
|
||||
int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
|
||||
const char *propname, struct fdt_pci_addr *addr);
|
||||
|
||||
/**
|
||||
* ofnode_read_pci_vendev() - look up PCI vendor and device id
|
||||
*
|
||||
* Look at the compatible property of a device node that represents a PCI
|
||||
* device and extract pci vendor id and device id from it.
|
||||
*
|
||||
* @param node node to examine
|
||||
* @param vendor vendor id of the pci device
|
||||
* @param device device id of the pci device
|
||||
* @return 0 if ok, negative on error
|
||||
*/
|
||||
int ofnode_read_pci_vendev(ofnode node, u16 *vendor, u16 *device);
|
||||
|
||||
/**
|
||||
* ofnode_read_addr_cells() - Get the number of address cells for a node
|
||||
*
|
||||
* This walks back up the tree to find the closest #address-cells property
|
||||
* which controls the given node.
|
||||
*
|
||||
* @node: Node to check
|
||||
* @return number of address cells this node uses
|
||||
*/
|
||||
int ofnode_read_addr_cells(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_read_size_cells() - Get the number of size cells for a node
|
||||
*
|
||||
* This walks back up the tree to find the closest #size-cells property
|
||||
* which controls the given node.
|
||||
*
|
||||
* @node: Node to check
|
||||
* @return number of size cells this node uses
|
||||
*/
|
||||
int ofnode_read_size_cells(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_read_simple_addr_cells() - Get the address cells property in a node
|
||||
*
|
||||
* This function matches fdt_address_cells().
|
||||
*
|
||||
* @np: Node pointer to check
|
||||
* @return value of #address-cells property in this node, or 2 if none
|
||||
*/
|
||||
int ofnode_read_simple_addr_cells(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_read_simple_size_cells() - Get the size cells property in a node
|
||||
*
|
||||
* This function matches fdt_size_cells().
|
||||
*
|
||||
* @np: Node pointer to check
|
||||
* @return value of #size-cells property in this node, or 2 if none
|
||||
*/
|
||||
int ofnode_read_simple_size_cells(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_pre_reloc() - check if a node should be bound before relocation
|
||||
*
|
||||
* Device tree nodes can be marked as needing-to-be-bound in the loader stages
|
||||
* via special device tree properties.
|
||||
*
|
||||
* Before relocation this function can be used to check if nodes are required
|
||||
* in either SPL or TPL stages.
|
||||
*
|
||||
* After relocation and jumping into the real U-Boot binary it is possible to
|
||||
* determine if a node was bound in one of SPL/TPL stages.
|
||||
*
|
||||
* There are 4 settings currently in use
|
||||
* - u-boot,dm-pre-proper: U-Boot proper pre-relocation only
|
||||
* - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL
|
||||
* Existing platforms only use it to indicate nodes needed in
|
||||
* SPL. Should probably be replaced by u-boot,dm-spl for
|
||||
* new platforms.
|
||||
* - u-boot,dm-spl: SPL and U-Boot pre-relocation
|
||||
* - u-boot,dm-tpl: TPL and U-Boot pre-relocation
|
||||
*
|
||||
* @node: node to check
|
||||
* @return true if node is needed in SPL/TL, false otherwise
|
||||
*/
|
||||
bool ofnode_pre_reloc(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_read_resource() - Read a resource from a node
|
||||
*
|
||||
* Read resource information from a node at the given index
|
||||
*
|
||||
* @node: Node to read from
|
||||
* @index: Index of resource to read (0 = first)
|
||||
* @res: Returns resource that was read, on success
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int ofnode_read_resource(ofnode node, uint index, struct resource *res);
|
||||
|
||||
/**
|
||||
* ofnode_read_resource_byname() - Read a resource from a node by name
|
||||
*
|
||||
* Read resource information from a node matching the given name. This uses a
|
||||
* 'reg-names' string list property with the names matching the associated
|
||||
* 'reg' property list.
|
||||
*
|
||||
* @node: Node to read from
|
||||
* @name: Name of resource to read
|
||||
* @res: Returns resource that was read, on success
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int ofnode_read_resource_byname(ofnode node, const char *name,
|
||||
struct resource *res);
|
||||
|
||||
/**
|
||||
* ofnode_by_compatible() - Find the next compatible node
|
||||
*
|
||||
* Find the next node after @from that is compatible with @compat
|
||||
*
|
||||
* @from: ofnode to start from (use ofnode_null() to start at the beginning)
|
||||
* @compat: Compatible string to match
|
||||
* @return ofnode found, or ofnode_null() if none
|
||||
*/
|
||||
ofnode ofnode_by_compatible(ofnode from, const char *compat);
|
||||
|
||||
/**
|
||||
* ofnode_by_prop_value() - Find the next node with given property value
|
||||
*
|
||||
* Find the next node after @from that has a @propname with a value
|
||||
* @propval and a length @proplen.
|
||||
*
|
||||
* @from: ofnode to start from (use ofnode_null() to start at the
|
||||
* beginning) @propname: property name to check @propval: property value to
|
||||
* search for @proplen: length of the value in propval @return ofnode
|
||||
* found, or ofnode_null() if none
|
||||
*/
|
||||
ofnode ofnode_by_prop_value(ofnode from, const char *propname,
|
||||
const void *propval, int proplen);
|
||||
|
||||
/**
|
||||
* ofnode_for_each_subnode() - iterate over all subnodes of a parent
|
||||
*
|
||||
* @node: child node (ofnode, lvalue)
|
||||
* @parent: parent node (ofnode)
|
||||
*
|
||||
* This is a wrapper around a for loop and is used like so:
|
||||
*
|
||||
* ofnode node;
|
||||
*
|
||||
* ofnode_for_each_subnode(node, parent) {
|
||||
* Use node
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* Note that this is implemented as a macro and @node is used as
|
||||
* iterator in the loop. The parent variable can be a constant or even a
|
||||
* literal.
|
||||
*/
|
||||
#define ofnode_for_each_subnode(node, parent) \
|
||||
for (node = ofnode_first_subnode(parent); \
|
||||
ofnode_valid(node); \
|
||||
node = ofnode_next_subnode(node))
|
||||
|
||||
/**
|
||||
* ofnode_translate_address() - Translate a device-tree address
|
||||
*
|
||||
* Translate an address from the device-tree into a CPU physical address. This
|
||||
* function walks up the tree and applies the various bus mappings along the
|
||||
* way.
|
||||
*
|
||||
* @ofnode: Device tree node giving the context in which to translate the
|
||||
* address
|
||||
* @in_addr: pointer to the address to translate
|
||||
* @return the translated address; OF_BAD_ADDR on error
|
||||
*/
|
||||
u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr);
|
||||
|
||||
/**
|
||||
* ofnode_translate_dma_address() - Translate a device-tree DMA address
|
||||
*
|
||||
* Translate a DMA address from the device-tree into a CPU physical address.
|
||||
* This function walks up the tree and applies the various bus mappings along
|
||||
* the way.
|
||||
*
|
||||
* @ofnode: Device tree node giving the context in which to translate the
|
||||
* DMA address
|
||||
* @in_addr: pointer to the DMA address to translate
|
||||
* @return the translated DMA address; OF_BAD_ADDR on error
|
||||
*/
|
||||
u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr);
|
||||
|
||||
/**
|
||||
* ofnode_device_is_compatible() - check if the node is compatible with compat
|
||||
*
|
||||
* This allows to check whether the node is comaptible with the compat.
|
||||
*
|
||||
* @node: Device tree node for which compatible needs to be verified.
|
||||
* @compat: Compatible string which needs to verified in the given node.
|
||||
* @return true if OK, false if the compatible is not found
|
||||
*/
|
||||
int ofnode_device_is_compatible(ofnode node, const char *compat);
|
||||
|
||||
/**
|
||||
* ofnode_write_prop() - Set a property of a ofnode
|
||||
*
|
||||
* Note that the value passed to the function is *not* allocated by the
|
||||
* function itself, but must be allocated by the caller if necessary.
|
||||
*
|
||||
* @node: The node for whose property should be set
|
||||
* @propname: The name of the property to set
|
||||
* @len: The length of the new value of the property
|
||||
* @value: The new value of the property (must be valid prior to calling
|
||||
* the function)
|
||||
* @return 0 if successful, -ve on error
|
||||
*/
|
||||
int ofnode_write_prop(ofnode node, const char *propname, int len,
|
||||
const void *value);
|
||||
|
||||
/**
|
||||
* ofnode_write_string() - Set a string property of a ofnode
|
||||
*
|
||||
* Note that the value passed to the function is *not* allocated by the
|
||||
* function itself, but must be allocated by the caller if necessary.
|
||||
*
|
||||
* @node: The node for whose string property should be set
|
||||
* @propname: The name of the string property to set
|
||||
* @value: The new value of the string property (must be valid prior to
|
||||
* calling the function)
|
||||
* @return 0 if successful, -ve on error
|
||||
*/
|
||||
int ofnode_write_string(ofnode node, const char *propname, const char *value);
|
||||
|
||||
/**
|
||||
* ofnode_set_enabled() - Enable or disable a device tree node given by its
|
||||
* ofnode
|
||||
*
|
||||
* This function effectively sets the node's "status" property to either "okay"
|
||||
* or "disable", hence making it available for driver model initialization or
|
||||
* not.
|
||||
*
|
||||
* @node: The node to enable
|
||||
* @value: Flag that tells the function to either disable or enable the
|
||||
* node
|
||||
* @return 0 if successful, -ve on error
|
||||
*/
|
||||
int ofnode_set_enabled(ofnode node, bool value);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,444 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
|
||||
*/
|
||||
|
||||
#ifndef __PINCTRL_H
|
||||
#define __PINCTRL_H
|
||||
|
||||
#define PINNAME_SIZE 10
|
||||
#define PINMUX_SIZE 40
|
||||
|
||||
/**
|
||||
* struct pinconf_param - pin config parameters
|
||||
*
|
||||
* @property: property name in DT nodes
|
||||
* @param: ID for this config parameter
|
||||
* @default_value: default value for this config parameter used in case
|
||||
* no value is specified in DT nodes
|
||||
*/
|
||||
struct pinconf_param {
|
||||
const char * const property;
|
||||
unsigned int param;
|
||||
u32 default_value;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pinctrl_ops - pin control operations, to be implemented by
|
||||
* pin controller drivers.
|
||||
*
|
||||
* The @set_state is the only mandatory operation. You can implement your
|
||||
* pinctrl driver with its own @set_state. In this case, the other callbacks
|
||||
* are not required. Otherwise, generic pinctrl framework is also available;
|
||||
* use pinctrl_generic_set_state for @set_state, and implement other operations
|
||||
* depending on your necessity.
|
||||
*
|
||||
* @get_pins_count: return number of selectable named pins available
|
||||
* in this driver. (necessary to parse "pins" property in DTS)
|
||||
* @get_pin_name: return the pin name of the pin selector,
|
||||
* called by the core to figure out which pin it shall do
|
||||
* operations to. (necessary to parse "pins" property in DTS)
|
||||
* @get_groups_count: return number of selectable named groups available
|
||||
* in this driver. (necessary to parse "groups" property in DTS)
|
||||
* @get_group_name: return the group name of the group selector,
|
||||
* called by the core to figure out which pin group it shall do
|
||||
* operations to. (necessary to parse "groups" property in DTS)
|
||||
* @get_functions_count: return number of selectable named functions available
|
||||
* in this driver. (necessary for pin-muxing)
|
||||
* @get_function_name: return the function name of the muxing selector,
|
||||
* called by the core to figure out which mux setting it shall map a
|
||||
* certain device to. (necessary for pin-muxing)
|
||||
* @pinmux_set: enable a certain muxing function with a certain pin.
|
||||
* The @func_selector selects a certain function whereas @pin_selector
|
||||
* selects a certain pin to be used. On simple controllers one of them
|
||||
* may be ignored. (necessary for pin-muxing against a single pin)
|
||||
* @pinmux_group_set: enable a certain muxing function with a certain pin
|
||||
* group. The @func_selector selects a certain function whereas
|
||||
* @group_selector selects a certain set of pins to be used. On simple
|
||||
* controllers one of them may be ignored.
|
||||
* (necessary for pin-muxing against a pin group)
|
||||
* @pinconf_num_params: number of driver-specific parameters to be parsed
|
||||
* from device trees (necessary for pin-configuration)
|
||||
* @pinconf_params: list of driver_specific parameters to be parsed from
|
||||
* device trees (necessary for pin-configuration)
|
||||
* @pinconf_set: configure an individual pin with a given parameter.
|
||||
* (necessary for pin-configuration against a single pin)
|
||||
* @pinconf_group_set: configure all pins in a group with a given parameter.
|
||||
* (necessary for pin-configuration against a pin group)
|
||||
* @set_state: do pinctrl operations specified by @config, a pseudo device
|
||||
* pointing a config node. (necessary for pinctrl_full)
|
||||
* @set_state_simple: do needed pinctrl operations for a peripherl @periph.
|
||||
* (necessary for pinctrl_simple)
|
||||
* @get_pin_muxing: display the muxing of a given pin.
|
||||
* @gpio_request_enable: requests and enables GPIO on a certain pin.
|
||||
* Implement this only if you can mux every pin individually as GPIO. The
|
||||
* affected GPIO range is passed along with an offset(pin number) into that
|
||||
* specific GPIO range - function selectors and pin groups are orthogonal
|
||||
* to this, the core will however make sure the pins do not collide.
|
||||
* @gpio_disable_free: free up GPIO muxing on a certain pin, the reverse of
|
||||
* @gpio_request_enable
|
||||
*/
|
||||
struct pinctrl_ops {
|
||||
int (*get_pins_count)(struct udevice *dev);
|
||||
const char *(*get_pin_name)(struct udevice *dev, unsigned selector);
|
||||
int (*get_groups_count)(struct udevice *dev);
|
||||
const char *(*get_group_name)(struct udevice *dev, unsigned selector);
|
||||
int (*get_functions_count)(struct udevice *dev);
|
||||
const char *(*get_function_name)(struct udevice *dev,
|
||||
unsigned selector);
|
||||
int (*pinmux_set)(struct udevice *dev, unsigned pin_selector,
|
||||
unsigned func_selector);
|
||||
int (*pinmux_group_set)(struct udevice *dev, unsigned group_selector,
|
||||
unsigned func_selector);
|
||||
unsigned int pinconf_num_params;
|
||||
const struct pinconf_param *pinconf_params;
|
||||
int (*pinconf_set)(struct udevice *dev, unsigned pin_selector,
|
||||
unsigned param, unsigned argument);
|
||||
int (*pinconf_group_set)(struct udevice *dev, unsigned group_selector,
|
||||
unsigned param, unsigned argument);
|
||||
int (*set_state)(struct udevice *dev, struct udevice *config);
|
||||
|
||||
/* for pinctrl-simple */
|
||||
int (*set_state_simple)(struct udevice *dev, struct udevice *periph);
|
||||
/**
|
||||
* request() - Request a particular pinctrl function
|
||||
*
|
||||
* This activates the selected function.
|
||||
*
|
||||
* @dev: Device to adjust (UCLASS_PINCTRL)
|
||||
* @func: Function number (driver-specific)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*request)(struct udevice *dev, int func, int flags);
|
||||
|
||||
/**
|
||||
* get_periph_id() - get the peripheral ID for a device
|
||||
*
|
||||
* This generally looks at the peripheral's device tree node to work
|
||||
* out the peripheral ID. The return value is normally interpreted as
|
||||
* enum periph_id. so long as this is defined by the platform (which it
|
||||
* should be).
|
||||
*
|
||||
* @dev: Pinctrl device to use for decoding
|
||||
* @periph: Device to check
|
||||
* @return peripheral ID of @periph, or -ENOENT on error
|
||||
*/
|
||||
int (*get_periph_id)(struct udevice *dev, struct udevice *periph);
|
||||
|
||||
/**
|
||||
* get_gpio_mux() - get the mux value for a particular GPIO
|
||||
*
|
||||
* This allows the raw mux value for a GPIO to be obtained. It is
|
||||
* useful for displaying the function being used by that GPIO, such
|
||||
* as with the 'gpio' command. This function is internal to the GPIO
|
||||
* subsystem and should not be used by generic code. Typically it is
|
||||
* used by a GPIO driver with knowledge of the SoC pinctrl setup.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @banknum: GPIO bank number
|
||||
* @index: GPIO index within the bank
|
||||
* @return mux value (SoC-specific, e.g. 0 for input, 1 for output)
|
||||
*/
|
||||
int (*get_gpio_mux)(struct udevice *dev, int banknum, int index);
|
||||
|
||||
/**
|
||||
* get_pin_muxing() - show pin muxing
|
||||
*
|
||||
* This allows to display the muxing of a given pin. It's useful for
|
||||
* debug purpose to know if a pin is configured as GPIO or as an
|
||||
* alternate function and which one.
|
||||
* Typically it is used by a PINCTRL driver with knowledge of the SoC
|
||||
* pinctrl setup.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin selector
|
||||
* @buf Pin's muxing description
|
||||
* @size Pin's muxing description length
|
||||
* return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*get_pin_muxing)(struct udevice *dev, unsigned int selector,
|
||||
char *buf, int size);
|
||||
|
||||
/**
|
||||
* gpio_request_enable: requests and enables GPIO on a certain pin.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin selector
|
||||
* return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*gpio_request_enable)(struct udevice *dev, unsigned int selector);
|
||||
|
||||
/**
|
||||
* gpio_disable_free: free up GPIO muxing on a certain pin.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin selector
|
||||
* return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*gpio_disable_free)(struct udevice *dev, unsigned int selector);
|
||||
};
|
||||
|
||||
#define pinctrl_get_ops(dev) ((struct pinctrl_ops *)(dev)->driver->ops)
|
||||
|
||||
/**
|
||||
* Generic pin configuration paramters
|
||||
*
|
||||
* enum pin_config_param - possible pin configuration parameters
|
||||
* @PIN_CONFIG_BIAS_BUS_HOLD: the pin will be set to weakly latch so that it
|
||||
* weakly drives the last value on a tristate bus, also known as a "bus
|
||||
* holder", "bus keeper" or "repeater". This allows another device on the
|
||||
* bus to change the value by driving the bus high or low and switching to
|
||||
* tristate. The argument is ignored.
|
||||
* @PIN_CONFIG_BIAS_DISABLE: disable any pin bias on the pin, a
|
||||
* transition from say pull-up to pull-down implies that you disable
|
||||
* pull-up in the process, this setting disables all biasing.
|
||||
* @PIN_CONFIG_BIAS_HIGH_IMPEDANCE: the pin will be set to a high impedance
|
||||
* mode, also know as "third-state" (tristate) or "high-Z" or "floating".
|
||||
* On output pins this effectively disconnects the pin, which is useful
|
||||
* if for example some other pin is going to drive the signal connected
|
||||
* to it for a while. Pins used for input are usually always high
|
||||
* impedance.
|
||||
* @PIN_CONFIG_BIAS_PULL_DOWN: the pin will be pulled down (usually with high
|
||||
* impedance to GROUND). If the argument is != 0 pull-down is enabled,
|
||||
* if it is 0, pull-down is total, i.e. the pin is connected to GROUND.
|
||||
* @PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: the pin will be pulled up or down based
|
||||
* on embedded knowledge of the controller hardware, like current mux
|
||||
* function. The pull direction and possibly strength too will normally
|
||||
* be decided completely inside the hardware block and not be readable
|
||||
* from the kernel side.
|
||||
* If the argument is != 0 pull up/down is enabled, if it is 0, the
|
||||
* configuration is ignored. The proper way to disable it is to use
|
||||
* @PIN_CONFIG_BIAS_DISABLE.
|
||||
* @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high
|
||||
* impedance to VDD). If the argument is != 0 pull-up is enabled,
|
||||
* if it is 0, pull-up is total, i.e. the pin is connected to VDD.
|
||||
* @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open
|
||||
* collector) which means it is usually wired with other output ports
|
||||
* which are then pulled up with an external resistor. Setting this
|
||||
* config will enable open drain mode, the argument is ignored.
|
||||
* @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source
|
||||
* (open emitter). Setting this config will enable open source mode, the
|
||||
* argument is ignored.
|
||||
* @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and
|
||||
* low, this is the most typical case and is typically achieved with two
|
||||
* active transistors on the output. Setting this config will enable
|
||||
* push-pull mode, the argument is ignored.
|
||||
* @PIN_CONFIG_DRIVE_STRENGTH: the pin will sink or source at most the current
|
||||
* passed as argument. The argument is in mA.
|
||||
* @PIN_CONFIG_DRIVE_STRENGTH_UA: the pin will sink or source at most the current
|
||||
* passed as argument. The argument is in uA.
|
||||
* @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode,
|
||||
* which means it will wait for signals to settle when reading inputs. The
|
||||
* argument gives the debounce time in usecs. Setting the
|
||||
* argument to zero turns debouncing off.
|
||||
* @PIN_CONFIG_INPUT_ENABLE: enable the pin's input. Note that this does not
|
||||
* affect the pin's ability to drive output. 1 enables input, 0 disables
|
||||
* input.
|
||||
* @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in
|
||||
* schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis,
|
||||
* the threshold value is given on a custom format as argument when
|
||||
* setting pins to this mode.
|
||||
* @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin.
|
||||
* If the argument != 0, schmitt-trigger mode is enabled. If it's 0,
|
||||
* schmitt-trigger mode is disabled.
|
||||
* @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power
|
||||
* operation, if several modes of operation are supported these can be
|
||||
* passed in the argument on a custom form, else just use argument 1
|
||||
* to indicate low power mode, argument 0 turns low power mode off.
|
||||
* @PIN_CONFIG_OUTPUT_ENABLE: this will enable the pin's output mode
|
||||
* without driving a value there. For most platforms this reduces to
|
||||
* enable the output buffers and then let the pin controller current
|
||||
* configuration (eg. the currently selected mux function) drive values on
|
||||
* the line. Use argument 1 to enable output mode, argument 0 to disable
|
||||
* it.
|
||||
* @PIN_CONFIG_OUTPUT: this will configure the pin as an output and drive a
|
||||
* value on the line. Use argument 1 to indicate high level, argument 0 to
|
||||
* indicate low level. (Please see Documentation/driver-api/pinctl.rst,
|
||||
* section "GPIO mode pitfalls" for a discussion around this parameter.)
|
||||
* @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power
|
||||
* supplies, the argument to this parameter (on a custom format) tells
|
||||
* the driver which alternative power source to use.
|
||||
* @PIN_CONFIG_SLEEP_HARDWARE_STATE: indicate this is sleep related state.
|
||||
* @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to
|
||||
* this parameter (on a custom format) tells the driver which alternative
|
||||
* slew rate to use.
|
||||
* @PIN_CONFIG_SKEW_DELAY: if the pin has programmable skew rate (on inputs)
|
||||
* or latch delay (on outputs) this parameter (in a custom format)
|
||||
* specifies the clock skew or latch delay. It typically controls how
|
||||
* many double inverters are put in front of the line.
|
||||
* @PIN_CONFIG_END: this is the last enumerator for pin configurations, if
|
||||
* you need to pass in custom configurations to the pin controller, use
|
||||
* PIN_CONFIG_END+1 as the base offset.
|
||||
* @PIN_CONFIG_MAX: this is the maximum configuration value that can be
|
||||
* presented using the packed format.
|
||||
*/
|
||||
enum pin_config_param {
|
||||
PIN_CONFIG_BIAS_BUS_HOLD,
|
||||
PIN_CONFIG_BIAS_DISABLE,
|
||||
PIN_CONFIG_BIAS_HIGH_IMPEDANCE,
|
||||
PIN_CONFIG_BIAS_PULL_DOWN,
|
||||
PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
|
||||
PIN_CONFIG_BIAS_PULL_UP,
|
||||
PIN_CONFIG_DRIVE_OPEN_DRAIN,
|
||||
PIN_CONFIG_DRIVE_OPEN_SOURCE,
|
||||
PIN_CONFIG_DRIVE_PUSH_PULL,
|
||||
PIN_CONFIG_DRIVE_STRENGTH,
|
||||
PIN_CONFIG_DRIVE_STRENGTH_UA,
|
||||
PIN_CONFIG_INPUT_DEBOUNCE,
|
||||
PIN_CONFIG_INPUT_ENABLE,
|
||||
PIN_CONFIG_INPUT_SCHMITT,
|
||||
PIN_CONFIG_INPUT_SCHMITT_ENABLE,
|
||||
PIN_CONFIG_LOW_POWER_MODE,
|
||||
PIN_CONFIG_OUTPUT_ENABLE,
|
||||
PIN_CONFIG_OUTPUT,
|
||||
PIN_CONFIG_POWER_SOURCE,
|
||||
PIN_CONFIG_SLEEP_HARDWARE_STATE,
|
||||
PIN_CONFIG_SLEW_RATE,
|
||||
PIN_CONFIG_SKEW_DELAY,
|
||||
PIN_CONFIG_END = 0x7F,
|
||||
PIN_CONFIG_MAX = 0xFF,
|
||||
};
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINCTRL_GENERIC)
|
||||
/**
|
||||
* pinctrl_generic_set_state() - generic set_state operation
|
||||
* Parse the DT node of @config and its children and handle generic properties
|
||||
* such as "pins", "groups", "functions", and pin configuration parameters.
|
||||
*
|
||||
* @pctldev: pinctrl device
|
||||
* @config: config device (pseudo device), pointing a config node in DTS
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_generic_set_state(struct udevice *pctldev, struct udevice *config);
|
||||
#else
|
||||
static inline int pinctrl_generic_set_state(struct udevice *pctldev,
|
||||
struct udevice *config)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINCTRL)
|
||||
/**
|
||||
* pinctrl_select_state() - set a device to a given state
|
||||
*
|
||||
* @dev: peripheral device
|
||||
* @statename: state name, like "default"
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_select_state(struct udevice *dev, const char *statename);
|
||||
#else
|
||||
static inline int pinctrl_select_state(struct udevice *dev,
|
||||
const char *statename)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* pinctrl_request() - Request a particular pinctrl function
|
||||
*
|
||||
* @dev: Device to check (UCLASS_PINCTRL)
|
||||
* @func: Function number (driver-specific)
|
||||
* @flags: Flags (driver-specific)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int pinctrl_request(struct udevice *dev, int func, int flags);
|
||||
|
||||
/**
|
||||
* pinctrl_request_noflags() - Request a particular pinctrl function
|
||||
*
|
||||
* This is similar to pinctrl_request() but uses 0 for @flags.
|
||||
*
|
||||
* @dev: Device to check (UCLASS_PINCTRL)
|
||||
* @func: Function number (driver-specific)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int pinctrl_request_noflags(struct udevice *dev, int func);
|
||||
|
||||
/**
|
||||
* pinctrl_get_periph_id() - get the peripheral ID for a device
|
||||
*
|
||||
* This generally looks at the peripheral's device tree node to work out the
|
||||
* peripheral ID. The return value is normally interpreted as enum periph_id.
|
||||
* so long as this is defined by the platform (which it should be).
|
||||
*
|
||||
* @dev: Pinctrl device to use for decoding
|
||||
* @periph: Device to check
|
||||
* @return peripheral ID of @periph, or -ENOENT on error
|
||||
*/
|
||||
int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
|
||||
|
||||
/**
|
||||
* pinctrl_get_gpio_mux() - get the mux value for a particular GPIO
|
||||
*
|
||||
* This allows the raw mux value for a GPIO to be obtained. It is
|
||||
* useful for displaying the function being used by that GPIO, such
|
||||
* as with the 'gpio' command. This function is internal to the GPIO
|
||||
* subsystem and should not be used by generic code. Typically it is
|
||||
* used by a GPIO driver with knowledge of the SoC pinctrl setup.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @banknum: GPIO bank number
|
||||
* @index: GPIO index within the bank
|
||||
* @return mux value (SoC-specific, e.g. 0 for input, 1 for output)
|
||||
*/
|
||||
int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index);
|
||||
|
||||
/**
|
||||
* pinctrl_get_pin_muxing() - Returns the muxing description
|
||||
*
|
||||
* This allows to display the muxing description of the given pin for
|
||||
* debug purpose
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector Pin index within pin-controller
|
||||
* @buf Pin's muxing description
|
||||
* @size Pin's muxing description length
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int pinctrl_get_pin_muxing(struct udevice *dev, int selector, char *buf,
|
||||
int size);
|
||||
|
||||
/**
|
||||
* pinctrl_get_pins_count() - display pin-controller pins number
|
||||
*
|
||||
* This allows to know the number of pins owned by a given pin-controller
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @return pins number if OK, -ve on error
|
||||
*/
|
||||
int pinctrl_get_pins_count(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* pinctrl_get_pin_name() - Returns the pin's name
|
||||
*
|
||||
* This allows to display the pin's name for debug purpose
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector Pin index within pin-controller
|
||||
* @buf Pin's name
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int pinctrl_get_pin_name(struct udevice *dev, int selector, char *buf,
|
||||
int size);
|
||||
|
||||
/**
|
||||
* pinctrl_gpio_request() - request a single pin to be used as GPIO
|
||||
*
|
||||
* @dev: GPIO peripheral device
|
||||
* @offset: the GPIO pin offset from the GPIO controller
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_gpio_request(struct udevice *dev, unsigned offset);
|
||||
|
||||
/**
|
||||
* pinctrl_gpio_free() - free a single pin used as GPIO
|
||||
*
|
||||
* @dev: GPIO peripheral device
|
||||
* @offset: the GPIO pin offset from the GPIO controller
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_gpio_free(struct udevice *dev, unsigned offset);
|
||||
|
||||
#endif /* __PINCTRL_H */
|
||||
@@ -0,0 +1,46 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2013 Google, Inc
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
* Marek Vasut <marex@denx.de>
|
||||
*/
|
||||
|
||||
#ifndef _DM_PLATDATA_H
|
||||
#define _DM_PLATDATA_H
|
||||
|
||||
#include <linker_lists.h>
|
||||
|
||||
/**
|
||||
* struct driver_info - Information required to instantiate a device
|
||||
*
|
||||
* NOTE: Avoid using this except in extreme circumstances, where device tree
|
||||
* is not feasible (e.g. serial driver in SPL where <8KB of SRAM is
|
||||
* available). U-Boot's driver model uses device tree for configuration.
|
||||
*
|
||||
* @name: Driver name
|
||||
* @platdata: Driver-specific platform data
|
||||
* @platdata_size: Size of platform data structure
|
||||
*/
|
||||
struct driver_info {
|
||||
const char *name;
|
||||
const void *platdata;
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
uint platdata_size;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* NOTE: Avoid using these except in extreme circumstances, where device tree
|
||||
* is not feasible (e.g. serial driver in SPL where <8KB of SRAM is
|
||||
* available). U-Boot's driver model uses device tree for configuration.
|
||||
*/
|
||||
#define U_BOOT_DEVICE(__name) \
|
||||
ll_entry_declare(struct driver_info, __name, driver_info)
|
||||
|
||||
/* Declare a list of devices. The argument is a driver_info[] array */
|
||||
#define U_BOOT_DEVICES(__name) \
|
||||
ll_entry_declare_list(struct driver_info, __name, driver_info)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2015 Vladimir Zapolskiy <vz@mleia.com>
|
||||
*/
|
||||
|
||||
#ifndef _LPC32XX_HSUART_PLAT_H
|
||||
#define _LPC32XX_HSUART_PLAT_H
|
||||
|
||||
/**
|
||||
* struct lpc32xx_hsuart_platdata - NXP LPC32xx HSUART platform data
|
||||
*
|
||||
* @base: Base register address
|
||||
*/
|
||||
struct lpc32xx_hsuart_platdata {
|
||||
unsigned long base;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2016 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
#ifndef _ETHOC_H
|
||||
#define _ETHOC_H
|
||||
|
||||
#include <net.h>
|
||||
|
||||
#ifdef CONFIG_DM_ETH
|
||||
|
||||
struct ethoc_eth_pdata {
|
||||
struct eth_pdata eth_pdata;
|
||||
phys_addr_t packet_base;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _ETHOC_H */
|
||||
@@ -0,0 +1,20 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2015-2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017 NXP
|
||||
*/
|
||||
|
||||
#ifndef __PFE_DM_ETH_H__
|
||||
#define __PFE_DM_ETH_H__
|
||||
#include <net.h>
|
||||
|
||||
struct pfe_ddr_address {
|
||||
void *ddr_pfe_baseaddr;
|
||||
unsigned long ddr_pfe_phys_baseaddr;
|
||||
};
|
||||
|
||||
struct pfe_eth_pdata {
|
||||
struct eth_pdata pfe_eth_pdata_mac;
|
||||
struct pfe_ddr_address pfe_ddr_addr;
|
||||
};
|
||||
#endif /* __PFE_DM_ETH_H__ */
|
||||
@@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* (C) Copyright 2016 Stephen Warren <swarren@wwwdotorg.org>
|
||||
*
|
||||
* Derived from pl01x code:
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef __serial_bcm283x_mu_h
|
||||
#define __serial_bcm283x_mu_h
|
||||
|
||||
/*
|
||||
*Information about a serial port
|
||||
*
|
||||
* @base: Register base address
|
||||
*/
|
||||
struct bcm283x_mu_serial_platdata {
|
||||
unsigned long base;
|
||||
unsigned int clock;
|
||||
bool skip_init;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2015 Angelo Dureghello <angelo@sysam.it>
|
||||
*/
|
||||
|
||||
#ifndef __serial_coldfire_h
|
||||
#define __serial_coldfire_h
|
||||
|
||||
/*
|
||||
* struct coldfire_serial_platdata - information about a coldfire port
|
||||
*
|
||||
* @base: Uart port base register address
|
||||
* @port: Uart port index, for cpu with pinmux for uart / gpio
|
||||
* baudrtatre: Uart port baudrate
|
||||
*/
|
||||
struct coldfire_serial_platdata {
|
||||
unsigned long base;
|
||||
int port;
|
||||
int baudrate;
|
||||
};
|
||||
|
||||
#endif /* __serial_coldfire_h */
|
||||
@@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef __serial_mxc_h
|
||||
#define __serial_mxc_h
|
||||
|
||||
/* Information about a serial port */
|
||||
struct mxc_serial_platdata {
|
||||
struct mxc_uart *reg; /* address of registers in physical memory */
|
||||
bool use_dte;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef __serial_pl01x_h
|
||||
#define __serial_pl01x_h
|
||||
|
||||
enum pl01x_type {
|
||||
TYPE_PL010,
|
||||
TYPE_PL011,
|
||||
};
|
||||
|
||||
/*
|
||||
*Information about a serial port
|
||||
*
|
||||
* @base: Register base address
|
||||
* @type: Port type
|
||||
* @clock: Input clock rate, used for calculating the baud rate divisor
|
||||
* @skip_init: Don't attempt to change port configuration (also means @clock
|
||||
* is ignored)
|
||||
*/
|
||||
struct pl01x_serial_platdata {
|
||||
unsigned long base;
|
||||
enum pl01x_type type;
|
||||
unsigned int clock;
|
||||
bool skip_init;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2016 Marcel Ziswiler <marcel.ziswiler@toradex.com>
|
||||
*/
|
||||
|
||||
#ifndef __SERIAL_PXA_H
|
||||
#define __SERIAL_PXA_H
|
||||
|
||||
/*
|
||||
* The numbering scheme differs here for PXA25x, PXA27x and PXA3xx so we can
|
||||
* easily handle enabling of clock.
|
||||
*/
|
||||
#ifdef CONFIG_CPU_MONAHANS
|
||||
#define UART_CLK_BASE CKENA_21_BTUART
|
||||
#define UART_CLK_REG CKENA
|
||||
#define BTUART_INDEX 0
|
||||
#define FFUART_INDEX 1
|
||||
#define STUART_INDEX 2
|
||||
#elif CONFIG_CPU_PXA25X
|
||||
#define UART_CLK_BASE (1 << 4) /* HWUART */
|
||||
#define UART_CLK_REG CKEN
|
||||
#define HWUART_INDEX 0
|
||||
#define STUART_INDEX 1
|
||||
#define FFUART_INDEX 2
|
||||
#define BTUART_INDEX 3
|
||||
#else /* PXA27x */
|
||||
#define UART_CLK_BASE CKEN5_STUART
|
||||
#define UART_CLK_REG CKEN
|
||||
#define STUART_INDEX 0
|
||||
#define FFUART_INDEX 1
|
||||
#define BTUART_INDEX 2
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only PXA250 has HWUART, to avoid poluting the code with more macros,
|
||||
* artificially introduce this.
|
||||
*/
|
||||
#ifndef CONFIG_CPU_PXA25X
|
||||
#define HWUART_INDEX 0xff
|
||||
#endif
|
||||
|
||||
/*
|
||||
* struct pxa_serial_platdata - information about a PXA port
|
||||
*
|
||||
* @base: Uart port base register address
|
||||
* @port: Uart port index, for cpu with pinmux for uart / gpio
|
||||
* baudrtatre: Uart port baudrate
|
||||
*/
|
||||
struct pxa_serial_platdata {
|
||||
struct pxa_uart_regs *base;
|
||||
int port;
|
||||
int baudrate;
|
||||
};
|
||||
|
||||
#endif /* __SERIAL_PXA_H */
|
||||
@@ -0,0 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
|
||||
* Copyright (c) 2014 Renesas Electronics Corporation
|
||||
*/
|
||||
|
||||
#ifndef __serial_sh_h
|
||||
#define __serial_sh_h
|
||||
|
||||
enum sh_clk_mode {
|
||||
INT_CLK,
|
||||
EXT_CLK,
|
||||
};
|
||||
|
||||
enum sh_serial_type {
|
||||
PORT_SCI,
|
||||
PORT_SCIF,
|
||||
PORT_SCIFA,
|
||||
PORT_SCIFB,
|
||||
};
|
||||
|
||||
/*
|
||||
* Information about SCIF port
|
||||
*
|
||||
* @base: Register base address
|
||||
* @clk: Input clock rate, used for calculating the baud rate divisor
|
||||
* @clk_mode: Clock mode, set internal (INT) or external (EXT)
|
||||
* @type: Type of SCIF
|
||||
*/
|
||||
struct sh_serial_platdata {
|
||||
unsigned long base;
|
||||
unsigned int clk;
|
||||
enum sh_clk_mode clk_mode;
|
||||
enum sh_serial_type type;
|
||||
};
|
||||
#endif /* __serial_sh_h */
|
||||
@@ -0,0 +1,29 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2018 Angelo Dureghello <angelo@sysam.it>
|
||||
*/
|
||||
|
||||
#ifndef __spi_coldfire_h
|
||||
#define __spi_coldfire_h
|
||||
|
||||
#define MAX_CTAR_REGS 8
|
||||
#define MAX_CTAR_FIELDS 8
|
||||
|
||||
/*
|
||||
* struct coldfire_spi_platdata - information about a coldfire spi module
|
||||
*
|
||||
* @regs_addr: base address for module registers
|
||||
* @speed_hz: default SCK frequency
|
||||
* @mode: default SPI mode
|
||||
* @num_cs: number of DSPI chipselect signals
|
||||
*/
|
||||
struct coldfire_spi_platdata {
|
||||
fdt_addr_t regs_addr;
|
||||
uint speed_hz;
|
||||
uint mode;
|
||||
uint num_cs;
|
||||
uint ctar[MAX_CTAR_REGS][MAX_CTAR_FIELDS];
|
||||
};
|
||||
|
||||
#endif /* __spi_coldfire_h */
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Jagan Teki <jagan@amarulasolutions.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __spi_davinci_h
|
||||
#define __spi_davinci_h
|
||||
|
||||
struct davinci_spi_platdata {
|
||||
struct davinci_spi_regs *regs;
|
||||
u8 num_cs; /* total no. of CS available */
|
||||
};
|
||||
|
||||
#endif /* __spi_davinci_h */
|
||||
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* (C) Copyright 2018
|
||||
* Quentin Schulz, Bootlin, quentin.schulz@bootlin.com
|
||||
*
|
||||
* Structure for use with U_BOOT_DEVICE for pl022 SPI devices or to use
|
||||
* in ofdata_to_platdata.
|
||||
*/
|
||||
|
||||
#ifndef __spi_pl022_h
|
||||
#define __spi_pl022_h
|
||||
|
||||
#include <fdtdec.h>
|
||||
|
||||
struct pl022_spi_pdata {
|
||||
fdt_addr_t addr;
|
||||
fdt_size_t size;
|
||||
unsigned int freq;
|
||||
};
|
||||
|
||||
#endif /* __spi_pl022_h */
|
||||
@@ -0,0 +1,892 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Function to read values from the device tree node attached to a udevice.
|
||||
*
|
||||
* Copyright (c) 2017 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*/
|
||||
|
||||
#ifndef _DM_READ_H
|
||||
#define _DM_READ_H
|
||||
|
||||
#include <dm/fdtaddr.h>
|
||||
#include <dm/ofnode.h>
|
||||
#include <dm/uclass.h>
|
||||
|
||||
struct resource;
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_LIVE)
|
||||
static inline const struct device_node *dev_np(struct udevice *dev)
|
||||
{
|
||||
return ofnode_to_np(dev->node);
|
||||
}
|
||||
#else
|
||||
static inline const struct device_node *dev_np(struct udevice *dev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dev_ofnode() - get the DT node reference associated with a udevice
|
||||
*
|
||||
* @dev: device to check
|
||||
* @return reference of the the device's DT node
|
||||
*/
|
||||
static inline ofnode dev_ofnode(struct udevice *dev)
|
||||
{
|
||||
return dev->node;
|
||||
}
|
||||
|
||||
static inline bool dev_of_valid(struct udevice *dev)
|
||||
{
|
||||
return ofnode_valid(dev_ofnode(dev));
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DM_DEV_READ_INLINE
|
||||
|
||||
/**
|
||||
* dev_read_u32() - read a 32-bit integer from a device's DT property
|
||||
*
|
||||
* @dev: device to read DT property from
|
||||
* @propname: name of the property to read from
|
||||
* @outp: place to put value (if found)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dev_read_u32(struct udevice *dev, const char *propname, u32 *outp);
|
||||
|
||||
/**
|
||||
* dev_read_u32_default() - read a 32-bit integer from a device's DT property
|
||||
*
|
||||
* @dev: device to read DT property from
|
||||
* @propname: name of the property to read from
|
||||
* @def: default value to return if the property has no value
|
||||
* @return property value, or @def if not found
|
||||
*/
|
||||
int dev_read_u32_default(struct udevice *dev, const char *propname, int def);
|
||||
|
||||
/**
|
||||
* dev_read_s32() - read a signed 32-bit integer from a device's DT property
|
||||
*
|
||||
* @dev: device to read DT property from
|
||||
* @propname: name of the property to read from
|
||||
* @outp: place to put value (if found)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dev_read_s32(struct udevice *dev, const char *propname, s32 *outp);
|
||||
|
||||
/**
|
||||
* dev_read_s32_default() - read a signed 32-bit int from a device's DT property
|
||||
*
|
||||
* @dev: device to read DT property from
|
||||
* @propname: name of the property to read from
|
||||
* @def: default value to return if the property has no value
|
||||
* @return property value, or @def if not found
|
||||
*/
|
||||
int dev_read_s32_default(struct udevice *dev, const char *propname, int def);
|
||||
|
||||
/**
|
||||
* dev_read_u32u() - read a 32-bit integer from a device's DT property
|
||||
*
|
||||
* This version uses a standard uint type.
|
||||
*
|
||||
* @dev: device to read DT property from
|
||||
* @propname: name of the property to read from
|
||||
* @outp: place to put value (if found)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dev_read_u32u(struct udevice *dev, const char *propname, uint *outp);
|
||||
|
||||
/**
|
||||
* dev_read_u64() - read a 64-bit integer from a device's DT property
|
||||
*
|
||||
* @dev: device to read DT property from
|
||||
* @propname: name of the property to read from
|
||||
* @outp: place to put value (if found)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dev_read_u64(struct udevice *dev, const char *propname, u64 *outp);
|
||||
|
||||
/**
|
||||
* dev_read_u64_default() - read a 64-bit integer from a device's DT property
|
||||
*
|
||||
* @dev: device to read DT property from
|
||||
* @propname: name of the property to read from
|
||||
* @def: default value to return if the property has no value
|
||||
* @return property value, or @def if not found
|
||||
*/
|
||||
u64 dev_read_u64_default(struct udevice *dev, const char *propname, u64 def);
|
||||
|
||||
/**
|
||||
* dev_read_string() - Read a string from a device's DT property
|
||||
*
|
||||
* @dev: device to read DT property from
|
||||
* @propname: name of the property to read
|
||||
* @return string from property value, or NULL if there is no such property
|
||||
*/
|
||||
const char *dev_read_string(struct udevice *dev, const char *propname);
|
||||
|
||||
/**
|
||||
* dev_read_bool() - read a boolean value from a device's DT property
|
||||
*
|
||||
* @dev: device to read DT property from
|
||||
* @propname: name of property to read
|
||||
* @return true if property is present (meaning true), false if not present
|
||||
*/
|
||||
bool dev_read_bool(struct udevice *dev, const char *propname);
|
||||
|
||||
/**
|
||||
* dev_read_subnode() - find a named subnode of a device
|
||||
*
|
||||
* @dev: device whose DT node contains the subnode
|
||||
* @subnode_name: name of subnode to find
|
||||
* @return reference to subnode (which can be invalid if there is no such
|
||||
* subnode)
|
||||
*/
|
||||
ofnode dev_read_subnode(struct udevice *dev, const char *subbnode_name);
|
||||
|
||||
/**
|
||||
* dev_read_size() - read the size of a property
|
||||
*
|
||||
* @dev: device to check
|
||||
* @propname: property to check
|
||||
* @return size of property if present, or -EINVAL if not
|
||||
*/
|
||||
int dev_read_size(struct udevice *dev, const char *propname);
|
||||
|
||||
/**
|
||||
* dev_read_addr_index() - Get the indexed reg property of a device
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @index: the 'reg' property can hold a list of <addr, size> pairs
|
||||
* and @index is used to select which one is required
|
||||
*
|
||||
* @return address or FDT_ADDR_T_NONE if not found
|
||||
*/
|
||||
fdt_addr_t dev_read_addr_index(struct udevice *dev, int index);
|
||||
|
||||
/**
|
||||
* dev_read_addr_size_index() - Get the indexed reg property of a device
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @index: the 'reg' property can hold a list of <addr, size> pairs
|
||||
* and @index is used to select which one is required
|
||||
* @size: place to put size value (on success)
|
||||
*
|
||||
* @return address or FDT_ADDR_T_NONE if not found
|
||||
*/
|
||||
fdt_addr_t dev_read_addr_size_index(struct udevice *dev, int index,
|
||||
fdt_size_t *size);
|
||||
|
||||
/**
|
||||
* dev_remap_addr_index() - Get the indexed reg property of a device
|
||||
* as a memory-mapped I/O pointer
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @index: the 'reg' property can hold a list of <addr, size> pairs
|
||||
* and @index is used to select which one is required
|
||||
*
|
||||
* @return pointer or NULL if not found
|
||||
*/
|
||||
void *dev_remap_addr_index(struct udevice *dev, int index);
|
||||
|
||||
/**
|
||||
* dev_read_addr_name() - Get the reg property of a device, indexed by name
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
|
||||
* 'reg-names' property providing named-based identification. @index
|
||||
* indicates the value to search for in 'reg-names'.
|
||||
*
|
||||
* @return address or FDT_ADDR_T_NONE if not found
|
||||
*/
|
||||
fdt_addr_t dev_read_addr_name(struct udevice *dev, const char* name);
|
||||
|
||||
/**
|
||||
* dev_read_addr_size_name() - Get the reg property of a device, indexed by name
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
|
||||
* 'reg-names' property providing named-based identification. @index
|
||||
* indicates the value to search for in 'reg-names'.
|
||||
* @size: place to put size value (on success)
|
||||
*
|
||||
* @return address or FDT_ADDR_T_NONE if not found
|
||||
*/
|
||||
fdt_addr_t dev_read_addr_size_name(struct udevice *dev, const char *name,
|
||||
fdt_size_t *size);
|
||||
|
||||
/**
|
||||
* dev_remap_addr_name() - Get the reg property of a device, indexed by name,
|
||||
* as a memory-mapped I/O pointer
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
|
||||
* 'reg-names' property providing named-based identification. @index
|
||||
* indicates the value to search for in 'reg-names'.
|
||||
*
|
||||
* @return pointer or NULL if not found
|
||||
*/
|
||||
void *dev_remap_addr_name(struct udevice *dev, const char* name);
|
||||
|
||||
/**
|
||||
* dev_read_addr() - Get the reg property of a device
|
||||
*
|
||||
* @dev: Device to read from
|
||||
*
|
||||
* @return address or FDT_ADDR_T_NONE if not found
|
||||
*/
|
||||
fdt_addr_t dev_read_addr(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_addr_ptr() - Get the reg property of a device
|
||||
* as a pointer
|
||||
*
|
||||
* @dev: Device to read from
|
||||
*
|
||||
* @return pointer or NULL if not found
|
||||
*/
|
||||
void *dev_read_addr_ptr(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_addr_pci() - Read an address and handle PCI address translation
|
||||
*
|
||||
* At present U-Boot does not have address translation logic for PCI in the
|
||||
* livetree implementation (of_addr.c). This special function supports this for
|
||||
* the flat tree implementation.
|
||||
*
|
||||
* This function should be removed (and code should use dev_read() instead)
|
||||
* once:
|
||||
*
|
||||
* 1. PCI address translation is added; and either
|
||||
* 2. everything uses livetree where PCI translation is used (which is feasible
|
||||
* in SPL and U-Boot proper) or PCI address translation is added to
|
||||
* fdtdec_get_addr() and friends.
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @return address or FDT_ADDR_T_NONE if not found
|
||||
*/
|
||||
fdt_addr_t dev_read_addr_pci(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_remap_addr() - Get the reg property of a device as a
|
||||
* memory-mapped I/O pointer
|
||||
*
|
||||
* @dev: Device to read from
|
||||
*
|
||||
* @return pointer or NULL if not found
|
||||
*/
|
||||
void *dev_remap_addr(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_addr_size() - get address and size from a device property
|
||||
*
|
||||
* This does no address translation. It simply reads an property that contains
|
||||
* an address and a size value, one after the other.
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @propname: property to read
|
||||
* @sizep: place to put size value (on success)
|
||||
* @return address value, or FDT_ADDR_T_NONE on error
|
||||
*/
|
||||
fdt_addr_t dev_read_addr_size(struct udevice *dev, const char *propname,
|
||||
fdt_size_t *sizep);
|
||||
|
||||
/**
|
||||
* dev_read_name() - get the name of a device's node
|
||||
*
|
||||
* @dev: Device to read from
|
||||
* @return name of node
|
||||
*/
|
||||
const char *dev_read_name(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_stringlist_search() - find string in a string list and return index
|
||||
*
|
||||
* Note that it is possible for this function to succeed on property values
|
||||
* that are not NUL-terminated. That's because the function will stop after
|
||||
* finding the first occurrence of @string. This can for example happen with
|
||||
* small-valued cell properties, such as #address-cells, when searching for
|
||||
* the empty string.
|
||||
*
|
||||
* @dev: device to check
|
||||
* @propname: name of the property containing the string list
|
||||
* @string: string to look up in the string list
|
||||
*
|
||||
* @return:
|
||||
* the index of the string in the list of strings
|
||||
* -ENODATA if the property is not found
|
||||
* -EINVAL on some other error
|
||||
*/
|
||||
int dev_read_stringlist_search(struct udevice *dev, const char *property,
|
||||
const char *string);
|
||||
|
||||
/**
|
||||
* dev_read_string_index() - obtain an indexed string from a string list
|
||||
*
|
||||
* @dev: device to examine
|
||||
* @propname: name of the property containing the string list
|
||||
* @index: index of the string to return
|
||||
* @out: return location for the string
|
||||
*
|
||||
* @return:
|
||||
* length of string, if found or -ve error value if not found
|
||||
*/
|
||||
int dev_read_string_index(struct udevice *dev, const char *propname, int index,
|
||||
const char **outp);
|
||||
|
||||
/**
|
||||
* dev_read_string_count() - find the number of strings in a string list
|
||||
*
|
||||
* @dev: device to examine
|
||||
* @propname: name of the property containing the string list
|
||||
* @return:
|
||||
* number of strings in the list, or -ve error value if not found
|
||||
*/
|
||||
int dev_read_string_count(struct udevice *dev, const char *propname);
|
||||
/**
|
||||
* dev_read_phandle_with_args() - Find a node pointed by phandle in a list
|
||||
*
|
||||
* This function is useful to parse lists of phandles and their arguments.
|
||||
* Returns 0 on success and fills out_args, on error returns appropriate
|
||||
* errno value.
|
||||
*
|
||||
* Caller is responsible to call of_node_put() on the returned out_args->np
|
||||
* pointer.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* phandle1: node1 {
|
||||
* #list-cells = <2>;
|
||||
* }
|
||||
*
|
||||
* phandle2: node2 {
|
||||
* #list-cells = <1>;
|
||||
* }
|
||||
*
|
||||
* node3 {
|
||||
* list = <&phandle1 1 2 &phandle2 3>;
|
||||
* }
|
||||
*
|
||||
* To get a device_node of the `node2' node you may call this:
|
||||
* dev_read_phandle_with_args(dev, "list", "#list-cells", 0, 1, &args);
|
||||
*
|
||||
* @dev: device whose node containing a list
|
||||
* @list_name: property name that contains a list
|
||||
* @cells_name: property name that specifies phandles' arguments count
|
||||
* @cells_count: Cell count to use if @cells_name is NULL
|
||||
* @index: index of a phandle to parse out
|
||||
* @out_args: optional pointer to output arguments structure (will be filled)
|
||||
* @return 0 on success (with @out_args filled out if not NULL), -ENOENT if
|
||||
* @list_name does not exist, -EINVAL if a phandle was not found,
|
||||
* @cells_name could not be found, the arguments were truncated or there
|
||||
* were too many arguments.
|
||||
*/
|
||||
int dev_read_phandle_with_args(struct udevice *dev, const char *list_name,
|
||||
const char *cells_name, int cell_count,
|
||||
int index,
|
||||
struct ofnode_phandle_args *out_args);
|
||||
|
||||
/**
|
||||
* dev_count_phandle_with_args() - Return phandle number in a list
|
||||
*
|
||||
* This function is usefull to get phandle number contained in a property list.
|
||||
* For example, this allows to allocate the right amount of memory to keep
|
||||
* clock's reference contained into the "clocks" property.
|
||||
*
|
||||
*
|
||||
* @dev: device whose node containing a list
|
||||
* @list_name: property name that contains a list
|
||||
* @cells_name: property name that specifies phandles' arguments count
|
||||
* @Returns number of phandle found on success, on error returns appropriate
|
||||
* errno value.
|
||||
*/
|
||||
|
||||
int dev_count_phandle_with_args(struct udevice *dev, const char *list_name,
|
||||
const char *cells_name);
|
||||
|
||||
/**
|
||||
* dev_read_addr_cells() - Get the number of address cells for a device's node
|
||||
*
|
||||
* This walks back up the tree to find the closest #address-cells property
|
||||
* which controls the given node.
|
||||
*
|
||||
* @dev: device to check
|
||||
* @return number of address cells this node uses
|
||||
*/
|
||||
int dev_read_addr_cells(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_size_cells() - Get the number of size cells for a device's node
|
||||
*
|
||||
* This walks back up the tree to find the closest #size-cells property
|
||||
* which controls the given node.
|
||||
*
|
||||
* @dev: device to check
|
||||
* @return number of size cells this node uses
|
||||
*/
|
||||
int dev_read_size_cells(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_addr_cells() - Get the address cells property in a node
|
||||
*
|
||||
* This function matches fdt_address_cells().
|
||||
*
|
||||
* @dev: device to check
|
||||
* @return number of address cells this node uses
|
||||
*/
|
||||
int dev_read_simple_addr_cells(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_size_cells() - Get the size cells property in a node
|
||||
*
|
||||
* This function matches fdt_size_cells().
|
||||
*
|
||||
* @dev: device to check
|
||||
* @return number of size cells this node uses
|
||||
*/
|
||||
int dev_read_simple_size_cells(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_phandle() - Get the phandle from a device
|
||||
*
|
||||
* @dev: device to check
|
||||
* @return phandle (1 or greater), or 0 if no phandle or other error
|
||||
*/
|
||||
int dev_read_phandle(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_prop()- - read a property from a device's node
|
||||
*
|
||||
* @dev: device to check
|
||||
* @propname: property to read
|
||||
* @lenp: place to put length on success
|
||||
* @return pointer to property, or NULL if not found
|
||||
*/
|
||||
const void *dev_read_prop(struct udevice *dev, const char *propname, int *lenp);
|
||||
|
||||
/**
|
||||
* dev_read_alias_seq() - Get the alias sequence number of a node
|
||||
*
|
||||
* This works out whether a node is pointed to by an alias, and if so, the
|
||||
* sequence number of that alias. Aliases are of the form <base><num> where
|
||||
* <num> is the sequence number. For example spi2 would be sequence number 2.
|
||||
*
|
||||
* @dev: device to look up
|
||||
* @devnump: set to the sequence number if one is found
|
||||
* @return 0 if a sequence was found, -ve if not
|
||||
*/
|
||||
int dev_read_alias_seq(struct udevice *dev, int *devnump);
|
||||
|
||||
/**
|
||||
* dev_read_u32_array() - Find and read an array of 32 bit integers
|
||||
*
|
||||
* Search for a property in a device node and read 32-bit value(s) from
|
||||
* it.
|
||||
*
|
||||
* The out_values is modified only if a valid u32 value can be decoded.
|
||||
*
|
||||
* @dev: device to look up
|
||||
* @propname: name of the property to read
|
||||
* @out_values: pointer to return value, modified only if return value is 0
|
||||
* @sz: number of array elements to read
|
||||
* @return 0 on success, -EINVAL if the property does not exist, -ENODATA if
|
||||
* property does not have a value, and -EOVERFLOW if the property data isn't
|
||||
* large enough.
|
||||
*/
|
||||
int dev_read_u32_array(struct udevice *dev, const char *propname,
|
||||
u32 *out_values, size_t sz);
|
||||
|
||||
/**
|
||||
* dev_read_first_subnode() - find the first subnode of a device's node
|
||||
*
|
||||
* @dev: device to look up
|
||||
* @return reference to the first subnode (which can be invalid if the device's
|
||||
* node has no subnodes)
|
||||
*/
|
||||
ofnode dev_read_first_subnode(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* ofnode_next_subnode() - find the next sibling of a subnode
|
||||
*
|
||||
* @node: valid reference to previous node (sibling)
|
||||
* @return reference to the next subnode (which can be invalid if the node
|
||||
* has no more siblings)
|
||||
*/
|
||||
ofnode dev_read_next_subnode(ofnode node);
|
||||
|
||||
/**
|
||||
* dev_read_u8_array_ptr() - find an 8-bit array
|
||||
*
|
||||
* Look up a device's node property and return a pointer to its contents as a
|
||||
* byte array of given length. The property must have at least enough data
|
||||
* for the array (count bytes). It may have more, but this will be ignored.
|
||||
* The data is not copied.
|
||||
*
|
||||
* @dev: device to look up
|
||||
* @propname: name of property to find
|
||||
* @sz: number of array elements
|
||||
* @return pointer to byte array if found, or NULL if the property is not
|
||||
* found or there is not enough data
|
||||
*/
|
||||
const uint8_t *dev_read_u8_array_ptr(struct udevice *dev, const char *propname,
|
||||
size_t sz);
|
||||
|
||||
/**
|
||||
* dev_read_enabled() - check whether a node is enabled
|
||||
*
|
||||
* This looks for a 'status' property. If this exists, then returns 1 if
|
||||
* the status is 'ok' and 0 otherwise. If there is no status property,
|
||||
* it returns 1 on the assumption that anything mentioned should be enabled
|
||||
* by default.
|
||||
*
|
||||
* @dev: device to examine
|
||||
* @return integer value 0 (not enabled) or 1 (enabled)
|
||||
*/
|
||||
int dev_read_enabled(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_read_resource() - obtain an indexed resource from a device.
|
||||
*
|
||||
* @dev: device to examine
|
||||
* @index index of the resource to retrieve (0 = first)
|
||||
* @res returns the resource
|
||||
* @return 0 if ok, negative on error
|
||||
*/
|
||||
int dev_read_resource(struct udevice *dev, uint index, struct resource *res);
|
||||
|
||||
/**
|
||||
* dev_read_resource_byname() - obtain a named resource from a device.
|
||||
*
|
||||
* @dev: device to examine
|
||||
* @name: name of the resource to retrieve
|
||||
* @res: returns the resource
|
||||
* @return 0 if ok, negative on error
|
||||
*/
|
||||
int dev_read_resource_byname(struct udevice *dev, const char *name,
|
||||
struct resource *res);
|
||||
|
||||
/**
|
||||
* dev_translate_address() - Translate a device-tree address
|
||||
*
|
||||
* Translate an address from the device-tree into a CPU physical address. This
|
||||
* function walks up the tree and applies the various bus mappings along the
|
||||
* way.
|
||||
*
|
||||
* @dev: device giving the context in which to translate the address
|
||||
* @in_addr: pointer to the address to translate
|
||||
* @return the translated address; OF_BAD_ADDR on error
|
||||
*/
|
||||
u64 dev_translate_address(struct udevice *dev, const fdt32_t *in_addr);
|
||||
|
||||
/**
|
||||
* dev_translate_dma_address() - Translate a device-tree DMA address
|
||||
*
|
||||
* Translate a DMA address from the device-tree into a CPU physical address.
|
||||
* This function walks up the tree and applies the various bus mappings along
|
||||
* the way.
|
||||
*
|
||||
* @dev: device giving the context in which to translate the DMA address
|
||||
* @in_addr: pointer to the DMA address to translate
|
||||
* @return the translated DMA address; OF_BAD_ADDR on error
|
||||
*/
|
||||
u64 dev_translate_dma_address(struct udevice *dev, const fdt32_t *in_addr);
|
||||
|
||||
/**
|
||||
* dev_read_alias_highest_id - Get highest alias id for the given stem
|
||||
* @stem: Alias stem to be examined
|
||||
*
|
||||
* The function travels the lookup table to get the highest alias id for the
|
||||
* given alias stem.
|
||||
* @return alias ID, if found, else -1
|
||||
*/
|
||||
int dev_read_alias_highest_id(const char *stem);
|
||||
|
||||
#else /* CONFIG_DM_DEV_READ_INLINE is enabled */
|
||||
|
||||
static inline int dev_read_u32(struct udevice *dev,
|
||||
const char *propname, u32 *outp)
|
||||
{
|
||||
return ofnode_read_u32(dev_ofnode(dev), propname, outp);
|
||||
}
|
||||
|
||||
static inline int dev_read_u32_default(struct udevice *dev,
|
||||
const char *propname, int def)
|
||||
{
|
||||
return ofnode_read_u32_default(dev_ofnode(dev), propname, def);
|
||||
}
|
||||
|
||||
static inline int dev_read_s32(struct udevice *dev,
|
||||
const char *propname, s32 *outp)
|
||||
{
|
||||
return ofnode_read_s32(dev_ofnode(dev), propname, outp);
|
||||
}
|
||||
|
||||
static inline int dev_read_s32_default(struct udevice *dev,
|
||||
const char *propname, int def)
|
||||
{
|
||||
return ofnode_read_s32_default(dev_ofnode(dev), propname, def);
|
||||
}
|
||||
|
||||
static inline int dev_read_u32u(struct udevice *dev,
|
||||
const char *propname, uint *outp)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = ofnode_read_u32(dev_ofnode(dev), propname, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
*outp = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dev_read_u64(struct udevice *dev,
|
||||
const char *propname, u64 *outp)
|
||||
{
|
||||
return ofnode_read_u64(dev_ofnode(dev), propname, outp);
|
||||
}
|
||||
|
||||
static inline u64 dev_read_u64_default(struct udevice *dev,
|
||||
const char *propname, u64 def)
|
||||
{
|
||||
return ofnode_read_u64_default(dev_ofnode(dev), propname, def);
|
||||
}
|
||||
|
||||
static inline const char *dev_read_string(struct udevice *dev,
|
||||
const char *propname)
|
||||
{
|
||||
return ofnode_read_string(dev_ofnode(dev), propname);
|
||||
}
|
||||
|
||||
static inline bool dev_read_bool(struct udevice *dev, const char *propname)
|
||||
{
|
||||
return ofnode_read_bool(dev_ofnode(dev), propname);
|
||||
}
|
||||
|
||||
static inline ofnode dev_read_subnode(struct udevice *dev,
|
||||
const char *subbnode_name)
|
||||
{
|
||||
return ofnode_find_subnode(dev_ofnode(dev), subbnode_name);
|
||||
}
|
||||
|
||||
static inline int dev_read_size(struct udevice *dev, const char *propname)
|
||||
{
|
||||
return ofnode_read_size(dev_ofnode(dev), propname);
|
||||
}
|
||||
|
||||
static inline fdt_addr_t dev_read_addr_index(struct udevice *dev, int index)
|
||||
{
|
||||
return devfdt_get_addr_index(dev, index);
|
||||
}
|
||||
|
||||
static inline fdt_addr_t dev_read_addr_size_index(struct udevice *dev,
|
||||
int index,
|
||||
fdt_size_t *size)
|
||||
{
|
||||
return devfdt_get_addr_size_index(dev, index, size);
|
||||
}
|
||||
|
||||
static inline fdt_addr_t dev_read_addr_name(struct udevice *dev,
|
||||
const char *name)
|
||||
{
|
||||
return devfdt_get_addr_name(dev, name);
|
||||
}
|
||||
|
||||
static inline fdt_addr_t dev_read_addr_size_name(struct udevice *dev,
|
||||
const char *name,
|
||||
fdt_size_t *size)
|
||||
{
|
||||
return devfdt_get_addr_size_name(dev, name, size);
|
||||
}
|
||||
|
||||
static inline fdt_addr_t dev_read_addr(struct udevice *dev)
|
||||
{
|
||||
return devfdt_get_addr(dev);
|
||||
}
|
||||
|
||||
static inline void *dev_read_addr_ptr(struct udevice *dev)
|
||||
{
|
||||
return devfdt_get_addr_ptr(dev);
|
||||
}
|
||||
|
||||
static inline fdt_addr_t dev_read_addr_pci(struct udevice *dev)
|
||||
{
|
||||
return devfdt_get_addr_pci(dev);
|
||||
}
|
||||
|
||||
static inline void *dev_remap_addr(struct udevice *dev)
|
||||
{
|
||||
return devfdt_remap_addr(dev);
|
||||
}
|
||||
|
||||
static inline void *dev_remap_addr_index(struct udevice *dev, int index)
|
||||
{
|
||||
return devfdt_remap_addr_index(dev, index);
|
||||
}
|
||||
|
||||
static inline void *dev_remap_addr_name(struct udevice *dev, const char *name)
|
||||
{
|
||||
return devfdt_remap_addr_name(dev, name);
|
||||
}
|
||||
|
||||
static inline fdt_addr_t dev_read_addr_size(struct udevice *dev,
|
||||
const char *propname,
|
||||
fdt_size_t *sizep)
|
||||
{
|
||||
return ofnode_get_addr_size(dev_ofnode(dev), propname, sizep);
|
||||
}
|
||||
|
||||
static inline const char *dev_read_name(struct udevice *dev)
|
||||
{
|
||||
return ofnode_get_name(dev_ofnode(dev));
|
||||
}
|
||||
|
||||
static inline int dev_read_stringlist_search(struct udevice *dev,
|
||||
const char *propname,
|
||||
const char *string)
|
||||
{
|
||||
return ofnode_stringlist_search(dev_ofnode(dev), propname, string);
|
||||
}
|
||||
|
||||
static inline int dev_read_string_index(struct udevice *dev,
|
||||
const char *propname, int index,
|
||||
const char **outp)
|
||||
{
|
||||
return ofnode_read_string_index(dev_ofnode(dev), propname, index, outp);
|
||||
}
|
||||
|
||||
static inline int dev_read_string_count(struct udevice *dev,
|
||||
const char *propname)
|
||||
{
|
||||
return ofnode_read_string_count(dev_ofnode(dev), propname);
|
||||
}
|
||||
|
||||
static inline int dev_read_phandle_with_args(struct udevice *dev,
|
||||
const char *list_name, const char *cells_name, int cell_count,
|
||||
int index, struct ofnode_phandle_args *out_args)
|
||||
{
|
||||
return ofnode_parse_phandle_with_args(dev_ofnode(dev), list_name,
|
||||
cells_name, cell_count, index,
|
||||
out_args);
|
||||
}
|
||||
|
||||
static inline int dev_count_phandle_with_args(struct udevice *dev,
|
||||
const char *list_name, const char *cells_name)
|
||||
{
|
||||
return ofnode_count_phandle_with_args(dev_ofnode(dev), list_name,
|
||||
cells_name);
|
||||
}
|
||||
|
||||
static inline int dev_read_addr_cells(struct udevice *dev)
|
||||
{
|
||||
/* NOTE: this call should walk up the parent stack */
|
||||
return fdt_address_cells(gd->fdt_blob, dev_of_offset(dev));
|
||||
}
|
||||
|
||||
static inline int dev_read_size_cells(struct udevice *dev)
|
||||
{
|
||||
/* NOTE: this call should walk up the parent stack */
|
||||
return fdt_size_cells(gd->fdt_blob, dev_of_offset(dev));
|
||||
}
|
||||
|
||||
static inline int dev_read_simple_addr_cells(struct udevice *dev)
|
||||
{
|
||||
return fdt_address_cells(gd->fdt_blob, dev_of_offset(dev));
|
||||
}
|
||||
|
||||
static inline int dev_read_simple_size_cells(struct udevice *dev)
|
||||
{
|
||||
return fdt_size_cells(gd->fdt_blob, dev_of_offset(dev));
|
||||
}
|
||||
|
||||
static inline int dev_read_phandle(struct udevice *dev)
|
||||
{
|
||||
return fdt_get_phandle(gd->fdt_blob, dev_of_offset(dev));
|
||||
}
|
||||
|
||||
static inline const void *dev_read_prop(struct udevice *dev,
|
||||
const char *propname, int *lenp)
|
||||
{
|
||||
return ofnode_get_property(dev_ofnode(dev), propname, lenp);
|
||||
}
|
||||
|
||||
static inline int dev_read_alias_seq(struct udevice *dev, int *devnump)
|
||||
{
|
||||
return fdtdec_get_alias_seq(gd->fdt_blob, dev->uclass->uc_drv->name,
|
||||
dev_of_offset(dev), devnump);
|
||||
}
|
||||
|
||||
static inline int dev_read_u32_array(struct udevice *dev, const char *propname,
|
||||
u32 *out_values, size_t sz)
|
||||
{
|
||||
return ofnode_read_u32_array(dev_ofnode(dev), propname, out_values, sz);
|
||||
}
|
||||
|
||||
static inline ofnode dev_read_first_subnode(struct udevice *dev)
|
||||
{
|
||||
return ofnode_first_subnode(dev_ofnode(dev));
|
||||
}
|
||||
|
||||
static inline ofnode dev_read_next_subnode(ofnode node)
|
||||
{
|
||||
return ofnode_next_subnode(node);
|
||||
}
|
||||
|
||||
static inline const uint8_t *dev_read_u8_array_ptr(struct udevice *dev,
|
||||
const char *propname, size_t sz)
|
||||
{
|
||||
return ofnode_read_u8_array_ptr(dev_ofnode(dev), propname, sz);
|
||||
}
|
||||
|
||||
static inline int dev_read_enabled(struct udevice *dev)
|
||||
{
|
||||
return fdtdec_get_is_enabled(gd->fdt_blob, dev_of_offset(dev));
|
||||
}
|
||||
|
||||
static inline int dev_read_resource(struct udevice *dev, uint index,
|
||||
struct resource *res)
|
||||
{
|
||||
return ofnode_read_resource(dev_ofnode(dev), index, res);
|
||||
}
|
||||
|
||||
static inline int dev_read_resource_byname(struct udevice *dev,
|
||||
const char *name,
|
||||
struct resource *res)
|
||||
{
|
||||
return ofnode_read_resource_byname(dev_ofnode(dev), name, res);
|
||||
}
|
||||
|
||||
static inline u64 dev_translate_address(struct udevice *dev, const fdt32_t *in_addr)
|
||||
{
|
||||
return ofnode_translate_address(dev_ofnode(dev), in_addr);
|
||||
}
|
||||
|
||||
static inline u64 dev_translate_dma_address(struct udevice *dev, const fdt32_t *in_addr)
|
||||
{
|
||||
return ofnode_translate_dma_address(dev_ofnode(dev), in_addr);
|
||||
}
|
||||
|
||||
static inline int dev_read_alias_highest_id(const char *stem)
|
||||
{
|
||||
return fdtdec_get_alias_highest_id(gd->fdt_blob, stem);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DM_DEV_READ_INLINE */
|
||||
|
||||
/**
|
||||
* dev_for_each_subnode() - Helper function to iterate through subnodes
|
||||
*
|
||||
* This creates a for() loop which works through the subnodes in a device's
|
||||
* device-tree node.
|
||||
*
|
||||
* @subnode: ofnode holding the current subnode
|
||||
* @dev: device to use for interation (struct udevice *)
|
||||
*/
|
||||
#define dev_for_each_subnode(subnode, dev) \
|
||||
for (subnode = dev_read_first_subnode(dev); \
|
||||
ofnode_valid(subnode); \
|
||||
subnode = ofnode_next_subnode(subnode))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,133 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2013 Google, Inc
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _DM_ROOT_H_
|
||||
#define _DM_ROOT_H_
|
||||
|
||||
struct udevice;
|
||||
|
||||
/**
|
||||
* dm_root() - Return pointer to the top of the driver tree
|
||||
*
|
||||
* This function returns pointer to the root node of the driver tree,
|
||||
*
|
||||
* @return pointer to root device, or NULL if not inited yet
|
||||
*/
|
||||
struct udevice *dm_root(void);
|
||||
|
||||
struct global_data;
|
||||
/**
|
||||
* dm_fixup_for_gd_move() - Handle global_data moving to a new place
|
||||
*
|
||||
* The uclass list is part of global_data. Due to the way lists work, moving
|
||||
* the list will cause it to become invalid. This function fixes that up so
|
||||
* that the uclass list will work correctly.
|
||||
*/
|
||||
void dm_fixup_for_gd_move(struct global_data *new_gd);
|
||||
|
||||
/**
|
||||
* dm_scan_platdata() - Scan all platform data and bind drivers
|
||||
*
|
||||
* This scans all available platdata and creates drivers for each
|
||||
*
|
||||
* @pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC
|
||||
* flag. If false bind all drivers.
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_scan_platdata(bool pre_reloc_only);
|
||||
|
||||
/**
|
||||
* dm_scan_fdt() - Scan the device tree and bind drivers
|
||||
*
|
||||
* This scans the device tree and creates a driver for each node. Only
|
||||
* the top-level subnodes are examined.
|
||||
*
|
||||
* @blob: Pointer to device tree blob
|
||||
* @pre_reloc_only: If true, bind only nodes with special devicetree properties,
|
||||
* or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_scan_fdt(const void *blob, bool pre_reloc_only);
|
||||
|
||||
/**
|
||||
* dm_extended_scan_fdt() - Scan the device tree and bind drivers
|
||||
*
|
||||
* This calls dm_scna_dft() which scans the device tree and creates a driver
|
||||
* for each node. the top-level subnodes are examined and also all sub-nodes
|
||||
* of "clocks" node.
|
||||
*
|
||||
* @blob: Pointer to device tree blob
|
||||
* @pre_reloc_only: If true, bind only nodes with special devicetree properties,
|
||||
* or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only);
|
||||
|
||||
/**
|
||||
* dm_scan_other() - Scan for other devices
|
||||
*
|
||||
* Some devices may not be visible to Driver Model. This weak function can
|
||||
* be provided by boards which wish to create their own devices
|
||||
* programmaticaly. They should do this by calling device_bind() on each
|
||||
* device.
|
||||
*
|
||||
* @pre_reloc_only: If true, bind only nodes with special devicetree properties,
|
||||
* or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_scan_other(bool pre_reloc_only);
|
||||
|
||||
/**
|
||||
* dm_init_and_scan() - Initialise Driver Model structures and scan for devices
|
||||
*
|
||||
* This function initialises the roots of the driver tree and uclass trees,
|
||||
* then scans and binds available devices from platform data and the FDT.
|
||||
* This calls dm_init() to set up Driver Model structures.
|
||||
*
|
||||
* @pre_reloc_only: If true, bind only nodes with special devicetree properties,
|
||||
* or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_init_and_scan(bool pre_reloc_only);
|
||||
|
||||
/**
|
||||
* dm_init() - Initialise Driver Model structures
|
||||
*
|
||||
* This function will initialize roots of driver tree and class tree.
|
||||
* This needs to be called before anything uses the DM
|
||||
*
|
||||
* @of_live: Enable live device tree
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_init(bool of_live);
|
||||
|
||||
/**
|
||||
* dm_uninit - Uninitialise Driver Model structures
|
||||
*
|
||||
* All devices will be removed and unbound
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_uninit(void);
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||
/**
|
||||
* dm_remove_devices_flags - Call remove function of all drivers with
|
||||
* specific removal flags set to selectively
|
||||
* remove drivers
|
||||
*
|
||||
* All devices with the matching flags set will be removed
|
||||
*
|
||||
* @flags: Flags for selective device removal
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_remove_devices_flags(uint flags);
|
||||
#else
|
||||
static inline int dm_remove_devices_flags(uint flags) { return 0; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,217 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2013 Google, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __DM_TEST_H
|
||||
#define __DM_TEST_H
|
||||
|
||||
#include <dm.h>
|
||||
#include <test/test.h>
|
||||
|
||||
/**
|
||||
* struct dm_test_cdata - configuration data for test instance
|
||||
*
|
||||
* @ping_add: Amonut to add each time we get a ping
|
||||
* @base: Base address of this device
|
||||
*/
|
||||
struct dm_test_pdata {
|
||||
int ping_add;
|
||||
uint32_t base;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct test_ops - Operations supported by the test device
|
||||
*
|
||||
* @ping: Ping operation
|
||||
* @dev: Device to operate on
|
||||
* @pingval: Value to ping the device with
|
||||
* @pingret: Returns resulting value from driver
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
struct test_ops {
|
||||
int (*ping)(struct udevice *dev, int pingval, int *pingret);
|
||||
};
|
||||
|
||||
/* Operations that our test driver supports */
|
||||
enum {
|
||||
DM_TEST_OP_BIND = 0,
|
||||
DM_TEST_OP_UNBIND,
|
||||
DM_TEST_OP_PROBE,
|
||||
DM_TEST_OP_REMOVE,
|
||||
|
||||
/* For uclass */
|
||||
DM_TEST_OP_POST_BIND,
|
||||
DM_TEST_OP_PRE_UNBIND,
|
||||
DM_TEST_OP_PRE_PROBE,
|
||||
DM_TEST_OP_POST_PROBE,
|
||||
DM_TEST_OP_PRE_REMOVE,
|
||||
DM_TEST_OP_INIT,
|
||||
DM_TEST_OP_DESTROY,
|
||||
|
||||
DM_TEST_OP_COUNT,
|
||||
};
|
||||
|
||||
/* Test driver types */
|
||||
enum {
|
||||
DM_TEST_TYPE_FIRST = 0,
|
||||
DM_TEST_TYPE_SECOND,
|
||||
};
|
||||
|
||||
/* The number added to the ping total on each probe */
|
||||
#define DM_TEST_START_TOTAL 5
|
||||
|
||||
/**
|
||||
* struct dm_test_priv - private data for the test devices
|
||||
*/
|
||||
struct dm_test_priv {
|
||||
int ping_total;
|
||||
int op_count[DM_TEST_OP_COUNT];
|
||||
int uclass_flag;
|
||||
int uclass_total;
|
||||
int uclass_postp;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dm_test_perdev_class_priv - private per-device data for test uclass
|
||||
*/
|
||||
struct dm_test_uclass_perdev_priv {
|
||||
int base_add;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dm_test_uclass_priv - private data for test uclass
|
||||
*/
|
||||
struct dm_test_uclass_priv {
|
||||
int total_add;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dm_test_parent_data - parent's information on each child
|
||||
*
|
||||
* @sum: Test value used to check parent data works correctly
|
||||
* @flag: Used to track calling of parent operations
|
||||
* @uclass_flag: Used to track calling of parent operations by uclass
|
||||
*/
|
||||
struct dm_test_parent_data {
|
||||
int sum;
|
||||
int flag;
|
||||
};
|
||||
|
||||
/* Test values for test device's uclass platform data */
|
||||
enum {
|
||||
TEST_UC_PDATA_INTVAL1 = 2,
|
||||
TEST_UC_PDATA_INTVAL2 = 334,
|
||||
TEST_UC_PDATA_INTVAL3 = 789452,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dm_test_uclass_platda - uclass's information on each device
|
||||
*
|
||||
* @intval1: set to TEST_UC_PDATA_INTVAL1 in .post_bind method of test uclass
|
||||
* @intval2: set to TEST_UC_PDATA_INTVAL2 in .post_bind method of test uclass
|
||||
* @intval3: set to TEST_UC_PDATA_INTVAL3 in .post_bind method of test uclass
|
||||
*/
|
||||
struct dm_test_perdev_uc_pdata {
|
||||
int intval1;
|
||||
int intval2;
|
||||
int intval3;
|
||||
};
|
||||
|
||||
/*
|
||||
* Operation counts for the test driver, used to check that each method is
|
||||
* called correctly
|
||||
*/
|
||||
extern int dm_testdrv_op_count[DM_TEST_OP_COUNT];
|
||||
|
||||
extern struct unit_test_state global_dm_test_state;
|
||||
|
||||
/*
|
||||
* struct dm_test_state - Entire state of dm test system
|
||||
*
|
||||
* This is often abreviated to dms.
|
||||
*
|
||||
* @root: Root device
|
||||
* @testdev: Test device
|
||||
* @force_fail_alloc: Force all memory allocs to fail
|
||||
* @skip_post_probe: Skip uclass post-probe processing
|
||||
* @removed: Used to keep track of a device that was removed
|
||||
*/
|
||||
struct dm_test_state {
|
||||
struct udevice *root;
|
||||
struct udevice *testdev;
|
||||
int force_fail_alloc;
|
||||
int skip_post_probe;
|
||||
struct udevice *removed;
|
||||
};
|
||||
|
||||
/* Test flags for each test */
|
||||
enum {
|
||||
DM_TESTF_SCAN_PDATA = 1 << 0, /* test needs platform data */
|
||||
DM_TESTF_PROBE_TEST = 1 << 1, /* probe test uclass */
|
||||
DM_TESTF_SCAN_FDT = 1 << 2, /* scan device tree */
|
||||
DM_TESTF_FLAT_TREE = 1 << 3, /* test needs flat DT */
|
||||
DM_TESTF_LIVE_TREE = 1 << 4, /* needs live device tree */
|
||||
};
|
||||
|
||||
/* Declare a new driver model test */
|
||||
#define DM_TEST(_name, _flags) UNIT_TEST(_name, _flags, dm_test)
|
||||
|
||||
/* This platform data is needed in tests, so declare it here */
|
||||
struct sandbox_sdl_plat {
|
||||
int xres;
|
||||
int yres;
|
||||
int bpix;
|
||||
int rot;
|
||||
const char *vidconsole_drv_name;
|
||||
int font_size;
|
||||
};
|
||||
|
||||
/* Declare ping methods for the drivers */
|
||||
int test_ping(struct udevice *dev, int pingval, int *pingret);
|
||||
int testfdt_ping(struct udevice *dev, int pingval, int *pingret);
|
||||
|
||||
/**
|
||||
* dm_check_operations() - Check that we can perform ping operations
|
||||
*
|
||||
* This checks that the ping operations work as expected for a device
|
||||
*
|
||||
* @dms: Overall test state
|
||||
* @dev: Device to test
|
||||
* @base: Base address, used to check ping return value
|
||||
* @priv: Pointer to private test information
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_check_operations(struct unit_test_state *uts, struct udevice *dev,
|
||||
uint32_t base, struct dm_test_priv *priv);
|
||||
|
||||
/**
|
||||
* dm_check_devices() - check the devices respond to operations correctly
|
||||
*
|
||||
* @dms: Overall test state
|
||||
* @num_devices: Number of test devices to check
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_check_devices(struct unit_test_state *uts, int num_devices);
|
||||
|
||||
/**
|
||||
* dm_leak_check_start() - Prepare to check for a memory leak
|
||||
*
|
||||
* Call this before allocating memory to record the amount of memory being
|
||||
* used.
|
||||
*
|
||||
* @dms: Overall test state
|
||||
*/
|
||||
void dm_leak_check_start(struct unit_test_state *uts);
|
||||
|
||||
/**
|
||||
* dm_leak_check_end() - Check that no memory has leaked
|
||||
*
|
||||
* Call this after dm_leak_check_start() and after you have hopefuilly freed
|
||||
* all the memory that was allocated. This function will print an error if
|
||||
* it sees a different amount of total memory allocated than before.
|
||||
*
|
||||
* @dms: Overall test state
|
||||
*/int dm_leak_check_end(struct unit_test_state *uts);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,123 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2013 Google, Inc
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _DM_UCLASS_ID_H
|
||||
#define _DM_UCLASS_ID_H
|
||||
|
||||
/* TODO(sjg@chromium.org): this could be compile-time generated */
|
||||
enum uclass_id {
|
||||
/* These are used internally by driver model */
|
||||
UCLASS_ROOT = 0,
|
||||
UCLASS_DEMO,
|
||||
UCLASS_TEST,
|
||||
UCLASS_TEST_FDT,
|
||||
UCLASS_TEST_BUS,
|
||||
UCLASS_TEST_PROBE,
|
||||
UCLASS_TEST_DUMMY,
|
||||
UCLASS_SPI_EMUL, /* sandbox SPI device emulator */
|
||||
UCLASS_I2C_EMUL, /* sandbox I2C device emulator */
|
||||
UCLASS_I2C_EMUL_PARENT, /* parent for I2C device emulators */
|
||||
UCLASS_PCI_EMUL, /* sandbox PCI device emulator */
|
||||
UCLASS_PCI_EMUL_PARENT, /* parent for PCI device emulators */
|
||||
UCLASS_USB_EMUL, /* sandbox USB bus device emulator */
|
||||
UCLASS_AXI_EMUL, /* sandbox AXI bus device emulator */
|
||||
|
||||
/* U-Boot uclasses start here - in alphabetical order */
|
||||
UCLASS_ADC, /* Analog-to-digital converter */
|
||||
UCLASS_AHCI, /* SATA disk controller */
|
||||
UCLASS_AUDIO_CODEC, /* Audio codec with control and data path */
|
||||
UCLASS_AXI, /* AXI bus */
|
||||
UCLASS_BLK, /* Block device */
|
||||
UCLASS_BOARD, /* Device information from hardware */
|
||||
UCLASS_BOOTCOUNT, /* Bootcount backing store */
|
||||
UCLASS_CACHE, /* Cache controller */
|
||||
UCLASS_CLK, /* Clock source, e.g. used by peripherals */
|
||||
UCLASS_CPU, /* CPU, typically part of an SoC */
|
||||
UCLASS_CROS_EC, /* Chrome OS EC */
|
||||
UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */
|
||||
UCLASS_DSI_HOST, /* Display Serial Interface host */
|
||||
UCLASS_DMA, /* Direct Memory Access */
|
||||
UCLASS_EFI, /* EFI managed devices */
|
||||
UCLASS_ETH, /* Ethernet device */
|
||||
UCLASS_FIRMWARE, /* Firmware */
|
||||
UCLASS_FS_FIRMWARE_LOADER, /* Generic loader */
|
||||
UCLASS_GPIO, /* Bank of general-purpose I/O pins */
|
||||
UCLASS_HWSPINLOCK, /* Hardware semaphores */
|
||||
UCLASS_I2C, /* I2C bus */
|
||||
UCLASS_I2C_EEPROM, /* I2C EEPROM device */
|
||||
UCLASS_I2C_GENERIC, /* Generic I2C device */
|
||||
UCLASS_I2C_MUX, /* I2C multiplexer */
|
||||
UCLASS_I2S, /* I2S bus */
|
||||
UCLASS_IDE, /* IDE device */
|
||||
UCLASS_IRQ, /* Interrupt controller */
|
||||
UCLASS_KEYBOARD, /* Keyboard input device */
|
||||
UCLASS_LED, /* Light-emitting diode (LED) */
|
||||
UCLASS_LPC, /* x86 'low pin count' interface */
|
||||
UCLASS_MAILBOX, /* Mailbox controller */
|
||||
UCLASS_MASS_STORAGE, /* Mass storage device */
|
||||
UCLASS_MDIO, /* MDIO bus */
|
||||
UCLASS_MDIO_MUX, /* MDIO MUX/switch */
|
||||
UCLASS_MISC, /* Miscellaneous device */
|
||||
UCLASS_MMC, /* SD / MMC card or chip */
|
||||
UCLASS_MOD_EXP, /* RSA Mod Exp device */
|
||||
UCLASS_MTD, /* Memory Technology Device (MTD) device */
|
||||
UCLASS_NOP, /* No-op devices */
|
||||
UCLASS_NORTHBRIDGE, /* Intel Northbridge / SDRAM controller */
|
||||
UCLASS_NVME, /* NVM Express device */
|
||||
UCLASS_PANEL, /* Display panel, such as an LCD */
|
||||
UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */
|
||||
UCLASS_PCH, /* x86 platform controller hub */
|
||||
UCLASS_PCI, /* PCI bus */
|
||||
UCLASS_PCI_EP, /* PCI endpoint device */
|
||||
UCLASS_PCI_GENERIC, /* Generic PCI bus device */
|
||||
UCLASS_PHY, /* Physical Layer (PHY) device */
|
||||
UCLASS_PINCONFIG, /* Pin configuration node device */
|
||||
UCLASS_PINCTRL, /* Pinctrl (pin muxing/configuration) device */
|
||||
UCLASS_PMIC, /* PMIC I/O device */
|
||||
UCLASS_POWER_DOMAIN, /* (SoC) Power domains */
|
||||
UCLASS_PWM, /* Pulse-width modulator */
|
||||
UCLASS_PWRSEQ, /* Power sequence device */
|
||||
UCLASS_RAM, /* RAM controller */
|
||||
UCLASS_REGULATOR, /* Regulator device */
|
||||
UCLASS_REMOTEPROC, /* Remote Processor device */
|
||||
UCLASS_RESET, /* Reset controller device */
|
||||
UCLASS_RTC, /* Real time clock device */
|
||||
UCLASS_SCSI, /* SCSI device */
|
||||
UCLASS_SERIAL, /* Serial UART */
|
||||
UCLASS_SIMPLE_BUS, /* Bus with child devices */
|
||||
UCLASS_SMEM, /* Shared memory interface */
|
||||
UCLASS_SOUND, /* Playing simple sounds */
|
||||
UCLASS_SPI, /* SPI bus */
|
||||
UCLASS_SPI_FLASH, /* SPI flash */
|
||||
UCLASS_SPI_GENERIC, /* Generic SPI flash target */
|
||||
UCLASS_SPMI, /* System Power Management Interface bus */
|
||||
UCLASS_SYSCON, /* System configuration device */
|
||||
UCLASS_SYSRESET, /* System reset device */
|
||||
UCLASS_TEE, /* Trusted Execution Environment device */
|
||||
UCLASS_THERMAL, /* Thermal sensor */
|
||||
UCLASS_TIMER, /* Timer device */
|
||||
UCLASS_TPM, /* Trusted Platform Module TIS interface */
|
||||
UCLASS_UFS, /* Universal Flash Storage */
|
||||
UCLASS_USB, /* USB bus */
|
||||
UCLASS_USB_DEV_GENERIC, /* USB generic device */
|
||||
UCLASS_USB_HUB, /* USB hub */
|
||||
UCLASS_USB_GADGET_GENERIC, /* USB generic device */
|
||||
UCLASS_VIDEO, /* Video or LCD device */
|
||||
UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */
|
||||
UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */
|
||||
UCLASS_VIDEO_OSD, /* On-screen display */
|
||||
UCLASS_VIRTIO, /* VirtIO transport device */
|
||||
UCLASS_W1, /* Dallas 1-Wire bus */
|
||||
UCLASS_W1_EEPROM, /* one-wire EEPROMs */
|
||||
UCLASS_WDT, /* Watchdog Timer driver */
|
||||
|
||||
UCLASS_COUNT,
|
||||
UCLASS_INVALID = -1,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,254 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2013 Google, Inc
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _DM_UCLASS_INTERNAL_H
|
||||
#define _DM_UCLASS_INTERNAL_H
|
||||
|
||||
#include <dm/ofnode.h>
|
||||
|
||||
/**
|
||||
* uclass_find_next_free_req_seq() - Get the next free req_seq number
|
||||
*
|
||||
* This returns the next free req_seq number. This is useful only if
|
||||
* OF_CONTROL is not used. The next free req_seq number is simply the
|
||||
* maximum req_seq of the uclass + 1.
|
||||
* This allows assiging req_seq number in the binding order.
|
||||
*
|
||||
* @id: Id number of the uclass
|
||||
* @return The next free req_seq number
|
||||
*/
|
||||
int uclass_find_next_free_req_seq(enum uclass_id id);
|
||||
|
||||
/**
|
||||
* uclass_get_device_tail() - handle the end of a get_device call
|
||||
*
|
||||
* This handles returning an error or probing a device as needed.
|
||||
*
|
||||
* @dev: Device that needs to be probed
|
||||
* @ret: Error to return. If non-zero then the device is not probed
|
||||
* @devp: Returns the value of 'dev' if there is no error
|
||||
* @return ret, if non-zero, else the result of the device_probe() call
|
||||
*/
|
||||
int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* dev_get_uclass_index() - Get uclass and index of device
|
||||
* @dev: - in - Device that we want the uclass/index of
|
||||
* @ucp: - out - A pointer to the uclass the device belongs to
|
||||
*
|
||||
* The device is not prepared for use - this is an internal function.
|
||||
*
|
||||
* @return the index of the device in the uclass list or -ENODEV if not found.
|
||||
*/
|
||||
int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp);
|
||||
|
||||
/**
|
||||
* uclass_find_device() - Return n-th child of uclass
|
||||
* @id: Id number of the uclass
|
||||
* @index: Position of the child in uclass's list
|
||||
* #devp: Returns pointer to device, or NULL on error
|
||||
*
|
||||
* The device is not prepared for use - this is an internal function.
|
||||
* The function uclass_get_device_tail() can be used to probe the device.
|
||||
*
|
||||
* @return the uclass pointer of a child at the given index or
|
||||
* return NULL on error.
|
||||
*/
|
||||
int uclass_find_device(enum uclass_id id, int index, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_first_device() - Return the first device in a uclass
|
||||
* @id: Id number of the uclass
|
||||
* #devp: Returns pointer to device, or NULL on error
|
||||
*
|
||||
* The device is not prepared for use - this is an internal function.
|
||||
* The function uclass_get_device_tail() can be used to probe the device.
|
||||
*
|
||||
* @return 0 if OK (found or not found), -ve on error
|
||||
*/
|
||||
int uclass_find_first_device(enum uclass_id id, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_next_device() - Return the next device in a uclass
|
||||
* @devp: On entry, pointer to device to lookup. On exit, returns pointer
|
||||
* to the next device in the same uclass, or NULL if none
|
||||
*
|
||||
* The device is not prepared for use - this is an internal function.
|
||||
* The function uclass_get_device_tail() can be used to probe the device.
|
||||
*
|
||||
* @return 0 if OK (found or not found), -ve on error
|
||||
*/
|
||||
int uclass_find_next_device(struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_device_by_name() - Find uclass device based on ID and name
|
||||
*
|
||||
* This searches for a device with the exactly given name.
|
||||
*
|
||||
* The device is NOT probed, it is merely returned.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @name: name of a device to find
|
||||
* @devp: Returns pointer to device (the first one with the name)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_find_device_by_name(enum uclass_id id, const char *name,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_device_by_seq() - Find uclass device based on ID and sequence
|
||||
*
|
||||
* This searches for a device with the given seq or req_seq.
|
||||
*
|
||||
* For seq, if an active device has this sequence it will be returned.
|
||||
* If there is no such device then this will return -ENODEV.
|
||||
*
|
||||
* For req_seq, if a device (whether activated or not) has this req_seq
|
||||
* value, that device will be returned. This is a strong indication that
|
||||
* the device will receive that sequence when activated.
|
||||
*
|
||||
* The device is NOT probed, it is merely returned.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @seq_or_req_seq: Sequence number to find (0=first)
|
||||
* @find_req_seq: true to find req_seq, false to find seq
|
||||
* @devp: Returns pointer to device (there is only one per for each seq)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
|
||||
bool find_req_seq, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_device_by_of_offset() - Find a uclass device by device tree node
|
||||
*
|
||||
* This searches the devices in the uclass for one attached to the given
|
||||
* device tree node.
|
||||
*
|
||||
* The device is NOT probed, it is merely returned.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @node: Device tree offset to search for (if -ve then -ENODEV is returned)
|
||||
* @devp: Returns pointer to device (there is only one for each node)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_find_device_by_of_offset(enum uclass_id id, int node,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_device_by_of_node() - Find a uclass device by device tree node
|
||||
*
|
||||
* This searches the devices in the uclass for one attached to the given
|
||||
* device tree node.
|
||||
*
|
||||
* The device is NOT probed, it is merely returned.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @node: Device tree offset to search for (if NULL then -ENODEV is returned)
|
||||
* @devp: Returns pointer to device (there is only one for each node)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_device_by_phandle() - Find a uclass device by phandle
|
||||
*
|
||||
* This searches the devices in the uclass for one with the given phandle.
|
||||
*
|
||||
* The device is NOT probed, it is merely returned.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @parent: Parent device containing the phandle pointer
|
||||
* @name: Name of property in the parent device node
|
||||
* @devp: Returns pointer to device (there is only one for each node)
|
||||
* @return 0 if OK, -ENOENT if there is no @name present in the node, other
|
||||
* -ve on error
|
||||
*/
|
||||
int uclass_find_device_by_phandle(enum uclass_id id, struct udevice *parent,
|
||||
const char *name, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_bind_device() - Associate device with a uclass
|
||||
*
|
||||
* Connect the device into uclass's list of devices.
|
||||
*
|
||||
* @dev: Pointer to the device
|
||||
* #return 0 on success, -ve on error
|
||||
*/
|
||||
int uclass_bind_device(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* uclass_unbind_device() - Deassociate device with a uclass
|
||||
*
|
||||
* Disconnect the device from uclass's list of devices.
|
||||
*
|
||||
* @dev: Pointer to the device
|
||||
* #return 0 on success, -ve on error
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||
int uclass_unbind_device(struct udevice *dev);
|
||||
#else
|
||||
static inline int uclass_unbind_device(struct udevice *dev) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* uclass_pre_probe_device() - Deal with a device that is about to be probed
|
||||
*
|
||||
* Perform any pre-processing that is needed by the uclass before it can be
|
||||
* probed. This includes the uclass' pre-probe() method and the parent
|
||||
* uclass' child_pre_probe() method.
|
||||
*
|
||||
* @dev: Pointer to the device
|
||||
* #return 0 on success, -ve on error
|
||||
*/
|
||||
int uclass_pre_probe_device(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* uclass_post_probe_device() - Deal with a device that has just been probed
|
||||
*
|
||||
* Perform any post-processing of a probed device that is needed by the
|
||||
* uclass.
|
||||
*
|
||||
* @dev: Pointer to the device
|
||||
* #return 0 on success, -ve on error
|
||||
*/
|
||||
int uclass_post_probe_device(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* uclass_pre_remove_device() - Handle a device which is about to be removed
|
||||
*
|
||||
* Perform any pre-processing of a device that is about to be removed.
|
||||
*
|
||||
* @dev: Pointer to the device
|
||||
* #return 0 on success, -ve on error
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||
int uclass_pre_remove_device(struct udevice *dev);
|
||||
#else
|
||||
static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* uclass_find() - Find uclass by its id
|
||||
*
|
||||
* @id: Id to serach for
|
||||
* @return pointer to uclass, or NULL if not found
|
||||
*/
|
||||
struct uclass *uclass_find(enum uclass_id key);
|
||||
|
||||
/**
|
||||
* uclass_destroy() - Destroy a uclass
|
||||
*
|
||||
* Destroy a uclass and all its devices
|
||||
*
|
||||
* @uc: uclass to destroy
|
||||
* @return 0 on success, -ve on error
|
||||
*/
|
||||
int uclass_destroy(struct uclass *uc);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,412 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2013 Google, Inc
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _DM_UCLASS_H
|
||||
#define _DM_UCLASS_H
|
||||
|
||||
#include <dm/ofnode.h>
|
||||
#include <dm/uclass-id.h>
|
||||
#include <linker_lists.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
/**
|
||||
* struct uclass - a U-Boot drive class, collecting together similar drivers
|
||||
*
|
||||
* A uclass provides an interface to a particular function, which is
|
||||
* implemented by one or more drivers. Every driver belongs to a uclass even
|
||||
* if it is the only driver in that uclass. An example uclass is GPIO, which
|
||||
* provides the ability to change read inputs, set and clear outputs, etc.
|
||||
* There may be drivers for on-chip SoC GPIO banks, I2C GPIO expanders and
|
||||
* PMIC IO lines, all made available in a unified way through the uclass.
|
||||
*
|
||||
* @priv: Private data for this uclass
|
||||
* @uc_drv: The driver for the uclass itself, not to be confused with a
|
||||
* 'struct driver'
|
||||
* @dev_head: List of devices in this uclass (devices are attached to their
|
||||
* uclass when their bind method is called)
|
||||
* @sibling_node: Next uclass in the linked list of uclasses
|
||||
*/
|
||||
struct uclass {
|
||||
void *priv;
|
||||
struct uclass_driver *uc_drv;
|
||||
struct list_head dev_head;
|
||||
struct list_head sibling_node;
|
||||
};
|
||||
|
||||
struct driver;
|
||||
struct udevice;
|
||||
|
||||
/* Members of this uclass sequence themselves with aliases */
|
||||
#define DM_UC_FLAG_SEQ_ALIAS (1 << 0)
|
||||
|
||||
/* Same as DM_FLAG_ALLOC_PRIV_DMA */
|
||||
#define DM_UC_FLAG_ALLOC_PRIV_DMA (1 << 5)
|
||||
|
||||
/**
|
||||
* struct uclass_driver - Driver for the uclass
|
||||
*
|
||||
* A uclass_driver provides a consistent interface to a set of related
|
||||
* drivers.
|
||||
*
|
||||
* @name: Name of uclass driver
|
||||
* @id: ID number of this uclass
|
||||
* @post_bind: Called after a new device is bound to this uclass
|
||||
* @pre_unbind: Called before a device is unbound from this uclass
|
||||
* @pre_probe: Called before a new device is probed
|
||||
* @post_probe: Called after a new device is probed
|
||||
* @pre_remove: Called before a device is removed
|
||||
* @child_post_bind: Called after a child is bound to a device in this uclass
|
||||
* @child_pre_probe: Called before a child in this uclass is probed
|
||||
* @child_post_probe: Called after a child in this uclass is probed
|
||||
* @init: Called to set up the uclass
|
||||
* @destroy: Called to destroy the uclass
|
||||
* @priv_auto_alloc_size: If non-zero this is the size of the private data
|
||||
* to be allocated in the uclass's ->priv pointer. If zero, then the uclass
|
||||
* driver is responsible for allocating any data required.
|
||||
* @per_device_auto_alloc_size: Each device can hold private data owned
|
||||
* by the uclass. If required this will be automatically allocated if this
|
||||
* value is non-zero.
|
||||
* @per_device_platdata_auto_alloc_size: Each device can hold platform data
|
||||
* owned by the uclass as 'dev->uclass_platdata'. If the value is non-zero,
|
||||
* then this will be automatically allocated.
|
||||
* @per_child_auto_alloc_size: Each child device (of a parent in this
|
||||
* uclass) can hold parent data for the device/uclass. This value is only
|
||||
* used as a fallback if this member is 0 in the driver.
|
||||
* @per_child_platdata_auto_alloc_size: A bus likes to store information about
|
||||
* its children. If non-zero this is the size of this data, to be allocated
|
||||
* in the child device's parent_platdata pointer. This value is only used as
|
||||
* a fallback if this member is 0 in the driver.
|
||||
* @ops: Uclass operations, providing the consistent interface to devices
|
||||
* within the uclass.
|
||||
* @flags: Flags for this uclass (DM_UC_...)
|
||||
*/
|
||||
struct uclass_driver {
|
||||
const char *name;
|
||||
enum uclass_id id;
|
||||
int (*post_bind)(struct udevice *dev);
|
||||
int (*pre_unbind)(struct udevice *dev);
|
||||
int (*pre_probe)(struct udevice *dev);
|
||||
int (*post_probe)(struct udevice *dev);
|
||||
int (*pre_remove)(struct udevice *dev);
|
||||
int (*child_post_bind)(struct udevice *dev);
|
||||
int (*child_pre_probe)(struct udevice *dev);
|
||||
int (*child_post_probe)(struct udevice *dev);
|
||||
int (*init)(struct uclass *class);
|
||||
int (*destroy)(struct uclass *class);
|
||||
int priv_auto_alloc_size;
|
||||
int per_device_auto_alloc_size;
|
||||
int per_device_platdata_auto_alloc_size;
|
||||
int per_child_auto_alloc_size;
|
||||
int per_child_platdata_auto_alloc_size;
|
||||
const void *ops;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/* Declare a new uclass_driver */
|
||||
#define UCLASS_DRIVER(__name) \
|
||||
ll_entry_declare(struct uclass_driver, __name, uclass)
|
||||
|
||||
/**
|
||||
* uclass_get() - Get a uclass based on an ID, creating it if needed
|
||||
*
|
||||
* Every uclass is identified by an ID, a number from 0 to n-1 where n is
|
||||
* the number of uclasses. This function allows looking up a uclass by its
|
||||
* ID.
|
||||
*
|
||||
* @key: ID to look up
|
||||
* @ucp: Returns pointer to uclass (there is only one per ID)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_get(enum uclass_id key, struct uclass **ucp);
|
||||
|
||||
/**
|
||||
* uclass_get_name() - Get the name of a uclass driver
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @returns the name of the uclass driver for that ID, or NULL if none
|
||||
*/
|
||||
const char *uclass_get_name(enum uclass_id id);
|
||||
|
||||
/**
|
||||
* uclass_get_by_name() - Look up a uclass by its driver name
|
||||
*
|
||||
* @name: Name to look up
|
||||
* @returns the associated uclass ID, or UCLASS_INVALID if not found
|
||||
*/
|
||||
enum uclass_id uclass_get_by_name(const char *name);
|
||||
|
||||
/**
|
||||
* uclass_get_device() - Get a uclass device based on an ID and index
|
||||
*
|
||||
* The device is probed to activate it ready for use.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @index: Device number within that uclass (0=first)
|
||||
* @devp: Returns pointer to device (there is only one per for each ID)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_get_device(enum uclass_id id, int index, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_get_device_by_name() - Get a uclass device by its name
|
||||
*
|
||||
* This searches the devices in the uclass for one with the exactly given name.
|
||||
*
|
||||
* The device is probed to activate it ready for use.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @name: name of a device to get
|
||||
* @devp: Returns pointer to device (the first one with the name)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_get_device_by_name(enum uclass_id id, const char *name,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_get_device_by_seq() - Get a uclass device based on an ID and sequence
|
||||
*
|
||||
* If an active device has this sequence it will be returned. If there is no
|
||||
* such device then this will check for a device that is requesting this
|
||||
* sequence.
|
||||
*
|
||||
* The device is probed to activate it ready for use.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @seq: Sequence number to find (0=first)
|
||||
* @devp: Returns pointer to device (there is only one for each seq)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_get_device_by_of_offset() - Get a uclass device by device tree node
|
||||
*
|
||||
* This searches the devices in the uclass for one attached to the given
|
||||
* device tree node.
|
||||
*
|
||||
* The device is probed to activate it ready for use.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @node: Device tree offset to search for (if -ve then -ENODEV is returned)
|
||||
* @devp: Returns pointer to device (there is only one for each node)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_get_device_by_of_offset(enum uclass_id id, int node,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_get_device_by_ofnode() - Get a uclass device by device tree node
|
||||
*
|
||||
* This searches the devices in the uclass for one attached to the given
|
||||
* device tree node.
|
||||
*
|
||||
* The device is probed to activate it ready for use.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @np: Device tree node to search for (if NULL then -ENODEV is returned)
|
||||
* @devp: Returns pointer to device (there is only one for each node)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_get_device_by_phandle_id() - Get a uclass device by phandle id
|
||||
*
|
||||
* This searches the devices in the uclass for one with the given phandle id.
|
||||
*
|
||||
* The device is probed to activate it ready for use.
|
||||
*
|
||||
* @id: uclass ID to look up
|
||||
* @phandle_id: the phandle id to look up
|
||||
* @devp: Returns pointer to device (there is only one for each node)
|
||||
* @return 0 if OK, -ENODEV if there is no device match the phandle, other
|
||||
* -ve on error
|
||||
*/
|
||||
int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_get_device_by_phandle() - Get a uclass device by phandle
|
||||
*
|
||||
* This searches the devices in the uclass for one with the given phandle.
|
||||
*
|
||||
* The device is probed to activate it ready for use.
|
||||
*
|
||||
* @id: uclass ID to look up
|
||||
* @parent: Parent device containing the phandle pointer
|
||||
* @name: Name of property in the parent device node
|
||||
* @devp: Returns pointer to device (there is only one for each node)
|
||||
* @return 0 if OK, -ENOENT if there is no @name present in the node, other
|
||||
* -ve on error
|
||||
*/
|
||||
int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
|
||||
const char *name, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_get_device_by_driver() - Get a uclass device for a driver
|
||||
*
|
||||
* This searches the devices in the uclass for one that uses the given
|
||||
* driver. Use DM_GET_DRIVER(name) for the @drv argument, where 'name' is
|
||||
* the driver name - as used in U_BOOT_DRIVER(name).
|
||||
*
|
||||
* The device is probed to activate it ready for use.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @drv: Driver to look for
|
||||
* @devp: Returns pointer to the first device with that driver
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_first_device() - Get the first device in a uclass
|
||||
*
|
||||
* The device returned is probed if necessary, and ready for use
|
||||
*
|
||||
* This function is useful to start iterating through a list of devices which
|
||||
* are functioning correctly and can be probed.
|
||||
*
|
||||
* @id: Uclass ID to look up
|
||||
* @devp: Returns pointer to the first device in that uclass if no error
|
||||
* occurred, or NULL if there is no first device, or an error occurred with
|
||||
* that device.
|
||||
* @return 0 if OK (found or not found), other -ve on error
|
||||
*/
|
||||
int uclass_first_device(enum uclass_id id, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_first_device_err() - Get the first device in a uclass
|
||||
*
|
||||
* The device returned is probed if necessary, and ready for use
|
||||
*
|
||||
* @id: Uclass ID to look up
|
||||
* @devp: Returns pointer to the first device in that uclass, or NULL if none
|
||||
* @return 0 if found, -ENODEV if not found, other -ve on error
|
||||
*/
|
||||
int uclass_first_device_err(enum uclass_id id, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_next_device() - Get the next device in a uclass
|
||||
*
|
||||
* The device returned is probed if necessary, and ready for use
|
||||
*
|
||||
* This function is useful to iterate through a list of devices which
|
||||
* are functioning correctly and can be probed.
|
||||
*
|
||||
* @devp: On entry, pointer to device to lookup. On exit, returns pointer
|
||||
* to the next device in the uclass if no error occurred, or NULL if there is
|
||||
* no next device, or an error occurred with that next device.
|
||||
* @return 0 if OK (found or not found), other -ve on error
|
||||
*/
|
||||
int uclass_next_device(struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_next_device_err() - Get the next device in a uclass
|
||||
*
|
||||
* The device returned is probed if necessary, and ready for use
|
||||
*
|
||||
* @devp: On entry, pointer to device to lookup. On exit, returns pointer
|
||||
* to the next device in the uclass if no error occurred, or -ENODEV if
|
||||
* there is no next device.
|
||||
* @return 0 if found, -ENODEV if not found, other -ve on error
|
||||
*/
|
||||
int uclass_next_device_err(struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_first_device_check() - Get the first device in a uclass
|
||||
*
|
||||
* The device returned is probed if necessary, and ready for use
|
||||
*
|
||||
* This function is useful to start iterating through a list of devices which
|
||||
* are functioning correctly and can be probed.
|
||||
*
|
||||
* @id: Uclass ID to look up
|
||||
* @devp: Returns pointer to the first device in that uclass, or NULL if there
|
||||
* is no first device
|
||||
* @return 0 if OK (found or not found), other -ve on error. If an error occurs
|
||||
* it is still possible to move to the next device.
|
||||
*/
|
||||
int uclass_first_device_check(enum uclass_id id, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_next_device_check() - Get the next device in a uclass
|
||||
*
|
||||
* The device returned is probed if necessary, and ready for use
|
||||
*
|
||||
* This function is useful to start iterating through a list of devices which
|
||||
* are functioning correctly and can be probed.
|
||||
*
|
||||
* @devp: On entry, pointer to device to lookup. On exit, returns pointer
|
||||
* to the next device in the uclass if any
|
||||
* @return 0 if OK (found or not found), other -ve on error. If an error occurs
|
||||
* it is still possible to move to the next device.
|
||||
*/
|
||||
int uclass_next_device_check(struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_resolve_seq() - Resolve a device's sequence number
|
||||
*
|
||||
* On entry dev->seq is -1, and dev->req_seq may be -1 (to allocate a
|
||||
* sequence number automatically, or >= 0 to select a particular number.
|
||||
* If the requested sequence number is in use, then this device will
|
||||
* be allocated another one.
|
||||
*
|
||||
* Note that the device's seq value is not changed by this function.
|
||||
*
|
||||
* @dev: Device for which to allocate sequence number
|
||||
* @return sequence number allocated, or -ve on error
|
||||
*/
|
||||
int uclass_resolve_seq(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* uclass_foreach_dev() - Helper function to iteration through devices
|
||||
*
|
||||
* This creates a for() loop which works through the available devices in
|
||||
* a uclass in order from start to end.
|
||||
*
|
||||
* @pos: struct udevice * to hold the current device. Set to NULL when there
|
||||
* are no more devices.
|
||||
* @uc: uclass to scan
|
||||
*/
|
||||
#define uclass_foreach_dev(pos, uc) \
|
||||
list_for_each_entry(pos, &uc->dev_head, uclass_node)
|
||||
|
||||
/**
|
||||
* uclass_foreach_dev_safe() - Helper function to safely iteration through devs
|
||||
*
|
||||
* This creates a for() loop which works through the available devices in
|
||||
* a uclass in order from start to end. Inside the loop, it is safe to remove
|
||||
* @pos if required.
|
||||
*
|
||||
* @pos: struct udevice * to hold the current device. Set to NULL when there
|
||||
* are no more devices.
|
||||
* @next: struct udevice * to hold the next next
|
||||
* @uc: uclass to scan
|
||||
*/
|
||||
#define uclass_foreach_dev_safe(pos, next, uc) \
|
||||
list_for_each_entry_safe(pos, next, &uc->dev_head, uclass_node)
|
||||
|
||||
/**
|
||||
* uclass_foreach_dev_probe() - Helper function to iteration through devices
|
||||
* of given uclass
|
||||
*
|
||||
* This creates a for() loop which works through the available devices in
|
||||
* a uclass in order from start to end. Devices are probed if necessary,
|
||||
* and ready for use.
|
||||
*
|
||||
* @id: Uclass ID
|
||||
* @dev: struct udevice * to hold the current device. Set to NULL when there
|
||||
* are no more devices.
|
||||
*/
|
||||
#define uclass_foreach_dev_probe(id, dev) \
|
||||
for (int _ret = uclass_first_device_err(id, &dev); !_ret && dev; \
|
||||
_ret = uclass_next_device_err(&dev))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2013 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef __DM_UTIL_H
|
||||
#define __DM_UTIL_H
|
||||
|
||||
#ifdef CONFIG_DM_WARN
|
||||
void dm_warn(const char *fmt, ...);
|
||||
#else
|
||||
static inline void dm_warn(const char *fmt, ...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
struct list_head;
|
||||
|
||||
/**
|
||||
* list_count_items() - Count number of items in a list
|
||||
*
|
||||
* @param head: Head of list
|
||||
* @return number of items, or 0 if empty
|
||||
*/
|
||||
int list_count_items(struct list_head *head);
|
||||
|
||||
/* Dump out a tree of all devices */
|
||||
void dm_dump_all(void);
|
||||
|
||||
/* Dump out a list of uclasses and their devices */
|
||||
void dm_dump_uclass(void);
|
||||
|
||||
#ifdef CONFIG_DEBUG_DEVRES
|
||||
/* Dump out a list of device resources */
|
||||
void dm_dump_devres(void);
|
||||
#else
|
||||
static inline void dm_dump_devres(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Check if an of node should be or was bound before relocation.
|
||||
*
|
||||
* Devicetree nodes can be marked as needed to be bound
|
||||
* in the loader stages via special devicetree properties.
|
||||
*
|
||||
* Before relocation this function can be used to check if nodes
|
||||
* are required in either SPL or TPL stages.
|
||||
*
|
||||
* After relocation and jumping into the real U-Boot binary
|
||||
* it is possible to determine if a node was bound in one of
|
||||
* SPL/TPL stages.
|
||||
*
|
||||
* There are 4 settings currently in use
|
||||
* - u-boot,dm-pre-proper: U-Boot proper pre-relocation only
|
||||
* - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL
|
||||
* Existing platforms only use it to indicate nodes needed in
|
||||
* SPL. Should probably be replaced by u-boot,dm-spl for
|
||||
* existing platforms.
|
||||
* - u-boot,dm-spl: SPL and U-Boot pre-relocation
|
||||
* - u-boot,dm-tpl: TPL and U-Boot pre-relocation
|
||||
* @node: of node
|
||||
*
|
||||
* Returns true if node is needed in SPL/TL, false otherwise.
|
||||
*/
|
||||
bool dm_ofnode_pre_reloc(ofnode node);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user